diff options
Diffstat (limited to 'contrib/llvm-project/lld/ELF/SymbolTable.cpp')
| -rw-r--r-- | contrib/llvm-project/lld/ELF/SymbolTable.cpp | 95 | 
1 files changed, 48 insertions, 47 deletions
diff --git a/contrib/llvm-project/lld/ELF/SymbolTable.cpp b/contrib/llvm-project/lld/ELF/SymbolTable.cpp index 3faeed8c2bdc..f7a8a99cf8f9 100644 --- a/contrib/llvm-project/lld/ELF/SymbolTable.cpp +++ b/contrib/llvm-project/lld/ELF/SymbolTable.cpp @@ -27,10 +27,9 @@ using namespace llvm;  using namespace llvm::object;  using namespace llvm::ELF; -using namespace lld; -using namespace lld::elf; - -SymbolTable *elf::symtab; +namespace lld { +namespace elf { +SymbolTable *symtab;  void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {    // Swap symbols as instructed by -wrap. @@ -71,21 +70,26 @@ Symbol *SymbolTable::insert(StringRef name) {    Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());    symVector.push_back(sym); +  // *sym was not initialized by a constructor. Fields that may get referenced +  // when it is a placeholder must be initialized here.    sym->setName(name);    sym->symbolKind = Symbol::PlaceholderKind; -  sym->versionId = config->defaultSymbolVersion; +  sym->versionId = VER_NDX_GLOBAL;    sym->visibility = STV_DEFAULT;    sym->isUsedInRegularObj = false;    sym->exportDynamic = false; +  sym->inDynamicList = false;    sym->canInline = true; +  sym->referenced = false; +  sym->traced = false;    sym->scriptDefined = false;    sym->partition = 1;    return sym;  } -Symbol *SymbolTable::addSymbol(const Symbol &New) { -  Symbol *sym = symtab->insert(New.getName()); -  sym->resolve(New); +Symbol *SymbolTable::addSymbol(const Symbol &newSym) { +  Symbol *sym = symtab->insert(newSym.getName()); +  sym->resolve(newSym);    return sym;  } @@ -118,10 +122,7 @@ StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {      for (Symbol *sym : symVector) {        if (!sym->isDefined() && !sym->isCommon())          continue; -      if (Optional<std::string> s = demangleItanium(sym->getName())) -        (*demangledSyms)[*s].push_back(sym); -      else -        (*demangledSyms)[sym->getName()].push_back(sym); +      (*demangledSyms)[demangleItanium(sym->getName())].push_back(sym);      }    }    return *demangledSyms; @@ -162,12 +163,8 @@ void SymbolTable::handleDynamicList() {      else        syms = findByVersion(ver); -    for (Symbol *b : syms) { -      if (!config->shared) -        b->exportDynamic = true; -      else if (b->includeInDynsym()) -        b->isPreemptible = true; -    } +    for (Symbol *sym : syms) +      sym->inDynamicList = true;    }  } @@ -192,7 +189,7 @@ void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,        return "VER_NDX_LOCAL";      if (ver == VER_NDX_GLOBAL)        return "VER_NDX_GLOBAL"; -    return ("version '" + config->versionDefinitions[ver - 2].name + "'").str(); +    return ("version '" + config->versionDefinitions[ver].name + "'").str();    };    // Assign the version. @@ -203,8 +200,12 @@ void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,      if (sym->getName().contains('@'))        continue; -    if (sym->versionId == config->defaultSymbolVersion) +    // 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)) { +      sym->verdefIndex = 0;        sym->versionId = versionId; +    }      if (sym->versionId == versionId)        continue; @@ -214,15 +215,14 @@ void SymbolTable::assignExactVersion(SymbolVersion ver, uint16_t versionId,  }  void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) { -  if (!ver.hasWildcard) -    return; - -  // Exact matching takes precendence over fuzzy matching, +  // Exact matching takes precedence over fuzzy matching,    // 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 *b : findAllByVersion(ver)) -    if (b->versionId == config->defaultSymbolVersion) -      b->versionId = versionId; +  for (Symbol *sym : findAllByVersion(ver)) +    if (sym->verdefIndex == UINT32_C(-1)) { +      sym->verdefIndex = 0; +      sym->versionId = versionId; +    }  }  // This function processes version scripts by updating the versionId @@ -233,26 +233,24 @@ void SymbolTable::assignWildcardVersion(SymbolVersion ver, uint16_t versionId) {  void SymbolTable::scanVersionScript() {    // First, we assign versions to exact matching symbols,    // i.e. version definitions not containing any glob meta-characters. -  for (SymbolVersion &ver : config->versionScriptGlobals) -    assignExactVersion(ver, VER_NDX_GLOBAL, "global"); -  for (SymbolVersion &ver : config->versionScriptLocals) -    assignExactVersion(ver, VER_NDX_LOCAL, "local");    for (VersionDefinition &v : config->versionDefinitions) -    for (SymbolVersion &ver : v.globals) -      assignExactVersion(ver, v.id, v.name); - -  // Next, we assign versions to fuzzy matching symbols, -  // i.e. version definitions containing glob meta-characters. -  for (SymbolVersion &ver : config->versionScriptGlobals) -    assignWildcardVersion(ver, VER_NDX_GLOBAL); -  for (SymbolVersion &ver : config->versionScriptLocals) -    assignWildcardVersion(ver, VER_NDX_LOCAL); - -  // Note that because the last match takes precedence over previous matches, -  // we iterate over the definitions in the reverse order. +    for (SymbolVersion &pat : v.patterns) +      assignExactVersion(pat, v.id, v.name); + +  // Next, assign versions to wildcards that are not "*". Note that because the +  // last match takes precedence over previous matches, we iterate over the +  // definitions in the reverse order.    for (VersionDefinition &v : llvm::reverse(config->versionDefinitions)) -    for (SymbolVersion &ver : v.globals) -      assignWildcardVersion(ver, v.id); +    for (SymbolVersion &pat : v.patterns) +      if (pat.hasWildcard && pat.name != "*") +        assignWildcardVersion(pat, v.id); + +  // Then, assign versions to "*". In GNU linkers they have lower priority than +  // other wildcards. +  for (VersionDefinition &v : config->versionDefinitions) +    for (SymbolVersion &pat : v.patterns) +      if (pat.hasWildcard && pat.name == "*") +        assignWildcardVersion(pat, v.id);    // Symbol themselves might know their versions because symbols    // can contain versions in the form of <name>@<version>. @@ -262,7 +260,10 @@ void SymbolTable::scanVersionScript() {    // isPreemptible is false at this point. To correctly compute the binding of a    // Defined (which is used by includeInDynsym()), we need to know if it is -  // VER_NDX_LOCAL or not. If defaultSymbolVersion is VER_NDX_LOCAL, we should -  // compute symbol versions before handling --dynamic-list. +  // VER_NDX_LOCAL or not. Compute symbol versions before handling +  // --dynamic-list.    handleDynamicList();  } + +} // namespace elf +} // namespace lld  | 
