wsect.c

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

C
1,344
字号
/****************************************************************************
*
*                            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:  DWARF section processing.
*
****************************************************************************/


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

#include "wdglb.h"
#include "wdfunc.h"

static readable_name readableTAGs[] = {
    #define DWTAGI( __n, __v  )   table( DW_TAG_##__n ),
    #include "dwtagi.h"
    #undef  DWTAGI
};

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

static readable_name readableFORMs[] = {
    #define DWFORMI( __n, __v  )   table( DW_FORM_##__n ),
    #include "dwformi.h"
    #undef  DWFORMI
};
#define NUM_FORMS       ( sizeof( readableFORMs ) / sizeof( readableFORMs[0] ) )

static readable_name readableATs[] = {
    #define DWATI( __n, __v  )   table( DW_AT_##__n ),
    #include "dwati.h"
    #undef  DWATI
};
#define NUM_ATS         ( sizeof( readableATs ) / sizeof( readableATs[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",
    ".WATCOM_references"
};


static int compare_table( const void *pa, const void *pb )
/********************************************************/
{
    const readable_name *a = pa;
    const readable_name *b = pb;

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


static void sort_tables( void )
/*****************************/
{
    static int  done = 0;

    if( !done ) {
        done = 1;
        qsort( readableTAGs, NUM_TAGS, sizeof( readable_name ), compare_table );
        qsort( readableFORMs, NUM_FORMS, sizeof( readable_name ), compare_table );
        qsort( readableATs, NUM_ATS, sizeof( readable_name ), compare_table );
    }
}


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 ),
        compare_table );
    if( result == NULL ) return( NULL );
    return( result->name );
}


static void getTAG( uint_32 value )
/*********************************/
{
    char        *result;
    int         i;

    result = Getname( value, readableTAGs, NUM_TAGS );
    if( result == NULL ) {
        Wdputs( "TAG_" );
        Puthex( value, 8 );
        Wdputs( "                  " );
    } else {
        Wdputs( result );
        for( i = strlen( result ); i < 30; i++ ) {
            Wdputc( ' ' );
        }
    }
}


static void getFORM( uint_32 value )
/**********************************/
{
    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( ' ' );
        }
    }
}


static void getAT( uint_32 value )
/********************************/
{
    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( ' ' );
        }
    }
}


static void dump_hex( 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;
        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;
    }
}

uint_8 *DecodeULEB128( const uint_8 *input, uint_32 *value )
/**********************************************************/
{
    uint_32     result;
    uint        shift;
    uint_8      byte;

    result = 0;
    shift = 0;
    for( ;; ) {
        byte = *input++;
        result |= ( byte & 0x7f ) << shift;
        if( ( byte & 0x80 ) == 0 ) break;
        shift += 7;
    }
    *value = result;
    return( (uint_8 *)input );
}

uint_8 *DecodeLEB128( const uint_8 *input, int_32 *value )
/********************************************************/
{
    int_32      result;
    uint        shift;
    uint_8      byte;

    result = 0;
    shift = 0;
    for( ;; ) {
        byte = *input++;
        result |= ( byte & 0x7f ) << shift;
        shift += 7;
        if( ( byte & 0x80 ) == 0 ) break;
    }
    if( ( shift < 32 ) && ( byte & 0x40 ) ) {
        result |= - ( 1 << shift );
    }
    *value = result;
    return( (uint_8 *)input );
}

uint_8 *find_abbrev( uint_32 start, uint_32 code )
/************************************************/
{
    uint_8      *p;
    uint_8      *stop;
    uint_32     tmp;
    uint_32     attr;

    p = Sections[ DW_DEBUG_ABBREV ].data;
    p += 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;
        }
    }
}

static dw_locop_op const LocOpr[] = {
#define DW_LOC_OP( __n, __v )    __v,
#include "dwlocinf.h"
#undef DW_LOC_OP
};

static char   * const OpName[] = {
#define DW_LOC_OP( __n, __v )    #__n,
#include "dwlocinf.h"
#undef DW_LOC_OP
};
static char  * const RegName[] = {
#define DW_REG( __n )    #__n,
#include "dwreginf.h"
#undef DW_REG
};

static char const *GetInt( char const *p, uint_32 *ret, int size )
/****************************************************************/
{
    switch( size ) {
    case 1:
        *ret = *(uint_8 *)p;
        break;
    case 2:
        *ret = get_u16( (uint_16 *)p );
        break;
    case 4:
        *ret = get_u32( (uint_32 *)p );
        break;
    default:
        *ret = 0xffffffff;
        break;
    }
    p += size;
    return( p );
}

static void DmpLoc( char 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         tmp;
    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 ] );
        Wdputs( " " );
        opr = LocOpr[ op ];
        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, &tmp );
            op1u = tmp;
            Putdec( op1u );
            break;
        case DW_LOP_S128:
            p = DecodeLEB128( p, (int_32 *)&tmp );
            op1s = tmp;
            if( op1s < 0 ) {
                Wdputs( "-" );
                op1s = -op1s;
            }
            Putdec( op1s );
            break;
        case DW_LOP_U128_S128:
            p = DecodeULEB128( p, &tmp );
            op1u = tmp;
            p = DecodeLEB128( p, (int_32 *)&tmp );
            op2s = tmp;
            Putdec( op1u );
            Wdputs( "," );
            if( op2s < 0 ) {
                Wdputs( "-" );
                op2s = -op2s;
            }
            Putdec( 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;

⌨️ 快捷键说明

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