testdump.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,165 行 · 第 1/3 页
C
1,165 行
uint_32 result;
uint shift;
uint_8 byte;
result = 0;
shift = 0;
for(;;) {
byte = *input++;
result |= ( byte & 0x7f ) << shift;
if( ( byte & 0x80 ) == 0 ) break;
shift += 7;
}
*value = result;
return( (uint_8 *)input );
}
uint_8 *DecodeLEB128( const uint_8 *input, int_32 *value ) {
int_32 result;
uint shift;
uint_8 byte;
result = 0;
shift = 0;
for(;;) {
byte = *input++;
result |= ( byte & 0x7f ) << shift;
shift += 7;
if( ( byte & 0x80 ) == 0 ) break;
}
if( ( shift < 32 ) && ( byte & 0x40 ) ) {
result |= - ( 1 << shift );
}
*value = result;
return( (uint_8 *)input );
}
uint_8 *findAbbrev( uint_32 code, uint_32 start ) {
uint_8 *p;
uint_8 *stop;
uint_32 tmp;
uint_32 attr;
p = Sections[ DW_DEBUG_ABBREV ].data + start;
stop = p + Sections[ DW_DEBUG_ABBREV ].max_offset;
for(;;) {
if( p >= stop ) return( NULL );
p = DecodeULEB128( p, &tmp );
if( tmp == code ) return( p );
if( p >= stop ) return( NULL );
p = DecodeULEB128( p, &tmp );
if( p >= stop ) return( NULL );
p++;
for(;;) {
p = DecodeULEB128( p, &attr );
if( p >= stop ) return( NULL );
p = DecodeULEB128( p, &tmp );
if( p >= stop ) return( NULL );
if( attr == 0 ) break;
}
}
}
static void printf_debug_str( unsigned int offset )
{
if( offset > Sections[ DW_DEBUG_STR ].max_offset ) {
printf( "\tstring @ .debug_str+%u (invalid offset)\n",
offset );
} else {
printf( "\t\"%s\"\n", Sections[ DW_DEBUG_STR ].data + offset );
}
}
static void dumpInfo( const uint_8 *input, uint length ) {
const uint_8 *p;
uint_32 abbrev_code;
uint_32 abbrev_offset;
uint_8 * abbrev;
uint_32 tag;
uint_32 attr;
uint_32 form;
uint_32 len;
uint_32 tmp;
int_32 stmp;
uint_32 unit_length;
int address_size;
const uint_8 *unit_base;
p = input;
while( p - input < length ) {
unit_length = getU32( (uint_32 *)p );
unit_base = p + sizeof( uint_32 );
address_size = *(p+10);
abbrev_offset = getU32( (uint_32 *)(p+6) );
printf( "Length: %08lx\nVersion: %04lx\nAbbrev: %08lx\nAddress Size %02lx\n",
unit_length, getU16( (uint_16 *)(p+4) ), abbrev_offset, address_size );
p += 11;
while( p - unit_base < unit_length ) {
printf( "offset %08lx: ", p - input );
p = DecodeULEB128( p, &abbrev_code );
printf( "Code: %08lx\n", abbrev_code );
if( abbrev_code == 0 ) continue;
abbrev = findAbbrev( abbrev_code, abbrev_offset );
if( abbrev == NULL ) {
printf( "can't find abbreviation %08lx\n", abbrev_code );
break;
}
if( p >= input + length ) break;
abbrev = DecodeULEB128( abbrev, &tag );
printf( "\t%s\n", getTAG( tag ) );
abbrev++;
for(;;) {
abbrev = DecodeULEB128( abbrev, &attr );
abbrev = DecodeULEB128( abbrev, &form );
if( attr == 0 ) break;
printf( "\t%-20s", getAT( attr ) );
decode_form:
switch( form ) {
case DW_FORM_addr:
switch( address_size ) {
case 4:
tmp = getU32( (uint_32 *)p );
p += sizeof( uint_32 );
printf( "\t%08lx\n", tmp );
break;
case 2:
tmp = getU16( (uint_16 *)p );
p += sizeof( uint_16 );
printf( "\t%04lx\n", tmp );
break;
default:
printf( "Unknown address size\n" );
p += address_size;
break;
}
break;
case DW_FORM_block:
p = DecodeULEB128( p, &len );
printf( "\n" );
dumpHex( p, len );
p += len;
break;
case DW_FORM_block1:
len = *p++;
printf( "\n" );
dumpHex( p, len );
p += len;
break;
case DW_FORM_block2:
len = getU16( (uint_16 *)p );
p += sizeof( uint_16 );
printf( "\n" );
dumpHex( p, len );
p += len;
break;
case DW_FORM_block4:
len = getU32( (uint_32 *)p );
p += sizeof( uint_32 );
printf( "\n" );
dumpHex( p, len );
p += len;
break;
case DW_FORM_data1:
case DW_FORM_ref1:
printf( "\t%02x\n", *p++ );
break;
case DW_FORM_data2:
case DW_FORM_ref2:
printf( "\t%04x\n", getU16( (uint_16 *)p ) );
p += sizeof( uint_16 );
break;
case DW_FORM_data4:
case DW_FORM_ref4:
printf( "\t%08lx\n", getU32( (uint_32 *)p ) );
p += sizeof( uint_32 );
break;
case DW_FORM_flag:
printf( "\t%s\n", *p++ ? "True" : "False" );
break;
case DW_FORM_indirect:
p = DecodeULEB128( p, &form );
printf( "\t(%s)", getFORM( form ) );
goto decode_form;
case DW_FORM_sdata:
p = DecodeLEB128( p, &stmp );
printf( "\t%08lx\n", stmp );
break;
case DW_FORM_string:
printf( "\t\"%s\"\n", p );
p += strlen( p ) + 1;
break;
case DW_FORM_strp: /* 4 byte index into .debug_str */
printf_debug_str( getU32( (unsigned long *)p ) );
p += 4;
break;
case DW_FORM_udata:
case DW_FORM_ref_udata:
p = DecodeULEB128( p, &tmp );
printf( "\t%08lx\n", tmp );
break;
case DW_FORM_ref_addr: //KLUDGE should really check addr_size
printf( "\t%08lx\n", getU32( ((uint_32 *)p) ) );
p += sizeof(uint_32);
break;
default:
printf( "unknown form!\n" );
return;
}
}
}
}
}
extern void dumpAbbrevs( const char *input, uint length ) {
const uint_8 *p;
uint_32 tmp;
uint_32 attr;
if( (NULL == input) || (0 == length) )
return;
p = input;
for(;;) {
if( p > input + length ) break;
p = DecodeULEB128( p, &tmp );
printf( "Code: %08lx\n", tmp );
if( tmp == 0 ) continue;
if( p >= input + length ) break;
p = DecodeULEB128( p, &tmp );
printf( "\t%s\n", getTAG( tmp ) );
if( *p == DW_CHILDREN_yes ) {
printf( "has children\n" );
} else {
printf( "childless\n" );
}
p++;
for(;;) {
if( p > input + length ) break;
p = DecodeULEB128( p, &attr );
printf( "\t%-20s", getAT( attr ) );
if( p > input + length ) break;
p = DecodeULEB128( p, &tmp );
printf( "\t%-15s\n", getFORM( tmp ) );
if( attr == 0 ) break;
}
}
}
static char *getStandardOp( uint_8 value ) {
static char buf[ 30 ];
char * result;
result = getName( value, readableStandardOps, NUM_STANDARD_OPS );
if( result == NULL ) {
sprintf( buf, "OP_%02x", value );
return( buf );
}
return( result );
}
typedef struct {
uint_32 address;
uint file;
uint_32 line;
uint_32 column;
uint_8 is_stmt : 1;
uint_8 basic_block : 1;
uint_8 end_sequence : 1;
} state_info;
static void initState( state_info *state, int default_is_stmt ) {
state->address = 0;
state->file = 1;
state->line = 1;
state->column = 0;
state->is_stmt = default_is_stmt;
state->basic_block = 0;
state->end_sequence = 0;
}
static void dumpState( state_info *state ) {
printf( "-- file %d addr %08lx line %d column %d",
state->file, state->address, state->line, state->column );
if( state->is_stmt ) printf( " is_stmt" );
if( state->basic_block ) printf( " basic_block" );
if( state->end_sequence ) printf( " end_sequence" );
printf( "\n" );
}
static void dumpLines(
const uint_8 * input,
uint length )
{
const uint_8 * p;
uint opcode_base;
uint * opcode_lengths;
uint u;
uint file_index;
const uint_8 * name;
uint_32 dir_index;
uint_32 mod_time;
uint_32 file_length;
uint_32 directory;
uint_8 op_code;
uint_8 op_len;
uint_32 tmp;
uint_16 tmp_seg;
uint line_range;
int line_base;
int_32 itmp;
int default_is_stmt;
state_info state;
uint min_instr;
uint_32 unit_length;
const uint_8 * unit_base;
p = input;
while( p - input < length ) {
unit_length = getU32( (uint_32 *)p );
p += sizeof( uint_32 );
unit_base = p;
printf( "total_length: 0x%08lx (%u)\n", unit_length, unit_length );
printf( "version: 0x%04x\n", getU16( (uint_16 *)p ) );
p += sizeof( uint_16 );
printf( "prologue_length: 0x%08lx (%u)\n", getU32( (uint_32 *)p ), getU32( (uint_32 *)p ) );
p += sizeof( uint_32 );
min_instr = *p;
printf( "minimum_instruction_length: 0x%02x (%u)\n", min_instr, min_instr );
p += 1;
default_is_stmt = *p;
printf( "default_is_stmt: 0x%02x (%u)\n", default_is_stmt, default_is_stmt );
p += 1;
line_base = *(int_8 *)p;
printf( "line_base: 0x%02x (%d)\n", (unsigned char)line_base, line_base );
p += 1;
line_range = *(uint_8 *)p;
printf( "line_range: 0x%02x (%u)\n", line_range, line_range );
p += 1;
opcode_base = *p;
printf( "opcode_base: 0x%02x (%u)\n", opcode_base, opcode_base );
p += 1;
opcode_lengths = alloca( sizeof( uint ) * opcode_base );
printf( "standard_opcode_lengths:\n" );
for( u = 0; u < opcode_base - 1; ++u ) {
opcode_lengths[ u ] = *p;
++p;
printf( "%4u: %u\n", u + 1, opcode_lengths[ u ] );
}
printf( "-- current_offset = %08lx\n", p - input );
if( p - input >= length ) return;
printf( "-- start include paths --\n");
file_index = 0;
while( *p != 0 ) {
++file_index;
name = p;
p += strlen( p ) + 1;
printf( "path %u: '%s'\n", file_index, name );
if( p - input >= length ) return;
}
printf( "-- end include paths --\n");
p++;
printf( "-- start files --\n");
file_index = 0;
while( *p != 0 ) {
++file_index;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?