From b289257c7f3ed78b7d3971c596d7c60a9050c705 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 13 Jan 2016 20:06:04 +0000 Subject: Vendor import of lld trunk r257626: https://llvm.org/svn/llvm-project/lld/trunk@257626 --- ELF/SymbolTable.cpp | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'ELF/SymbolTable.cpp') 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 SymbolTable::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::addFile(std::unique_ptr File) { if (auto *F = dyn_cast>(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>(File.release())); @@ -100,17 +99,20 @@ SymbolBody *SymbolTable::addUndefinedOpt(StringRef Name) { } template -void SymbolTable::addAbsolute(StringRef Name, - typename ELFFile::Elf_Sym &ESym) { - resolve(new (Alloc) DefinedRegular(Name, ESym, nullptr)); +SymbolBody *SymbolTable::addAbsolute(StringRef Name, Elf_Sym &ESym) { + // Pass nullptr because absolute symbols have no corresponding input sections. + auto *Sym = new (Alloc) DefinedRegular(Name, ESym, nullptr); + resolve(Sym); + return Sym; } template -void SymbolTable::addSynthetic(StringRef Name, - OutputSectionBase &Section, - typename ELFFile::uintX_t Value) { +SymbolBody *SymbolTable::addSynthetic(StringRef Name, + OutputSectionBase &Section, + uintX_t Value) { auto *Sym = new (Alloc) DefinedSynthetic(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::addSynthetic(StringRef Name, // file's symbol table. Such symbols are useful for some linker-defined symbols. template SymbolBody *SymbolTable::addIgnored(StringRef Name) { - auto *Sym = new (Alloc) - DefinedRegular(Name, ElfSym::IgnoreUndef, nullptr); - resolve(Sym); - return Sym; + return addAbsolute(Name, ElfSym::IgnoredWeak); +} + +// The 'strong' variant of the addIgnored. Adds symbol which has a global +// binding and cannot be substituted. +template +SymbolBody *SymbolTable::addIgnoredStrong(StringRef Name) { + return addAbsolute(Name, ElfSym::Ignored); +} + +// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM. +// Used to implement --wrap. +template void SymbolTable::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 *SymbolTable::findFile(SymbolBody *B) { return nullptr; } +// Construct a string in the form of "Sym in File1 and File2". +// Used to construct an error message. template std::string SymbolTable::conflictMsg(SymbolBody *Old, SymbolBody *New) { ELFFileBase *OldFile = findFile(Old); @@ -184,8 +205,8 @@ template void SymbolTable::resolve(SymbolBody *New) { Sym->Body = New; } +// Find an existing symbol or create and insert a new one. template Symbol *SymbolTable::insert(SymbolBody *New) { - // Find an existing Symbol or create and insert a new one. StringRef Name = New->getName(); Symbol *&Sym = Symtab[Name]; if (!Sym) -- cgit v1.2.3