search_result DoLookupSym( imp_image_handle *ii, symbol_source ss, void *source, lookup_item *li, location_context *lc, void *d ) { int (*cmp)(const void *, const void *, size_t); msym_sym *s; source = source; switch( ss ) { case SS_MODULE: case SS_SCOPED: break; default: return( SR_NONE ); } if( li->type != ST_NONE ) return( SR_NONE ); if( li->scope.start != NULL ) return( SR_NONE ); if( li->case_sensitive ) { cmp = memcmp; } else { cmp = memicmp; } for( s = ii->gbl; s != NULL; s = s->next ) { if( s->len == li->name.len && cmp( s->name, li->name.start, s->len ) == 0 ) { DCSymCreate( ii, d )->p = s; return( SR_EXACT ); } } return( SR_NONE ); }
static bool AMemLookup( dr_handle var, int index, void *_d ) /**********************************************************/ { type_wlk_lookup *d = _d; imp_sym_handle *is; char *name; unsigned 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 bool AEnumMemLookup( dr_handle var, int index, void *_d ) /**************************************************************/ { type_wlk_lookup *d = _d; imp_sym_handle *is; char *name; unsigned 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 ); }
static search_result DoLookupSym( imp_image_handle *ii, symbol_source ss, void *source, lookup_item *li, location_context *lc, void *d ) { imp_mod_handle im; search_result sr; lookup_item sym_li; char *buff; const char *src; char *dst; size_t len; unsigned op_len; imp_sym_handle *scope_is; lc = lc; if( GETU8( li->name.start ) == SH_ESCAPE ) { CollectSymHdl( li->name.start, DCSymCreate( ii, d ) ); return( SR_EXACT ); } if( li->type == ST_NAMESPACE ) return( SR_NONE ); sym_li = *li; if( ss == SS_SCOPESYM ) { char *scope_name; scope_is = source; len = ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, NULL, 0 ); scope_name = __alloca( len + 1 ); ImpInterface.SymName( ii, scope_is, NULL, SN_SOURCE, scope_name, len + 1 ); sym_li.scope.start = scope_name; sym_li.scope.len = len; ss = SS_MODULE; sym_li.mod = IMH2MH( scope_is->im ); source = &sym_li.mod; } if( sym_li.type == ST_OPERATOR ) { src = sym_li.name.start; len = sym_li.name.len; buff = __alloca( len + 20 ); dst = buff; for( ;; ) { if( len == 0 ) break; if( src == sym_li.source.start ) { op_len = __mangle_operator( src, sym_li.source.len, buff ); if( op_len == 0 ) { DCStatus( DS_ERR|DS_INVALID_OPERATOR ); return( SR_NONE ); } dst += op_len; src += sym_li.source.len; len -= sym_li.source.len; } else { *dst++ = *src++; --len; } } sym_li.name.len = dst - buff; sym_li.name.start = buff; } sr = SR_NONE; im = IMH_NOMOD; switch( ss ) { case SS_SCOPED: if( ImpInterface.AddrMod( ii, *(address *)source, &im ) == SR_NONE ) { im = MH2IMH( sym_li.mod ); } else if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) { if( !sym_li.file_scope && sym_li.type == ST_NONE ) { sr = SearchLclScope( ii, im, (address *)source, &sym_li, d ); } } else { im = MH2IMH( sym_li.mod ); } if( im != IMH_NOMOD && sr == SR_NONE ) { sr = SearchFileScope( ii, im, &sym_li, d ); } break; case SS_MODULE: im = *(imp_mod_handle *)source; if( MH2IMH( sym_li.mod ) == IMH_NOMOD || MH2IMH( sym_li.mod ) == im ) { sr = SearchFileScope( ii, im, &sym_li, d ); } break; case SS_TYPE: if( MH2IMH( sym_li.mod ) != IMH_NOMOD ) return( SR_NONE ); switch( sym_li.type ) { case ST_TYPE: case ST_STRUCT_TAG: case ST_CLASS_TAG: case ST_UNION_TAG: case ST_ENUM_TAG: return( SR_NONE ); } return( SearchMbr( ii, (imp_type_handle *)source, &sym_li, d ) ); } if( sr == SR_NONE ) { switch( sym_li.type ) { case ST_NONE: case ST_DESTRUCTOR: case ST_OPERATOR: sr = SearchGbl( ii, im, MH2IMH( sym_li.mod ), &sym_li, d ); break; } } return( sr ); }
search_result DoLookupSym( imp_image_handle *ii, symbol_source ss, void *source, lookup_item *li, location_context *lc, void *d ) { imp_mod_handle im; search_result sr; lookup_item item; char *buff; char *src; char *dst; unsigned len; unsigned op_len; imp_sym_handle *scope_is; if( *li->name.start == SH_ESCAPE ) { CollectSymHdl( (byte *)li->name.start, DCSymCreate( ii, d ) ); return( SR_EXACT ); } if( li->type == ST_NAMESPACE ) return( SR_NONE ); item = *li; if( ss == SS_SCOPESYM ) { scope_is = source; len = ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, NULL, 0 ); item.scope.start = __alloca( len + 1 ); ImpInterface.sym_name( ii, scope_is, NULL, SN_SOURCE, item.scope.start, len + 1 ); item.scope.len = len; ss = SS_MODULE; item.mod = scope_is->im; source = &item.mod; } if( item.type == ST_OPERATOR ) { src = item.name.start; len = item.name.len; buff = __alloca( len + 20 ); dst = buff; for( ;; ) { if( len == 0 ) break; if( src == item.source.start ) { op_len = __mangle_operator( src, item.source.len, buff ); if( op_len == 0 ) { DCStatus( DS_ERR|DS_INVALID_OPERATOR ); return( SR_NONE ); } dst += op_len; src += item.source.len; len -= item.source.len; } else { *dst++ = *src++; --len; } } item.name.len = dst - buff; item.name.start = buff; } sr = SR_NONE; switch( ss ) { case SS_SCOPED: if( ImpInterface.addr_mod( ii, *(address *)source, &im ) == SR_NONE ) { im = item.mod; } else if( item.mod == NO_MOD || item.mod == im ) { if( !item.file_scope && item.type == ST_NONE ) { sr = SearchLclScope( ii, im, (address *)source, &item, d ); } } else { im = item.mod; } if( im != NO_MOD && sr == SR_NONE ) { sr = SearchFileScope( ii, im, &item, d ); } break; case SS_MODULE: im = *(imp_mod_handle *)source; if( item.mod == NO_MOD || item.mod == im ) { sr = SearchFileScope( ii, im, &item, d ); } break; case SS_TYPE: if( item.mod != NO_MOD ) return( SR_NONE ); switch( item.type ) { case ST_TYPE: case ST_STRUCT_TAG: case ST_CLASS_TAG: case ST_UNION_TAG: case ST_ENUM_TAG: return( SR_NONE ); } return( SearchMbr( ii, (imp_type_handle *)source, &item, d ) ); } if( sr == SR_NONE ) { switch( item.type ) { case ST_NONE: case ST_DESTRUCTOR: case ST_OPERATOR: sr = SearchGbl( ii, im, (imp_mod_handle)item.mod, &item, d ); break; } } return( sr ); }
/* * SearchGbl -- look up a global symbol name */ static search_result LkupGblName( section_info *inf, imp_mod_handle cim, imp_mod_handle im, lookup_item *li, void *d ) { gbl_link *lnk; gbl_link *lnk_array; gbl_info *gbl; hash_link lnk_off; int (*compare)(void const*,void const*,size_t); char *gblname; size_t gbllen; char *nam = NULL; size_t namlen = 0; char *snam; size_t snamlen; char *mangled; size_t mangle_len; unsigned entry; info_block *blk; int lkup_dtor; int lkup_full = 0; imp_sym_handle *is; address addr; search_result sr; sr = SR_NONE; compare = li->case_sensitive ? memcmp : memicmp; lkup_dtor = (li->type == ST_DESTRUCTOR); /* only want to hash the source code portion of the name */ switch( source_name( li->name.start, li->name.len, &snam, &snamlen ) ) { case __NOT_MANGLED: lkup_full = 0; nam = snam; namlen = snamlen; break; case __MANGLED_DTOR: lkup_dtor = 1; /* fall through */ case __MANGLED_CTOR: case __MANGLED: case __MANGLED_INTERNAL: lkup_full = 1; nam = li->name.start; namlen = li->name.len; break; } for( blk = inf->gbl; blk != NULL; blk = blk->next ) { lnk_array = LINK( blk )->link; lnk_off = LINK( blk )->hash[ GblNameHash( snam, snamlen ) ]; while( lnk_off != HL_END ) { lnk = MAKE_LP( lnk_array, lnk_off ); gbl = lnk->gbl; if( lnk->dtor != lkup_dtor ) goto next_global; if( lkup_full ) { if( GBL_NAMELEN( gbl ) != namlen ) goto next_global; } else { if( lnk->src_len != namlen ) goto next_global; } if( im == IMH_NOMOD ) { if( GBL_KIND( gbl ) & GBL_KIND_STATIC && cim != GBL_MOD( gbl ) ) goto next_global; } else { if( im != GBL_MOD( gbl ) ) goto next_global; } mangled = GBL_NAME( gbl ); gblname = mangled; if( !lkup_full ) gblname += lnk->src_off; if( compare( gblname, nam, namlen ) != 0 ) goto next_global; if( li->scope.start != NULL ) { mangle_len = GBL_NAMELEN( gbl ); entry = 0; for( ;; ) { if( !__scope_name( mangled, mangle_len, entry, (const char **)&gblname, &gbllen ) ) goto next_global; if( li->scope.len == gbllen && compare( li->scope.start, gblname, gbllen ) == 0 ) { break; } ++entry; } } is = DCSymCreate( inf->ctl, d ); is->im = GBL_MOD( gbl ); MK_ADDR( addr, gbl->addr, inf->sect_id ); /* need to see if there's a local symbol at the right address and use that instead */ if( cim == is->im ) { /* We've already checked the local symbols. It ain't there. */ GblCreate( is, gbl ); } else if( LookupLclAddr( inf->ctl, addr, is ) == SR_EXACT ) { SetGblLink( is, gbl ); } else { GblCreate( is, gbl ); } sr = SR_EXACT; next_global: lnk_off = lnk->hash_off; } } return( sr ); }
imp_sym_handle * DIGCLIENT XDIPCliSymCreate( imp_image_handle *ii, void *d ) { return( DCSymCreate( ii, d ) ); }