void PurgeSymbols( void ) /******************************/ { symbol ** list; symbol * sym; WalkHashTables( PurgeHashTable ); WalkHashTables( CleanupOldAltdefs ); list = &HeadSym; while( *list != NULL ) { sym = *list; if( sym->info & SYM_KILL ) { *list = sym->link; FreeSymbol( sym ); } else if( sym->info & SYM_IS_ALTDEF ) { *list = sym->link; // gonna get rid of these later } else { if( IS_SYM_ALIAS(sym) && sym->info & SYM_WAS_LAZY ) { WipeSym( sym ); sym->info = SYM_WEAK_REF | SYM_REFERENCED; } LastSym = sym; list = &(*list)->link; } } }
void MakeSymAlias( char *name, size_t namelen, char *target, size_t targetlen ) /*****************************************************************************/ /* make a symbol table alias */ { symbol *sym; symbol *targ; if( namelen == targetlen && (*CmpRtn)( name, target, namelen ) == 0 ) { char *buff; buff = alloca( targetlen + 1 ); memcpy( buff, target, targetlen ); buff[ targetlen ] = '\0'; LnkMsg( WRN+MSG_CIRCULAR_ALIAS_FOUND, "s", buff ); return; // <--------- NOTE: premature return!!!! } sym = SymOp( ST_CREATE | ST_NOALIAS, name, namelen ); if( IS_SYM_ALIAS( sym ) ) { LnkMsg( WRN+MSG_MULTIPLE_ALIASES, "S", sym ); if( sym->info & SYM_FREE_ALIAS ) { _LnkFree( sym->p.alias ); } } else if( sym->info & SYM_DEFINED ) { return; // <--------- NOTE: premature return!!!! } sym->info |= SYM_FREE_ALIAS; /* * need to defined aliased symbol as well, so aliases in .obj files can be * hauled in from libraries */ targ = SymOp( ST_CREATE, target, targetlen ); SetSymAlias( sym, targ->name, targetlen ); }
static void MarkDefaultSyms( void ) /*********************************/ { symbol *sym; for( sym = HeadSym; sym != NULL; sym = sym->link ) { if( IS_SYM_ALIAS( sym ) && (sym->info & SYM_WAS_LAZY) ) { sym->e.def->info |= SYM_RELOC_REFD; } } }
symbol *UnaliasSym( sym_flags op, symbol *sym ) /*****************************************************/ { symbol *orig_sym = sym; while( sym != NULL && IS_SYM_ALIAS(sym) ) { sym = DoSymOp( op, sym->p.alias, sym->u.aliaslen ); /* circular ref, may be a weak symbol ! */ if( sym == orig_sym ) { break; } } return( sym ); }
static void PrepSymbol( void *_sym, void *info ) /**********************************************/ { symbol *sym = _sym; char *save; symbol *mainsym; if( sym->info & SYM_IS_FREE ) { *((unsigned_32 *)sym) = CARVE_INVALID_INDEX; return; } sym->hash = CarveGetIndex( CarveSymbol, sym->hash ); sym->link = CarveGetIndex( CarveSymbol, sym->link ); sym->publink = CarveGetIndex( CarveSymbol, sym->publink ); if( sym->info & SYM_IS_ALTDEF ) { mainsym = sym->e.mainsym; if( !(mainsym->info & SYM_NAME_XLATED) ) { mainsym->name = GetString( info, mainsym->name ); mainsym->info |= SYM_NAME_XLATED; } sym->name = mainsym->name; } else if( !(sym->info & SYM_NAME_XLATED) ) { sym->name = GetString( info, sym->name ); sym->info |= SYM_NAME_XLATED; } sym->mod = CarveGetIndex( CarveModEntry, sym->mod ); if( IS_SYM_ALIAS( sym ) ) { save = sym->p.alias; sym->p.alias = GetString( info, sym->p.alias ); if( sym->info & SYM_FREE_ALIAS ) { _LnkFree( save ); } } else if( IS_SYM_IMPORTED(sym) ) { if( FmtData.type & (MK_OS2 | MK_PE) ) { sym->p.import = CarveGetIndex( CarveDLLInfo, sym->p.import ); } } else if( !(sym->info & SYM_IS_ALTDEF) || IS_SYM_COMDAT(sym) ) { sym->p.seg = CarveGetIndex( CarveSegData, sym->p.seg ); sym->u.altdefs = CarveGetIndex( CarveSymbol, sym->u.altdefs ); } if( sym->info & SYM_EXPORTED ) { if( FmtData.type & (MK_OS2 | MK_PE | MK_WIN_VXD) ) { sym->e.export = CarveGetIndex( CarveExportInfo, sym->e.export ); } } else if( sym->e.def != NULL ) {
static void WipeSym( symbol *sym ) /********************************/ { if( IS_SYM_IMPORTED(sym) && !(FmtData.type & MK_ELF) ) { if( FmtData.type & MK_NOVELL ) { if( sym->p.import != DUMMY_IMPORT_PTR ) { _LnkFree( sym->p.import ); } } else { FreeImport( sym->p.import ); } sym->p.import = NULL; } else if( IS_SYM_ALIAS(sym) ) { if( sym->info & SYM_FREE_ALIAS ) { _LnkFree( sym->p.alias ); } sym->u.aliaslen = 0; // make sure this is nulled again } }
static void CleanAltDefs( symbol *sym ) /*************************************/ { symbol * testring; symbol * altsym; if( IS_SYM_ALIAS( sym ) || sym->info & SYM_DEAD || sym->u.altdefs == NULL ) return; testring = NULL; while( (altsym = RingPop( &sym->u.altdefs)) != NULL ) { if( altsym->info & SYM_KILL ) { if( altsym->info & SYM_HAS_DATA ) { altsym->u.datasym = NULL; RingAppend( &testring, altsym ); } } else if( !(altsym->info & SYM_HAS_DATA) ) { RingLookup( testring, SetNewDataSym, altsym ); } } }
group_entry *SymbolGroup( symbol *sym ) /********************************************/ { group_entry *group; if( IS_SYM_ALIAS(sym) ) { group = NULL; } else if( IS_SYM_GROUP(sym) ) { for( group = Groups; group != NULL; group = group->next_group ) { if( sym == group->sym ) { break; } } } else { if( sym->p.seg != NULL ) { group = sym->p.seg->u.leader->group; } else { group = NULL; } } return group; }
symbol *SymOp( sym_flags op, char *symname, size_t length ) /*********************************************************/ /* search for symbols, handling aliases */ { symbol * sym; sym = DoSymOp( op, symname, length ); if( !(op & ST_NOALIAS) ) { sym = UnaliasSym( op, sym ); } if( sym != NULL ) { if( op & ST_DEFINE ) { if( IS_SYM_ALIAS( sym ) && sym->info & SYM_FREE_ALIAS ) { _LnkFree( sym->p.alias ); sym->info &= ~SYM_FREE_ALIAS; } sym->info |= SYM_DEFINED; } if( op & ST_REFERENCE ) { sym->info |= SYM_REFERENCED; } } return( sym ); }