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 + -
显示快捷键?