diff options
Diffstat (limited to 'ELF/InputFiles.h')
-rw-r--r-- | ELF/InputFiles.h | 105 |
1 files changed, 51 insertions, 54 deletions
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h index 006218b45d9e..427f2fdea53e 100644 --- a/ELF/InputFiles.h +++ b/ELF/InputFiles.h @@ -11,12 +11,10 @@ #define LLD_ELF_INPUT_FILES_H #include "Config.h" -#include "Error.h" -#include "InputSection.h" -#include "Symbols.h" +#include "lld/Common/ErrorHandler.h" -#include "lld/Core/LLVM.h" -#include "lld/Core/Reproduce.h" +#include "lld/Common/LLVM.h" +#include "lld/Common/Reproduce.h" #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" @@ -40,9 +38,10 @@ class InputFile; namespace lld { namespace elf { class InputFile; +class InputSectionBase; } -// Returns "(internal)", "foo.a(bar.o)" or "baz.o". +// Returns "<internal>", "foo.a(bar.o)" or "baz.o". std::string toString(const elf::InputFile *F); namespace elf { @@ -50,7 +49,7 @@ namespace elf { using llvm::object::Archive; class Lazy; -class SymbolBody; +class Symbol; // If -reproduce option is given, all input files are written // to this tar archive. @@ -63,9 +62,9 @@ llvm::Optional<MemoryBufferRef> readFile(StringRef Path); class InputFile { public: enum Kind { - ObjectKind, + ObjKind, SharedKind, - LazyObjectKind, + LazyObjKind, ArchiveKind, BitcodeKind, BinaryKind, @@ -79,10 +78,18 @@ public: // Returns sections. It is a runtime error to call this function // on files that don't have the notion of sections. ArrayRef<InputSectionBase *> getSections() const { - assert(FileKind == ObjectKind || FileKind == BinaryKind); + assert(FileKind == ObjKind || FileKind == BinaryKind); return Sections; } + // Returns object file symbols. It is a runtime error to call this + // function on files of other types. + ArrayRef<Symbol *> getSymbols() { + assert(FileKind == ObjKind || FileKind == BitcodeKind || + FileKind == ArchiveKind); + return Symbols; + } + // Filename of .a which contained this file. If this file was // not in an archive file, it is the empty string. We use this // string for creating error messages. @@ -100,6 +107,7 @@ public: protected: InputFile(Kind K, MemoryBufferRef M); std::vector<InputSectionBase *> Sections; + std::vector<Symbol *> Symbols; private: const Kind FileKind; @@ -115,21 +123,22 @@ public: ELFFileBase(Kind K, MemoryBufferRef M); static bool classof(const InputFile *F) { Kind K = F->kind(); - return K == ObjectKind || K == SharedKind; + return K == ObjKind || K == SharedKind; } llvm::object::ELFFile<ELFT> getObj() const { - return llvm::object::ELFFile<ELFT>(MB.getBuffer()); + return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer())); } StringRef getStringTable() const { return StringTable; } uint32_t getSectionIndex(const Elf_Sym &Sym) const; - Elf_Sym_Range getGlobalSymbols(); + Elf_Sym_Range getGlobalELFSyms(); + Elf_Sym_Range getELFSyms() const { return ELFSyms; } protected: - ArrayRef<Elf_Sym> Symbols; + ArrayRef<Elf_Sym> ELFSyms; uint32_t FirstNonLocal = 0; ArrayRef<Elf_Word> SymtabSHNDX; StringRef StringTable; @@ -137,7 +146,7 @@ protected: }; // .o file. -template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { +template <class ELFT> class ObjFile : public ELFFileBase<ELFT> { typedef ELFFileBase<ELFT> Base; typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; @@ -150,34 +159,29 @@ template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec); public: - static bool classof(const InputFile *F) { - return F->kind() == Base::ObjectKind; - } + static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } - ArrayRef<SymbolBody *> getSymbols(); - ArrayRef<SymbolBody *> getLocalSymbols(); + ArrayRef<Symbol *> getLocalSymbols(); - ObjectFile(MemoryBufferRef M, StringRef ArchiveName); + ObjFile(MemoryBufferRef M, StringRef ArchiveName); void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); - InputSectionBase *getSection(const Elf_Sym &Sym) const; - - SymbolBody &getSymbolBody(uint32_t SymbolIndex) const { - if (SymbolIndex >= SymbolBodies.size()) + Symbol &getSymbol(uint32_t SymbolIndex) const { + if (SymbolIndex >= this->Symbols.size()) fatal(toString(this) + ": invalid symbol index"); - return *SymbolBodies[SymbolIndex]; + return *this->Symbols[SymbolIndex]; } - template <typename RelT> - SymbolBody &getRelocTargetSym(const RelT &Rel) const { + template <typename RelT> Symbol &getRelocTargetSym(const RelT &Rel) const { uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL); - return getSymbolBody(SymIndex); + return getSymbol(SymIndex); } // Returns source line information for a given offset. // If no information is available, returns "". std::string getLineInfo(InputSectionBase *S, uint64_t Offset); llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t); + llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef Name); // MIPS GP0 value defined by this file. This value represents the gp value // used to create the relocatable object and required to support @@ -193,16 +197,13 @@ private: void initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); void initializeSymbols(); - void initializeDwarfLine(); + void initializeDwarf(); InputSectionBase *getRelocTarget(const Elf_Shdr &Sec); InputSectionBase *createInputSection(const Elf_Shdr &Sec); StringRef getSectionName(const Elf_Shdr &Sec); bool shouldMerge(const Elf_Shdr &Sec); - SymbolBody *createSymbolBody(const Elf_Sym *Sym); - - // List of all symbols referenced or defined by this file. - std::vector<SymbolBody *> SymbolBodies; + Symbol *createSymbol(const Elf_Sym *Sym); // .shstrtab contents. StringRef SectionStringTable; @@ -212,34 +213,33 @@ private: // single object file, so we cache debugging information in order to // parse it only once for each object file we link. std::unique_ptr<llvm::DWARFDebugLine> DwarfLine; + llvm::DenseMap<StringRef, std::pair<unsigned, unsigned>> VariableLoc; llvm::once_flag InitDwarfLine; }; -// LazyObjectFile is analogous to ArchiveFile in the sense that +// LazyObjFile is analogous to ArchiveFile in the sense that // the file contains lazy symbols. The difference is that -// LazyObjectFile wraps a single file instead of multiple files. +// LazyObjFile wraps a single file instead of multiple files. // // This class is used for --start-lib and --end-lib options which // instruct the linker to link object files between them with the // archive file semantics. -class LazyObjectFile : public InputFile { +class LazyObjFile : public InputFile { public: - LazyObjectFile(MemoryBufferRef M, StringRef ArchiveName, - uint64_t OffsetInArchive) - : InputFile(LazyObjectKind, M), OffsetInArchive(OffsetInArchive) { + LazyObjFile(MemoryBufferRef M, StringRef ArchiveName, + uint64_t OffsetInArchive) + : InputFile(LazyObjKind, M), OffsetInArchive(OffsetInArchive) { this->ArchiveName = ArchiveName; } - static bool classof(const InputFile *F) { - return F->kind() == LazyObjectKind; - } + static bool classof(const InputFile *F) { return F->kind() == LazyObjKind; } template <class ELFT> void parse(); MemoryBufferRef getBuffer(); InputFile *fetch(); private: - std::vector<StringRef> getSymbols(); + std::vector<StringRef> getSymbolNames(); template <class ELFT> std::vector<StringRef> getElfSymbols(); std::vector<StringRef> getBitcodeSymbols(); @@ -253,7 +253,6 @@ public: explicit ArchiveFile(std::unique_ptr<Archive> &&File); static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } template <class ELFT> void parse(); - ArrayRef<Symbol *> getSymbols() { return Symbols; } // Returns a memory buffer for a given symbol and the offset in the archive // for the member. An empty memory buffer and an offset of zero @@ -264,7 +263,6 @@ public: private: std::unique_ptr<Archive> File; llvm::DenseSet<uint64_t> Seen; - std::vector<Symbol *> Symbols; }; class BitcodeFile : public InputFile { @@ -274,11 +272,7 @@ public: static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } template <class ELFT> void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups); - ArrayRef<Symbol *> getSymbols() { return Symbols; } std::unique_ptr<llvm::lto::InputFile> Obj; - -private: - std::vector<Symbol *> Symbols; }; // .so file. @@ -296,9 +290,9 @@ template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { const Elf_Shdr *VerdefSec = nullptr; public: + std::vector<const Elf_Verdef *> Verdefs; std::string SoName; - const Elf_Shdr *getSection(const Elf_Sym &Sym) const; llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } static bool classof(const InputFile *F) { @@ -324,9 +318,7 @@ public: std::map<const Elf_Verdef *, NeededVer> VerdefMap; // Used for --as-needed - bool AsNeeded = false; - bool IsUsed = false; - bool isNeeded() const { return !AsNeeded || IsUsed; } + bool IsNeeded; }; class BinaryFile : public InputFile { @@ -340,6 +332,11 @@ InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", uint64_t OffsetInArchive = 0); InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName); +extern std::vector<BinaryFile *> BinaryFiles; +extern std::vector<BitcodeFile *> BitcodeFiles; +extern std::vector<InputFile *> ObjectFiles; +extern std::vector<InputFile *> SharedFiles; + } // namespace elf } // namespace lld |