drutils.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,082 行 · 第 1/3 页
C
1,082 行
extern dwr_formcl DWRFormClass( unsigned_16 form )
/************************************************/
// class a form
{
dwr_formcl formcl;
switch( form ) {
case DW_FORM_addr:
formcl = DWR_FORMCL_address;
break;
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_block:
formcl = DWR_FORMCL_block;
break;
case DW_FORM_flag:
formcl = DWR_FORMCL_flag;
break;
case DW_FORM_data1:
case DW_FORM_data2:
case DW_FORM_data4:
case DW_FORM_data8:
case DW_FORM_sdata:
case DW_FORM_udata:
formcl = DWR_FORMCL_data;
break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
case DW_FORM_ref_udata:
formcl = DWR_FORMCL_ref;
break;
case DW_FORM_ref_addr:
formcl = DWR_FORMCL_ref_addr;
break;
case DW_FORM_string:
formcl = DWR_FORMCL_string;
break;
case DW_FORM_indirect:
formcl = DWR_FORMCL_indirect;
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
return( formcl );
}
extern unsigned_32 ReadConst( unsigned form, dr_handle info )
/***********************************************************/
{
unsigned_32 retval;
switch( form ) {
case DW_FORM_data1:
case DW_FORM_ref1:
case DW_FORM_flag:
retval = DWRVMReadByte( info );
break;
case DW_FORM_data2:
case DW_FORM_ref2:
retval = DWRVMReadWord( info );
break;
case DW_FORM_ref_addr: // NYI: non-standard behaviour for DW_FORM_ref
case DW_FORM_data4:
case DW_FORM_ref4:
retval = DWRVMReadDWord( info );
break;
case DW_FORM_sdata:
retval = DWRVMReadSLEB128( &info );
break;
case DW_FORM_udata:
case DW_FORM_ref_udata:
retval = DWRVMReadULEB128( &info );
break;
case DW_FORM_indirect:
retval = DWRVMReadULEB128( &info );
retval = ReadConst( retval, info );
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
return( retval );
}
extern unsigned_32 DWRReadConstant( dr_handle abbrev, dr_handle info )
/********************************************************************/
{
unsigned form;
form = DWRVMReadULEB128( &abbrev );
return( ReadConst( form, info ) );
}
extern dr_handle DWRReadReference( dr_handle abbrev, dr_handle info )
/*******************************************************************/
// references are just a constant with the start of the compile unit added on.
{
dr_handle handle;
dw_formnum form;
form = DWRVMReadULEB128( &abbrev );
handle = ReadConst( form, info );
if( handle != 0 ) { // if not NULL relocate
if( form != DW_FORM_ref_addr ) {
handle += DWRFindCompileUnit( info );
} else {
if( DWRCurrNode->wat_version == 1 ) { // handle Watcom 10.x DWARF
handle += DWRFindCompileUnit( info );
} else {
handle += DWRCurrNode->sections[DR_DEBUG_INFO].base;
}
}
}
return( handle );
}
extern dr_handle DWRReadAddr( dr_handle abbrev, dr_handle info )
/**************************************************************/
// address size dependent on CCU info
{
dr_handle handle;
unsigned addr_size;
unsigned_32 retval;
unsigned form;
form = DWRVMReadULEB128( &abbrev );
if( form != DW_FORM_addr ) {
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
if( DWRCurrNode->addr_size == 0 ) {
handle = DWRFindCompileUnit( info );
addr_size = DWRGetAddrSize( handle );
} else {
addr_size = DWRCurrNode->addr_size;
}
switch( addr_size ) {
case 1:
retval = DWRVMReadByte( info );
break;
case 2:
retval = DWRVMReadWord( info );
break;
case 4:
retval = DWRVMReadDWord( info );
break;
}
return( retval );
}
extern char * DWRReadString( dr_handle abbrev, dr_handle info )
/*************************************************************/
{
unsigned form;
unsigned_32 offset;
form = DWRVMReadULEB128( &abbrev );
switch( form ) {
case DW_FORM_string:
return( DWRCopyString( &info ) );
case DW_FORM_strp:
offset = ReadConst( DW_FORM_data4, info );
return( DWRCopyDbgSecString( &info, offset ) );
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
return( NULL );
}
extern int DWRReadFlag( dr_handle abbrev, dr_handle info )
/********************************************************/
{
unsigned form;
form = DWRVMReadULEB128( &abbrev );
if( form == DW_FORM_data1 || form == DW_FORM_flag ) {
return( DWRVMReadByte( info ) );
} else {
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
return( 0 );
}
extern dr_handle DWRGetAbbrev( dr_handle *entry )
/***********************************************/
{
dr_handle abbrev;
compunit_info *cu;
cu = DWRFindCompileInfo( *entry );
abbrev = DWRVMReadULEB128( entry );
abbrev = cu->abbrevs[abbrev];
DWRVMSkipLEB128( &abbrev ); // skip the tag.
abbrev++; // skip the child pointer.
return( abbrev );
}
extern dr_handle DWRLookupAbbrev( dr_handle entry, dr_handle abbr )
/*****************************************************************/
{
dr_handle abbrev;
compunit_info *cu;
cu = DWRFindCompileInfo( entry );
if( abbr >= cu->numabbrevs ) {
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
abbrev = 0;
} else
abbrev = cu->abbrevs[abbr];
return( abbrev );
}
extern dr_handle DWRReadAbbrev( dr_handle entry )
/***********************************************/
{
dr_handle abbrev;
abbrev = DWRVMReadULEB128( &entry );
return( DWRLookupAbbrev( entry, abbrev ) );
}
extern char * DWRCopyString( dr_handle *info )
/********************************************/
{
unsigned count;
char *str;
count = DWRStrLen( *info );
str = DWRALLOC( count + 1 );
DWRGetString( str, info );
return( str );
}
extern char * DWRCopyDbgSecString( dr_handle *info, unsigned_32 offset )
/**********************************************************************/
{
unsigned count;
char *str;
dr_handle dbgsec_str;
dbgsec_str = DWRCurrNode->sections[DR_DEBUG_STR].base + offset;
count = DWRStrLen( dbgsec_str );
str = DWRALLOC( count + 1 );
DWRGetString( str, &dbgsec_str );
return( str );
}
extern dw_atnum DWRScanForAttrib( dr_handle *abbrev, dr_handle *info,
dw_atnum at )
/*******************************************************************/
/* look for a specific attribute in the list of attributes */
{
dw_atnum attrib;
dw_formnum form;
for( ;; ) {
attrib = DWRVMReadULEB128( abbrev );
if( attrib == at ) break;
form = DWRVMReadULEB128( abbrev );
if( attrib == 0 ) break;
DWRSkipForm( info, form );
}
return( attrib );
}
static unsigned_16 CompUnitTag[] = { DW_TAG_compile_unit, 0 };
extern void DWRGetCompileUnitHdr( dr_handle mod,
DWRCUWLK fn,
void *data )
/**********************************************/
{
dr_search_context ctxt;
compunit_info *compunit;
compunit = DWRFindCompileInfo( mod );
ctxt.compunit = compunit;
ctxt.start = compunit->start;
ctxt.end = compunit->start + DWRVMReadDWord( compunit->start );
ctxt.start += COMPILE_UNIT_HDR_SIZE;
ctxt.stack.size = 0;
ctxt.stack.free = 0;
ctxt.stack.stack = NULL;
DWRScanCompileUnit( &ctxt, fn, CompUnitTag, 0, data );
DWRFreeContextStack( &ctxt.stack );
}
extern dr_handle DRGetCompileUnitTag( dr_handle comp_unit )
/*********************************************************/
{ // given the start of the compilation unit header
// return the start of the DW_TAG_compile_unit
// assume it starts after header
comp_unit += COMPILE_UNIT_HDR_SIZE;
return( comp_unit );
}
#define DEMANGLE_BUF_SIZE 256
extern char * DWRGetName( dr_handle abbrev, dr_handle entry )
/***********************************************************/
{
char *name;
char buffer[ DEMANGLE_BUF_SIZE ];
int len;
int base_len;
name = NULL;
if( DWRScanForAttrib( &abbrev, &entry, DW_AT_name ) != 0 ) {
name = DWRReadString( abbrev, entry );
len = strlen( name );
if( __is_mangled( name, len ) ) {
base_len = __demangled_basename( name, len,
buffer, DEMANGLE_BUF_SIZE );
DWRREALLOC( name, base_len + 1 );
strncpy( name, buffer, base_len + 1 );
}
}
return( name );
}
void DRIterateCompileUnits( void *data, bool (*callback)( void *, dr_handle ) )
/*****************************************************************************/
{
compunit_info *compunit;
compunit = &DWRCurrNode->compunit;
do {
if( !callback( data, compunit->start ) ) break; // FALSE == quit
compunit = compunit->next;
} while( compunit != NULL );
}
bool DWRScanAllCompileUnits( dr_search_context * startingCtxt,
DWRCUWLK fn,
unsigned_16 const *tagarray, dr_depth depth, void * data )
/********************************************************************************/
{
bool cont;
dr_search_context ctxt;
int i;
if( startingCtxt == NULL ) {
ctxt.compunit = &DWRCurrNode->compunit;
ctxt.start = ((compunit_info *)ctxt.compunit)->start;
ctxt.end = ctxt.start + DWRVMReadDWord( ctxt.start );
ctxt.start += COMPILE_UNIT_HDR_SIZE;
ctxt.classhdl = 0;
ctxt.functionhdl = 0;
ctxt.stack.size = 0;
ctxt.stack.free = 0;
ctxt.stack.stack = NULL;
} else {
ctxt = *startingCtxt; /* structure copy */
/* but allocate and copy own stack */
ctxt.stack.stack = DWRALLOC( ctxt.stack.size * sizeof( uint_32 ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?