search_result DIPENTRY DIPImpAddrSym( imp_image_handle *ii, imp_mod_handle im, address addr, imp_sym_handle *is ) { search_result sr; if( im == NO_MOD ) { if( ImpInterface.addr_mod( ii, addr, &is->im ) == SR_NONE ) return( SR_NONE ); } else { is->im = im; } sr = LookupLclAddr( ii, addr, is ); if( sr != SR_NONE ) return( sr ); return( LookupGblAddr( ii, addr, is ) ); }
/* * 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 ); }