1 //===- InputFiles.h ---------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLD_ELF_INPUT_FILES_H 11 #define LLD_ELF_INPUT_FILES_H 12 13 #include "Config.h" 14 #include "InputSection.h" 15 #include "Error.h" 16 #include "Symbols.h" 17 18 #include "lld/Core/LLVM.h" 19 #include "llvm/ADT/DenseSet.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Object/Archive.h" 22 #include "llvm/Object/ELF.h" 23 24 namespace lld { 25 namespace elf2 { 26 27 using llvm::object::Archive; 28 29 class InputFile; 30 class Lazy; 31 class SymbolBody; 32 33 // The root class of input files. 34 class InputFile { 35 public: 36 enum Kind { ObjectKind, SharedKind, ArchiveKind }; 37 Kind kind() const { return FileKind; } 38 39 StringRef getName() const { return MB.getBufferIdentifier(); } 40 41 protected: 42 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} 43 MemoryBufferRef MB; 44 45 private: 46 const Kind FileKind; 47 }; 48 49 template <typename ELFT> class ELFFileBase : public InputFile { 50 public: 51 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 52 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 53 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 54 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 55 56 ELFFileBase(Kind K, MemoryBufferRef M); 57 static bool classof(const InputFile *F) { 58 Kind K = F->kind(); 59 return K == ObjectKind || K == SharedKind; 60 } 61 62 static ELFKind getELFKind(); 63 const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; } 64 llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; } 65 66 uint16_t getEMachine() const { return getObj().getHeader()->e_machine; } 67 uint8_t getOSABI() const { 68 return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; 69 } 70 71 StringRef getStringTable() const { return StringTable; } 72 73 uint32_t getSectionIndex(const Elf_Sym &Sym) const; 74 75 protected: 76 llvm::object::ELFFile<ELFT> ELFObj; 77 const Elf_Shdr *Symtab = nullptr; 78 ArrayRef<Elf_Word> SymtabSHNDX; 79 StringRef StringTable; 80 void initStringTable(); 81 Elf_Sym_Range getNonLocalSymbols(); 82 Elf_Sym_Range getSymbolsHelper(bool); 83 }; 84 85 // .o file. 86 template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { 87 typedef ELFFileBase<ELFT> Base; 88 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 89 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 90 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 91 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 92 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 93 94 // uint32 in ELFT's byte order 95 typedef llvm::support::detail::packed_endian_specific_integral< 96 uint32_t, ELFT::TargetEndianness, 2> 97 uint32_X; 98 99 StringRef getShtGroupSignature(const Elf_Shdr &Sec); 100 ArrayRef<uint32_X> getShtGroupEntries(const Elf_Shdr &Sec); 101 102 public: 103 static bool classof(const InputFile *F) { 104 return F->kind() == Base::ObjectKind; 105 } 106 107 ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; } 108 109 explicit ObjectFile(MemoryBufferRef M); 110 void parse(llvm::DenseSet<StringRef> &ComdatGroups); 111 112 ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; } 113 InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const; 114 115 SymbolBody *getSymbolBody(uint32_t SymbolIndex) const { 116 uint32_t FirstNonLocal = this->Symtab->sh_info; 117 if (SymbolIndex < FirstNonLocal) 118 return nullptr; 119 return SymbolBodies[SymbolIndex - FirstNonLocal]; 120 } 121 122 Elf_Sym_Range getLocalSymbols(); 123 const Elf_Sym *getLocalSymbol(uintX_t SymIndex); 124 125 const Elf_Shdr *getSymbolTable() const { return this->Symtab; }; 126 127 // Get MIPS GP0 value defined by this file. This value represents the gp value 128 // used to create the relocatable object and required to support 129 // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. 130 uint32_t getMipsGp0() const; 131 132 private: 133 void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups); 134 void initializeSymbols(); 135 InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec); 136 137 SymbolBody *createSymbolBody(const Elf_Sym *Sym); 138 139 // List of all sections defined by this file. 140 std::vector<InputSectionBase<ELFT> *> Sections; 141 142 // List of all symbols referenced or defined by this file. 143 std::vector<SymbolBody *> SymbolBodies; 144 145 // MIPS .reginfo section defined by this file. 146 MipsReginfoInputSection<ELFT> *MipsReginfo = nullptr; 147 148 llvm::BumpPtrAllocator Alloc; 149 llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> MAlloc; 150 llvm::SpecificBumpPtrAllocator<EHInputSection<ELFT>> EHAlloc; 151 }; 152 153 class ArchiveFile : public InputFile { 154 public: 155 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} 156 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } 157 void parse(); 158 159 // Returns a memory buffer for a given symbol. An empty memory buffer 160 // is returned if we have already returned the same memory buffer. 161 // (So that we don't instantiate same members more than once.) 162 MemoryBufferRef getMember(const Archive::Symbol *Sym); 163 164 llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; } 165 166 private: 167 std::unique_ptr<Archive> File; 168 std::vector<Lazy> LazySymbols; 169 llvm::DenseSet<uint64_t> Seen; 170 }; 171 172 // .so file. 173 template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { 174 typedef ELFFileBase<ELFT> Base; 175 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 176 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 177 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 178 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 179 180 std::vector<SharedSymbol<ELFT>> SymbolBodies; 181 std::vector<StringRef> Undefs; 182 StringRef SoName; 183 184 public: 185 StringRef getSoName() const { return SoName; } 186 llvm::MutableArrayRef<SharedSymbol<ELFT>> getSharedSymbols() { 187 return SymbolBodies; 188 } 189 const Elf_Shdr *getSection(const Elf_Sym &Sym) const; 190 llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } 191 192 static bool classof(const InputFile *F) { 193 return F->kind() == Base::SharedKind; 194 } 195 196 explicit SharedFile(MemoryBufferRef M); 197 198 void parseSoName(); 199 void parseRest(); 200 201 // Used for --as-needed 202 bool AsNeeded = false; 203 bool IsUsed = false; 204 bool isNeeded() const { return !AsNeeded || IsUsed; } 205 }; 206 207 std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB); 208 std::unique_ptr<InputFile> createSharedFile(MemoryBufferRef MB); 209 210 } // namespace elf2 211 } // namespace lld 212 213 #endif 214