Skip to content

Commit

Permalink
Decode
Browse files Browse the repository at this point in the history
Fixes in orbuculum decode files for instruction tracing.
  • Loading branch information
Lukas committed Oct 24, 2024
1 parent 81b64da commit ac9514e
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 54 deletions.
5 changes: 3 additions & 2 deletions Inc/loadelf.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#ifndef _LOADELF_H_
#define _LOADELF_H_

#include <stdbool.h>
#include <capstone/capstone.h>
Expand Down Expand Up @@ -88,7 +89,7 @@ struct symbol
csh caphandle;
};

enum instructionClass { LE_IC_NONE, LE_IC_JUMP = ( 1 << 0 ), LE_IC_4BYTE = ( 1 << 1 ), LE_IC_CALL = ( 1 << 2 ), LE_IC_IMMEDIATE = ( 1 << 3 ), LE_IC_IRET = ( 1 << 4 ) };
enum instructionClass { LE_IC_NONE, LE_IC_JUMP = ( 1 << 0 ), LE_IC_4BYTE = ( 1 << 1 ), LE_IC_CALL = ( 1 << 2 ), LE_IC_IMMEDIATE = ( 1 << 3 ), LE_IC_IRET = ( 1 << 4 ), LE_IC_SYNC_BARRIER = ( 1 << 5 ), LE_IC_COPROCESSOR = ( 1 << 6 )};

// ====================================================================================================

Expand Down Expand Up @@ -120,7 +121,7 @@ const char *symbolGetFilename( struct symbol *p, unsigned int index );
symbolMemptr symbolCodeAt( struct symbol *p, symbolMemaddr addr, unsigned int *len );

/* Return assembly code representing this line, with annotations */
char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbolMemaddr addr, symbolMemaddr *newaddr );
char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbolMemaddr addr, symbolMemaddr *newaddr);

/* Delete symbol set */
void symbolDelete( struct symbol *p );
Expand Down
7 changes: 6 additions & 1 deletion Inc/traceDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ enum TRACEchanges
EV_CH_VMID,
EV_CH_TSTAMP,
EV_CH_CYCLECOUNT,
EV_CH_ASYNC,
EV_CH_CONTEXTID,
EV_CH_TRIGGER,
EV_CH_SECURE,
Expand Down Expand Up @@ -143,6 +144,10 @@ struct TRACECPUState

// Convinience, for debug reporting
genericsReportCB report;

// Debugging
uint64_t overflows;
uint64_t ASyncs;
};

// ============================================================================
Expand All @@ -163,7 +168,7 @@ struct TRACEDecoderEngine
const char ( *name ) ( void );

/* Config specific to ETM3.5 */
void ( *altAddrEncode ) ( struct TRACEDecoderEngine *e, bool using );
void ( *altAddrEncode ) ( struct TRACEDecoderEngine *e, bool _using );
};

struct TRACEDecoder
Expand Down
84 changes: 54 additions & 30 deletions Src/loadelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ static void _processFunctionDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die di

Dwarf_Attribute attr_data;
Dwarf_Half attr_tag;
Dwarf_Die name_die = die;
bool isinline = false;
struct symbolFunctionStore *newFunc;

Expand All @@ -369,15 +370,16 @@ static void _processFunctionDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die di
attr_tag = DW_AT_abstract_origin;
dwarf_attr( die, attr_tag, &attr_data, 0 );
dwarf_global_formref( attr_data, &abstract_origin_offset, 0 );
dwarf_offdie_b( dbg, abstract_origin_offset, IS_INFO, &abstract_origin_die, 0 );
isinline = true;
}
else
{
dwarf_highpc_b ( die, &h, 0, &formclass, 0 );
dwarf_lowpc ( die, &l, 0 );
if (DW_DLV_OK == dwarf_offdie_b( dbg, abstract_origin_offset, IS_INFO, &abstract_origin_die, 0 ))
{
isinline = true;
name_die = abstract_origin_die;
}
}

dwarf_highpc_b ( die, &h, 0, &formclass, 0 );
dwarf_lowpc ( die, &l, 0 );

if ( formclass == DW_FORM_CLASS_CONSTANT )
{
h += l;
Expand All @@ -391,14 +393,14 @@ static void _processFunctionDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die di
dwarf_formstring( attr_data, &manglename, 0 );
}

if ( DW_DLV_OK != dwarf_diename( die, &name, 0 ) )
if ( DW_DLV_OK != dwarf_diename( name_die, &name, 0 ) )
{
/* Name will be hidden in a specification reference */
attr_tag = DW_AT_specification;

if ( dwarf_attr( die, attr_tag, &attr_data, 0 ) == DW_DLV_OK )
if ( dwarf_attr( name_die, attr_tag, &attr_data, 0 ) == DW_DLV_OK )
{
dwarf_attr( die, attr_tag, &attr_data, 0 );
dwarf_attr( name_die, attr_tag, &attr_data, 0 );

if ( DW_DLV_OK == dwarf_global_formref( attr_data, &specification_offset, 0 ) )
{
Expand Down Expand Up @@ -449,14 +451,20 @@ static void _processFunctionDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die di

// ====================================================================================================

static void _processDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die die, int level, int filenameN, int producerN, Dwarf_Addr cu_base_addr )
static void _processDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die die, int level, int filenameN,char *name, int producerN, Dwarf_Addr cu_base_addr )

{
Dwarf_Half tag;
Dwarf_Die child;

Dwarf_Die sib = die;

// arm_exception is filename and funcname handle this
if ( strstr( name, "arm_exception" ) )
{
_processFunctionDie(p,dbg,sib,filenameN,producerN,cu_base_addr);
}

while ( DW_DLV_OK == dwarf_siblingof_b( dbg, sib, IS_INFO, &sib, 0 ) )
{
dwarf_tag( sib, &tag, 0 );
Expand All @@ -471,7 +479,7 @@ static void _processDie( struct symbol *p, Dwarf_Debug dbg, Dwarf_Die die, int l

if ( DW_DLV_OK == dwarf_child( die, &child, 0 ) )
{
_processDie( p, dbg, child, level + 1, filenameN, producerN, cu_base_addr );
_processDie( p, dbg, child, level + 1, filenameN,name, producerN, cu_base_addr );
dwarf_dealloc( dbg, child, DW_DLA_DIE );
}
}
Expand Down Expand Up @@ -535,6 +543,10 @@ static bool _readLines( struct symbol *p )
unsigned int filenameN;
unsigned int producerN;

Dwarf_Addr h = 0;
Dwarf_Addr l = 0;
enum Dwarf_Form_Class formclass = DW_FORM_CLASS_UNKNOWN;

if ( 0 != dwarf_init_b( p->fd, DW_GROUPNUMBER_ANY, NULL, NULL, &dbg, &err ) )
{
return false;
Expand Down Expand Up @@ -576,6 +588,7 @@ static bool _readLines( struct symbol *p )
dwarf_siblingof_b( dbg, NULL, IS_INFO, &cu_die, 0 );

dwarf_diename( cu_die, &name, 0 );

dwarf_die_text( cu_die, DW_AT_producer, &producer, 0 );
dwarf_die_text( cu_die, DW_AT_comp_dir, &compdir, 0 );

Expand All @@ -588,7 +601,7 @@ static bool _readLines( struct symbol *p )
/* Kickoff the process for the DIE and its children to get the functions in this cu */

dwarf_lowpc( cu_die, &cu_low_addr, 0 );
_processDie( p, dbg, cu_die, 0, filenameN, producerN, cu_low_addr );
_processDie( p, dbg, cu_die, 0, filenameN, name, producerN, cu_low_addr );

/* ...and the source lines */
_getSourceLines( p, dbg, cu_die );
Expand Down Expand Up @@ -975,11 +988,9 @@ void symbolDelete( struct symbol *p )
}

// ====================================================================================================

char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbolMemaddr addr, symbolMemaddr *newaddr )
char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbolMemaddr addr, symbolMemaddr *newaddr)

/* Return assembly code representing this line */

{
cs_insn *insn;
size_t count;
Expand All @@ -995,7 +1006,7 @@ char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbol
if ( !p->caphandle )
{
/* Disassembler isn't initialised yet */
if ( cs_open( CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &p->caphandle ) != CS_ERR_OK )
if ( cs_open( CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN + CS_MODE_MCLASS, &p->caphandle ) != CS_ERR_OK )
{
return NULL;
}
Expand All @@ -1011,10 +1022,10 @@ char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbol
return NULL;
}

// This line disassembles the code with the handler initialised above
count = cs_disasm( p->caphandle, m, 4, addr, 0, &insn );
*ic = LE_IC_NONE;


if ( count > 0 )
{
/* Characterise the instruction using rules from F1.3 of ARM IHI0064H.a */
Expand All @@ -1026,18 +1037,30 @@ char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbol
*ic |= ( ( insn->id == ARM_INS_BL ) || ( insn->id == ARM_INS_BLX ) ) ? LE_IC_JUMP | LE_IC_CALL : 0;

/* Was it a regular call? */
*ic |= ( ( insn->id == ARM_INS_B ) || ( insn->id == ARM_INS_BX ) || ( insn->id == ARM_INS_ISB ) ||
*ic |= ( ( insn->id == ARM_INS_B ) || ( insn->id == ARM_INS_BX ) ||
( insn->id == ARM_INS_WFI ) || ( insn->id == ARM_INS_WFE ) || ( insn->id == ARM_INS_TBB ) ||
( insn->id == ARM_INS_TBH ) || ( insn->id == ARM_INS_BXJ ) || ( insn->id == ARM_INS_CBZ ) ||
( insn->id == ARM_INS_CBNZ ) || ( insn->id == ARM_INS_WFI ) || ( insn->id == ARM_INS_WFE )
) ? LE_IC_JUMP : 0;

*ic |= (
( ( ( insn->id == ARM_INS_SUB ) || ( insn->id == ARM_INS_MOV ) ||
( insn->id == ARM_INS_LDM ) || ( insn->id == ARM_INS_POP ) )
( insn->id == ARM_INS_LDM ) || ( insn->id == ARM_INS_POP ) ||
( insn->id == ARM_INS_ISB ) || ( insn->id == ARM_INS_ORR ) )
&& strstr( insn->op_str, "pc" ) )
) ? LE_IC_JUMP : 0;
*ic |= (
( ( insn->id == ARM_INS_ISB ) && strstr( insn->op_str, "sy" ) )
) ? LE_IC_SYNC_BARRIER : 0;
*ic |= (insn->id == ARM_INS_STC2L) ? LE_IC_COPROCESSOR : 0;

/* create a copy to check if load in pc */
char *copy = strdup(insn->op_str);
*ic |= (
( ( ( insn->id == ARM_INS_LDR ) )
&& strstr(strtok(copy,","), "pc" ) )
) ? LE_IC_JUMP : 0;
/* free the copy */
free(copy);
/* Was it an exception return? */
*ic |= ( ( insn->id == ARM_INS_ERET ) ) ? LE_IC_JUMP | LE_IC_IRET : 0;

Expand All @@ -1057,19 +1080,21 @@ char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbol

if ( detail->arm.op_count )
{

for ( int n = 0; n < insn->detail->arm.op_count; n++ )
{
if ( insn->detail->arm.operands[n].type == ARM_OP_IMM )
if (n<2)
{
*ic |= LE_IC_IMMEDIATE;

if ( newaddr )
if ( insn->detail->arm.operands[n].type == ARM_OP_IMM )
{
*newaddr = detail->arm.operands[0].imm;
}
*ic |= LE_IC_IMMEDIATE;

break;
if ( newaddr )
{
*newaddr = detail->arm.operands[n].imm;
}

break;
}
}
}
}
Expand All @@ -1087,7 +1112,6 @@ char *symbolDisassembleLine( struct symbol *p, enum instructionClass *ic, symbol
}

cs_free( insn, count );

return op;
}

Expand Down
Loading

0 comments on commit ac9514e

Please sign in to comment.