drutils.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,082 行 · 第 1/3 页
C
1,082 行
for( i = 0; i < ctxt.stack.free; i += 1 ) {
ctxt.stack.stack[ i ] = startingCtxt->stack.stack[ i ];
}
}
do {
cont = DWRScanCompileUnit( &ctxt, fn, tagarray, depth, data );
ctxt.compunit = ((compunit_info *) ctxt.compunit)->next;
if( ctxt.compunit ) {
ctxt.start = ((compunit_info *) ctxt.compunit)->start;
ctxt.end = ctxt.start + DWRVMReadDWord( ctxt.start );
ctxt.start += COMPILE_UNIT_HDR_SIZE;
}
} while( cont && ctxt.compunit != NULL );
DWRFreeContextStack( &ctxt.stack );
return( cont ); /* false if more symbols, true if at end of info */
}
extern bool DWRWalkCompileUnit( dr_handle mod, DWRCUWLK fn,
unsigned_16 const *tagarray, dr_depth depth, void *data )
/*******************************************************************************/
{
bool cont;
dr_search_context ctxt;
compunit_info *compunit;
compunit = DWRFindCompileInfo( mod );
ctxt.compunit = compunit;
ctxt.start = mod;
ctxt.end = compunit->start + DWRVMReadDWord( compunit->start );
ctxt.classhdl = 0;
ctxt.functionhdl = 0;
ctxt.stack.size = 0;
ctxt.stack.free = 0;
ctxt.stack.stack = NULL;
cont = DWRScanCompileUnit( &ctxt, fn, tagarray, depth, data );
DWRFreeContextStack( &ctxt.stack );
return( cont ); /* false if more symbols, true if at end of info */
}
extern int DWRWalkChildren( dr_handle mod, unsigned_16 const *tags,
DRWLKBLK *wlks, void *d )
/*****************************************************************/
// takes an array of tags and wlks and calls wlk on tag match
// default func called if the 0 tag at end of array has a non NULL func
{
dr_handle abbrev;
dr_handle curr;
dw_tagnum tag;
unsigned_8 haschild;
int index;
DRWLKBLK wlk;
compunit_info *cu;
cu = DWRFindCompileInfo( mod );
abbrev = DWRVMReadULEB128( &mod );
if( abbrev == 0 ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
abbrev = cu->abbrevs[abbrev];
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 ); /* skip child byte */
DWRSkipAttribs( abbrev, &mod );
if( haschild == DW_CHILDREN_yes ) {
curr = mod;
for( ;; ) {
mod = curr;
abbrev = DWRVMReadULEB128( &curr );
if( abbrev == 0 ) break;
abbrev = cu->abbrevs[ abbrev ];
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 );
index = 0;
while( tags[index] != 0 ) {
if( tags[index] == tag ) break;
++index;
}
wlk = wlks[index];
if( wlk != NULL ) {
if( !wlk( mod, index, d ) )
return( FALSE ); // FALSE == quit
}
if( haschild ) {
DWRSkipChildren( &abbrev, &curr );
} else {
DWRSkipAttribs( abbrev, &curr );
}
}
}
return( TRUE );
}
extern int DWRWalkContaining( dr_handle mod, dr_handle target,
DRWLKBLK wlk, void *d )
/************************************************************/
// Walk into tags that enclose target
// The final call shoud be target else a goose chase
{
dr_handle abbrev;
dr_handle curr;
dw_tagnum tag;
unsigned_8 haschild;
abbrev = DWRVMReadULEB128( &mod );
if( abbrev == 0 ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
abbrev = DWRLookupAbbrev( mod, abbrev );
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 ); /* skip child byte */
DWRSkipAttribs( abbrev, &mod );
if( haschild == DW_CHILDREN_yes ) {
curr = mod;
for( ;; ) {
dr_handle old_abbrev;
dr_handle old_curr;
if( curr > target ) break;
mod = curr;
abbrev = DWRVMReadULEB128( &curr );
if( abbrev == 0 ) break;
abbrev = DWRLookupAbbrev( mod, abbrev );
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 );
old_abbrev = abbrev;
old_curr = curr;
if( haschild ) {
DWRSkipChildren( &abbrev, &curr );
} else {
DWRSkipAttribs( abbrev, &curr );
}
if( curr > target ) { // mod < target < curr - encloses
if( !wlk( mod, 0, d ) ){
return( FALSE ); // FALSE == quit
}
abbrev = old_abbrev; // rest cause we are going in
curr = old_curr;
DWRSkipAttribs( abbrev, &curr ); // skip current tags stuff
}
}
}
return( TRUE );
}
extern bool DWRWalkSiblings( dr_handle curr,
unsigned_16 const *tags,
DRWLKBLK *wlks, void *d )
/*************************************************************/
// takes an array of tags and wlks and calls wlk on tag match
// default func called if the 0 tag at end of array has a non NULL func
// positions curr at next tag return TRUE if end of list
{
dr_handle abbrev;
dr_handle start;
dw_tagnum tag;
unsigned_8 haschild;
int index;
int cont;
DRWLKBLK wlk;
cont = TRUE;
for( ;; ) {
start = curr;
abbrev = DWRVMReadULEB128( &curr );
if( abbrev == 0 ) break;
abbrev = DWRLookupAbbrev( curr, abbrev );
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 );
index = 0;
while( tags[index] != 0 ) {
if( tags[index] == tag ) break;
++index;
}
wlk = wlks[index];
if( wlk != NULL ) {
cont = wlk( start, index, d );
}
if( !cont ) break;
if( haschild ) {
DWRSkipChildren( &abbrev, &curr );
} else {
DWRSkipAttribs( abbrev, &curr );
}
}
return( cont );
}
extern int DWRWalkScope( dr_handle mod,
unsigned_16 const *tags,
DRWLKBLK wlk, void *d )
/************************************************/
// walk a scope starting at mod
// if a block go into it, if a tag we are interested in call user
{
dr_handle abbrev;
dr_handle curr;
dw_tagnum tag;
unsigned_8 haschild;
int index;
if( !wlk( mod, 0, d ) ) // call with parent
return( FALSE ); // FALSE == quit
abbrev = DWRVMReadULEB128( &mod );
if( abbrev == 0 ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
abbrev = DWRLookupAbbrev( mod, abbrev );
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 ); /* skip child byte */
DWRSkipAttribs( abbrev, &mod );
if( haschild == DW_CHILDREN_yes ) {
int depth;
int skip;
depth = 1;
skip = TRUE;
curr = mod;
for( ;; ) {
mod = curr;
abbrev = DWRVMReadULEB128( &curr );
if( abbrev == 0 ) {
if( --depth == 0 ) break;
continue;
}
abbrev = DWRLookupAbbrev( curr, abbrev );
tag = DWRVMReadULEB128( &abbrev );
haschild = DWRVMReadByte( abbrev );
abbrev += sizeof( unsigned_8 );
index = 0;
while( tags[index] != 0 ) {
if( tags[index] == tag ) {
if( !wlk( mod, depth, d ) )
return( FALSE ); // FALSE == quit
break;
}
++index;
}
if( tag == DW_TAG_lexical_block ) {
++depth; // go into block
DWRSkipAttribs( abbrev, &curr );
} else {
if( haschild ) { // skip fuzz
DWRSkipChildren( &abbrev, &curr );
} else {
DWRSkipAttribs( abbrev, &curr );
}
}
}
}
return( TRUE );
}
static compunit_info * FindCompileInfo( compunit_info *compunit, dr_handle addr )
/*******************************************************************************/
{
for( ;; ) {
if( (addr >= compunit->start) && (addr <= compunit->end) ) break;
compunit = compunit->next;
if( compunit == NULL ) break;
}
if( compunit == NULL ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
return( compunit );
}
compunit_info * DWRFindCompileInfo( dr_handle addr )
/**************************************************/
/* gets the dr_handle of the module that addr is in */
{
compunit_info *compunit;
compunit = DWRCurrNode->last_ccu;
if( addr < compunit->start ) { // start at begining
compunit = &DWRCurrNode->compunit;
}
compunit = FindCompileInfo( compunit, addr );
DWRCurrNode->last_ccu = compunit;
return( compunit );
}
dr_handle DWRFindCompileUnit( dr_handle addr )
/********************************************/
{
compunit_info *compunit;
compunit = DWRFindCompileInfo( addr );
return( compunit->start );
}
#define CONTEXT_GUESS 0x10
extern void DWRContextPush( dr_context_stack *stack, uint_32 val )
/****************************************************************/
{
if( stack->stack == NULL ) {
stack->stack = DWRALLOC( CONTEXT_GUESS * sizeof( uint_32 ) );
stack->free = 0;
stack->size = CONTEXT_GUESS;
}
if( stack->free >= stack->size ) {
stack->size += CONTEXT_GUESS;
stack->stack = DWRREALLOC( stack->stack, stack->size * sizeof( dr_handle ) );
}
stack->stack[ stack->free ] = val;
stack->free += 1;
}
extern uint_32 DWRContextPop( dr_context_stack *stack )
/*****************************************************/
{
if( stack->free <= 0 ) {
DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
}
stack->free -= 1;
return( stack->stack[ stack->free ] );
}
extern dr_handle DWRContext( dr_context_stack *stack, int up )
/************************************************************/
{
int free;
free = stack->free;
free -= up+1;
if( free <= 0 ) {
return( 0 );
}
return( stack->stack[free] );
}
extern void DWRFreeContextStack( dr_context_stack *stack )
/********************************************************/
{
DWRFREE( stack->stack );
stack->free = 0;
stack->size = 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?