Beispiel #1
0
static void dumpAbbrevs( const unsigned_8 *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( ; p <= input + length; ) {
            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;
            }
        }
    }
}
Beispiel #2
0
extern void dump_abbrevs( const uint_8 *input, uint length )
/**********************************************************/
{
    const uint_8    *p;
    uint_32         tmp;
    uint_32         attr;
    uint_32         abbr_off;
//    bool            start;

    if( Sections[ DW_DEBUG_ABBREV ].data == 0 ) {
        Sections[ DW_DEBUG_ABBREV ].data = Wmalloc( length );
        Sections[ DW_DEBUG_ABBREV ].max_offset = length;
        memcpy( Sections[ DW_DEBUG_ABBREV ].data, input, length );
    }
    p = input;
    for( ;; ) {
        if( p > input + length )
            break;
        abbr_off = tmp = p - input;
        p = DecodeULEB128( p, &tmp );
        if( tmp == 0 ) {
            Wdputslc( "End_CU\n" );
//            start = true;
            continue; /* compile unit separator */
        }
        Wdputs( "Offset: " );
        Puthex( abbr_off, 8 );
        Wdputs( "  Code: " );
        Puthex( tmp, 8 );
        Wdputslc( "\n" );
        if( p >= input + length )
            break;
        if( tmp == 0 )
            continue; /* compile unit separator */
        p = DecodeULEB128( p, &tmp );
        Wdputs( "        " );
        getTAG( tmp );
        Wdputslc( "\n" );
        if( *p == DW_CHILDREN_yes ) {
            Wdputslc( "has children\n" );
        } else {
            Wdputslc( "childless\n" );
        }
        p++;
        for( ;; ) {
            if( p > input + length )
                break;
            p = DecodeULEB128( p, &attr );
            if( p > input + length )
                break;
            p = DecodeULEB128( p, &tmp );
            if( attr == 0 && tmp == 0 ) {
                Wdputslc( "        End_form\n" );
                break;
            }
            Wdputs( "        " );
            getAT( attr );
            Wdputs( "        " );
            getFORM( tmp );
            Wdputslc( "\n" );
            if( attr == 0 ) {
                break;
            }
        }
    }
}
Beispiel #3
0
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: %04x\nAbbrev: %08lx\nAddress Size %02x\n",
            unit_length, getU16( (uint_16 *)(p + 4) ), abbrev_offset, address_size );
        p += 11;
        while( p - unit_base < unit_length ) {
            printf( "offset %08x: ", 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, 0 );
                    p += len;
                    break;
                case DW_FORM_block1:
                    len = *p++;
                    printf( "\n" );
                    dumpHex( p, len, 0 );
                    p += len;
                    break;
                case DW_FORM_block2:
                    len = getU16( (uint_16 *)p );
                    p += sizeof( uint_16 );
                    printf( "\n" );
                    dumpHex( p, len, 0 );
                    p += len;
                    break;
                case DW_FORM_block4:
                    len = getU32( (uint_32 *)p );
                    p += sizeof( uint_32 );
                    printf( "\n" );
                    dumpHex( p, len, 0 );
                    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( (const char *)p ) + 1;
                    break;
                case DW_FORM_strp:  /* 4 byte index into .debug_str */
                    printf_debug_str( getU32( (uint_32 *)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;
                }
            }
        }
    }
}
Beispiel #4
0
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          itmp;
    bool            is_loc;
    uint_8 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 = DecodeSLEB128( p, &itmp );
            Puthex( itmp, 8 );
            Wdputslc( "\n" );
            break;
        case DW_FORM_string:
            Wdputc( '"' );
            Wdputs( (char *)p );
            Wdputslc( "\"\n" );
            p += strlen( (const char *)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( (const char *)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 );
}