diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:04 +0000 |
commit | b289257c7f3ed78b7d3971c596d7c60a9050c705 (patch) | |
tree | d6b57e29a5a86347a020d6f0cae76cc2d0f3bf8d /ELF/SymbolTable.cpp | |
parent | fba2c04f31e119eacf142fcbbaabd5a9e63a39ed (diff) | |
download | src-b289257c7f3ed78b7d3971c596d7c60a9050c705.tar.gz src-b289257c7f3ed78b7d3971c596d7c60a9050c705.zip |
Vendor import of lld trunk r257626:vendor/lld/lld-trunk-r257626
Notes
Notes:
svn path=/vendor/lld/dist/; revision=293846
svn path=/vendor/lld/lld-trunk-r257626/; revision=293847; tag=vendor/lld/lld-trunk-r257626
Diffstat (limited to 'ELF/SymbolTable.cpp')
-rw-r--r-- | ELF/SymbolTable.cpp | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp index 74951bad410f..65f5dff9d7a3 100644 --- a/ELF/SymbolTable.cpp +++ b/ELF/SymbolTable.cpp @@ -18,6 +18,7 @@ #include "Config.h" #include "Error.h" #include "Symbols.h" +#include "llvm/Support/StringSaver.h" using namespace llvm; using namespace llvm::object; @@ -26,8 +27,6 @@ using namespace llvm::ELF; using namespace lld; using namespace lld::elf2; -template <class ELFT> SymbolTable<ELFT>::SymbolTable() {} - // All input object files must be for the same architecture // (e.g. it does not make sense to link x86 object files with // MIPS object files.) This function checks for that error. @@ -64,7 +63,7 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) { if (auto *F = dyn_cast<SharedFile<ELFT>>(FileP)) { // DSOs are uniquified not by filename but by soname. F->parseSoName(); - if (!IncludedSoNames.insert(F->getSoName()).second) + if (!SoNames.insert(F->getSoName()).second) return; SharedFiles.emplace_back(cast<SharedFile<ELFT>>(File.release())); @@ -100,17 +99,20 @@ SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) { } template <class ELFT> -void SymbolTable<ELFT>::addAbsolute(StringRef Name, - typename ELFFile<ELFT>::Elf_Sym &ESym) { - resolve(new (Alloc) DefinedRegular<ELFT>(Name, ESym, nullptr)); +SymbolBody *SymbolTable<ELFT>::addAbsolute(StringRef Name, Elf_Sym &ESym) { + // Pass nullptr because absolute symbols have no corresponding input sections. + auto *Sym = new (Alloc) DefinedRegular<ELFT>(Name, ESym, nullptr); + resolve(Sym); + return Sym; } template <class ELFT> -void SymbolTable<ELFT>::addSynthetic(StringRef Name, - OutputSectionBase<ELFT> &Section, - typename ELFFile<ELFT>::uintX_t Value) { +SymbolBody *SymbolTable<ELFT>::addSynthetic(StringRef Name, + OutputSectionBase<ELFT> &Section, + uintX_t Value) { auto *Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, Value, Section); resolve(Sym); + return Sym; } // Add Name as an "ignored" symbol. An ignored symbol is a regular @@ -118,10 +120,27 @@ void SymbolTable<ELFT>::addSynthetic(StringRef Name, // file's symbol table. Such symbols are useful for some linker-defined symbols. template <class ELFT> SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) { - auto *Sym = new (Alloc) - DefinedRegular<ELFT>(Name, ElfSym<ELFT>::IgnoreUndef, nullptr); - resolve(Sym); - return Sym; + return addAbsolute(Name, ElfSym<ELFT>::IgnoredWeak); +} + +// The 'strong' variant of the addIgnored. Adds symbol which has a global +// binding and cannot be substituted. +template <class ELFT> +SymbolBody *SymbolTable<ELFT>::addIgnoredStrong(StringRef Name) { + return addAbsolute(Name, ElfSym<ELFT>::Ignored); +} + +// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM. +// Used to implement --wrap. +template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) { + if (Symtab.count(Name) == 0) + return; + StringSaver Saver(Alloc); + Symbol *Sym = addUndefined(Name)->getSymbol(); + Symbol *Real = addUndefined(Saver.save("__real_" + Name))->getSymbol(); + Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name))->getSymbol(); + Real->Body = Sym->Body; + Sym->Body = Wrap->Body; } // Returns a file from which symbol B was created. @@ -136,6 +155,8 @@ ELFFileBase<ELFT> *SymbolTable<ELFT>::findFile(SymbolBody *B) { return nullptr; } +// Construct a string in the form of "Sym in File1 and File2". +// Used to construct an error message. template <class ELFT> std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Old, SymbolBody *New) { ELFFileBase<ELFT> *OldFile = findFile(Old); @@ -184,8 +205,8 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) { Sym->Body = New; } +// Find an existing symbol or create and insert a new one. template <class ELFT> Symbol *SymbolTable<ELFT>::insert(SymbolBody *New) { - // Find an existing Symbol or create and insert a new one. StringRef Name = New->getName(); Symbol *&Sym = Symtab[Name]; if (!Sym) |