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