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 #include "llvm/Support/StringSaver.h" 24 25 namespace lld { 26 namespace elf { 27 28 using llvm::object::Archive; 29 30 class InputFile; 31 class Lazy; 32 class SymbolBody; 33 34 // The root class of input files. 35 class InputFile { 36 public: 37 enum Kind { ObjectKind, SharedKind, ArchiveKind, BitcodeKind }; 38 Kind kind() const { return FileKind; } 39 40 StringRef getName() const { return MB.getBufferIdentifier(); } 41 MemoryBufferRef MB; 42 43 // Filename of .a which contained this file. If this file was 44 // not in an archive file, it is the empty string. We use this 45 // string for creating error messages. 46 StringRef ArchiveName; 47 48 protected: 49 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} 50 51 private: 52 const Kind FileKind; 53 }; 54 55 template <typename ELFT> class ELFFileBase : public InputFile { 56 public: 57 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 58 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 59 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 60 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 61 62 ELFFileBase(Kind K, MemoryBufferRef M); 63 static bool classof(const InputFile *F) { 64 Kind K = F->kind(); 65 return K == ObjectKind || K == SharedKind; 66 } 67 68 static ELFKind getELFKind(); 69 const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; } 70 llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; } 71 72 uint16_t getEMachine() const { return getObj().getHeader()->e_machine; } 73 uint8_t getOSABI() const { 74 return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; 75 } 76 77 StringRef getStringTable() const { return StringTable; } 78 79 uint32_t getSectionIndex(const Elf_Sym &Sym) const; 80 81 protected: 82 llvm::object::ELFFile<ELFT> ELFObj; 83 const Elf_Shdr *Symtab = nullptr; 84 ArrayRef<Elf_Word> SymtabSHNDX; 85 StringRef StringTable; 86 void initStringTable(); 87 Elf_Sym_Range getNonLocalSymbols(); 88 Elf_Sym_Range getSymbolsHelper(bool); 89 }; 90 91 // .o file. 92 template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> { 93 typedef ELFFileBase<ELFT> Base; 94 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 95 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 96 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 97 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 98 typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; 99 100 // uint32 in ELFT's byte order 101 typedef llvm::support::detail::packed_endian_specific_integral< 102 uint32_t, ELFT::TargetEndianness, 2> 103 uint32_X; 104 105 StringRef getShtGroupSignature(const Elf_Shdr &Sec); 106 ArrayRef<uint32_X> getShtGroupEntries(const Elf_Shdr &Sec); 107 108 public: 109 static bool classof(const InputFile *F) { 110 return F->kind() == Base::ObjectKind; 111 } 112 113 ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; } 114 115 explicit ObjectFile(MemoryBufferRef M); 116 void parse(llvm::DenseSet<StringRef> &ComdatGroups); 117 118 ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; } 119 InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const; 120 121 SymbolBody *getSymbolBody(uint32_t SymbolIndex) const { 122 uint32_t FirstNonLocal = this->Symtab->sh_info; 123 if (SymbolIndex < FirstNonLocal) 124 return nullptr; 125 return SymbolBodies[SymbolIndex - FirstNonLocal]; 126 } 127 128 Elf_Sym_Range getLocalSymbols(); 129 const Elf_Sym *getLocalSymbol(uintX_t SymIndex); 130 131 const Elf_Shdr *getSymbolTable() const { return this->Symtab; }; 132 133 // Get MIPS GP0 value defined by this file. This value represents the gp value 134 // used to create the relocatable object and required to support 135 // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations. 136 uint32_t getMipsGp0() const; 137 138 // The number is the offset in the string table. It will be used as the 139 // st_name of the symbol. 140 std::vector<std::pair<const Elf_Sym *, unsigned>> KeptLocalSyms; 141 142 private: 143 void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups); 144 void initializeSymbols(); 145 InputSectionBase<ELFT> *createInputSection(const Elf_Shdr &Sec); 146 147 SymbolBody *createSymbolBody(const Elf_Sym *Sym); 148 149 // List of all sections defined by this file. 150 std::vector<InputSectionBase<ELFT> *> Sections; 151 152 // List of all symbols referenced or defined by this file. 153 std::vector<SymbolBody *> SymbolBodies; 154 155 // MIPS .reginfo section defined by this file. 156 MipsReginfoInputSection<ELFT> *MipsReginfo = nullptr; 157 158 llvm::BumpPtrAllocator Alloc; 159 llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> MAlloc; 160 llvm::SpecificBumpPtrAllocator<EHInputSection<ELFT>> EHAlloc; 161 }; 162 163 class ArchiveFile : public InputFile { 164 public: 165 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {} 166 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } 167 void parse(); 168 169 // Returns a memory buffer for a given symbol. An empty memory buffer 170 // is returned if we have already returned the same memory buffer. 171 // (So that we don't instantiate same members more than once.) 172 MemoryBufferRef getMember(const Archive::Symbol *Sym); 173 174 llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; } 175 176 private: 177 std::unique_ptr<Archive> File; 178 std::vector<Lazy> LazySymbols; 179 llvm::DenseSet<uint64_t> Seen; 180 }; 181 182 class BitcodeFile : public InputFile { 183 public: 184 explicit BitcodeFile(MemoryBufferRef M); 185 static bool classof(const InputFile *F); 186 void parse(); 187 ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; } 188 189 private: 190 std::vector<SymbolBody *> SymbolBodies; 191 llvm::BumpPtrAllocator Alloc; 192 llvm::StringSaver Saver{Alloc}; 193 }; 194 195 // .so file. 196 template <class ELFT> class SharedFile : public ELFFileBase<ELFT> { 197 typedef ELFFileBase<ELFT> Base; 198 typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 199 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym; 200 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word; 201 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; 202 203 std::vector<SharedSymbol<ELFT>> SymbolBodies; 204 std::vector<StringRef> Undefs; 205 StringRef SoName; 206 207 public: 208 StringRef getSoName() const { return SoName; } 209 llvm::MutableArrayRef<SharedSymbol<ELFT>> getSharedSymbols() { 210 return SymbolBodies; 211 } 212 const Elf_Shdr *getSection(const Elf_Sym &Sym) const; 213 llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; } 214 215 static bool classof(const InputFile *F) { 216 return F->kind() == Base::SharedKind; 217 } 218 219 explicit SharedFile(MemoryBufferRef M); 220 221 void parseSoName(); 222 void parseRest(); 223 224 // Used for --as-needed 225 bool AsNeeded = false; 226 bool IsUsed = false; 227 bool isNeeded() const { return !AsNeeded || IsUsed; } 228 }; 229 230 std::unique_ptr<InputFile> createObjectFile(MemoryBufferRef MB, 231 StringRef ArchiveName = ""); 232 std::unique_ptr<InputFile> createSharedFile(MemoryBufferRef MB); 233 234 } // namespace elf 235 } // namespace lld 236 237 #endif 238