dftype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,391 行 · 第 1/3 页
C
1,391 行
}else if( !DRIsSymDefined( var ) ){
is->sclass = SYM_MEMF; // memfunc decl
}else{
is->sclass = SYM_MEMVAR; // inlined defn treat like a var
}
break;
}
saved = DRGetDebug();
d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d );
DRSetDebug( saved );
if( d->wr != WR_CONTINUE ){
cont = FALSE;
}
return( cont );
}
static int AInherit( dr_handle inh, int index, void *_d ) {
/*************************************************/
//TODO: Need to track virtual base as not to visit same place twice
type_wlk_wlk *d = _d;
int cont;
dr_handle btype;
dr_handle old_inh;
imp_sym_handle *is;
dr_dbg_handle saved;
walk_result wr;
index = index;
cont = TRUE;
btype = DRGetTypeAT( inh );
btype = DRSkipTypeChain( btype ); /* skip modifiers and typedefs */
if( DRGetVirtuality( inh ) == DR_VIRTUALITY_VIRTUAL ){
if( !AddBase( btype, &d->com.vbase ) ){
return( cont );
}
}
is = d->is;
SetSymHandle( (type_wlk *)d, is );
is->sym = inh;
is->sclass = SYM_MEM; // treat inherit like a var
saved = DRGetDebug();
wr = d->wk( d->com.ii, SWI_INHERIT_START, is, d->com.d );
DRSetDebug( saved );
if( wr == WR_CONTINUE ) {
old_inh = d->com.inh;
d->com.inh = inh;
DRWalkStruct( btype, StrucWlk, d );
d->com.inh = old_inh;
saved = DRGetDebug();
d->wk( d->com.ii, SWI_INHERIT_END, NULL, d->com.d );
DRSetDebug( saved );
if( d->wr != WR_CONTINUE ){
cont = FALSE;
}
}
return( cont );
}
static int AMemLookup( dr_handle var, int index, void *d );
static int AInheritLookup( dr_handle inh, int index, void *d );
static DRWLKBLK StrucWlkLookup[DR_WLKBLK_STRUCT] = {
AMemLookup,
AInheritLookup,
AMemLookup,
AMemLookup,
NULL
};
static int AMemLookup( dr_handle var, int index, void *_d ){
/*************************************************/
type_wlk_lookup *d = _d;
imp_sym_handle *is;
char *name;
int len;
name = DRGetName( var );
if( name == NULL ){
DCStatus( DS_FAIL );
return( FALSE );
}
len = strlen( name );
if( len == d->li->name.len && d->comp(name, d->li->name.start,len)==0 ) {
is = DCSymCreate( d->com.ii, d->com.d );
SetSymHandle( (type_wlk *)d, is );
is->sym = var;
switch( index ){
case 0:
is->sclass = SYM_MEM;
break;
case 2:
is->sclass = SYM_MEMVAR; // static member
break;
case 3:
if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL ){
is->sclass = SYM_VIRTF; // virtual func
}else if( !DRIsSymDefined( var ) ){
is->sclass = SYM_MEMF; // memfunc decl
}else{
is->sclass = SYM_MEMVAR; // inlined defn treat like a var
}
break;
}
d->sr = SR_EXACT;
}
DCFree( name );
return( TRUE );
}
static int AInheritLookup( dr_handle inh, int index, void *_d ){
/*************************************************/
//Push inherit handle and search
type_wlk_lookup *d = _d;
dr_handle btype;
dr_handle old_inh;
index = index;
btype = DRGetTypeAT( inh );
btype = DRSkipTypeChain( btype ); /* skip modifiers and typedefs */
if( DRGetVirtuality( inh ) == DR_VIRTUALITY_VIRTUAL ){
if( !AddBase( btype, &d->com.vbase ) ){
return( TRUE );
}
}
old_inh = d->com.inh;
d->com.inh = inh;
DRWalkStruct( btype, StrucWlkLookup, d );
d->com.inh = old_inh;
return( TRUE );
}
static int AEnumMem( dr_handle var, int index, void *_d ) {
/*********************************************************/
type_wlk_wlk *d = _d;
int cont;
imp_sym_handle *is;
dr_dbg_handle saved;
index = index;
cont = TRUE;
is = d->is;
SetSymHandle( (type_wlk *)d, is );
is->sym = var;
saved = DRGetDebug();
d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d );
DRSetDebug( saved );
if( d->wr != WR_CONTINUE ){
cont = FALSE;
}
return( cont );
}
static int AEnumMemLookup( dr_handle var, int index, void *_d ) {
/***************************************************************/
type_wlk_lookup *d = _d;
imp_sym_handle *is;
char *name;
int len;
index = index;
name = DRGetName( var );
if( name == NULL ){
DCStatus( DS_FAIL );
return( FALSE );
}
len = strlen( name );
if( len == d->li->name.len && d->comp(name, d->li->name.start,len)==0 ) {
is = DCSymCreate( d->com.ii, d->com.d );
SetSymHandle( (type_wlk *)d, is );
is->sym = var;
d->sr = SR_EXACT;
}
DCFree( name );
return( TRUE );
}
extern walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it,
IMP_SYM_WKR *wk, imp_sym_handle *is, void *d ){
dr_handle btype;
type_wlk_wlk df;
df_cleaner cleanup;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( it->state == DF_NOT ){
if( DRGetTypeInfo( it->type, &it->typeinfo ) ){
it->state = DF_SET;
}
}
if( it->state == DF_NOT ){
return( WR_STOP );
}
df.com.imx = it->imx;
df.com.ii = ii;
df.com.d = d;
df.com.root = it->type;
df.com.inh = NULL;
df.com.vbase = NULL;
cleanup.rtn = FreeBases; //push cleanup
cleanup.d = &df.com.vbase;
cleanup.prev = Cleaners;
Cleaners = &cleanup;
btype = DRSkipTypeChain( it->type );
df.is = is;
df.wk = wk;
df.wr = WR_CONTINUE;
switch( it->typeinfo.kind ){
case DR_TYPEK_ENUM:
df.com.sclass = SYM_ENUM;
df.com.einfo.size = it->typeinfo.size;
df.com.einfo.sign = it->typeinfo.modifier.sign;
DRWalkEnum( btype, AEnumMem, &df );
break;
case DR_TYPEK_STRUCT:
case DR_TYPEK_UNION:
case DR_TYPEK_CLASS:
df.com.sclass = SYM_MEM;
DRWalkStruct( btype, StrucWlk, &df );
break;
default:
DCStatus( DS_ERR | DS_BAD_PARM );
df.wr = WR_STOP;
}
FreeBases( &df.com.vbase ); // free virtual base list
Cleaners = cleanup.prev; // pop cleanup
return( df.wr );
}
extern search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it,
lookup_item *li, void *d ){
//Search for matching lookup item
dr_handle btype;
type_wlk_lookup df;
df_cleaner cleanup;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( it->state == DF_NOT ){
if( DRGetTypeInfo( it->type, &it->typeinfo ) ){
it->state = DF_SET;
}
}
if( it->state == DF_NOT ){
return( SR_NONE );
}
df.com.imx = it->imx;
df.com.ii = ii;
df.com.d = d;
df.com.root = it->type;
df.com.inh = NULL;
df.com.vbase = NULL;
cleanup.rtn = FreeBases; //push cleanup
cleanup.d = &df.com.vbase;
cleanup.prev = Cleaners;
Cleaners = &cleanup;
btype = DRSkipTypeChain( it->type );
if( li->case_sensitive ) {
df.comp = memcmp;
} else {
df.comp = memicmp;
}
df.li = li;
df.sr = SR_NONE;
switch( it->typeinfo.kind ){
case DR_TYPEK_ENUM:
df.com.sclass = SYM_ENUM;
df.com.einfo.size = it->typeinfo.size;
df.com.einfo.sign = it->typeinfo.modifier.sign;
DRWalkEnum( btype, AEnumMemLookup, &df );
break;
case DR_TYPEK_STRUCT:
case DR_TYPEK_UNION:
case DR_TYPEK_CLASS:
df.com.sclass = SYM_MEM;
DRWalkStruct( btype, StrucWlkLookup, &df );
break;
default:
DCStatus( DS_ERR | DS_BAD_PARM );
df.sr = SR_FAIL;
}
FreeBases( &df.com.vbase ); // free virtual base list
Cleaners = cleanup.prev; // pop cleanup
return( df.sr );
}
/*********************************************/
/* Search for a derived type then eval loc */
/*********************************************/
typedef struct inh_path {
struct inh_path *next;
dr_handle inh;
}inh_path;
typedef struct type_wlk_inherit {
imp_image_handle *ii;
dr_handle dr_derived;
location_context *lc;
address *addr;
inh_path *head;
inh_path **lnk;
dip_status wr;
bool cont;
}type_wlk_inherit;
static int AInhFind( dr_handle inh, int index, void *df );
static DRWLKBLK InheritWlk[DR_WLKBLK_STRUCT] = {
NULL,
AInhFind,
NULL,
NULL,
NULL,
};
static int AInhFind( dr_handle inh, int index, void *_df ){
/*************************************************/
//Push inherit handle and search
type_wlk_inherit *df = _df;
dr_handle dr_derived;
inh_path head, *curr, **old_lnk;
index = index;
head.inh = inh;
head.next = NULL;
old_lnk = df->lnk;
*df->lnk = &head;
df->lnk = &head.next;
dr_derived = DRGetTypeAT( inh ); /* get base type */
if( dr_derived == df->dr_derived ){
curr = df->head;
while( curr != NULL ){
df->wr = EvalLocAdj( df->ii, df->lc, curr->inh, df->addr );
if( df->wr != DS_OK )break;
curr = curr->next;
}
df->cont = FALSE;
}else{
dr_derived = DRSkipTypeChain( dr_derived); /* skip modifiers and typedefs */
DRWalkStruct( dr_derived, InheritWlk, df ); /* walk struct looking for inheritance */
}
df->lnk = old_lnk;
return( df->cont );
}
extern dip_status DFBaseAdjust( imp_image_handle *ii,
dr_handle base, dr_handle derived,
location_context *lc, address *addr ){
type_wlk_inherit df;
dr_handle dr_base;
df.ii = ii;
df.dr_derived = derived;
df.lc = lc;
df.addr = addr;
df.head = NULL;
df.lnk = &df.head;
df.wr = DS_FAIL;
df.cont = TRUE;
dr_base = DRSkipTypeChain( base ); /* skip modifiers and typedefs */
DRWalkStruct( dr_base, InheritWlk, &df ); /* walk struct looking for inheritance */
return( df.wr );
}
dip_status DIPENTRY DIPImpTypeThunkAdjust( imp_image_handle *ii,
imp_type_handle *base, imp_type_handle *derived,
location_context *lc, address *addr )
{
/*
When you convert a pointer to a C++ class to a pointer at one
of its derived classes you have to adjust the pointer so that
it points at the start of the derived class. The 'derived' type
may not actually be a derived type of 'base'. In that case, return
DS_FAIL and nothing to 'addr'. If it is a derived type, let 'disp'
be the displacement between the 'base' type and the 'derived' type.
You need to do the following. "addr->mach.offset += disp;".
*/
return( DFBaseAdjust( ii, base->type, derived->type, lc, addr ) );
}
unsigned DIPENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it,
unsigned num, symbol_type *tag, char *buff, unsigned max )
{
/*
Given the imp_type_handle, copy the name of the type into 'buff'.
Do not copy more than 'max' - 1 characters into the buffer and
append a trailing '\0' character. Return the real length
of the type name (not including the trailing '\0' character) even
if you had to truncate it to fit it into the buffer. If something
went wrong and you can't get the type name, call DCStatus and
return zero. NOTE: the client might pass in zero for 'max'. In that
case, just return the length of the module name and do not attempt
to put anything into the buffer.
Since there can be a "string" of typedef names associated with
a type_handle, the 'num' parm indicates which one of the names
the client wants returned. Zero is the first type name, one is
the second, etc. Fill in '*tag' with ST_ENUM_TAG, ST_UNION_TAG,
ST_STRUCT_TAG, ST_CLASS_TAG if the name is a enum, union, struct,
or class tag name respectively. If not, set '*tag' to ST_NONE.
If the type does not have a name, return zero.
*/
char *name;
dr_handle dr_type;
dr_typeinfo typeinfo;
unsigned len;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
++num;
len = 0;
dr_type = it->type;
while( dr_type != NULL ){
name = DRGetName( dr_type );
if( name != NULL ){
if( --num == 0 )break;
DCFree( name );
}
dr_type = DRGetTypeAT( dr_type );
}
if( num == 0 ){
DRGetTypeInfo( dr_type, &typeinfo );
switch( typeinfo.kind ){
case DR_TYPEK_ENUM:
*tag = ST_ENUM_TAG;
break;
case DR_TYPEK_STRUCT:
*tag = ST_STRUCT_TAG;
break;
case DR_TYPEK_UNION:
*tag = ST_UNION_TAG;
break;
case DR_TYPEK_CLASS:
*tag = ST_CLASS_TAG;
break;
default:
*tag = ST_NONE;
break;
}
len = NameCopy( buff, name, max );
DCFree( name );
}
return( len );
}
dip_status DIPENTRY DIPImpTypeAddRef( imp_image_handle *ii, imp_type_handle *it )
{
ii=ii;
it=it;
return(DS_OK);
}
dip_status DIPENTRY DIPImpTypeRelease( imp_image_handle *ii, imp_type_handle *it )
{
ii=ii;
it=it;
return(DS_OK);
}
dip_status DIPENTRY DIPImpTypeFreeAll( imp_image_handle *ii )
{
ii=ii;
return(DS_OK);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?