aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/SymbolTable.cpp')
-rw-r--r--lld/ELF/SymbolTable.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index e615fb70a40f..a12c5f22c4fe 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -29,7 +29,7 @@ using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;
-SymbolTable *elf::symtab;
+std::unique_ptr<SymbolTable> elf::symtab;
void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// Redirect __real_foo to the original foo and foo to the original __wrap_foo.
@@ -64,16 +64,18 @@ Symbol *SymbolTable::insert(StringRef name) {
// Since this is a hot path, the following string search code is
// optimized for speed. StringRef::find(char) is much faster than
// StringRef::find(StringRef).
+ StringRef stem = name;
size_t pos = name.find('@');
if (pos != StringRef::npos && pos + 1 < name.size() && name[pos + 1] == '@')
- name = name.take_front(pos);
-
- auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
- int &symIndex = p.first->second;
- bool isNew = p.second;
-
- if (!isNew)
- return symVector[symIndex];
+ stem = name.take_front(pos);
+
+ auto p = symMap.insert({CachedHashStringRef(stem), (int)symVector.size()});
+ if (!p.second) {
+ Symbol *sym = symVector[p.first->second];
+ if (stem.size() != name.size())
+ sym->setName(name);
+ return sym;
+ }
Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
symVector.push_back(sym);
@@ -105,10 +107,7 @@ Symbol *SymbolTable::find(StringRef name) {
auto it = symMap.find(CachedHashStringRef(name));
if (it == symMap.end())
return nullptr;
- Symbol *sym = symVector[it->second];
- if (sym->isPlaceholder())
- return nullptr;
- return sym;
+ return symVector[it->second];
}
// A version script/dynamic list is only meaningful for a Defined symbol.
@@ -131,7 +130,7 @@ static bool canBeVersioned(const Symbol &sym) {
// other than trying to match a pattern against all demangled symbols.
// So, if "extern C++" feature is used, we need to demangle all known
// symbols.
-StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
+StringMap<SmallVector<Symbol *, 0>> &SymbolTable::getDemangledSyms() {
if (!demangledSyms) {
demangledSyms.emplace();
std::string demangled;
@@ -152,7 +151,7 @@ StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
return *demangledSyms;
}
-std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
+SmallVector<Symbol *, 0> SymbolTable::findByVersion(SymbolVersion ver) {
if (ver.isExternCpp)
return getDemangledSyms().lookup(ver.name);
if (Symbol *sym = find(ver.name))
@@ -161,9 +160,9 @@ std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion ver) {
return {};
}
-std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver,
- bool includeNonDefault) {
- std::vector<Symbol *> res;
+SmallVector<Symbol *, 0> SymbolTable::findAllByVersion(SymbolVersion ver,
+ bool includeNonDefault) {
+ SmallVector<Symbol *, 0> res;
SingleStringMatcher m(ver.name);
auto check = [&](StringRef name) {
size_t pos = name.find('@');
@@ -189,8 +188,8 @@ std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion ver,
}
void SymbolTable::handleDynamicList() {
+ SmallVector<Symbol *, 0> syms;
for (SymbolVersion &ver : config->dynamicList) {
- std::vector<Symbol *> syms;
if (ver.hasWildcard)
syms = findAllByVersion(ver, /*includeNonDefault=*/true);
else
@@ -207,7 +206,7 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
StringRef versionName,
bool includeNonDefault) {
// Get a list of symbols which we need to assign the version to.
- std::vector<Symbol *> syms = findByVersion(ver);
+ SmallVector<Symbol *, 0> syms = findByVersion(ver);
auto getName = [](uint16_t ver) -> std::string {
if (ver == VER_NDX_LOCAL)
@@ -228,7 +227,7 @@ bool SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,
// If the version has not been assigned, verdefIndex is -1. Use an arbitrary
// number (0) to indicate the version has been assigned.
- if (sym->verdefIndex == UINT32_C(-1)) {
+ if (sym->verdefIndex == uint16_t(-1)) {
sym->verdefIndex = 0;
sym->versionId = versionId;
}
@@ -247,7 +246,7 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId,
// so we set a version to a symbol only if no version has been assigned
// to the symbol. This behavior is compatible with GNU.
for (Symbol *sym : findAllByVersion(ver, includeNonDefault))
- if (sym->verdefIndex == UINT32_C(-1)) {
+ if (sym->verdefIndex == uint16_t(-1)) {
sym->verdefIndex = 0;
sym->versionId = versionId;
}
@@ -262,7 +261,6 @@ void SymbolTable::scanVersionScript() {
SmallString<128> buf;
// First, we assign versions to exact matching symbols,
// i.e. version definitions not containing any glob meta-characters.
- std::vector<Symbol *> syms;
for (VersionDefinition &v : config->versionDefinitions) {
auto assignExact = [&](SymbolVersion pat, uint16_t id, StringRef ver) {
bool found =