testdump.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,165 行 · 第 1/3 页

C
1,165
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Dump the contents of DWARF debug sections.
*
****************************************************************************/


#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include "walloca.h"

#include "watcom.h"
#include "bool.h"
#include "dw.h"
#include "dwarf.h"
#include "client.h"

extern bool byte_swap;

typedef struct {
    uint_32     value;
    char *      name;
} readable_name;

#pragma pack( push, 1 )
typedef struct arange_header {
    uint_32     len;
    uint_16     version;
    uint_32     dbg_pos;
    uint_8      addr_size;
    uint_8      seg_size;
} _WCUNALIGNED arange_header;
#pragma pack( pop )

#define table( x )      { x, #x }

static readable_name readableTAGs[] = {
    table( DW_TAG_padding ),
    table( DW_TAG_array_type ),
    table( DW_TAG_class_type ),
    table( DW_TAG_entry_point ),
    table( DW_TAG_enumeration_type ),
    table( DW_TAG_formal_parameter ),
    table( DW_TAG_imported_declaration ),
    table( DW_TAG_label ),
    table( DW_TAG_lexical_block ),
    table( DW_TAG_member ),
    table( DW_TAG_pointer_type ),
    table( DW_TAG_reference_type ),
    table( DW_TAG_compile_unit ),
    table( DW_TAG_string_type ),
    table( DW_TAG_structure_type ),
    table( DW_TAG_subroutine_type ),
    table( DW_TAG_typedef ),
    table( DW_TAG_union_type ),
    table( DW_TAG_unspecified_parameters ),
    table( DW_TAG_variant ),
    table( DW_TAG_common_block ),
    table( DW_TAG_common_inclusion ),
    table( DW_TAG_inheritance ),
    table( DW_TAG_inlined_subroutine ),
    table( DW_TAG_module ),
    table( DW_TAG_ptr_to_member_type ),
    table( DW_TAG_set_type ),
    table( DW_TAG_subrange_type ),
    table( DW_TAG_with_stmt ),
    table( DW_TAG_access_declaration ),
    table( DW_TAG_base_type ),
    table( DW_TAG_catch_block ),
    table( DW_TAG_const_type ),
    table( DW_TAG_constant ),
    table( DW_TAG_enumerator ),
    table( DW_TAG_file_type ),
    table( DW_TAG_friend ),
    table( DW_TAG_namelist ),
    table( DW_TAG_namelist_item ),
    table( DW_TAG_packed_type ),
    table( DW_TAG_subprogram ),
    table( DW_TAG_template_type_param ),
    table( DW_TAG_template_value_param ),
    table( DW_TAG_thrown_type ),
    table( DW_TAG_try_block ),
    table( DW_TAG_variant_part ),
    table( DW_TAG_variable ),
    table( DW_TAG_volatile_type ),
    table( DW_TAG_WATCOM_address_class_type ),
    table( DW_TAG_WATCOM_namespace )
};

#define NUM_TAGS        ( sizeof( readableTAGs ) / sizeof( readableTAGs[0] ) )

static readable_name readableFORMs[] = {
    table( DW_FORM_addr ),
    table( DW_FORM_block ),
    table( DW_FORM_block1 ),
    table( DW_FORM_block2 ),
    table( DW_FORM_block4 ),
    table( DW_FORM_data1 ),
    table( DW_FORM_data2 ),
    table( DW_FORM_data4 ),
    table( DW_FORM_data8 ),
    table( DW_FORM_flag ),
    table( DW_FORM_sdata ),
    table( DW_FORM_string ),
    table( DW_FORM_strp ),
    table( DW_FORM_udata ),
    table( DW_FORM_ref_addr ),
    table( DW_FORM_ref1 ),
    table( DW_FORM_ref2 ),
    table( DW_FORM_ref4 ),
    table( DW_FORM_ref8 ),
    table( DW_FORM_ref_udata ),
    table( DW_FORM_indirect )
};
#define NUM_FORMS       ( sizeof( readableFORMs ) / sizeof( readableFORMs[0] ) )

static readable_name readableATs[] = {
    table( DW_AT_sibling ),
    table( DW_AT_location ),
    table( DW_AT_name ),
    table( DW_AT_ordering ),
    table( DW_AT_byte_size ),
    table( DW_AT_bit_offset ),
    table( DW_AT_bit_size ),
    table( DW_AT_stmt_list ),
    table( DW_AT_low_pc ),
    table( DW_AT_high_pc ),
    table( DW_AT_language ),
    table( DW_AT_discr ),
    table( DW_AT_discr_value ),
    table( DW_AT_visibility ),
    table( DW_AT_import ),
    table( DW_AT_string_length ),
    table( DW_AT_common_reference ),
    table( DW_AT_comp_dir ),
    table( DW_AT_const_value ),
    table( DW_AT_containing_type ),
    table( DW_AT_default_value ),
    table( DW_AT_inline ),
    table( DW_AT_is_optional ),
    table( DW_AT_lower_bound ),
    table( DW_AT_producer ),
    table( DW_AT_prototyped ),
    table( DW_AT_return_addr ),
    table( DW_AT_start_scope ),
    table( DW_AT_stride_size ),
    table( DW_AT_upper_bound ),
    table( DW_AT_abstract_origin ),
    table( DW_AT_accessibility ),
    table( DW_AT_address_class ),
    table( DW_AT_artificial ),
    table( DW_AT_base_types ),
    table( DW_AT_calling_convention ),
    table( DW_AT_count ),
    table( DW_AT_data_member_location ),
    table( DW_AT_decl_column ),
    table( DW_AT_decl_file ),
    table( DW_AT_decl_line ),
    table( DW_AT_declaration ),
    table( DW_AT_discr_list ),
    table( DW_AT_encoding ),
    table( DW_AT_external ),
    table( DW_AT_frame_base ),
    table( DW_AT_friend ),
    table( DW_AT_identifier_case ),
    table( DW_AT_macro_info ),
    table( DW_AT_namelist_item ),
    table( DW_AT_priority ),
    table( DW_AT_segment ),
    table( DW_AT_specification ),
    table( DW_AT_static_link ),
    table( DW_AT_type ),
    table( DW_AT_use_location ),
    table( DW_AT_variable_parameter ),
    table( DW_AT_virtuality ),
    table( DW_AT_vtable_elem_location ),
    table( DW_AT_WATCOM_memory_model ),
    table( DW_AT_WATCOM_parm_entry ),
    table( DW_AT_WATCOM_references_start )
};
#define NUM_ATS         ( sizeof( readableATs ) / sizeof( readableATs[0] ) )


static readable_name readableStandardOps[] = {
    table( DW_LNS_copy ),
    table( DW_LNS_advance_pc ),
    table( DW_LNS_advance_line ),
    table( DW_LNS_set_file ),
    table( DW_LNS_set_column ),
    table( DW_LNS_negate_stmt ),
    table( DW_LNS_set_basic_block ),
    table( DW_LNS_const_add_pc ),
    table( DW_LNS_fixed_advance_pc )
};
#define NUM_STANDARD_OPS \
    ( sizeof( readableStandardOps ) / sizeof( readableStandardOps[0] ) )

static readable_name readableReferenceOps[] = {
    table( REF_BEGIN_SCOPE ),
    table( REF_END_SCOPE ),
    table( REF_SET_FILE ),
    table( REF_SET_LINE ),
    table( REF_SET_COLUMN ),
    table( REF_ADD_LINE ),
    table( REF_ADD_COLUMN ),
    table( REF_COPY )
};
#define NUM_REFERENCE_OPS \
    ( sizeof( readableReferenceOps ) / sizeof( readableReferenceOps[0] ) )

static char *sectionNames[] = {
    ".debug_info",
    ".debug_pubnames",
    ".debug_aranges",
    ".debug_line",
    ".debug_loc",
    ".debug_abbrev",
    ".debug_macinfo",
    ".debug_str",
    ".debug_ref"
};


static uint_32  getU32( uint_32 *src )
{
    if( byte_swap ) {
#ifdef __BIG_ENDIAN__
        return( GET_LE_32( *src ) );
#else
        return( GET_BE_32( *src ) );
#endif
    } else {
        return( *src );
    }
}

static uint_16  getU16( uint_16 *src )
{
    if( byte_swap ) {
#ifdef __BIG_ENDIAN__
        return( GET_LE_16( *src ) );
#else
        return( GET_BE_16( *src ) );
#endif
    } else {
        return( *src );
    }
}

static int compareTable( const void *_a, const void *_b ) {
    readable_name *a = (readable_name *)_a;
    readable_name *b = (readable_name *)_b;

    if( a->value > b->value ) {
        return( 1 );
    } else if( a->value == b->value ) {
        return( 0 );
    }
    return( -1 );
}


static void sortTables( void ) {

    qsort( readableTAGs, NUM_TAGS, sizeof( readable_name ), compareTable );
    qsort( readableFORMs, NUM_FORMS, sizeof( readable_name ), compareTable );
    qsort( readableATs, NUM_ATS, sizeof( readable_name ), compareTable );
}


static char *getName( uint_32 value, readable_name *table, size_t size ) {

    readable_name       dummy;
    readable_name *     result;

    dummy.value = value;
    result = bsearch( &dummy, table, size, sizeof( readable_name ),
        compareTable );
    if( result == NULL ) return( NULL );
    return( result->name );
}


static char *getTAG( uint_32 value ) {

    static char                 buf[ 30 ];
    char *                      result;

    result = getName( value, readableTAGs, NUM_TAGS );
    if( result == NULL ) {
        sprintf( buf, "TAG_%08lx", value );
        return( buf );
    }
    return( result );
}


static char *getFORM( uint_32 value ) {

    static char                 buf[ 30 ];
    char *                      result;

    result = getName( value, readableFORMs, NUM_FORMS );
    if( result == NULL ) {
        sprintf( buf, "FORM_%08lx", value );
        return( buf );
    }
    return( result );
}


static char *getAT( uint_32 value ) {

    static char                 buf[ 30 ];
    char *                      result;

    result = getName( value, readableATs, NUM_ATS );
    if( result == NULL ) {
        sprintf( buf, "AT_%08lx", value );
        return( buf );
    }
    return( result );
}


static void dumpHex( const char *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;
        printf( "%08lx:%-49s <%s>\n", old_offset, hex, printable );
        p = printable;
        i = 0;
        if( offset == length ) break;
    }
}

uint_8 *DecodeULEB128( const uint_8 *input, uint_32 *value ) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?