diff options
Diffstat (limited to 'ELF/Symbols.h')
-rw-r--r-- | ELF/Symbols.h | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/ELF/Symbols.h b/ELF/Symbols.h index d640495b0e011..d43568fe295c7 100644 --- a/ELF/Symbols.h +++ b/ELF/Symbols.h @@ -21,6 +21,13 @@ #include "llvm/Object/ELF.h" namespace lld { +std::string toString(const elf::Symbol &); + +// There are two different ways to convert an Archive::Symbol to a string: +// One for Microsoft name mangling and one for Itanium name mangling. +// Call the functions toCOFFString and toELFString, not just toString. +std::string toELFString(const llvm::object::Archive::Symbol &); + namespace elf { class CommonSymbol; class Defined; @@ -30,12 +37,6 @@ class LazyObject; class SharedSymbol; class Symbol; class Undefined; -} // namespace elf - -std::string toString(const elf::Symbol &); -std::string toString(const elf::InputFile *); - -namespace elf { // This is a StringRef-like container that doesn't run strlen(). // @@ -112,21 +113,35 @@ public: // are unreferenced except by other bitcode objects. unsigned isUsedInRegularObj : 1; - // If this flag is true and the symbol has protected or default visibility, it - // will appear in .dynsym. This flag is set by interposable DSO symbols in - // executables, by most symbols in DSOs and executables built with - // --export-dynamic, and by dynamic lists. + // Used by a Defined symbol with protected or default visibility, to record + // whether it is required to be exported into .dynsym. This is set when any of + // the following conditions hold: + // + // - If there is an interposable symbol from a DSO. + // - If -shared or --export-dynamic is specified, any symbol in an object + // file/bitcode sets this property, unless suppressed by LTO + // canBeOmittedFromSymbolTable(). unsigned exportDynamic : 1; + // True if the symbol is in the --dynamic-list file. A Defined symbol with + // protected or default visibility with this property is required to be + // exported into .dynsym. + unsigned inDynamicList : 1; + // False if LTO shouldn't inline whatever this symbol points to. If a symbol // is overwritten after LTO, LTO shouldn't inline the symbol because it // doesn't know the final contents of the symbol. unsigned canInline : 1; + // Used by Undefined and SharedSymbol to track if there has been at least one + // undefined reference to the symbol. The binding may change to STB_WEAK if + // the first undefined reference from a non-shared object is weak. + unsigned referenced : 1; + // True if this symbol is specified by --trace-symbol option. unsigned traced : 1; - inline void replace(const Symbol &New); + inline void replace(const Symbol &newSym); bool includeInDynsym() const; uint8_t computeBinding() const; @@ -224,9 +239,10 @@ protected: : file(file), nameData(name.data), nameSize(name.size), binding(binding), type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3), isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind), - exportDynamic(isExportDynamic(k, visibility)), canInline(false), - traced(false), needsPltAddr(false), isInIplt(false), gotInIgot(false), - isPreemptible(false), used(!config->gcSections), needsTocRestore(false), + exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false), + canInline(false), referenced(false), traced(false), needsPltAddr(false), + isInIplt(false), gotInIgot(false), isPreemptible(false), + used(!config->gcSections), needsTocRestore(false), scriptDefined(false) {} public: @@ -363,11 +379,6 @@ public: uint64_t value; // st_value uint64_t size; // st_size uint32_t alignment; - - // This is true if there has been at least one undefined reference to the - // symbol. The binding may change to STB_WEAK if the first undefined reference - // is weak. - bool referenced = false; }; // LazyArchive and LazyObject represent a symbols that is not yet in the link, @@ -507,7 +518,7 @@ size_t Symbol::getSymbolSize() const { // replace() replaces "this" object with a given symbol by memcpy'ing // it over to "this". This function is called as a result of name // resolution, e.g. to replace an undefind symbol with a defined symbol. -void Symbol::replace(const Symbol &New) { +void Symbol::replace(const Symbol &newSym) { using llvm::ELF::STT_TLS; // Symbols representing thread-local variables must be referenced by @@ -515,22 +526,23 @@ void Symbol::replace(const Symbol &New) { // non-TLS relocations, so there's a clear distinction between TLS // and non-TLS symbols. It is an error if the same symbol is defined // as a TLS symbol in one file and as a non-TLS symbol in other file. - if (symbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) { - bool tlsMismatch = (type == STT_TLS && New.type != STT_TLS) || - (type != STT_TLS && New.type == STT_TLS); - if (tlsMismatch) - error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " + - toString(New.file) + "\n>>> defined in " + toString(file)); - } + if (symbolKind != PlaceholderKind && !isLazy() && !newSym.isLazy() && + (type == STT_TLS) != (newSym.type == STT_TLS)) + error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " + + toString(newSym.file) + "\n>>> defined in " + toString(file)); Symbol old = *this; - memcpy(this, &New, New.getSymbolSize()); + memcpy(this, &newSym, newSym.getSymbolSize()); + // old may be a placeholder. The referenced fields must be initialized in + // SymbolTable::insert. versionId = old.versionId; visibility = old.visibility; isUsedInRegularObj = old.isUsedInRegularObj; exportDynamic = old.exportDynamic; + inDynamicList = old.inDynamicList; canInline = old.canInline; + referenced = old.referenced; traced = old.traced; isPreemptible = old.isPreemptible; scriptDefined = old.scriptDefined; |