// Set a flag for --trace-symbol so that we can print out a log message
// if a new symbol with the same name is inserted into the symbol table.
template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
- Symbol *S;
- bool WasInserted;
- std::tie(S, WasInserted) = insert(Name);
- assert(WasInserted);
-
- S->Traced = true;
-
- // We created a new symbol just to turn on Trace flag.
- // Write a dummy SymbolBody so that trace() does not affect
- // normal symbol operations.
- new (S->body()) SymbolBody(SymbolBody::PlaceholderKind);
+ Symtab.insert({Name, {-1, true}});
}
// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
// Find an existing symbol or create and insert a new one.
template <class ELFT>
std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
- unsigned NumSyms = SymVector.size();
- auto P = Symtab.insert(std::make_pair(Name, NumSyms));
+ auto P = Symtab.insert({Name, {(int)SymVector.size(), false}});
+ SymIndex &V = P.first->second;
bool IsNew = P.second;
+ if (V.Idx == -1) {
+ IsNew = true;
+ V = {(int)SymVector.size(), true};
+ }
+
Symbol *Sym;
if (IsNew) {
Sym = new (Alloc) Symbol;
Sym->IsUsedInRegularObj = false;
Sym->ExportDynamic = false;
Sym->VersionId = Config->DefaultSymbolVersion;
- Sym->Traced = false;
+ Sym->Traced = V.Traced;
SymVector.push_back(Sym);
} else {
- Sym = SymVector[P.first->second];
- if (Sym->body()->kind() == SymbolBody::PlaceholderKind)
- IsNew = true;
+ Sym = SymVector[V.Idx];
}
return {Sym, IsNew};
}
auto It = Symtab.find(Name);
if (It == Symtab.end())
return nullptr;
- return SymVector[It->second]->body();
+ SymIndex V = It->second;
+ if (V.Idx == -1)
+ return nullptr;
+ return SymVector[V.Idx]->body();
}
// Returns a list of defined symbols that match with a given glob pattern.
std::map<std::string, SymbolBody *> getDemangledSyms();
+ struct SymIndex {
+ int Idx : 31;
+ unsigned Traced : 1;
+ };
+
// The order the global symbols are in is not defined. We can use an arbitrary
// order, but it has to be reproducible. That is true even when cross linking.
// The default hashing of StringRef produces different results on 32 and 64
// but a bit inefficient.
// FIXME: Experiment with passing in a custom hashing or sorting the symbols
// once symbol resolution is finished.
- llvm::DenseMap<SymName, unsigned> Symtab;
+ llvm::DenseMap<SymName, SymIndex> Symtab;
std::vector<Symbol *> SymVector;
llvm::BumpPtrAllocator Alloc;
std::vector<DefinedCommon *> CommonSymbols;
for (Symbol *S : Symtab.getSymbols()) {
SymbolBody *Body = S->body();
- if (Body->kind() == SymbolBody::PlaceholderKind)
- continue;
// We only report undefined symbols in regular objects. This means that we
// will accept an undefined reference in bitcode if it can be optimized out.