dfsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,799 行 · 第 1/4 页
C
1,799 行
static int WalkBlockSymList( blk_wlk *df, BLKLF fn, scope_block *scope )
/***********************************************************************/
{
imp_image_handle *ii;
dr_handle cu_tag;
im_idx imx;
dr_handle blk;
dr_tag_type sc;
int cont;
ii = df->com.ii;
if( DFAddrMod( ii, scope->start, &imx ) != SR_NONE ) {
DRSetDebug( df->com.ii->dwarf->handle ); /* must do at each call into DWARF */
df->com.imx = imx;
cu_tag = ii->mod_map[imx].cu_tag;
blk = scope->unique + cu_tag;
sc = DRGetTagType( blk );
if( sc == DR_TAG_CLASS ) {
imp_type_handle it;
it.state = DF_NOT;
it.type = blk;
it.imx = imx;
if( df->com.kind == WLK_WLK ) {
df->wlk.wr = WalkTypeSymList( ii, &it, df->wlk.wk,
df->wlk.is, df->com.d );
} else {
df->lookup.sr = SearchMbr( ii, &it,
df->lookup.li, df->com.d );
}
} else {
cont = WalkOneBlock( df, fn, blk );
}
} else {
cont = TRUE;
}
return( cont );
}
static int WalkSymSymList( blk_wlk *df, BLKLF fn, imp_sym_handle *is )
/********************************************************************/
{
imp_image_handle *ii;
im_idx imx;
int cont;
imx = is->imx;
ii = df->com.ii;
df->com.imx = imx;
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, is->sym );
return( cont );
}
static walk_result WalkMyLDSyms( imp_image_handle *ii, im_idx imx, void *_df )
/*****************************************************************************/
{
blk_wlk *df = _df;
df->wlk.com.imx = imx;
WalkModSymList( df, &ASym, imx );
return( df->wlk.wr );
}
static walk_result DFWalkSymList( imp_image_handle *ii,
symbol_source ss,
void *source,
IMP_SYM_WKR *wk,
imp_sym_handle *is,
void *d )
/******************************************************/
{
imp_mod_handle im;
walk_result wr;
blk_wlk df;
int cont;
df.com.ii = ii;
df.com.d = d;
df.com.what = DR_SRCH_func_var;
df.com.containing = 0;
df.com.cont = TRUE;
df.com.kind = WLK_WLK;
df.wlk.wk = wk;
df.wlk.is = is;
df.wlk.wr = WR_CONTINUE;
switch( ss ) {
case SS_TYPE: /* special case */
wr = WalkTypeSymList( ii, (imp_type_handle *)source, wk, is, d );
break;
case SS_SCOPED:
cont = WalkScopedSymList( &df, &ASym, (address *)source );
wr = df.wlk.wr;
break;
case SS_SCOPESYM:
is = (imp_sym_handle *)source;
WalkSymSymList( &df, &ASym, is );
if( cont ) {
df.com.containing = is->sym;
WalkModSymList( &df, &ASymCont, is->imx );
}
wr = df.wlk.wr;
break;
case SS_BLOCK:
WalkBlockSymList( &df, &ASym, (scope_block *)source );
wr = df.wlk.wr;
break;
case SS_MODULE:
im = *(imp_mod_handle *)source;
if( im == (imp_mod_handle)NO_MOD ) {
wr = DFWalkModList( ii, WalkMyLDSyms, &df );
} else {
WalkModSymList( &df, &AModSym, IM2IMX( im ) );
wr = df.wlk.wr;
}
break;
}
return( wr );
}
walk_result DIPENTRY DIPImpWalkSymList( imp_image_handle *ii,
symbol_source ss,
void *source,
IMP_SYM_WKR *wk,
imp_sym_handle *is,
void *d )
/***************************************************************/
{
return( DFWalkSymList( ii, ss, source, wk, is, d ) );
}
walk_result DIPENTRY DIPImpWalkSymListEx( imp_image_handle *ii,
symbol_source ss,
void *source,
IMP_SYM_WKR *wk,
imp_sym_handle *is,
location_context *lc,
void *d )
/*****************************************************************/
{
lc = lc;
return( DFWalkSymList( ii, ss, source, wk, is, d ) );
}
#define SH_ESCAPE '\xf0'
static void CollectSymHdl( byte *ep, imp_sym_handle *is )
/*******************************************************/
{
byte *sp;
byte curr;
static byte escapes[] = { SH_ESCAPE, '\0', '`' };
++ep;
sp = (byte *)is;
++is;
while( sp < (byte *)is ) {
curr = *ep++;
if( curr == SH_ESCAPE ) curr = escapes[ *ep++ - 1 ];
*sp++ = curr;
}
}
typedef struct {
imp_image_handle *ii;
void *d;
int (*compare)(char const *, char const *);
char *name;
dr_handle sym;
} hash_look_data;
static int AHashItem( void *_find, dr_handle sym, char *name )
/************************************************************/
{
hash_look_data *find = _find;
imp_sym_handle *is;
if( find->compare( name, find->name ) == 0 ) {
find->sym = sym;
is = DCSymCreate( find->ii, find->d );
is->imx = DwarfModIdx( find->ii, sym );
is->sclass = SYM_VAR;
is->sym = sym;
is->state = DF_NOT;
}
return( TRUE );
}
typedef struct {
char *p;
int len;
} strv;
static int StrVCopy( strv *dst, strv *src )
/*****************************************/
{
/* Copy source until null char or source runs out
* to dest until it runs out, return total length of source
*/
int total;
total = src->len;
for( ;; ) {
if( src->len == 0 ) break;
if( *src->p == '\0' ) break;
if( dst->len > 0 ) {
*dst->p = *src->p;
++dst->p;
--dst->len;
}
++src->p;
--src->len;
}
total -= src->len;
return( total );
}
static int QualifiedName( char *buff, lookup_item *li, int max )
/***************************************************************/
{
int total;
strv curr;
strv dst;
strv tmp;
curr.p = li->scope.start;
curr.len = li->scope.len;
dst.p = buff;
dst.len = max;
total = 0;
while( curr.len > 0 ) {
total += StrVCopy( &dst, &curr );
if( *curr.p == '\0' ) {
++curr.p;
--curr.len;
}
tmp.p = "::";
tmp.len = 2;
total += StrVCopy( &dst, &tmp );
}
curr.p = li->name.start;
curr.len = li->name.len;
total += StrVCopy( &dst, &curr );
if( dst.len > 0 ) {
*dst.p = '\0';
}
total += 1;
return( total );
}
static search_result HashSearchGbl( imp_image_handle *ii,
lookup_item *li, void *d )
/*****************************************************************/
{
char buff[256];
int len;
search_result sr;
hash_look_data data;
name_wlk wlk;
sr = SR_NONE;
data.ii = ii;
data.compare = li->case_sensitive ? &strcmp : &stricmp;
data.sym = NULL;
len = QualifiedName( buff, li, sizeof( buff ) );
if( len <= sizeof( buff ) ) {
data.name = buff;
} else {
data.name = DCAlloc( len + 1 );
len = QualifiedName( data.name, li, len + 1 );
}
data.d = d;
wlk.fn = AHashItem;
wlk.name = data.name;
wlk.d = &data;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
FindHashWalk( ii->name_map, &wlk );
if( data.sym != NULL ) {
sr = SR_EXACT;
}
if( data.name != buff ) {
DCFree( data.name );
}
return( sr );
}
extern search_result DoLookupSym( imp_image_handle *ii,
symbol_source ss, void *source, lookup_item *li,
location_context *lc, void *d )
/**************************************************************/
{
imp_mod_handle im;
imp_sym_handle *is;
search_result sr;
char *src;
unsigned len;
blk_wlk df;
char buff[256];
int cont;
if( *li->name.start == SH_ESCAPE ) {
CollectSymHdl( li->name.start, DCSymCreate( ii, d ) );
return( SR_EXACT );
}
if( li->type == ST_OPERATOR ) {
//TODO this operator
src = li->name.start;
len = li->name.len;
return( SR_NONE );
}
if( ss == SS_TYPE ) {
if( li->mod != NO_MOD ) {
sr = SR_NONE;
} else {
sr = SearchMbr( ii, (imp_type_handle *)source, li, d );
}
return( sr );
}
df.com.ii = ii;
df.com.d = d;
df.com.what = Dip2DwarfSrch( li->type );
df.com.containing = 0;
df.com.cont = TRUE;
df.com.kind = WLK_LOOKUP;
df.lookup.comp = li->case_sensitive ? &memcmp : &memicmp;
df.lookup.li = li;
df.lookup.len = li->name.len+1;
if( df.lookup.len <= sizeof( buff ) ) {
df.lookup.buff = buff;
} else {
df.lookup.buff = DCAlloc( df.lookup.len );
}
df.lookup.sr = SR_NONE;
switch( ss ) {
case SS_SCOPED:
if( li->scope.len == 0 ) {
cont = WalkScopedSymList( &df, &ASymLookup, (address *)source );
} else {
cont = TRUE;
}
sr = df.lookup.sr;
if( cont ) {
if( DR_SRCH_func_var == df.com.what ) {
sr = HashSearchGbl( ii, li, d );
}
}
break;
case SS_MODULE:
im = *(imp_mod_handle *)source;
if( im == (imp_mod_handle)NO_MOD ) {
if( DR_SRCH_func_var == df.com.what ) {
sr = HashSearchGbl( ii, li, d );
}
} else {
WalkModSymList( &df, &ASymLookup, IM2IMX( im ) );
sr = df.lookup.sr;
}
break;
case SS_SCOPESYM:
is = (imp_sym_handle *)source;
WalkSymSymList( &df, &ASymLookup, is );
df.com.containing = is->sym; //check for out of line defn
WalkModSymList( &df, &ASymContLookup, is->imx );
sr = df.lookup.sr;
break;
}
if( df.lookup.buff != buff ) {
DCFree( df.lookup.buff );
}
return( sr );
}
extern search_result DIPENTRY DIPImpLookupSym( imp_image_handle *ii,
symbol_source ss, void *source, lookup_item *li, void *d )
/************************************************************************/
{
return( DoLookupSym( ii, ss, source, li, NULL, d ) );
}
extern search_result DIPENTRY DIPImpLookupSymEx( imp_image_handle *ii,
symbol_source ss, void *source, lookup_item *li,
location_context *lc, void *d )
/**********************************************************************/
{
return( DoLookupSym( ii, ss, source, li, lc, d ) );
}
int DIPENTRY DIPImpSymCmp( imp_image_handle *ii, imp_sym_handle *is1,
imp_sym_handle *is2 )
/*******************************************************************/
{
/* Compare two sym handles and return 0 if they refer to the same
* information. If they refer to differnt things return either a
* positive or negative value to impose an 'order' on the information.
* The value should obey the following constraints.
* Given three handles H1, H2, H3:
* - if H1 < H2 then H1 is always < H2
* - if H1 < H2 and H2 < H3 then H1 is < H3
* The reason for the constraints is so that a client can sort a
* list of handles and binary search them.
*/
long diff;
ii = ii;
diff = is1->sym - is2->sym;
return( diff );
}
dip_status DIPENTRY DIPImpSymAddRef( imp_image_handle *ii, imp_sym_handle *is )
/*****************************************************************************/
{
ii = ii;
is = is;
return( DS_OK );
}
dip_status DIPENTRY DIPImpSymRelease( imp_image_handle *ii, imp_sym_handle *is )
/******************************************************************************/
{
ii = ii;
is = is;
return( DS_OK );
}
dip_status DIPENTRY DIPImpSymFreeAll( imp_image_handle *ii )
/**********************************************************/
{
ii = ii;
return( DS_OK );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?