diff options
| -rw-r--r-- | lld/ELF/Config.h | 4 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 7 | ||||
| -rw-r--r-- | lld/ELF/Driver.h | 2 | ||||
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 63 | ||||
| -rw-r--r-- | lld/ELF/InputFiles.h | 136 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 17 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.h | 4 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 2 |
8 files changed, 108 insertions, 127 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index b740579221f..e376dc151ab 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -18,7 +18,7 @@ namespace lld { namespace elf2 { -class ELFFileBase; +class InputFile; class SymbolBody; enum ELFKind { @@ -31,7 +31,7 @@ enum ELFKind { struct Configuration { SymbolBody *EntrySym = nullptr; - ELFFileBase *FirstElf = nullptr; + InputFile *FirstElf = nullptr; llvm::StringRef DynamicLinker; llvm::StringRef Entry; llvm::StringRef Emulation; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 0e081d18dda..7f8f6f4254c 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -100,12 +100,9 @@ void LinkerDriver::addFile(StringRef Path) { } Files.push_back(make_unique<ArchiveFile>(MBRef)); return; - case file_magic::elf_shared_object: { - std::unique_ptr<ELFFileBase> File = createELFFile<SharedFile>(MBRef); - cast<SharedFileBase>(File.get())->AsNeeded = Config->AsNeeded; - Files.push_back(std::move(File)); + case file_magic::elf_shared_object: + Files.push_back(createELFFile<SharedFile>(MBRef)); return; - } default: Files.push_back(createELFFile<ObjectFile>(MBRef)); } diff --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h index 6a7ca8f5dc7..2641155104d 100644 --- a/lld/ELF/Driver.h +++ b/lld/ELF/Driver.h @@ -33,7 +33,7 @@ public: private: template <template <class> class T> - std::unique_ptr<ELFFileBase> createELFInputFile(MemoryBufferRef MB); + std::unique_ptr<InputFile> createELFInputFile(MemoryBufferRef MB); llvm::BumpPtrAllocator Alloc; bool WholeArchive = false; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index b0a5b16c57b..a4a9c672e83 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -21,28 +21,6 @@ using namespace llvm::sys::fs; using namespace lld; using namespace lld::elf2; -template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) { - bool IsShared = isa<SharedFileBase>(B); - if (IsShared) - return cast<SharedFile<ELFT>>(B).getEMachine(); - return cast<ObjectFile<ELFT>>(B).getEMachine(); -} - -uint16_t ELFFileBase::getEMachine() const { - switch (EKind) { - case ELF32BEKind: - return ::getEMachine<ELF32BE>(*this); - case ELF32LEKind: - return ::getEMachine<ELF32LE>(*this); - case ELF64BEKind: - return ::getEMachine<ELF64BE>(*this); - case ELF64LEKind: - return ::getEMachine<ELF64LE>(*this); - default: - llvm_unreachable("Invalid kind"); - } -} - namespace { class ECRAII { std::error_code EC; @@ -54,12 +32,12 @@ public: } template <class ELFT> -ELFData<ELFT>::ELFData(MemoryBufferRef MB) - : ELFObj(MB.getBuffer(), ECRAII().getEC()) {} +ELFFileBase<ELFT>::ELFFileBase(Kind K, ELFKind EKind, MemoryBufferRef M) + : InputFile(K, M), EKind(EKind), ELFObj(MB.getBuffer(), ECRAII().getEC()) {} template <class ELFT> -typename ELFData<ELFT>::Elf_Sym_Range -ELFData<ELFT>::getSymbolsHelper(bool Local) { +typename ELFFileBase<ELFT>::Elf_Sym_Range +ELFFileBase<ELFT>::getSymbolsHelper(bool Local) { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); Elf_Sym_Range Syms = ELFObj.symbols(Symtab); @@ -73,7 +51,7 @@ ELFData<ELFT>::getSymbolsHelper(bool Local) { return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal); } -template <class ELFT> void ELFData<ELFT>::initStringTable() { +template <class ELFT> void ELFFileBase<ELFT>::initStringTable() { if (!Symtab) return; ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); @@ -82,13 +60,14 @@ template <class ELFT> void ELFData<ELFT>::initStringTable() { } template <class ELFT> -typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() { +typename ELFFileBase<ELFT>::Elf_Sym_Range +ELFFileBase<ELFT>::getNonLocalSymbols() { return getSymbolsHelper(false); } template <class ELFT> ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) - : ObjectFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} + : ObjectFileBase<ELFT>(getStaticELFKind<ELFT>(), M) {} template <class ELFT> typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() { @@ -178,7 +157,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { break; } default: - Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec); + Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec); break; } } @@ -188,9 +167,9 @@ template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { this->initStringTable(); Elf_Sym_Range Syms = this->getNonLocalSymbols(); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); - SymbolBodies.reserve(NumSymbols); + this->SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) - SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); + this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); } template <class ELFT> @@ -203,11 +182,11 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, uint32_t SecIndex = Sym->st_shndx; switch (SecIndex) { case SHN_ABS: - return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym); + return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym); case SHN_UNDEF: - return new (Alloc) Undefined<ELFT>(Name, *Sym); + return new (this->Alloc) Undefined<ELFT>(Name, *Sym); case SHN_COMMON: - return new (Alloc) DefinedCommon<ELFT>(Name, *Sym); + return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym); case SHN_XINDEX: SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab, SymtabSHNDX); @@ -225,8 +204,8 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, case STB_GNU_UNIQUE: { InputSection<ELFT> *Sec = Sections[SecIndex]; if (Sec == &InputSection<ELFT>::Discarded) - return new (Alloc) Undefined<ELFT>(Name, *Sym); - return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec); + return new (this->Alloc) Undefined<ELFT>(Name, *Sym); + return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec); } } } @@ -281,7 +260,7 @@ std::vector<MemoryBufferRef> ArchiveFile::getMembers() { template <class ELFT> SharedFile<ELFT>::SharedFile(MemoryBufferRef M) - : SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} + : SharedFileBase<ELFT>(getStaticELFKind<ELFT>(), M) {} template <class ELFT> void SharedFile<ELFT>::parseSoName() { typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; @@ -298,7 +277,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { } this->initStringTable(); - SoName = getName(); + this->SoName = this->getName(); if (DynamicSec) { auto *Begin = @@ -310,7 +289,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) error("Invalid DT_SONAME entry"); - SoName = StringRef(this->StringTable.data() + Val); + this->SoName = StringRef(this->StringTable.data() + Val); break; } } @@ -335,6 +314,10 @@ template <class ELFT> void SharedFile<ELFT>::parse() { namespace lld { namespace elf2 { +template class ELFFileBase<llvm::object::ELF32LE>; +template class ELFFileBase<llvm::object::ELF32BE>; +template class ELFFileBase<llvm::object::ELF64LE>; +template class ELFFileBase<llvm::object::ELF64BE>; template class elf2::ObjectFile<llvm::object::ELF32LE>; template class elf2::ObjectFile<llvm::object::ELF32BE>; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 288f1364cc3..acbcd2d7f36 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -47,10 +47,12 @@ private: const Kind FileKind; }; -class ELFFileBase : public InputFile { +template <typename ELFT> class ELFFileBase : public InputFile { public: - ELFFileBase(Kind K, ELFKind EKind, MemoryBufferRef M) - : InputFile(K, M), EKind(EKind) {} + typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; + typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; + + ELFFileBase(Kind K, ELFKind EKind, MemoryBufferRef M); static bool classof(const InputFile *F) { Kind K = F->kind(); return K == ObjectKind || K == SharedKind; @@ -58,18 +60,36 @@ public: ELFKind getELFKind() const { return EKind; } - uint16_t getEMachine() const; + const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; } + llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; } + + uint16_t getEMachine() const { return getObj().getHeader()->e_machine; } + uint8_t getOSABI() const { + return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; + } + + StringRef getStringTable() const { return StringTable; } protected: const ELFKind EKind; + llvm::object::ELFFile<ELFT> ELFObj; + const Elf_Shdr *Symtab = nullptr; + StringRef StringTable; + void initStringTable(); + Elf_Sym_Range getNonLocalSymbols(); + Elf_Sym_Range getSymbolsHelper(bool); }; // .o file. -class ObjectFileBase : public ELFFileBase { +template <typename ELFT> class ObjectFileBase : public ELFFileBase<ELFT> { + typedef ELFFileBase<ELFT> Base; + public: ObjectFileBase(ELFKind EKind, MemoryBufferRef M) - : ELFFileBase(ObjectKind, EKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } + : ELFFileBase<ELFT>(Base::ObjectKind, EKind, M) {} + static bool classof(const InputFile *F) { + return F->kind() == Base::ObjectKind; + } ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; } virtual void parse(llvm::DenseSet<StringRef> &Comdats) = 0; @@ -92,33 +112,8 @@ template <class ELFT> static ELFKind getStaticELFKind() { return ELF64BEKind; } -template <class ELFT> class ELFData { -public: - ELFData(MemoryBufferRef MB); - typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; - typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; - - const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; } - llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; } - - uint16_t getEMachine() const { return getObj().getHeader()->e_machine; } - uint8_t getOSABI() const { - return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; - } - - StringRef getStringTable() const { return StringTable; } - -protected: - llvm::object::ELFFile<ELFT> ELFObj; - const Elf_Shdr *Symtab = nullptr; - StringRef StringTable; - void initStringTable(); - Elf_Sym_Range getNonLocalSymbols(); - Elf_Sym_Range getSymbolsHelper(bool); -}; - -template <class ELFT> -class ObjectFile : public ObjectFileBase, public ELFData<ELFT> { +template <class ELFT> class ObjectFile : public ObjectFileBase<ELFT> { + typedef ObjectFileBase<ELFT> Base; typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; @@ -130,11 +125,9 @@ class ObjectFile : public ObjectFileBase, public ELFData<ELFT> { ArrayRef<GroupEntryType> getShtGroupEntries(const Elf_Shdr &Sec); public: - using ELFData<ELFT>::getEMachine; - static bool classof(const InputFile *F) { - return F->kind() == ObjectKind && - cast<ELFFileBase>(F)->getELFKind() == getStaticELFKind<ELFT>(); + return F->kind() == Base::ObjectKind && + cast<ELFFileBase<ELFT>>(F)->getELFKind() == getStaticELFKind<ELFT>(); } explicit ObjectFile(MemoryBufferRef M); @@ -146,7 +139,7 @@ public: uint32_t FirstNonLocal = this->Symtab->sh_info; if (SymbolIndex < FirstNonLocal) return nullptr; - return SymbolBodies[SymbolIndex - FirstNonLocal]; + return this->SymbolBodies[SymbolIndex - FirstNonLocal]; } Elf_Sym_Range getLocalSymbols(); @@ -187,14 +180,20 @@ private: }; // .so file. -class SharedFileBase : public ELFFileBase { +template <typename ELFT> class SharedFileBase : public ELFFileBase<ELFT> { + typedef ELFFileBase<ELFT> Base; + protected: StringRef SoName; public: SharedFileBase(ELFKind EKind, MemoryBufferRef M) - : ELFFileBase(SharedKind, EKind, M) {} - static bool classof(const InputFile *F) { return F->kind() == SharedKind; } + : ELFFileBase<ELFT>(Base::SharedKind, EKind, M) { + AsNeeded = Config->AsNeeded; + } + static bool classof(const InputFile *F) { + return F->kind() == Base::SharedKind; + } StringRef getSoName() const { return SoName; } virtual void parseSoName() = 0; virtual void parse() = 0; @@ -205,8 +204,8 @@ public: bool isNeeded() const { return !AsNeeded || IsUsed; } }; -template <class ELFT> -class SharedFile : public SharedFileBase, public ELFData<ELFT> { +template <class ELFT> class SharedFile : public SharedFileBase<ELFT> { + typedef SharedFileBase<ELFT> Base; typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; @@ -214,14 +213,13 @@ class SharedFile : public SharedFileBase, public ELFData<ELFT> { std::vector<SharedSymbol<ELFT>> SymbolBodies; public: - using ELFData<ELFT>::getEMachine; llvm::MutableArrayRef<SharedSymbol<ELFT>> getSharedSymbols() { return SymbolBodies; } static bool classof(const InputFile *F) { - return F->kind() == SharedKind && - cast<ELFFileBase>(F)->getELFKind() == getStaticELFKind<ELFT>(); + return F->kind() == Base::SharedKind && + cast<ELFFileBase<ELFT>>(F)->getELFKind() == getStaticELFKind<ELFT>(); } explicit SharedFile(MemoryBufferRef M); @@ -230,8 +228,23 @@ public: void parse() override; }; +template <typename T> +std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) { + std::unique_ptr<T> Ret = llvm::make_unique<T>(MB); + + if (!Config->FirstElf) + Config->FirstElf = Ret.get(); + + if (Config->ElfKind == ELFNoneKind) { + Config->ElfKind = Ret->getELFKind(); + Config->EMachine = Ret->getEMachine(); + } + + return std::move(Ret); +} + template <template <class> class T> -std::unique_ptr<ELFFileBase> createELFFile(MemoryBufferRef MB) { +std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) { using namespace llvm; std::pair<unsigned char, unsigned char> Type = @@ -239,30 +252,17 @@ std::unique_ptr<ELFFileBase> createELFFile(MemoryBufferRef MB) { if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) error("Invalid data encoding: " + MB.getBufferIdentifier()); - std::unique_ptr<ELFFileBase> Ret; if (Type.first == ELF::ELFCLASS32) { if (Type.second == ELF::ELFDATA2LSB) - Ret.reset(new T<object::ELF32LE>(MB)); - else - Ret.reset(new T<object::ELF32BE>(MB)); - } else if (Type.first == ELF::ELFCLASS64) { - if (Type.second == ELF::ELFDATA2LSB) - Ret.reset(new T<object::ELF64LE>(MB)); - else - Ret.reset(new T<object::ELF64BE>(MB)); - } else { - error("Invalid file class: " + MB.getBufferIdentifier()); + return createELFFileAux<T<object::ELF32LE>>(MB); + return createELFFileAux<T<object::ELF32BE>>(MB); } - - if (!Config->FirstElf) - Config->FirstElf = Ret.get(); - - if (Config->ElfKind == ELFNoneKind) { - Config->ElfKind = Ret->getELFKind(); - Config->EMachine = Ret->getEMachine(); + if (Type.first == ELF::ELFCLASS64) { + if (Type.second == ELF::ELFDATA2LSB) + return createELFFileAux<T<object::ELF64LE>>(MB); + return createELFFileAux<T<object::ELF64BE>>(MB); } - - return Ret; + error("Invalid file class: " + MB.getBufferIdentifier()); } } // namespace elf2 diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index bfad8c333b3..a1c1429bfb3 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -29,7 +29,7 @@ template <class ELFT> bool SymbolTable<ELFT>::shouldUseRela() const { template <class ELFT> void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) { - if (auto *E = dyn_cast<ELFFileBase>(File.get())) { + if (auto *E = dyn_cast<ELFFileBase<ELFT>>(File.get())) { if (E->getELFKind() != Config->ElfKind || E->getEMachine() != Config->EMachine) { StringRef A = E->getName(); @@ -47,15 +47,15 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) { addLazy(&Sym); return; } - if (auto *S = dyn_cast<SharedFileBase>(File.get())) { + if (auto *S = dyn_cast<SharedFileBase<ELFT>>(File.get())) { S->parseSoName(); if (!IncludedSoNames.insert(S->getSoName()).second) return; S->parse(); } else { - cast<ObjectFileBase>(File.get())->parse(Comdats); + cast<ObjectFileBase<ELFT>>(File.get())->parse(Comdats); } - addELFFile(cast<ELFFileBase>(File.release())); + addELFFile(cast<ELFFileBase<ELFT>>(File.release())); } template <class ELFT> @@ -90,13 +90,14 @@ template <class ELFT> void SymbolTable<ELFT>::addIgnoredSym(StringRef Name) { resolve(Sym); } -template <class ELFT> void SymbolTable<ELFT>::addELFFile(ELFFileBase *File) { +template <class ELFT> +void SymbolTable<ELFT>::addELFFile(ELFFileBase<ELFT> *File) { if (auto *O = dyn_cast<ObjectFile<ELFT>>(File)) ObjectFiles.emplace_back(O); else if (auto *S = dyn_cast<SharedFile<ELFT>>(File)) SharedFiles.emplace_back(S); - if (auto *O = dyn_cast<ObjectFileBase>(File)) { + if (auto *O = dyn_cast<ObjectFileBase<ELFT>>(File)) { for (SymbolBody *Body : O->getSymbols()) resolve(Body); } @@ -116,8 +117,8 @@ void SymbolTable<ELFT>::reportConflict(const Twine &Message, const Elf_Sym &OldE = cast<ELFSymbolBody<ELFT>>(Old).Sym; const Elf_Sym &NewE = cast<ELFSymbolBody<ELFT>>(New).Sym; - ELFFileBase *OldFile = nullptr; - ELFFileBase *NewFile = nullptr; + ELFFileBase<ELFT> *OldFile = nullptr; + ELFFileBase<ELFT> *NewFile = nullptr; for (const std::unique_ptr<ObjectFile<ELFT>> &File : ObjectFiles) { Elf_Sym_Range Syms = File->getObj().symbols(File->getSymbolTable()); diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 7495ad67b70..a21a050b35d 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -33,7 +33,7 @@ public: void addFile(std::unique_ptr<InputFile> File); - const ELFFileBase *getFirstELF() const { + const ELFFileBase<ELFT> *getFirstELF() const { if (!ObjectFiles.empty()) return ObjectFiles[0].get(); if (!SharedFiles.empty()) @@ -63,7 +63,7 @@ public: private: Symbol *insert(SymbolBody *New); - void addELFFile(ELFFileBase *File); + void addELFFile(ELFFileBase<ELFT> *File); void addLazy(Lazy *New); void addMemberFile(Lazy *Body); void init(uint16_t EMachine); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index bb3cd1aeb3c..5a9a459f326 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -229,7 +229,7 @@ static void reportUndefined(const SymbolTable<ELFT> &S, const SymbolBody &Sym) { return; const Elf_Sym &SymE = cast<ELFSymbolBody<ELFT>>(Sym).Sym; - ELFFileBase *SymFile = nullptr; + ELFFileBase<ELFT> *SymFile = nullptr; for (const std::unique_ptr<ObjectFile<ELFT>> &File : S.getObjectFiles()) { Elf_Sym_Range Syms = File->getObj().symbols(File->getSymbolTable()); |

