Пример #1
0
/*
 * Dump the type and offsets.
 */
static void dmp_type_offset( unsigned_32 bsize )
/**********************************************/
{
    unsigned_32             i;
    unsigned                prev;
    pe_fixup_entry          entry;

    Wdputslc( "type:offset               type --\n" );
    Wdputslc( "0 = ABSOLUTE, 1 = LOW, 2 = HIGH, 3 = HIGHLOW, 4 = HIGHADJUST, 5 = MIPSJMPADDR\n" );
    prev = 0;
    for( i = 0; i < bsize; i++ ) {
        Wread( &entry, sizeof( pe_fixup_entry ) );
        if( i != 0 ) {
            if( (i) % 8 == 0 ) {
                Wdputslc( "\n" );
            } else {
                Wdputs( "     " );
            }
        }
        if( prev == 4 ) {
            Wdputc( ' ' );
            Puthex( entry, 4 );
            prev = 0;
        } else {
            prev = entry >> 12;
            Puthex( prev, 1 );
            Wdputc( ':' );
            Puthex( entry, 3 );
        }
    }
    Wdputslc( "\n" );
}
Пример #2
0
/*
 * desc_array - dump info
 */
static void desc_array( unsigned_8 *ptr, bool is386 )
/***************************************************/
{
    addr32_ptr  *p32;
    addr48_ptr  *p48;

    Wdputs( "          scalar type 1 = " );
    scalar_type( ptr[0] );
    Wdputs( "  scalar type 2 = " );
    scalar_type( ptr[1] );
    ptr += 2;
    Wdputslc( "\n          addr = " );
    if( is386 ) {
        p48 = (addr48_ptr *)ptr;
        ptr += sizeof(addr48_ptr);
        Puthex( p48->segment, 4 );
        Wdputc( ':' );
        Puthex( p48->offset, 8 );
    } else {
        p32 = (addr32_ptr *)ptr;
        ptr += sizeof(addr32_ptr);
        Puthex( p32->segment, 4 );
        Wdputc( ':' );
        Puthex( p32->offset, 4 );
    }
    base_type_index( ptr );

} /* desc_array */
Пример #3
0
/*
 * Dump segments.
 */
static void dmp_seg( unsigned_16 size )
/*************************************/
{
    unsigned_16     i;
    unsigned_32     seg;

    if( !size ) {
        return;
    }
    Wdputslc( "segments = type:size\n" );
    Wdputslc( "type  0==read/write, 1==read-only, 2==execute/read, 3==execute-only\n" );
    for( i = 0; i < size; i++ ) {
        if( i != 0 ) {
            if( i % 6 == 0 ) {
                Wdputslc( "\n" );
            } else {
                Wdputs( "    " );
            }
        }
        Wread( &seg, sizeof( unsigned_32 ) );
        Puthex( seg >> 28, 1 );
        Wdputc( ':' );
        Puthex( seg, 7 );
    }
    Wdputslc( "\n" );
}
Пример #4
0
/*
 * dump_global_info - dump out global info
 */
static void dump_global_info( section_dbg_header *sdh )
/*****************************************************/
{
    unsigned_32 total_bytes;
    unsigned_32 bytes_read;
    v3_gbl_info *gi;
    long        cpos;
    char        name[256];

    total_bytes = sdh->addr_offset - sdh->gbl_offset;
    print_info_title( "Global" );

    bytes_read = 0;
    gi = (v3_gbl_info *) Wbuff;
    cpos = Curr_sectoff + sdh->gbl_offset;
    while( bytes_read < total_bytes ) {
        Wlseek( cpos );
        Wread( Wbuff, sizeof( v3_gbl_info ) + 255 );
        bytes_read += sizeof( v3_gbl_info ) + gi->name[0];
        cpos += sizeof( v3_gbl_info ) + gi->name[0];
        get_len_prefix_string( name, gi->name );
        Wdputs( "  Name:  " );
        Wdputs(  name );
        Wdputslc( "\n" );
        Wdputs( "    address      = " );
        Puthex( gi->addr.segment, 4 );
        Wdputc( ':' );
        Puthex( gi->addr.offset, 8 );
        Wdputslc( "\n" );
        Wdputs( "    module index = " );
        Putdec( gi->mod );
        Wdputslc( "\n" );
        Wdputs( "    kind:         " );
        if( gi->kind & GBL_KIND_STATIC ) {
            Wdputs( " (static pubdef)" );
        }
        if( gi->kind & GBL_KIND_CODE ) {
            Wdputs( " (code)" );
        }
        if( gi->kind & GBL_KIND_DATA ) {
            Wdputs( " (data)" );
        }
        Wdputslc( "\n" );
    }
    Wdputslc( "\n" );

} /* dump_global_info */
Пример #5
0
/*
 * Dump the Resource Id's.
 */
static void dmp_res_name_id( unsigned_16 count, bool is_name )
/***********************************************************/
{
    unsigned_16             i, j, cnt;
    unsigned_32             offset, tmp_off;
    resource_dir_header     pe_res_name;
    resource_dir_entry      pe_res_dir;
    res_name                name;

    if( count == 0 ) return;
    offset = Res_off + sizeof( resource_dir_header );
    for( i = 0; i < count; i++ ) {
        Wlseek( offset );
        Wread( &pe_res_dir, sizeof( resource_dir_entry ) );
        offset += sizeof( resource_dir_entry );
        tmp_off = Res_off +( pe_res_dir.id_name & PE_RESOURCE_MASK );
        if( is_name ) {
            name = get_name( tmp_off );
        } else {
            name.len = 0;
            name.rname = NULL;
        }
        tmp_off = Res_off +( pe_res_dir.entry_rva & PE_RESOURCE_MASK );
        Wlseek( tmp_off );
        Wread( &pe_res_name, sizeof( resource_dir_header ) );
        tmp_off += sizeof( resource_dir_header );
        cnt = pe_res_name.num_name_entries + pe_res_name.num_id_entries;
        for( j = 0; j < cnt; j++ ) {
            if( is_name ) {
                Wdputs( name.rname );
                for( j = name.len; j <= SLEN; j++ ) {
                    Wdputc( ' ' );
                }
            } else {
                Puthex( pe_res_dir.id_name, 8 );
                Wdputs( "                       " );
            }
            if( j >= pe_res_name.num_name_entries ) {
                dmp_name_id( tmp_off, FALSE );
            } else {
                dmp_name_id( tmp_off, TRUE );
            }
            tmp_off += sizeof( resource_dir_entry );
            Wdputslc( "\n" );
        }
    }
}
Пример #6
0
static void getAT( uint_32 value )
/********************************/
{
    const char  *result;
    int         i;

    result = Getname( value, readableATs, NUM_ATS );
    if( result == NULL ) {
        Wdputs( "AT_" );
        Puthex( value, 8 );
        Wdputs( "                   " );
    } else {
        Wdputs( result );
        for( i = strlen( result ); i < 30; i++ ) {
            Wdputc( ' ' );
        }
    }
}
Пример #7
0
static void getFORM( uint_32 value )
/**********************************/
{
    const char  *result;
    int         i;

    result = Getname( value, readableFORMs, NUM_FORMS );
    if( result == NULL ) {
        Wdputs( "FORM_" );
        Puthex( value, 8 );
        Wdputs( "     " );
    } else {
        Wdputs( result );
        for( i = strlen( result ); i < 18; i++ ) {
            Wdputc( ' ' );
        }
    }
}
Пример #8
0
static void get_reference_op( uint_8 value )
/******************************************/
{
    const char  *result;
    int         i;

    result = Getname( value, readableReferenceOps, NUM_REFERENCE_OPS );
    if( result == NULL ) {
        Wdputs( "REF_" );
        Puthex( value, 2 );
        Wdputs( "          " );
    } else {
        Wdputs( result );
        for( i = strlen( result ); i < 16; i++ ) {
            Wdputc( ' ' );
        }
    }
}
Пример #9
0
/*
 * printout a resource name
 */
static void dmp_resrc_nam( unsigned_16 res_type )
/***********************************************/
{
    char    *name;

    Wdputc( ' ' );
    if( res_type & SEG_RESRC_HIGH ) {
        res_type &= ~SEG_RESRC_HIGH;
        Wdputs( "resource id: " );
        Putdec( res_type );
        Wdputslc( "\n" );
    } else {
        name = get_resrc_nam( res_type );
        Wdputs( name );
        Wdputslc( "\n" );
        free( name );
    }
}
Пример #10
0
static void get_standard_op( uint_8 value )
/*****************************************/
{
    const char      *result;
    int             i;

    result = Getname( value, readableStandardOps, NUM_STANDARD_OPS );
    if( result == NULL ) {
        Wdputs( "OP_" );
        Puthex( value, 2 );
        Wdputs( "                   " );
    } else {
        Wdputs( result );
        for( i = strlen( result ); i < 24; i++ ) {
            Wdputc( ' ' );
        }
    }
}
Пример #11
0
/*
 * Dump external reference (import) table.
 */
static void dmp_external_ref( void )
/**********************************/
{
    unsigned_32     i,j;
    unsigned_8      len;
    char            *name;
    unsigned_32     num;
    unsigned_32     reloc;

    if( Nlm_head.numberOfExternalReferences  == 0 ) {
        return;
    }
    Wdputslc( "\n" );
    Wlseek( Nlm_head.externalReferencesOffset );
    Banner( "External Reference (Import) Table" );
    Wdputslc( "80000000H = relocation not relative to current position\n" );
    Wdputslc( "40000000H = relocation to code segment\n" );
    for( i = 0; i < Nlm_head.numberOfExternalReferences; i++ ) {
        Wread( &len, sizeof( unsigned_8 ) );
        name = Wmalloc( len );
        Wread( name, len );
        name[len] = '\0';
        Wdputs( name );
        Wdputs( ",  relocations:" );
        Wdputslc( "\n" );
        Wread( &num, sizeof( unsigned_32 ) );
        Wdputs( "        " );
        for( j = 0; j < num; j++ ) {
            Wread( &reloc, sizeof( unsigned_32 ) );
            if( j != 0 ) {
                if( (j) % 4 == 0 ) {
                    Wdputslc( "\n        " );
                } else {
                    Wdputs( "      " );
                }
            }
            Putdecl( j, 2 );
            Wdputc( ':' );
            Puthex( reloc, 8 );
        }
        Wdputslc( "\n" );
    }
}
Пример #12
0
static void dump_hex( const uint_8 *input, uint length )
/******************************************************/
{
    char        *p;
    int         i;
    uint        offset;
    uint        old_offset;
    char        hex[ 80 ];
    char        printable[ 17 ];
    int         ch;

    offset = 0;
    for( ;; ) {
        i = 0;
        p = hex;
        old_offset = offset;
        for( ;; ) {
            if( offset == length ) break;
            if( i > 0xf ) break;
            if( i == 0x8 ) {
                *p++ = ' ';
            }
            ch = input[ offset ];
            p += sprintf( p, " %02x", ch );
            printable[ i ] = isprint( ch ) ? ch : '.';
            ++i;
            ++offset;
        }
        *p = '\0';
        printable[i] = '\0';
        Puthex( old_offset, 8 );
        Wdputc( ':' );
        Wdputs( hex );
        Wdputs( " <" );
        Wdputs( printable );
        Wdputslc( ">\n" );
//      Wdputs( "%08lx:%-49s <%s>\n", old_offset, hex, printable );
        p = printable;
        i = 0;
        if( offset == length ) break;
    }
}
Пример #13
0
/*
 * Dump Segment Table Entry
 */
static void dmp_seg_ent( struct segment_record *seg_ent )
/*******************************************************/
{
    Wdputc( ' ' );
    Puthex( (unsigned_32)seg_ent->address
        << Os2_head.align, 8 );
    Wdputc( ' ' );
    Puthex( seg_ent->size, 4 );
    Wdputc( ' ' );
    Puthex( seg_ent->min, 4 );
    Wdputc( ' ' );
    Wdputc( ' ' );
    Puthex( seg_ent->info >> SEG_SHIFT_PRI_LVL , 4 );
    Wdputc( ' ' );
    Wdputc( ' ' );
    Puthex( seg_ent->info >> SEG_SHIFT_PMODE_LVL, 4 );
    Wdputc( ' ' );
    Puthex( seg_ent->info, 4 );
    Wdputslc( "\n" );
    dmp_seg_flag( seg_ent->info );
    Wdputslc( "\n" );
}
Пример #14
0
/*
 * Dump the Resource Names.
 */
static void dmp_name_id( unsigned_32 offset, bool is_name )
/*********************************************************/
{
    unsigned_16             i, j, cnt;
    resource_dir_entry      pe_res_dir, tmp_dir;
    resource_dir_header     pe_res_lang;
    res_name                name;

    Wlseek( offset );
    Wread( &pe_res_dir, sizeof( resource_dir_entry ) );
    offset = Res_off +( pe_res_dir.id_name & PE_RESOURCE_MASK );
    if( is_name ) {
        name = get_name( offset );
        Wdputs( name.rname );
        for( j = name.len; j <= SLEN; j++ ) {
            Wdputc( ' ' );
        }
    } else {
        Puthex( pe_res_dir.id_name, 8 );
        Wdputs( "                       " );
    }
    offset = Res_off +( pe_res_dir.entry_rva & PE_RESOURCE_MASK );
    if( pe_res_dir.entry_rva & PE_RESOURCE_MASK_ON ) {
        Wlseek( offset );
        Wread( &pe_res_lang, sizeof( resource_dir_header ) );
        offset += sizeof( resource_dir_header );
        Wlseek( offset );
        cnt = pe_res_lang.num_id_entries;
        for( i = 0; i < cnt; i++ ) {
            Wread( &tmp_dir, sizeof( resource_dir_entry ) );
            Puthex( tmp_dir.id_name, 8 );
            if( i != cnt - 1 ) {
                Wdputslc( "\n                                                             " );
            }
        }
        offset = Res_off +( tmp_dir.entry_rva & PE_RESOURCE_MASK );
    }
    if( Data_off == 0 ) {
        Data_off = offset;
    }
}
Пример #15
0
/*
 * Dump fixups.
 */
static void dmp_fixup( unsigned_16 size, bool float_pt )
/******************************************************/
{
    lmf_data        fixup;
    unsigned_16     i;

    Wdputslc( "\n" );
    if( float_pt ) {
        Banner( "Floating Point Fixup Table" );
    } else {
        Banner( "Fixup Table" );
    }
    Wdputs( "size = " );
    Puthex( size, 4 );
    if( Options_dmp & FIX_DMP ) {
        if( float_pt ) {
            Wdputslc( "      segment : type:offset\n" );
        } else {
            Wdputslc( "      segment : offset\n" );
        }
        for( i = 0; i < size / sizeof( lmf_data ); i++ ) {
            Wread( &fixup, sizeof( lmf_data ) );
            if( i != 0 ) {
                if( i % 4 == 0 ) {
                    Wdputslc( "\n" );
                } else {
                    Wdputs( "     " );
                }
            }
            Puthex( fixup.segment, 4 );
            Wdputs( " : " );
            if( float_pt ) {
                Puthex( fixup.offset >> 28, 1 );
                Wdputc( ':' );
                Puthex( fixup.offset, 7 );
            } else {
                Puthex( fixup.offset, 8 );
            }
        }
    }
Пример #16
0
/*
 * printout a resource type name
 */
static void dmp_resrc_type_nam( unsigned_16 res_type )
/****************************************************/
{
    char    *name;

    Wdputc( ' ' );
    if( res_type & SEG_RESRC_HIGH ) {
        res_type &= ~SEG_RESRC_HIGH;
        if( res_type > 15 ) {
            Wdputs( "Type number: " );
            Putdec( res_type );
            Wdputslc( "\n" );
        } else {
            Wdputslc( resource_type[ res_type ] );
        }
    } else {
        name = get_resrc_nam( res_type );
        Wdputs( name );
        Wdputslc( "\n" );
        free( name );
    }
}
Пример #17
0
static int parse_options( int argc, char * const *argv )
/******************************************************/
{
    int     c;
    char    *arg;

    Options_dmp = EXE_INFO;
    Segspec = 0;
    Hexoff = 0;

    for( ;; ) {
        while(optind < argc &&
              (c = getopt( argc, argv, ":aA:bB:dD:efipqrsS:x" )) != -1 ) {
            switch( c ) {
            case 'A':
                Options_dmp |= FIX_DMP | PAGE_DMP | RESRC_DMP | EXE_INFO | DOS_SEG_DMP | OS2_SEG_DMP;
                Segspec = atoi( optarg );
                if( Segspec == 0 ) {
                    Options_dmp &= ~OS2_SEG_DMP;
                } else {
                    Options_dmp &= ~DOS_SEG_DMP;
                }
                break;
            case 'a':
                Options_dmp |= FIX_DMP | PAGE_DMP | RESRC_DMP | EXE_INFO | DOS_SEG_DMP | OS2_SEG_DMP;
                break;
            case 'B':
                Hexoff = strtol( optarg, NULL, 16 );
                /* fall through */
            case 'b':
                Options_dmp |= BINARY_DMP;
                Options_dmp &= ~EXE_INFO;
                break;
            case 'D':
                Debug_options = 0;
                arg = optarg;
                while( islower( *arg ) || isupper( *arg ) ) {
                    debug_opts( *arg++ );
                }
                /* fall through */
            case 'd':
                Options_dmp |= DEBUG_INFO;
                Options_dmp &= ~EXE_INFO;
                break;
            case 'e':
                Options_dmp |= EXE_INFO;
                break;
            case 'f':
                Options_dmp |= EXE_INFO;
                Options_dmp |= FIX_DMP;
                break;
            case 'i':
                Options_dmp |= IMPORT_LIB;
                Options_dmp |= QUIET;
                Options_dmp &= ~EXE_INFO;
                break;
            case 'p':
                Options_dmp |= EXE_INFO | PAGE_DMP;
                break;
            case 'q':
                Options_dmp |= QUIET;
                break;
            case 'r':
                Options_dmp |= EXE_INFO | RESRC_DMP;
                break;
            case 'S':
                Options_dmp |= EXE_INFO | DOS_SEG_DMP | OS2_SEG_DMP;
                Segspec = atoi( optarg );
                if( Segspec == 0 ) {
                    Options_dmp &= ~OS2_SEG_DMP;
                } else {
                    Options_dmp &= ~DOS_SEG_DMP;
                }
                break;
            case 's':
                Options_dmp |= EXE_INFO | DOS_SEG_DMP | OS2_SEG_DMP;
                break;
            case 'x':
                Options_dmp |= IMPORT_DEF;
                Options_dmp |= QUIET;
                Options_dmp &= ~EXE_INFO;
                break;
            case ':':
                Wdputs( "wdump: option requires argument: -" );
                Wdputc( optopt );
                Wdputslc( "\n" );
                return( 1 );
            case '?':
                usage();
                return( 1 );
            default:
                Wdputs( "wdump: invalid option: -" );
                Wdputc( c );
                Wdputslc( "\n" );
                return( 1 );
            }
        }
        if( optind < argc ) {
            if( Name == NULL ) {
                Name = argv[optind++];
            } else {
                Wdputs( "wdump: multiple pathnames not accepted\n" );
                return( 1 );
            }
        } else {
            break;
        }
    }
    return( 0 );
}
Пример #18
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" );
    }
}
Пример #19
0
/*
 * Dump the program and section headers.
 */
static void dmp_prog_sec( unsigned_32 start )
/*******************************************/
{
    Elf32_Phdr      elf_prog;
    Elf32_Shdr      elf_sec;
    unsigned_32     offset;
    char            *string_table;
    int             i;

    // grab the string table, if it exists
    if( Options_dmp & DEBUG_INFO ) {
        set_dwarf( start );
    }
    if( Elf_head.e_shstrndx ) {
        offset = Elf_head.e_shoff
               + Elf_head.e_shstrndx * Elf_head.e_shentsize+start;
        Wlseek( offset );
        Wread( &elf_sec, sizeof( Elf32_Shdr ) );
        swap_shdr( &elf_sec );
        string_table = Wmalloc( elf_sec.sh_size );
        Wlseek( elf_sec.sh_offset + start );
        Wread( string_table, elf_sec.sh_size );
    } else {
        string_table = 0;
    }
    if( Elf_head.e_phnum ) {
        Banner( "ELF Program Header" );
        offset = Elf_head.e_phoff + start;
        for( i = 0; i < Elf_head.e_phnum; i++ ) {
            Wdputs( "                Program Header #" );
            Putdec( i + 1 );
            Wdputslc( "\n" );
            if( start != 0 ) {
                Wdputs("File Offset:");
                Puthex( offset, 8 );
                Wdputslc( "\n");
            }
            Wlseek( offset );
            Wread( &elf_prog, sizeof( Elf32_Phdr ) );
            swap_phdr( &elf_prog );
//          elf_prog.p_offset += start; //Relocate file pos
            offset += sizeof( Elf32_Phdr );
            Data_count++;
            dmp_prog_type( elf_prog.p_type );
            Dump_header( &elf_prog, elf_prog_msg );
            dmp_prog_flgs( elf_prog.p_flags );
            if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) {
                if( Segspec == 0 || Segspec == Data_count ) {
                    Dmp_seg_data( elf_prog.p_offset + start, elf_prog.p_filesz );
                }
            } else if( elf_prog.p_type == PT_NOTE ) {
                dmp_sec_note( elf_prog.p_offset + start, elf_prog.p_filesz );
            }
            Wdputslc( "\n" );
        }
    }
    if( Elf_head.e_shnum ) {
        Banner( "ELF Section Header" );
        offset = Elf_head.e_shoff+start;
        for( i = 0; i < Elf_head.e_shnum; i++ ) {
            Wlseek( offset );
            Wread( &elf_sec, sizeof( Elf32_Shdr ) );
            swap_shdr( &elf_sec );
//          elf_sec.sh_offset += start;  // relocate file pos
            Wdputs( "             Section Header #" );
            Putdec( i );
            if( string_table ) {
                Wdputs( " \"" );
                Wdputs( &(string_table[elf_sec.sh_name]) );
                Wdputs( "\"" );
            }
            Wdputslc( "\n" );
            if( start != 0 ) {
                Wdputs( "File Offset:" );
                Puthex( offset, 8 );
                Wdputslc( "\n" );
            }
            dmp_sec_type( elf_sec.sh_type );
            Dump_header( &elf_sec.sh_name, elf_sec_msg );
            dmp_sec_flgs( elf_sec.sh_flags );
            if( Options_dmp & FIX_DMP ) {
                if( elf_sec.sh_type==SHT_REL || elf_sec.sh_type==SHT_RELA ) {
                    Elf32_Shdr      rel_sec;
                    Elf32_Rela      elf_rela;
                    int             loc, ctr, rel_size;

                    Wdputs( "relocation information for section #" );
                    Putdec( elf_sec.sh_info );
                    Wlseek( Elf_head.e_shoff + start +
                            Elf_head.e_shentsize * elf_sec.sh_info );
                    Wread( &rel_sec, sizeof( Elf32_Shdr ) );
                    swap_shdr( &rel_sec );
                    if( string_table ) {
                        Wdputs( " \"" );
                        Wdputs( &string_table[rel_sec.sh_name] );
                        Wdputs( "\"" );
                    } else {
                        Wdputs( " no_name (no associated string table)" );
                    }
                    Wdputslc( ":\n" );
                    Wdputs( "symbol index refers to section #" );
                    Putdec( elf_sec.sh_link );
                    Wdputslc( "\n" );
                    Wdputslc( "Offset   Sym Idx  Addend   Type      Offset   Sym Idx  Addend   Type\n" );
                    rel_size = (elf_sec.sh_type == SHT_REL ? sizeof( Elf32_Rel ) : sizeof( Elf32_Rela ));
                    for( loc = 0, ctr = 0; loc < elf_sec.sh_size; loc += rel_size, ctr++ ) {
                        Wlseek( elf_sec.sh_offset + start + loc );
                        Wread( &elf_rela, rel_size );
                        Puthex( elf_rela.r_offset, 8 );
                        Wdputc( ' ' );
                        Puthex( ELF32_R_SYM( elf_rela.r_info ), 8 );
                        Wdputc( ' ' );
                        if( elf_sec.sh_type == SHT_RELA ) {
                            Puthex( elf_rela.r_addend, 8 );
                        } else {
                            Wdputs( "n/a     " );
                        }
                        Wdputc( ' ' );
                        Puthex( ELF32_R_TYPE( elf_rela.r_info ), 2 );
                        if( ctr % 2 == 1 ) {
                            Wdputslc( "\n" );
                        } else {
                            Wdputs( "        " );
                        }
                    }
                    if( ctr % 2 != 0 ) {
                        Wdputslc( "\n" );
                    }
                }
            }
            if( Options_dmp & DEBUG_INFO ) {
                Wdputslc( "\n" );
                if( string_table ) {
                    dmp_sec_data( &(string_table[elf_sec.sh_name]),
                                  elf_sec.sh_type,
                                  elf_sec.sh_offset+start,
                                  elf_sec.sh_size );
                } else {
                    dmp_sec_data( NULL,
                                  elf_sec.sh_type,
                                  elf_sec.sh_offset+start,
                                  elf_sec.sh_size );
                }
            } else if( Options_dmp & OS2_SEG_DMP ) {
                if( elf_sec.sh_size && elf_sec.sh_type != SHT_NOBITS ) {
                    Wdputslc( "Section dump:\n" );
                    Dmp_seg_data( elf_sec.sh_offset + start, elf_sec.sh_size );
                }
            }
            Wdputslc( "\n" );
            offset +=  Elf_head.e_shentsize;
        }
    }
    if( string_table ) {
        free( string_table );
    }
}
Пример #20
0
/*
 * dump_locals - dump all local variable information
 */
static void dump_locals( mod_info *mi )
/*************************************/
{
    int         i;
    unsigned_32 *offs;
    int         cnt;
    unsigned_32 coff;
    unsigned_8  buff[256];
    char        name[256];
    set_base    *sb;
    set_base386 *sb386;
    unsigned_8  *ptr;
    addr32_ptr  *p32;
    addr48_ptr  *p48;
    unsigned_16 index;

    cnt = mi->di[DMND_LOCALS].u.entries;
    if( cnt == 0 ) {
        return;
    }
    Wdputslc( "\n" );
    Wdputslc( "   *** Locals ***\n" );
    Wdputslc( "   ==============\n" );

    offs = alloca( (cnt+1) * sizeof( unsigned_32 ) );
    if( offs == NULL ) {
        Wdputslc( "Error! Not enough stack.\n" );
        longjmp( Se_env, 1 );
    }
    Wlseek( Curr_sectoff + mi->di[DMND_LOCALS].info_off );
    Wread( offs, (cnt+1) * sizeof( unsigned_32 ) );
    for( i = 0; i < cnt; i++ ) {
        coff = 0;
        Wdputs( "      Data " );
        Putdec( i );
        Wdputs( ":  offset " );
        Puthex( offs[i], 8 );
        Wdputslc( "\n" );
        for( ;; ) {
            Wlseek( coff + Curr_sectoff + offs[i] );
            Wread( buff, sizeof( buff ) );
            Wdputs( "        " );
            Puthex( coff, 4 );
            Wdputs( ": " );
            switch( buff[1] ) {
            case MODULE:
                Wdputslc( "MODULE\n" );
                ptr = buff+2;
                p32 = (addr32_ptr *)ptr;
                ptr += sizeof( addr32_ptr );
                ptr = Get_type_index( ptr, &index );
                Get_local_name( name, ptr, buff );
                Wdputs( "          \"" );
                Wdputs( name );
                Wdputs( "\"  addr = " );
                Puthex( p32->segment, 4 );
                Wdputc( ':' );
                Puthex( p32->offset, 4 );
                Wdputs( ", type = " );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case LOCAL:
                Wdputslc( "LOCAL\n" );
                ptr = buff+2;
                Wdputs( "          address: " );
                ptr = Dump_location_expression( ptr, "            " );
                ptr = Get_type_index( ptr, &index );
                Get_local_name( name, ptr, buff );
                Wdputs( "          name = \"" );
                Wdputs( name );
                Wdputs( "\",  type = " );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case MODULE_386:
                Wdputslc( "MODULE_386\n" );
                ptr = buff+2;
                p48 = (addr48_ptr *)ptr;
                ptr += sizeof( addr48_ptr );
                ptr = Get_type_index( ptr, &index );
                Get_local_name( name, ptr, buff );
                Wdputs( "          \"" );
                Wdputs( name );
                Wdputs( "\" addr = " );
                Puthex( p48->segment, 4 );
                Wdputc( ':' );
                Puthex( p48->offset, 8 );
                Wdputs( ",  type = " );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case MODULE_LOC:
                Wdputslc( "MODULE_LOC\n" );
                ptr = buff+2;
                Wdputs( "          address: " );
                ptr = Dump_location_expression( ptr, "            " );
                ptr = Get_type_index( ptr, &index );
                Get_local_name( name, ptr, buff );
                Wdputs( "          name = \"" );
                Wdputs( name );
                Wdputs( "\",  type = " );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case BLOCK:
                Wdputslc( "BLOCK\n" );
                dump_block( buff, FALSE );
                break;
            case NEAR_RTN:
                Wdputslc( "NEAR_RTN\n" );
                dump_rtn( buff );
                break;
            case FAR_RTN:
                Wdputslc( "FAR_RTN\n" );
                dump_rtn( buff );
                break;
            case BLOCK_386:
                Wdputslc( "BLOCK_386\n" );
                dump_block( buff, TRUE );
                break;
            case NEAR_RTN_386:
                Wdputslc( "NEAR_RTN_386\n" );
                dump_rtn386( buff );
                break;
            case FAR_RTN_386:
                Wdputslc( "FAR_RTN_386\n" );
                dump_rtn386( buff );
                break;
            case MEMBER_SCOPE:
                Wdputslc( "MEMBER_SCOPE\n" );
                index = 5;
                ptr = buff+2;
                Wdputs( "          parent offset = " );
                Puthex( *ptr, 4 );
                ptr += 2;
                if( *ptr & 0x80 ) {
                    index = 6;
                }
                Wdputs( "  class type = " );
                ptr = Get_type_index( ptr, &index );
                Putdec( index );
                if( buff[0] > index ) {
                    Wdputslc( "\n          object ptr type = " );
                    Puthex( *ptr++, 2 );
                    Wdputs( "  object loc = " );
                    Dump_location_expression( ptr, "            " );
                }
                Wdputslc( "\n" );
                break;
            case ADD_PREV_SEG:
                Wdputslc( "ADD_PREV_SEG\n" );
                Wdputs( "          segment increment = " );
                Puthex( *(buff+2), 4 );
                Wdputslc( "\n" );
                break;
            case SET_BASE:
                Wdputslc( "SET_BASE\n" );
                sb = (set_base *) buff;
                Wdputs( "          base = " );
                Puthex( sb->seg, 4 );
                Wdputc( ':' );
                Puthex( sb->off, 4 );
                Wdputslc( "\n" );
                break;
            case SET_BASE_386:
                Wdputslc( "SET_BASE_386\n" );
                sb386 = (set_base386 *) buff;
                Wdputs( "          base = " );
                Puthex( sb386->seg, 4 );
                Wdputc( ':' );
                Puthex( sb386->off, 8 );
                Wdputslc( "\n" );
                break;
            }
            coff += buff[0];
            if( coff >= (offs[i+1] - offs[i]) ) {
                break;
            }
        }
    }

} /* dump_locals */
Пример #21
0
/*
 * dump_single_location_entry - dump a single location expression entry
 */
static unsigned_8 *dump_single_location_entry( unsigned_8 *buff )
/***************************************************************/
{
    unsigned_8  type;
    addr32_ptr  *p32;
    addr48_ptr  *p48;
    int         i;
    int         num;

    type = *buff;
    buff++;
    switch( type ) {
    case 0:
        Wdputslc( "<none>\n" );
        break;
    case BP_OFFSET_BYTE:
        Wdputs( "BP_OFFSET_BYTE( " );
        Puthex( *buff, 2 );
        Wdputslc( " )\n" );
        buff++;
        break;
    case BP_OFFSET_WORD:
        Wdputs( "BP_OFFSET_WORD( " );
        Puthex( *buff, 4 );
        Wdputslc( " )\n" );
        buff += sizeof( unsigned_16 );
        break;
    case BP_OFFSET_DWORD:
        Wdputs( "BP_OFFSET_DWORD( " );
        Puthex( *buff, 8 );
        Wdputslc( " )\n" );
        buff += sizeof( unsigned_32 );
        break;
    case CONST_ADDR286:
        p32 = (addr32_ptr *) buff;
        buff += sizeof( addr32_ptr );
        Wdputs( "CONST_ADDR286( " );
        Puthex( p32->segment, 4 );
        Wdputc( ':' );
        Puthex( p32->offset, 4 );
        Wdputslc( " )\n" );
        break;
    case CONST_ADDR386:
        p48 = (addr48_ptr *) buff;
        buff += sizeof( addr48_ptr );
        Wdputs( "CONST_ADDR386( " );
        Puthex( p48->segment, 4 );
        Wdputc( ':' );
        Puthex( p48->offset, 8 );
        Wdputslc( " )\n" );
        break;
    case CONST_INT_1:
        Wdputs( "CONST_INT_1( " );
        Puthex( *buff, 2 );
        Wdputslc( " )\n" );
        buff++;
        break;
    case CONST_INT_2:
        Wdputs( "CONST_INT_2( " );
        Puthex( *buff, 4 );
        Wdputslc( " )\n" );
        buff += sizeof( unsigned_16 );
        break;
    case CONST_INT_4:
        Wdputs( "CONST_INT_4( " );
        Puthex( *buff, 8 );
        Wdputslc( " )\n" );
        buff += sizeof( unsigned_32 );
        break;
    case IND_REG_CALLOC_NEAR:
        Wdputs( "IND_REG_CALLOC_NEAR( " );
        Wdputs( regLocStrs[ *buff ] );
        Wdputslc( " )\n" );
        buff++;
        break;
    case IND_REG_CALLOC_FAR:
        Wdputs( "IND_REG_CALLOC_FAR( " );
        Wdputs( regLocStrs[ *buff ] );
        Wdputc( ':' );
        Wdputs( regLocStrs[ *(buff+1) ] );
        Wdputslc( " )\n" );
        buff += 2;
        break;
    case IND_REG_RALLOC_NEAR:
        Wdputs( "IND_REG_RALLOC_NEAR( " );
        Wdputs( regLocStrs[ *buff ] );
        Wdputslc( " )\n" );
        buff++;
        break;
    case IND_REG_RALLOC_FAR:
        Wdputs( "IND_REG_RALLOC_FAR( " );
        Wdputs( regLocStrs[ *buff ] );
        Wdputc( ':' );
        Wdputs( regLocStrs[ *(buff+1) ] );
        Wdputslc( " )\n" );
        buff += 2;
        break;
    case OPERATOR_IND_2:
        Wdputslc( "OPERATOR_IND_2\n" );
        break;
    case OPERATOR_IND_4:
        Wdputslc( "OPERATOR_IND_4\n" );
        break;
    case OPERATOR_IND_ADDR286:
        Wdputslc( "OPERATOR_IND_ADDR286\n" );
        break;
    case OPERATOR_IND_ADDR386:
        Wdputslc( "OPERATOR_IND_ADDR386\n" );
        break;
    case OPERATOR_ZEB:
        Wdputslc( "OPERATOR_ZEB\n" );
        break;
    case OPERATOR_ZEW:
        Wdputslc( "OPERATOR_ZEW\n" );
        break;
    case OPERATOR_MK_FP:
        Wdputslc( "OPERATOR_MK_FP\n" );
        break;
    case OPERATOR_POP:
        Wdputslc( "OPERATOR_POP\n" );
        break;
    case OPERATOR_XCHG:
        Wdputs( "OPERATOR_XCHG: " );
        Puthex( *buff, 2 );
        Wdputslc( "\n" );
        buff++;
        break;
    case OPERATOR_ADD:
        Wdputslc( "OPERATOR_ADD\n" );
        break;
    case OPERATOR_DUP:
        Wdputslc( "OPERATOR_DUP\n" );
        break;
    case OPERATOR_NOP:
        Wdputslc( "OPERATOR_NOP\n" );
        break;
    default:
        if( type & 0x30 ) {
            num = (type & 0x0f)+1;
            Wdputs( "MULTI_REG(" );
            Putdec( num );
            Wdputs( "): " );
            for( i=0;i<num;i++ ) {
                Wdputs( regLocStrs[ *buff ] );
                if( i != num-1 ) {
                    Wdputs( ", " );
                } else {
                    Wdputslc( "\n" );
                }
                buff++;
            }
        } else if( type & 0x40 ) {
            Wdputs( "REG: " );
            Wdputs( regLocStrs[ type & 0x0f ] );
            Wdputslc( "\n" );
        } else {
            Wdputslc( "**** UNKNOWN LOCATION EXPRESSION!! ****\n" );
        }
        break;
    }

    return( buff );

} /* dump_single_location_entry */
Пример #22
0
/*
 * Dump_types - dump all typing information
 */
void Dmp_type( int cnt, unsigned_32 *offs )
/*****************************************/
{
    int         i;
    addr32_ptr  *p32;
    addr48_ptr  *p48;
    unsigned_8  *ptr;
    unsigned_16 index;
    unsigned_16 curr_index;
    unsigned_32 coff;
    char        name[256];
    unsigned_8  buff[256];

    for( i = 0; i < cnt; i++ ) {
        coff = 0;
        Wdputs( "      Data " );
        Putdec( i );
        Wdputs( ":  offset " );
        Puthex( offs[i], 8 );
        Wdputslc( "\n" );
        curr_index = 0;
        for( ;; ) {
            Wlseek( coff + Curr_sectoff + offs[i] );
            Wread( buff, sizeof( buff ) );
            Wdputs( "        " );
            Puthex( coff, 4 );
            Wdputs( ": " );
            ptr = buff+2;
            switch( buff[1] ) {
            case SCALAR:
                StartType( "SCALAR", ++curr_index );
                ptr = buff+3;
                Get_local_name( name, ptr, buff );
                Wdputs( "          \"" );
                Wdputs( name );
                Wdputs( "\"  scalar type = " );
                scalar_type( buff[2] );
                Wdputslc( "\n" );
                break;
            case SCOPE:
                StartType( "SCOPE", ++curr_index);
                Get_local_name( name, ptr, buff );
                Wdputs( "          \"" );
                Wdputs( name );
                Wdputslc( "\"\n" );
                break;
            case NAME:
                StartType( "NAME", ++curr_index);
                ptr = Get_type_index( ptr, &index );
                ptr = Get_type_index( ptr, &index );
                Get_local_name( name, ptr, buff );
                Wdputs( "          \"" );
                Wdputs( name );
                Wdputs( "\"  type idx = " );
                Putdec( index );
                Wdputs( "  scope idx = " );
                ptr = Get_type_index( buff+2, &index );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case CUE_TABLE:
                Wdputs( "cue table offset=" );
                Puthex( *(unsigned_32 *)ptr, 8 );
                Wdputslc( "\n" );
                break;
            case TYPE_EOF:
                return;
            case BYTE_INDEX:
                StartType( "BYTE_INDEX ARRAY", ++curr_index);
                array_index( ptr, 1 );
                break;
            case WORD_INDEX:
                StartType( "WORD_INDEX ARRAY", ++curr_index);
                array_index( ptr, 2 );
                break;
            case LONG_INDEX:
                StartType( "LONG_INDEX ARRAY", ++curr_index);
                array_index( ptr, 4 );
                break;
            case TYPE_INDEX:
                StartType( "TYPE_INDEX ARRAY", ++curr_index);
                Wdputs( "          index type = " );
                ptr = Get_type_index( ptr, &index );
                Putdec( index );
                base_type_index( ptr );
                break;
            case DESC_INDEX:
                StartType( "DESC_INDEX ARRAY", ++curr_index);
                desc_array( ptr, false );
                break;
            case DESC_INDEX_386:
                StartType( "DESC_INDEX ARRAY", ++curr_index);
                desc_array( ptr, true );
                break;
            case BYTE_RANGE:
                StartType( "BYTE_RANGE", ++curr_index);
                range( ptr, 1 );
                break;
            case WORD_RANGE:
                StartType( "WORD_RANGE", ++curr_index);
                range( ptr, 2 );
                break;
            case LONG_RANGE:
                StartType( "LONG_RANGE", ++curr_index);
                range( ptr, 4 );
                break;
            case PTR_NEAR:
                StartType( "NEAR PTR", ++curr_index);
                Wdputs( "       " );
                near_ptr( buff );
                break;
            case PTR_FAR:
                StartType( "FAR PTR", ++curr_index);
                Wdputs( "       " );
                base_type_index( ptr );
                break;
            case PTR_HUGE:
                StartType( "HUGE PTR", ++curr_index);
                Wdputs( "       " );
                base_type_index( ptr );
                break;
            case PTR_NEAR_DEREF:
                StartType( "NEAR_DEREF PTR", ++curr_index);
                Wdputs( "       " );
                near_ptr( buff );
                break;
            case PTR_FAR_DEREF:
                StartType( "FAR_DEREF PTR", ++curr_index);
                Wdputs( "       " );
                base_type_index( ptr );
                break;
            case PTR_HUGE_DEREF:
                StartType( "HUGE_DEREF PTR", ++curr_index);
                Wdputs( "       " );
                base_type_index( ptr );
                break;
            case PTR_NEAR386:
                StartType( "NEAR386 PTR", ++curr_index);
                Wdputs( "       " );
                near_ptr( buff );
                break;
            case PTR_FAR386:
                StartType( "FAR386 PTR", ++curr_index);
                Wdputs( "       " );
                base_type_index( ptr );
                break;
            case PTR_NEAR386_DEREF:
                StartType( "NEAR386_DEREF PTR", ++curr_index);
                Wdputs( "       " );
                near_ptr( buff );
                break;
            case PTR_FAR386_DEREF:
                StartType( "FAR386_DEREF PTR", ++curr_index);
                Wdputs( "\n       " );
                base_type_index( ptr );
                break;
            case CLIST:
                StartType( "ENUM_LIST", ++curr_index);
                Wdputs( "          number of consts = " );
                Puthex( *ptr, 4 );
                Wdputs( "   scalar type = " );
                scalar_type( buff[4] );
                Wdputslc( "\n" );
                break;
            case CONST_BYTE:
                Wdputslc( "CONST_BYTE\n" );
                enum_const( buff, 1 );
                break;
            case CONST_WORD:
                Wdputslc( "CONST_WORD\n" );
                enum_const( buff, 2 );
                break;
            case CONST_LONG:
                Wdputslc( "CONST_LONG\n" );
                enum_const( buff, 4 );
                break;
            case FLIST:
                StartType( "FIELD_LIST", ++curr_index);
                Wdputs( "          number of fields = " );
                Puthex( *ptr, 4 );
                if( buff[0] > 4 ) {
                    Wdputs( "   size = " );
                    ptr += 2;
                    Puthex( *ptr, 8 );
                }
                Wdputslc( "\n" );
                break;
            case FIELD_BYTE:
                Wdputslc( "FIELD_BYTE\n" );
                bit_field_struct( buff, 1, false );
                break;
            case FIELD_WORD:
                Wdputslc( "FIELD_WORD\n" );
                bit_field_struct( buff, 2, false );
                break;
            case FIELD_LONG:
                Wdputslc( "FIELD_LONG\n" );
                bit_field_struct( buff, 4, false );
                break;
            case BIT_BYTE:
                Wdputslc( "BIT_BYTE\n" );
                bit_field_struct( buff, 1, true );
                break;
            case BIT_WORD:
                Wdputslc( "BIT_WORD\n" );
                bit_field_struct( buff, 2, true );
                break;
            case BIT_LONG:
                Wdputslc( "BIT_LONG\n" );
                bit_field_struct( buff, 4, true );
                break;
            case FIELD_CLASS:
                Wdputslc( "FIELD_CLASS\n" );
                bit_field_class( buff, false );
                break;
            case BIT_CLASS:
                Wdputslc( "BIT_CLASS\n" );
                bit_field_class( buff, true );
                break;
            case INHERIT_CLASS:
                Wdputslc( "INHERIT_CLASS\n" );
                Wdputs( "          adjust locator = " );
                ptr = Dump_location_expression( ptr, "            " );
                Wdputs( "          ancestor type = " );
                Get_type_index( ptr, &index );
                Putdec( index );
                Wdputslc( "\n" );
                break;
            case PNEAR:
                StartType( "NEAR PROC", ++curr_index);
                near_far_proc( buff );
                break;
            case PFAR:
                StartType( "FAR PROC", ++curr_index);
                near_far_proc( buff );
                break;
            case PNEAR386:
                StartType( "NEAR386 PROC", ++curr_index);
                near_far_proc( buff );
                break;
            case PFAR386:
                StartType( "FAR386 PROC", ++curr_index);
                near_far_proc( buff );
                break;
            case EXT_PARMS:
                Wdputslc( "EXT_PARMS\n" );
                param_type_index( (unsigned_8)buff[0]-2, ptr );
                break;
            case CHAR_BYTE:
                StartType( "CHAR_BYTE", ++curr_index);
                Wdputs( "        length = " );
                Puthex( *ptr, 2 );
                Wdputslc( "\n" );
                break;
            case CHAR_WORD:
                StartType( "CHAR_WORD", ++curr_index);
                Wdputs( "        length = " );
                Puthex( *ptr, 4 );
                Wdputslc( "\n" );
                break;
            case CHAR_LONG:
                StartType( "CHAR_LONG", ++curr_index);
                Wdputs( "        length = " );
                Puthex( *ptr, 8 );
                Wdputslc( "\n" );
                break;
            case CHAR_IND:
                StartType( "CHAR_IND", ++curr_index);
                Wdputs( "       scalar type = " );
                scalar_type( buff[2] );
                p32 = (addr32_ptr *)ptr;
                Puthex( p32->segment, 4 );
                Wdputc( ':' );
                Puthex( p32->offset, 4 );
                Wdputslc( "\n" );
                break;
            case CHAR_IND_386:
                StartType( "CHAR_IND_386", ++curr_index);
                Wdputs( "       scalar type = " );
                scalar_type( buff[2] );
                p48 = (addr48_ptr *)ptr;
                Puthex( p48->segment, 4 );
                Wdputc( ':' );
                Puthex( p48->offset, 8 );
                Wdputslc( "\n" );
                break;
            case CHAR_LOCATION:
                StartType( "CHAR_LOC", ++curr_index);
                Wdputs( "       scalar type = " );
                scalar_type( buff[2] );
                Wdputs( "          size locator = " );
                ptr = Dump_location_expression( ptr + 1, "            " );
                Wdputslc( "\n" );
                break;
            }
            coff += buff[0];
            if( coff >= (offs[i+1] - offs[i]) ) {
                break;
            }
        }
    }

} /* Dmp_type */
Пример #23
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 );
}