dfsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,799 行 · 第 1/4 页
C
1,799 行
}
}
if( ctl->root != NULL ) {
node = FindScope( ctl->root, addr.mach.offset );
if( node != NULL ) {
scope->start = addr;
scope->start.mach.offset = node->start;
scope->len = node->end - node->start;
DCMapAddr( &scope->start.mach, ii->dcmap );
scope->unique = node->what;
scope->unique -= ii->mod_map[imx].cu_tag; /* make relative */
ret = SR_CLOSEST;
}
}
return( ret );
}
search_result DIPENTRY DIPImpAddrScope( imp_image_handle *ii,
imp_mod_handle im, address addr, scope_block *scope )
/*******************************************************************/
{
/* Find the range of the lexical scope block enclosing 'addr' in
* module 'im'. If there is no such scope, return SR_NONE. Otherwise
* fill in scope->start with the address of the start of the lexical
* block and scope->len with the size of the block. Fill in
* scope->unique with something that uniquely identifies the lexical
* block in question. This is used to disamibiguate between blocks
* that start at the same address and have the same length. The value
* should be chosen so that
* 1. It remains valid and consistant across a DIPUnloadInfo
* and DIPLoadInfo of the same information.
* 2. It remains the same whether the scope_block was obtained
* by DIPImpAddrScope or DIPImpScopeOuter.
* Then return SR_EXACT/SR_CLOSEST as appropriate.
*/
return( DFAddrScope( ii, IM2IMX( im ), addr, scope ) );
}
static search_result DFScopeOuter( imp_image_handle *ii,
im_idx imx, scope_block *in, scope_block *out )
/*************************************************************/
{
/* Given the scope_block pointed to by 'in' in the module 'im', find
* the parent lexical block of it and fill in the scope_block pointed
* to by 'out' with the information. Return SR_EXACT/SR_CLOSEST as
* appropriate. Return SR_NONE if there is no parent block.
* Make sure that the case where 'in' and 'out' point to the same
* address is handled.
*/
dr_handle what;
search_result ret;
address addr;
scope_ctl *ctl;
scope_node *node;
ret = SR_NONE;
addr = in->start;
Real2Map( ii->addr_map, &addr );
ctl = &ii->scope;
if( !IsInScope( ctl, addr ) ) {
addrsym_info info;
seg_list *addr_sym;
addr_sym = DFLoadAddrSym( ii, imx );
if( FindAddrSym( addr_sym, &addr.mach, &info ) >= 0 ) {
DRSetDebug( ii->dwarf->handle ); /* must do at each interface */
if( DRIsFunc( info.sym ) ) {
FiniScope( ctl );
ctl->base = addr;
ctl->base.mach.offset = info.map_offset;
ctl->base.mach.segment = info.map_seg;
DRWalkScope( info.sym, InBlk, ctl );
}
}
}
if( ctl->root != NULL ) {
ret = SR_NONE;
node = FindScope( ctl->root, addr.mach.offset );
what = in->unique;
what += ii->mod_map[imx].cu_tag; /* make absolute */
while( node != NULL ) {
if( node->what == what ) {
node = node->down;
break;
}
node = node->down;
}
if( node != NULL ) {
out->start = addr;
out->start.mach.offset = node->start;
out->len = node->end - node->start;
DCMapAddr( &out->start.mach, ii->dcmap );
what = node->what;
what -= ii->mod_map[imx].cu_tag;
out->unique = what; /* make relative */
ret = SR_EXACT;
}
}
return( ret );
}
static dr_handle GetContainingClass( dr_handle curr )
/***************************************************/
{
dr_tag_type sc;
curr = DRGetContaining( curr );
if( curr != NULL ) {
curr = DRSkipTypeChain( curr ); /* PCH typedef link */
sc = DRGetTagType( curr );
if( sc != DR_TAG_CLASS ) {
curr = NULL;
}
}
return( curr );
}
search_result DIPENTRY DIPImpScopeOuter( imp_image_handle *ii,
imp_mod_handle im, scope_block *in, scope_block *out )
/********************************************************************/
{
search_result ret;
dr_handle curr;
dr_tag_type sc;
dr_handle cu_tag;
im_idx imx;
DRSetDebug( ii->dwarf->handle ); /* must do at each interface */
imx = IM2IMX( im );
cu_tag = ii->mod_map[imx].cu_tag;
curr = in->unique + cu_tag;
sc = DRGetTagType( curr );
switch( sc ) {
case DR_TAG_CLASS:
DCStatus( DS_FAIL );
ret = SR_NONE;
break;
case DR_TAG_FUNCTION:
curr = GetContainingClass( curr );
if( curr != NULL ) {
*out = *in;
out->unique = curr-cu_tag;
ret = SR_EXACT;
} else {
DCStatus( DS_FAIL );
ret = SR_NONE;
}
break;
default:
ret = DFScopeOuter( ii, imx, in, out );
}
return( ret );
}
/**********************************************/
/* Walk or Search various scopes for symbols */
/**********************************************/
typedef struct {
im_idx imx;
imp_image_handle *ii;
void *d;
dr_handle containing;
dr_srch what;
bool cont; //continue to next scope
enum {
WLK_LOOKUP,
WLK_WLK,
} kind;
} blk_wlk_com;
typedef struct {
blk_wlk_com com;
walk_result wr;
IMP_SYM_WKR *wk;
imp_sym_handle *is;
} blk_wlk_wlk;
typedef struct {
blk_wlk_com com;
int (*comp)();
lookup_item *li;
search_result sr;
char *buff;
unsigned len;
} blk_wlk_lookup;
typedef union {
blk_wlk_com com;
blk_wlk_wlk wlk;
blk_wlk_lookup lookup;
} blk_wlk;
typedef int (*BLKLF)( dr_handle var, int index, void *df );
static dr_srch Dip2DwarfSrch( symbol_type dip )
/*********************************************/
{
dr_srch ret;
switch( dip ) {
case ST_NONE:
case ST_OPERATOR:
case ST_DESTRUCTOR:
ret = DR_SRCH_func_var;
break;
case ST_TYPE:
ret = DR_SRCH_ctypes;
break;
case ST_STRUCT_TAG:
case ST_CLASS_TAG:
case ST_UNION_TAG:
ret = DR_SRCH_class;
break;
case ST_ENUM_TAG:
ret = DR_SRCH_enum;
break;
}
return( ret );
}
static int ASym( dr_handle var, int index, void *_df )
/****************************************************/
{
blk_wlk_wlk *df = _df;
int cont;
imp_sym_handle *is;
dr_dbg_handle saved;
index = index;
is = df->is;
is->sclass = SYM_VAR;
is->imx = df->com.imx;
is->sym = var;
is->state = DF_NOT;
saved = DRGetDebug();
df->wr = df->wk( df->com.ii, SWI_SYMBOL, is, df->com.d );
DRSetDebug( saved );
cont = TRUE;
if( df->wr != WR_CONTINUE ) {
cont = FALSE;
}
df->com.cont = cont;
return( cont );
}
static int ASymCont( dr_handle var, int index, void *_df )
/********************************************************/
{
blk_wlk_wlk *df = _df;
dr_handle contain;
int cont;
cont = TRUE;
contain = DRGetContaining( var );
if( contain != NULL ) {
contain = DRSkipTypeChain( contain ); /* PCH typedef link */
}
if( df->com.containing == contain ) {
cont = ASym( var, index, df );
}
return( cont );
}
static int AModSym( dr_handle var, int index, void *_df )
/*******************************************************/
{
blk_wlk_wlk *df = _df;
int cont;
imp_sym_handle *is;
dr_tag_type sc;
dr_dbg_handle saved;
index = index;
sc = DRGetTagType( var );
if( sc == DR_TAG_NAMESPACE ) {
DRWalkBlock( var, df->com.what, AModSym, df );
cont = TRUE;
} else {
is = df->is;
is->sclass = SYM_VAR;
is->imx = df->com.imx;
is->sym = var;
is->state = DF_NOT;
saved = DRGetDebug();
df->wr = df->wk( df->com.ii, SWI_SYMBOL, is, df->com.d );
DRSetDebug( saved );
cont = TRUE;
}
if( df->wr != WR_CONTINUE ) {
cont = FALSE;
}
df->com.cont = cont;
return( cont );
}
static int ASymLookup( dr_handle var, int index, void *_df )
/**********************************************************/
{
blk_wlk_lookup *df = _df;
imp_sym_handle *is;
int len;
len = DRGetNameBuff( var, df->buff, df->len );
if( len == df->len
&& df->comp( df->buff, df->li->name.start, df->li->name.len ) == 0 ) {
/* Found symbol by name */
if( !DRIsFunc( var ) && !DRIsStatic( var ) && !DRIsSymDefined( var ) ) {
/* If symbol is a global variable declaration, ignore it; it
* won't have location information and will likely be found in
* another module.
*/
} else {
is = DCSymCreate( df->com.ii, df->com.d );
is->sclass = SYM_VAR;
is->imx = df->com.imx;
is->sym = var;
is->state = DF_NOT;
df->sr = SR_EXACT;
df->com.cont = FALSE;
}
}
return( TRUE );
}
static int ASymContLookup( dr_handle var, int index, void *_df )
/**************************************************************/
{
blk_wlk_lookup *df = _df;
dr_handle contain;
int cont;
cont = TRUE;
contain = DRGetContaining( var );
if( contain != NULL ) {
contain = DRSkipTypeChain( contain ); /* PCH typedef link */
}
if( df->com.containing == contain ) {
cont = ASymLookup( var, index, df );
}
return( cont );
}
static int WalkOneBlock( blk_wlk *df, BLKLF fn, dr_handle blk )
/*************************************************************/
{
DRSetDebug( df->com.ii->dwarf->handle ); /* must do at each call into DWARF */
DRWalkBlock( blk, df->com.what, fn, df );
return( df->com.cont );
}
static int WalkModSymList( blk_wlk *df, BLKLF fn, im_idx imx )
/************************************************************/
{
imp_image_handle *ii;
dr_handle cu_tag;
int cont;
df->com.imx = imx;
ii = df->com.ii;
cu_tag = ii->mod_map[imx].cu_tag;
if( df->com.what == DR_SRCH_ctypes
&& ii->mod_map[imx].lang == DR_LANG_CPLUSPLUS ) {
df->com.what = DR_SRCH_cpptypes;
}
cont = WalkOneBlock( df, fn, cu_tag );
return( cont );
}
static int WalkScopedSymList( blk_wlk *df, BLKLF fn, address *addr )
/******************************************************************/
{
/* Walk inner to outer function scopes, then containing class
* if present, then module scope.
*/
imp_image_handle *ii;
scope_block scope;
dr_handle cu_tag;
dr_tag_type sc;
im_idx imx;
dr_handle curr;
int cont;
ii = df->com.ii;
cont = TRUE;
if( DFAddrMod( ii, *addr, &imx ) != SR_NONE ) {
if( DFAddrScope( ii, imx, *addr, &scope ) != SR_NONE ) {
df->com.imx = imx;
cu_tag = ii->mod_map[imx].cu_tag;
for( ;; ) {
curr = scope.unique + cu_tag;
cont = WalkOneBlock( df, fn, curr );
if( !cont ) break;
if( DFScopeOuter( ii, imx, &scope, &scope ) == SR_NONE ) {
cont = TRUE;
break;
}
}
if( cont ) {
sc = DRGetTagType( curr );
if( sc == DR_TAG_FUNCTION ) {
imp_type_handle it;
curr = GetContainingClass( curr );
if( curr != NULL ) {
it.state = DF_NOT;
it.type = curr;
it.imx = imx;
if( df->com.kind == WLK_WLK ) {
df->wlk.wr = WalkTypeSymList( ii, &it,
df->wlk.wk, df->wlk.is, df->com.d );
if( df->wlk.wr != WR_CONTINUE ) {
cont = FALSE;
}
} else {
df->lookup.sr = SearchMbr( ii, &it,
df->lookup.li, df->com.d );
if( df->lookup.sr == SR_EXACT ) {
cont = FALSE;
}
}
}
}
}
}
if( cont ) {
cont = WalkModSymList( df, fn, imx );
}
if( cont && ii->mod_map[imx].dbg_pch != NULL ) {
imx = CuTag2ModIdx( ii, ii->mod_map[imx].dbg_pch );
cont = WalkModSymList( df, fn, imx );
}
}
return( cont );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?