diff options
Diffstat (limited to 'ELF/Symbols.cpp')
-rw-r--r-- | ELF/Symbols.cpp | 66 |
1 files changed, 34 insertions, 32 deletions
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp index 62c552e04828..c0cba21cfe8d 100644 --- a/ELF/Symbols.cpp +++ b/ELF/Symbols.cpp @@ -23,9 +23,20 @@ using namespace llvm; using namespace llvm::object; using namespace llvm::ELF; -using namespace lld; -using namespace lld::elf; +namespace lld { +// Returns a symbol for an error message. +static std::string demangle(StringRef symName) { + if (elf::config->demangle) + return demangleItanium(symName); + return symName; +} +std::string toString(const elf::Symbol &b) { return demangle(b.getName()); } +std::string toELFString(const Archive::Symbol &b) { + return demangle(b.getName()); +} + +namespace elf { Defined *ElfSym::bss; Defined *ElfSym::etext1; Defined *ElfSym::etext2; @@ -213,7 +224,7 @@ void Symbol::parseSymbolVersion() { if (isDefault) verstr = verstr.substr(1); - for (VersionDefinition &ver : config->versionDefinitions) { + for (const VersionDefinition &ver : namedVersionDefs()) { if (ver.name != verstr) continue; @@ -250,20 +261,20 @@ void Symbol::fetch() const { } MemoryBufferRef LazyArchive::getMemberBuffer() { - Archive::Child c = CHECK( - sym.getMember(), "could not get the member for symbol " + sym.getName()); + Archive::Child c = + CHECK(sym.getMember(), + "could not get the member for symbol " + toELFString(sym)); return CHECK(c.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + - sym.getName()); + toELFString(sym)); } uint8_t Symbol::computeBinding() const { if (config->relocatable) return binding; - if (visibility != STV_DEFAULT && visibility != STV_PROTECTED) - return STB_LOCAL; - if (versionId == VER_NDX_LOCAL && isDefined() && !isPreemptible) + if ((visibility != STV_DEFAULT && visibility != STV_PROTECTED) || + versionId == VER_NDX_LOCAL) return STB_LOCAL; if (!config->gnuUnique && binding == STB_GNU_UNIQUE) return STB_GLOBAL; @@ -281,11 +292,11 @@ bool Symbol::includeInDynsym() const { if (isUndefWeak() && config->pie && sharedFiles.empty()) return false; - return isUndefined() || isShared() || exportDynamic; + return isUndefined() || isShared() || exportDynamic || inDynamicList; } // Print out a log message for --trace-symbol. -void elf::printTraceSymbol(const Symbol *sym) { +void printTraceSymbol(const Symbol *sym) { std::string s; if (sym->isUndefined()) s = ": reference to "; @@ -301,7 +312,7 @@ void elf::printTraceSymbol(const Symbol *sym) { message(toString(sym->file) + s + sym->getName()); } -void elf::maybeWarnUnorderableSymbol(const Symbol *sym) { +void maybeWarnUnorderableSymbol(const Symbol *sym) { if (!config->warnSymbolOrdering) return; @@ -331,14 +342,6 @@ void elf::maybeWarnUnorderableSymbol(const Symbol *sym) { report(": unable to order discarded symbol: "); } -// Returns a symbol for an error message. -std::string lld::toString(const Symbol &b) { - if (config->demangle) - if (Optional<std::string> s = demangleItanium(b.getName())) - return *s; - return b.getName(); -} - static uint8_t getMinVisibility(uint8_t va, uint8_t vb) { if (va == STV_DEFAULT) return vb; @@ -485,17 +488,13 @@ void Symbol::resolveUndefined(const Undefined &other) { if (dyn_cast_or_null<SharedFile>(other.file)) return; - if (isUndefined()) { - // The binding may "upgrade" from weak to non-weak. - if (other.binding != STB_WEAK) + if (isUndefined() || isShared()) { + // The binding will be weak if there is at least one reference and all are + // weak. The binding has one opportunity to change to weak: if the first + // reference is weak. + if (other.binding != STB_WEAK || !referenced) binding = other.binding; - } else if (auto *s = dyn_cast<SharedSymbol>(this)) { - // The binding of a SharedSymbol will be weak if there is at least one - // reference and all are weak. The binding has one opportunity to change to - // weak: if the first reference is weak. - if (other.binding != STB_WEAK || !s->referenced) - binding = other.binding; - s->referenced = true; + referenced = true; } } @@ -553,7 +552,7 @@ int Symbol::compare(const Symbol *other) const { auto *oldSym = cast<Defined>(this); auto *newSym = cast<Defined>(other); - if (other->file && isa<BitcodeFile>(other->file)) + if (dyn_cast_or_null<BitcodeFile>(other->file)) return 0; if (!oldSym->section && !newSym->section && oldSym->value == newSym->value && @@ -651,6 +650,9 @@ void Symbol::resolveShared(const SharedSymbol &other) { uint8_t bind = binding; replace(other); binding = bind; - cast<SharedSymbol>(this)->referenced = true; + referenced = true; } } + +} // namespace elf +} // namespace lld |