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 + -
显示快捷键?