Exemplo n.º 1
0
static 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;
            }
        }
    }
}
Exemplo n.º 2
0
static void dumpRef( const uint_8 *input, uint length )
{
    const uint_8    *p;
    uint_8          op_code;
    uint_32         tmp;
    int_32          itmp;
    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: %08lx\n", getU32( (uint_32 *)p ) );

        while( p - unit_base < unit_length ) {
            op_code = *p++;
            if( op_code < REF_CODE_BASE ) {
                printf( "%s", getReferenceOp( op_code ) );
                switch( op_code ) {
                case REF_BEGIN_SCOPE:
                    printf( " %08lx\n", getU32( (uint_32 *)p ) );
                    p += sizeof( uint_32 );
                    break;
                case REF_END_SCOPE:
                case REF_COPY:
                    printf( "\n" );
                    break;
                case REF_SET_FILE:
                case REF_SET_LINE:
                case REF_SET_COLUMN:
                    p = DecodeULEB128( p, &tmp );
                    printf( " %lu\n", tmp );
                    break;
                case REF_ADD_LINE:
                case REF_ADD_COLUMN:
                    p = DecodeLEB128( p, &itmp );
                    printf( " %ld\n", itmp );
                    break;
                }
            } else {
                op_code -= REF_CODE_BASE;
                printf( "REF line += %d, column += %d, %08lx\n",
                    op_code / REF_COLUMN_RANGE, op_code % REF_COLUMN_RANGE,
                    getU32( (uint_32 *)p )
                );
                p += sizeof( uint_32 );
            }
        }
    }
}
Exemplo n.º 3
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;
            }
        }
    }
}
Exemplo n.º 4
0
void Dump_lines( const uint_8 *input, uint length )
/*************************************************/
{
    const uint_8                *p;
    const uint_8                *stmt_start;
    uint                        opcode_base;
    uint                        *opcode_lengths;
    uint                        u;
    uint                        file_index;
    const uint_8                *name;
    uint_32                     mod_time;
    uint_32                     file_length;
    uint_32                     directory;
    uint_8                      op_code;
    uint_32                     op_len;
    uint_32                     tmp;
    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 = get_u32( (uint_32 *)p );
        p += sizeof( uint_32 );
        unit_base = p;

        Wdputs( "total_length: " );
        Puthex( unit_length, 8 );

        Wdputslc( "\nversion: " );
        Puthex( get_u16( (uint_16 *)p ), 4 );
        p += sizeof( uint_16 );

        Wdputslc( "\nprologue_length: " );
        Puthex( get_u32( (uint_32 *)p ), 8 );
        stmt_start = p;
        stmt_start += get_u32( (uint_32 *)p );
        p += sizeof( uint_32 );
        stmt_start += sizeof( uint_32 );
        min_instr = *p;
        Wdputslc( "\nminimum_instruction_length: " );
        Puthex( min_instr, 2 );
        p += 1;

        default_is_stmt = *p;
        Wdputslc( "\ndefault_is_stmt: " );
        Puthex( default_is_stmt, 2 );
        p += 1;

        line_base = *(int_8 *)p;
        Wdputslc( "\nline_base: " );
        Puthex( line_base, 2 );
        p += 1;

        line_range = *(uint_8 *)p;
        Wdputslc( "\nline_range: " );
        Puthex( line_range, 2 );
        p += 1;

        opcode_base = *p;
        Wdputslc( "\nopcode_base: " );
        Puthex( opcode_base, 2 );
        Wdputslc( "\n" );
        p += 1;
        opcode_lengths = malloc( sizeof( uint ) * opcode_base );
        Wdputslc( "standard_opcode_lengths:\n" );
        for( u = 0; u < opcode_base - 1; ++u ) {
            opcode_lengths[ u ] = *p;
            ++p;
            Putdecl( u, 4 );
            Wdputs( ": " );
            Putdec( opcode_lengths[ u ] );
            Wdputslc( "\n" );
        }

        Wdputs( "-- current_offset = " );
        Puthex( p - input, 8 );
        Wdputslc( "\n" );

        if( p - input >= length ) return;

        Wdputslc( "include directories\n" );
        file_index = 0;
        while( *p != 0 ) {
            ++file_index;
            name = p;
            p += strlen( (char *)p ) + 1;
            Wdputs( "path " );
            Putdec( file_index );
            Wdputs( ": '" );
            Wdputs( (char *)name );
            Wdputslc( "'\n" );
            if( p - input >= length ) return;
        }
        p++;
        Wdputslc( "file names\n" );
        file_index = 0;
        while( *p != 0 ) {
            ++file_index;
            name = p;
            p += strlen( (char *)p ) + 1;
            p = DecodeULEB128( p, &directory );
            p = DecodeULEB128( p, &mod_time );
            p = DecodeULEB128( p, &file_length );
            Wdputs( "file " );
                Putdec( file_index );
            Wdputs( ": '" );
                Wdputs( (char *)name );
            Wdputs( "' directory " );
                Putdec( directory );
            Wdputs( " mod_time " );
                Puthex( mod_time, 8 );
            Wdputs( " length " );
                Puthex( file_length, 8 );
            Wdputslc( "\n" );
            if( p - input >= length ) return;
        }
        p++;
        init_state( &state, default_is_stmt );
        Wdputs( "-- current_offset = " );
        Puthex( p - input, 8 );
        if( p != stmt_start ) {
            Wdputs( ":***Prologue length off***" );
        }
        Wdputslc( "\n" );
        while( p - unit_base < unit_length ) {
            op_code = *p;
            ++p;
            if( op_code == 0 ) {
                /* extended op_code */
                p = DecodeULEB128( p, &op_len );
                Wdputs( "len: " );
                Putdecl( op_len, 3 );
                Wdputc( ' ' );
                op_code = *p;
                ++p;
                --op_len;
                switch( op_code ) {
                case DW_LNE_end_sequence:
                    Wdputslc( "END_SEQUENCE\n" );
                    state.end_sequence = 1;
                    dump_state( &state );
                    init_state( &state, default_is_stmt );
                    p+= op_len;
                    break;
                case DW_LNE_set_address:
                    Wdputs( "SET_ADDRESS " );
                    if( op_len == 4 ) {
                        tmp = get_u32( (uint_32 *)p );
                    } else if( op_len == 2 ) {
                        tmp = get_u16( (uint_16 *)p );
                    } else {
                        tmp = 0xffffffff;
                    }
                    state.address = tmp;
                    Puthex( tmp, op_len*2 );
                    Wdputslc( "\n" );
                    p += op_len;
                    break;
                case DW_LNE_set_segment:
                    Wdputs( "SET_SEGMENT " );
                    if( op_len == 4 ) {
                        tmp = get_u32( (uint_32 *)p );
                    } else if( op_len == 2 ) {
                        tmp = get_u16( (uint_16 *)p );
                    } else {
                        tmp = 0xffffffff;
                    }
                    state.segment = tmp;
                    Puthex( tmp, op_len*2 );
                    Wdputslc( "\n" );
                    p += op_len;
                    break;
                case DW_LNE_define_file:
                    ++file_index;
                    name = p;
                    p += strlen( (char *)p ) + 1;
                    p = DecodeULEB128( p, &directory );
                    p = DecodeULEB128( p, &mod_time );
                    p = DecodeULEB128( p, &file_length );
                    Wdputs( "DEFINE_FILE " );
                    Putdec( file_index );
                    Wdputs( ": '" );
                    Wdputs( (char *)name );
                    Wdputs( "' directory " );
                    Putdec( directory );
                    Wdputs( " mod_time " );
                    Puthex( mod_time, 8 );
                    Wdputs( " length " );
                    Puthex( file_length, 8 );
                    break;
                default:
                    Wdputs( "** unknown extended opcode: " );
                    Puthex( op_code, 2 );
                    Wdputslc( "\n" );
                    p += op_len;
                    break;
                }
            } else if( op_code < opcode_base ) {
                get_standard_op( op_code );
                switch( op_code ) {
                case DW_LNS_copy:
                    dump_state( &state );
                    state.basic_block = 0;
                    break;
                case DW_LNS_advance_pc:
                    p = DecodeLEB128( p, &itmp );
                    Putdec( itmp );
                    state.address += itmp * min_instr;
                    break;
                case DW_LNS_advance_line:
                    p = DecodeLEB128( p, &itmp );
                    Putdec( itmp );
                    state.line += itmp;
                    break;
                case DW_LNS_set_file:
                    p = DecodeLEB128( p, &itmp );
                    Putdec( itmp );
                    state.file = itmp;
                    break;
                case DW_LNS_set_column:
                    p = DecodeLEB128( p, &itmp );
                    Putdec( itmp );
                    state.column = itmp;
                    break;
                case DW_LNS_negate_stmt:
                    state.is_stmt = !state.is_stmt;
                    break;
                case DW_LNS_set_basic_block:
                    state.basic_block = 1;
                    break;
                case DW_LNS_const_add_pc:
                    state.address += ( ( 255 - opcode_base ) / line_range ) * min_instr;
                    break;
                case DW_LNS_fixed_advance_pc:
                    tmp = get_u16( (uint_16 *)p );
                    p += sizeof( uint_16 );
                    Puthex( tmp, 4 );
                    state.address += tmp;
                    break;
                default:
                    for( u = 0; u < opcode_lengths[ op_code - 1 ]; ++u ) {
                        p = DecodeLEB128( p, &itmp );
                        Puthex( itmp, 8 );
                    }
                }
            } else {
                Wdputs( "SPECIAL " );
                Puthex( op_code, 2 );
                op_code -= opcode_base;
                Wdputs( ": addr incr: " );
                Putdec( op_code / line_range );
                Wdputs( "  line incr: " );
                Putdec( line_base + op_code % line_range );
                state.line += line_base + op_code % line_range;
                state.address += ( op_code / line_range ) * min_instr;
                dump_state( &state );
                state.basic_block = 0;
            }
            Wdputslc( "\n" );
        }
        free( opcode_lengths  );
        Wdputs( "-- current_offset = " );
        Puthex( p - input, 8 );
        Wdputslc( "\n" );
    }
}
Exemplo n.º 5
0
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( "=== unit dump start ===\n" );
        dumpHex( unit_base - sizeof( uint_32 ), unit_length + sizeof (uint_32 ), 1 );
        printf( "=== unit dump end ===\n" );

        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 = %08x\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( (const char *)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;
            name = p;
            p += strlen( (const char *)p ) + 1;
            p = DecodeULEB128( p, &dir_index );
            p = DecodeULEB128( p, &mod_time );
            p = DecodeULEB128( p, &file_length );
            printf( "file %u: '%s' dir_index %08lx mod_time %08lx length %08lx\n",
                file_index, name, dir_index, mod_time, file_length );
            if( p - input >= length ) {
                return;
            }
        }
        printf( "-- end files --\n");
        p++;
        initState( &state, default_is_stmt );

        while( p - unit_base < unit_length ) {
            op_code = *p;
            ++p;
            if( op_code == 0 ) {
                printf( "EXTENDED 0x%02x: ", op_code );
                /* extended op_code */
                op_len = *p;
                ++p;
                printf( "len: %03d ", op_len );
                op_code = *p;
                ++p;
                switch( op_code ) {
                case DW_LNE_end_sequence:
                    printf( "END_SEQUENCE\n" );
                    state.end_sequence = 1;
                    dumpState( &state );
                    initState( &state, default_is_stmt );
                    break;
                case DW_LNE_set_address:
                    if( op_len == 3 ) {
                        tmp = getU16( (uint_16 *)p );
                        p += sizeof( uint_16 );
                    } else {
                        tmp = getU32( (uint_32 *)p );
                        p += sizeof( uint_32 );
                    }
#if 0   /* Why did they choose 6 byte here?  */
                    tmp_seg = getU16( (uint_16 *)p );
                    p += sizeof( uint_16 );
                    printf( "SET_ADDRESS %04x:%08lx\n", tmp_seg, tmp );
#else
                    tmp_seg = 0;    /* stop warning */
                    printf( "SET_ADDRESS %08lx\n", tmp );
#endif
                    break;
                case DW_LNE_WATCOM_set_segment_OLD:
                case DW_LNE_WATCOM_set_segment:
                    tmp_seg = getU16( (uint_16 *)p );
                    p += sizeof( uint_16 );
                    printf( "SET_ADDRESS_SEG %04x\n", tmp_seg );
                    break;
                case DW_LNE_define_file:
                    ++file_index;
                    name = p;
                    p += strlen( (const char *)p ) + 1;
                    p = DecodeULEB128( p, &directory );
                    p = DecodeULEB128( p, &mod_time );
                    p = DecodeULEB128( p, &file_length );
                    printf( "DEFINE_FILE %u: '%s' directory %ld mod_time %08lx length %08lx\n",
                        file_index, name, directory, mod_time, file_length );
                    break;
                default:
                    printf( "** unknown extended opcode: %02x - %u bytes\n", op_code, op_len );
                    printf( "** losing %u bytes\n", unit_length - ( p - unit_base ));

                    dumpHex( p-3, (unit_length - ( p - unit_base )) + 3, 1 );

                    p = unit_base + unit_length;
                    goto hacky;
//                    return;
                }
            } else if( op_code < opcode_base ) {
                printf( "%s", getStandardOp( op_code ) );
                switch( op_code ) {
                case DW_LNS_copy:
                    printf( "\n" );
                    dumpState( &state );
                    state.basic_block = 0;
                    break;
                case DW_LNS_advance_pc:
                    p = DecodeLEB128( p, &itmp );
                    printf( " %ld\n", itmp );
                    state.address += itmp * min_instr;
                    break;
                case DW_LNS_advance_line:
                    p = DecodeLEB128( p, &itmp );
                    printf( " %ld\n", itmp );
                    state.line += itmp;
                    break;
                case DW_LNS_set_file:
                    p = DecodeLEB128( p, &itmp );
                    printf( " %ld\n", itmp );
                    state.file = itmp;
                    break;
                case DW_LNS_set_column:
                    p = DecodeLEB128( p, &itmp );
                    printf( " %ld\n", itmp );
                    state.column = itmp;
                    break;
                case DW_LNS_negate_stmt:
                    printf( "\n" );
                    state.is_stmt = !state.is_stmt;
                    break;
                case DW_LNS_set_basic_block:
                    printf( "\n" );
                    state.basic_block = 1;
                    break;
                case DW_LNS_const_add_pc:
                    printf( "\n" );
                    state.address += ( ( 255 - opcode_base ) / line_range ) * min_instr;
                    break;
                case DW_LNS_fixed_advance_pc:
                    tmp = getU16( (uint_16 *)p );
                    p += sizeof( uint_16 );
                    printf( " %04x\n", tmp );
                    state.address += tmp;
                    break;
                default:
                    for( u = 0; u < opcode_lengths[op_code - 1]; ++u ) {
                        p = DecodeLEB128( p, &itmp );
                        printf( " %08lx", itmp );
                    }
                    printf( "\n" );
                }
            } else {
                printf( "SPECIAL 0x%02x:", op_code );
                op_code -= opcode_base;
                printf( " addr incr: %d  line incr: %d\n",
                    op_code / line_range,
                    line_base + op_code % line_range );
                state.line += line_base + op_code % line_range;
                state.address += ( op_code / line_range ) * min_instr;
                dumpState( &state );
                state.basic_block = 0;
            }
        }
hacky:
        printf( "-- current_offset = %08x\n", p - input );
    }
}
Exemplo n.º 6
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;
                }
            }
        }
    }
}
Exemplo n.º 7
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;
            }
        }
    }
}
Exemplo n.º 8
0
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;
        unit_length = get_u32( (uint_32 *)p );
        unit_base = p + sizeof( uint_32 );
        Wdputs( "Length: " );
        Puthex( unit_length, 8 );
        Wdputslc( "\nVersion: " );
        Puthex( get_u16( (uint_16 *)(p + 4) ), 4 );
        Wdputslc( "\nAbbrev: " );
        abbrev_offset =  get_u32( (uint_32 *)(p + 6) );
        Puthex( abbrev_offset, 8 );
        state.addr_size = *(p + 10);
        Wdputslc( "\nAddress Size " );
        Puthex( *(p + 10), 2 );
        Wdputslc( "\n" );
        p += 11;
        while( p - unit_base < unit_length ) {
            tag_offset = p - input;
            p = DecodeULEB128( p, &abbrev_code );
            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 );
            abbrev++;
            state.abbrev = abbrev;
            state.p = p;
            if( tag_offset == 0x59a125 ) {
                found = true;
            }
            if( found ) {
                Wdputs( "Offset: " );
                Puthex(  tag_offset, 8 );
                Wdputs( "  Code: " );
                Puthex( abbrev_code, 8 );
                Wdputslc( "\n" );
                Wdputs( "        " );
                getTAG( tag );
                Wdputslc( "\n" );
               if( !dump_tag( &state ) )break;
            } else {
                skip_tag( &state );
            }
            p = state.p;
        }
        if( found )break;
    }
}
Exemplo n.º 9
0
static bool skip_tag( info_state *info )
/*****************************************************/
{
    uint_8      *abbrev;
    uint_32     attr;
    uint_32     form;
    uint_32     len;
    uint_32     tmp;
    int_32      itmp;
    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 = DecodeSLEB128( p, &itmp );
            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 );
}
Exemplo n.º 10
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 );
}
Exemplo n.º 11
0
static void DmpLoc( uint_8 const *p, uint length, uint addr_size )
/****************************************************************/
{
    uint_8 const    *end;
    uint_8          op;
    dw_locop_op     opr;
    int_32          op1s;
    uint_32         op1u;
    int_32          op2s;
    uint_32         addr;

    end = &p[length];

    Wdputslc( "\n            Loc expr: " );
    if( p == end ) {
      Wdputslc( "<NULL>\n" );
    }
    while( p  < end ) {
        op = *p;
        ++p;

        Wdputs( OpName[ op ] );
        opr = LocOpr[ op ];
        if( opr == DW_LOP_REG1 || opr == DW_LOP_BRG1 ) {
            Wdputs( "/" );
        } else {
            Wdputs( " " );
        }
        switch( opr ) {
        case DW_LOP_NOOP:
            break;
        case DW_LOP_ADDR:
            if( addr_size == 4 ) {
                addr = *(uint_32 *)p;
            } else if( addr_size == 2 ) {
                addr = *(uint_16 *)p;
            } else if( addr_size == 1 ) {
                addr = *(uint_8 *)p;
            } else {
                addr = 0;
            }
            Puthex( addr, addr_size * 2 );
            p += addr_size;
            break;
        case DW_LOP_OPU1:
            op1u = *(uint_8 *)p;
            p += sizeof( uint_8 );
            Putdec( op1u );
            break;
        case DW_LOP_OPS1:
            op1s = *(int_8 *)p;
            p += sizeof(int_8 );
            Putdec( op1s );
            break;
        case DW_LOP_OPU2:
            op1u = get_u16( (uint_16 *)p );
            p += sizeof( uint_16 );
            Putdec( op1u );
            break;
        case DW_LOP_OPS2:
            op1s = get_s16( (int_16 *)p );
            p += sizeof( int_16 );
            Putdec( op1s );
            break;
        case DW_LOP_OPU4:
            op1u = get_u32( (uint_32 *)p );
            p += sizeof( uint_32 );
            Putdec( op1u );
            break;
        case DW_LOP_OPS4:
            op1s = get_s32( (int_32 *)p );
            p += sizeof( int_32 );
            Putdec( op1s );
            break;
        case DW_LOP_U128:
            p = DecodeULEB128( p, &op1u );
            Putdec( op1u );
            break;
        case DW_LOP_S128:
            p = DecodeSLEB128( p, &op1s );
            Putdecs( op1s );
            break;
        case DW_LOP_U128_S128:
            p = DecodeULEB128( p, &op1u );
            p = DecodeSLEB128( p, &op2s );
            Putdec( op1u );
            Wdputs( "," );
            Putdecs( op2s );
            break;
        case DW_LOP_LIT1:
            op1u = op-DW_OP_lit0;
            op = DW_OP_lit0;
            break;
        case DW_LOP_REG1:
            op1u = op-DW_OP_reg0;
            op = DW_OP_reg0;
            Wdputs( RegName[ op1u] );
            break;
        case DW_LOP_BRG1:
            op1u = op-DW_OP_breg0;
            p = DecodeSLEB128( p, &op2s );
            Wdputs( RegName[ op1u] );
            if( op2s < 0 ) {
                Wdputs( " -" );
                op2s = -op2s;
            } else {
                Wdputs( " +" );
            }
            Putdec( op2s );
            op = DW_OP_breg0;
            break;
        }
        Wdputslc( " " );
    }
        Wdputslc( "\n" );
}
Exemplo n.º 12
0
static void dump_ref( const uint_8 *input, uint length )
/******************************************************/
{
    const uint_8    *p;
    uint_8          op_code;
    uint_32         tmp;
    int_32          itmp;
    uint_32         unit_length;
    const uint_8    *unit_base;
    ref_info        registers =  { { 0, 0, NULL }, 0L, 1L, 1L, 1 };

    p = input;

    while( p - input < length ) {
        unit_length = get_u32( (uint_32 *)p );
        p += sizeof( uint_32 );
        unit_base = p;
        Wdputs( "total_length: " );
        Puthex( get_u32( (uint_32 *)p ), 8 );
        Wdputslc( "\n" );

        while( p - unit_base < unit_length ) {
            op_code = *p++;
            if( op_code < REF_CODE_BASE ) {
                get_reference_op( op_code );
                switch( op_code ) {
                case REF_BEGIN_SCOPE:
                    Puthex( get_u32( (uint_32 *)p ), 8 );
                    ScopePush( &registers.scope, get_u32( (uint_32 *)p ) );
                    p += sizeof( uint_32 );
                    break;
                case REF_END_SCOPE:
                    ScopePop( &registers.scope );
                    break;
                case REF_COPY:
                    Wdputs( "    " );
                    PutRefRegisters( &registers );
                    break;
                case REF_SET_FILE:
                    p = DecodeULEB128( p, &tmp );
                    Putdec( tmp );
                    registers.file = tmp;
                    break;
                case REF_SET_LINE:
                    p = DecodeULEB128( p, &tmp );
                    Putdec( tmp );
                    registers.line = tmp;
                    registers.column = 0;
                    break;
                case REF_SET_COLUMN:
                    p = DecodeULEB128( p, &tmp );
                    Putdec( tmp );
                    registers.column = tmp;
                    break;
                case REF_ADD_LINE:
                    p = DecodeSLEB128( p, &itmp );
                    Putdecs( itmp );
                    registers.line += itmp;
                    break;
                case REF_ADD_COLUMN:
                    p = DecodeULEB128( p, &tmp );
                    Putdec( tmp );
                    registers.column += tmp;
                    break;
                }
            } else {
                op_code -= REF_CODE_BASE;
                Wdputs( "REF line += " );
                Putdec( op_code / REF_COLUMN_RANGE );
                registers.line += op_code / REF_COLUMN_RANGE;

                Wdputs( ", column += " );
                Putdec( op_code % REF_COLUMN_RANGE );
                registers.column += op_code % REF_COLUMN_RANGE;

                Wdputs( ", " );
                Puthex( get_u32( (uint_32 *)p ), 8 );
                registers.dependent = get_u32( (uint_32 *)p );

                Wdputs( "    " );
                PutRefRegisters( &registers );

                p += sizeof( uint_32 );
            }
            Wdputslc( "\n" );
        }
    }
}