wsect.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,344 行 · 第 1/3 页
C
1,344 行
op = DW_OP_reg0;
Wdputs( RegName[ op1u] );
break;
case DW_LOP_BRG1:
op1u = op-DW_OP_breg0;
p = DecodeLEB128( p, (int_32 *)&tmp );
op2s = tmp;
Wdputs( RegName[ op1u] );
Wdputs( "," );
if( op2s < 0 ) {
Wdputs( "-" );
op2s = -op2s;
}
Putdec( op2s );
op = DW_OP_breg0;
break;
}
Wdputslc( " " );
}
Wdputslc( "\n" );
}
static void DmpLocList( uint_32 start, uint addr_size )
/*****************************************************/
{
uint_32 low;
uint_32 high;
int len;
char const *p;
char const *stop;
p = Sections[ DW_DEBUG_LOC ].data;
stop = p + Sections[ DW_DEBUG_LOC ].max_offset;
if( p == NULL ) {
Wdputslc( "Error: No location list section\n" );
return;
}
p += start;
while( p < stop ) {
p = GetInt( p, &low, addr_size );
p = GetInt( p, &high, addr_size );
if( low == high && low == 0 ) {
Wdputslc( " <end>\n" );
return;
}
len = get_u16( (uint_16 *)p );
p+= sizeof( uint_16 );
Wdputslc( "\n Range: " );
Puthex( low, addr_size * 2 );
Wdputs( ":" );
Puthex( high, addr_size * 2 );
Wdputslc( "\n" );
DmpLoc( p, len, addr_size );
p += len;
}
}
typedef struct {
char const *p;
uint_8 *abbrev;
int addr_size;
uint_32 cu_header;
} info_state;
static bool dump_tag( info_state *info )
/**************************************/
{
uint_8 *abbrev;
uint_32 attr;
uint_32 offset;
uint_32 form;
uint_32 len;
uint_32 tmp;
int_32 stmp;
bool is_loc;
char const *p;
p = info->p;
abbrev = info->abbrev;
for( ;; ) {
abbrev = DecodeULEB128( abbrev, &attr );
abbrev = DecodeULEB128( abbrev, &form );
if( attr == 0 ) break;
Wdputs( " " );
getAT( attr );
if( attr == DW_AT_location
|| attr == DW_AT_segment
|| attr == DW_AT_return_addr
|| attr == DW_AT_frame_base
|| attr == DW_AT_static_link
|| attr == DW_AT_data_member_location
|| attr == DW_AT_string_length
|| attr == DW_AT_vtable_elem_location
|| attr == DW_AT_WATCOM_parm_entry
|| attr == DW_AT_use_location ) {
is_loc = TRUE;
} else {
is_loc = FALSE;
}
decode_form:
switch( form ) {
case DW_FORM_addr:
if( info->addr_size == 4 ) {
tmp = get_u32( (uint_32 *)p );
} else if( info->addr_size == 2 ) {
tmp = get_u16( (uint_16 *)p );
} else if( info->addr_size == 1 ) {
tmp = *(uint_8 *)p;
} else {
tmp = info->addr_size;
Wdputs( "?addr:" );
}
p += info->addr_size;
Puthex( tmp, info->addr_size*2 );
Wdputslc( "\n" );
break;
case DW_FORM_block:
p = DecodeULEB128( p, &len );
if( is_loc ) {
DmpLoc( p, len, info->addr_size );
} else {
Wdputslc( "\n" );
dump_hex( p, len );
}
p += len;
break;
case DW_FORM_block1:
len = *p++;
if( is_loc ) {
DmpLoc( p, len, info->addr_size );
} else {
Wdputslc( "\n" );
dump_hex( p, len );
}
p += len;
break;
case DW_FORM_block2:
len = get_u16( (uint_16 *)p );
p += sizeof( uint_16 );
if( is_loc ) {
DmpLoc( p, len, info->addr_size );
} else {
Wdputslc( "\n" );
dump_hex( p, len );
}
p += len;
break;
case DW_FORM_block4:
len = get_u32( (uint_32 *)p );
p += sizeof( uint_32 );
if( is_loc ) {
DmpLoc( p, len, info->addr_size );
} else {
Wdputslc( "\n" );
dump_hex( p, len );
}
p += len;
break;
case DW_FORM_data1:
Puthex( *p++, 2 );
Wdputslc( "\n" );
break;
case DW_FORM_ref1:
Puthex( info->cu_header + *p++ , 2 );
Wdputslc( "\n" );
break;
case DW_FORM_data2:
Puthex( get_u16( (uint_16 *)p ), 4 );
Wdputslc( "\n" );
p += sizeof( uint_16 );
break;
case DW_FORM_ref2:
Puthex( info->cu_header + get_u16( (uint_16 *)p ), 4 );
Wdputslc( "\n" );
p += sizeof( uint_16 );
break;
case DW_FORM_data4:
if( is_loc ) {
DmpLocList( get_u32( (uint_32 *)p ), info->addr_size );
} else {
Puthex( get_u32( (uint_32 *)p ), 8 );
Wdputslc( "\n" );
}
p += sizeof( uint_32 );
break;
case DW_FORM_ref4:
Puthex( info->cu_header + get_u32( (uint_32 *)p ), 8 );
Wdputslc( "\n" );
p += sizeof( uint_32 );
break;
case DW_FORM_flag:
Wdputs( *p++ ? "True" : "False" );
Wdputslc( "\n" );
break;
case DW_FORM_indirect:
p = DecodeULEB128( p, &form );
Wdputc( '(' );
getFORM( form );
Wdputc( ')' );
goto decode_form;
case DW_FORM_sdata:
p = DecodeLEB128( p, &stmp );
Puthex( stmp, 8 );
Wdputslc( "\n" );
break;
case DW_FORM_string:
Wdputc( '"' );
Wdputs( (char *)p );
Wdputslc( "\"\n" );
p += strlen( p ) + 1;
break;
case DW_FORM_strp:
offset = get_u32( (uint_32 *)p );
if( offset > Sections[ DW_DEBUG_STR ].max_offset ) {
Wdputslc( "Error: strp - invalid offset\n" );
} else {
Wdputs( Sections[ DW_DEBUG_STR ].data + offset );
Wdputslc( "\n" );
}
p += sizeof( uint_32 );
break;
case DW_FORM_udata:
p = DecodeULEB128( p, &tmp );
Puthex( tmp, 8 );
Wdputslc( "\n" );
break;
case DW_FORM_ref_udata:
p = DecodeULEB128( p, &tmp );
Puthex( info->cu_header + tmp, 8 );
Wdputslc( "\n" );
break;
case DW_FORM_ref_addr:
if( is_loc ) { // history
DmpLocList( get_u32( (uint_32 *)p ), info->addr_size );
} else {
Puthex( get_u32( (uint_32 *)p ), 8 );
Wdputslc( "\n" );
}
p += sizeof( uint_32 );
break;
default:
Wdputslc( "unknown form\n" );
info->p = p;
return( FALSE );
}
}
info->p = p;
return( TRUE );
}
static void dump_info( 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 unit_length;
const uint_8 *unit_base;
info_state state;
p = input;
state.addr_size = 0;
while( p - input < length ) {
state.cu_header = p-input;
unit_length = get_u32( (uint_32 *)p );
unit_base = p + sizeof( uint_32 );
Wdputs( "Offset: " );
Puthex( p - input, 8 );
Wdputs( " Length: " );
Puthex( unit_length, 8 );
Wdputslc( "\nVersion: " );
Puthex( get_u16( (uint_16 *)(p+4) ), 4 );
Wdputs( " Abbrev: " );
abbrev_offset = get_u32( (uint_32 *)(p+6) );
Puthex( abbrev_offset, 8 );
state.addr_size = *(p+10);
Wdputs( " Address Size " );
Puthex( *(p+10), 2 );
Wdputslc( "\n" );
p += 11;
while( p - unit_base < unit_length ) {
Wdputs( "Offset: " );
Puthex( p - input, 8 );
p = DecodeULEB128( p, &abbrev_code );
Wdputs( " Code: " );
Puthex( abbrev_code, 8 );
Wdputslc( "\n" );
if( abbrev_code == 0 ) continue;
abbrev = find_abbrev( abbrev_offset, abbrev_code );
if( abbrev == NULL ) {
Wdputs( "can't find abbreviation " );
Puthex( abbrev_code, 8 );
Wdputslc( "\n" );
break;
}
if( p >= input + length ) break;
abbrev = DecodeULEB128( abbrev, &tag );
Wdputs( " " );
getTAG( tag );
Wdputslc( "\n" );
abbrev++;
state.abbrev = abbrev;
state.p = p;
if( !dump_tag( &state ) )break;
p = state.p;
}
}
}
#if 0 // used for debugging
static bool skip_tag( info_state *info )
/*****************************************************/
{
uint_8 *abbrev;
uint_32 attr;
uint_32 form;
uint_32 len;
uint_32 tmp;
int_32 stmp;
bool is_loc;
char const *p;
p = info->p;
abbrev = info->abbrev;
for( ;; ) {
abbrev = DecodeULEB128( abbrev, &attr );
abbrev = DecodeULEB128( abbrev, &form );
if( attr == 0 ) break;
if( attr == DW_AT_location
|| attr == DW_AT_segment
|| attr == DW_AT_return_addr
|| attr == DW_AT_frame_base
|| attr == DW_AT_static_link
|| attr == DW_AT_data_member_location
|| attr == DW_AT_string_length
|| attr == DW_AT_use_location ) {
is_loc = TRUE;
} else {
is_loc = FALSE;
}
decode_form:
switch( form ) {
case DW_FORM_addr:
if( info->addr_size == 4 ) {
tmp = get_u32( (uint_32 *)p );
} else if( info->addr_size == 2 ) {
tmp = get_u16( (uint_16 *)p );
} else if( info->addr_size == 1 ) {
tmp = *(uint_8 *)p;
} else {
tmp = info->addr_size;
Wdputs( "?addr:" );
}
p += info->addr_size;
break;
case DW_FORM_block:
p = DecodeULEB128( p, &len );
p += len;
break;
case DW_FORM_block1:
len = *p++;
p += len;
break;
case DW_FORM_block2:
len = get_u16( (uint_16 *)p );
p += sizeof( uint_16 );
p += len;
break;
case DW_FORM_block4:
len = get_u32( (uint_32 *)p );
p += sizeof( uint_32 );
p += len;
break;
case DW_FORM_data1:
++p;
break;
case DW_FORM_ref1:
++p;
break;
case DW_FORM_data2:
p += sizeof( uint_16 );
break;
case DW_FORM_ref2:
p += sizeof( uint_16 );
break;
case DW_FORM_data4:
p += sizeof( uint_32 );
break;
case DW_FORM_ref4:
p += sizeof( uint_32 );
break;
case DW_FORM_flag:
++p;
break;
case DW_FORM_indirect:
p = DecodeULEB128( p, &form );
goto decode_form;
case DW_FORM_sdata:
p = DecodeLEB128( p, &stmp );
break;
case DW_FORM_string:
p += strlen( p ) + 1;
break;
case DW_FORM_strp:
abort();
break;
case DW_FORM_udata:
p = DecodeULEB128( p, &tmp );
break;
case DW_FORM_ref_udata:
p = DecodeULEB128( p, &tmp );
break;
case DW_FORM_ref_addr:
p += sizeof( uint_32 );
break;
default:
Wdputslc( "unknown form\n" );
info->p = p;
return( FALSE );
}
}
info->p = p;
return( TRUE );
}
static void dump_info_headers( const char *input, uint length )
/*************************************************************/
{
const uint_8 *p;
uint_32 abbrev_code;
uint_32 abbrev_offset;
uint_8 * abbrev;
uint_32 tag;
uint_32 unit_length;
uint_32 tag_offset;
const uint_8 *unit_base;
info_state state;
bool found;
p = input;
state.addr_size = 0;
found = FALSE;
while( p - input < length ) {
state.cu_header = p-input;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?