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_COFF_INPUT_FILES_H 11 #define LLD_COFF_INPUT_FILES_H 12 13 #include "lld/Core/LLVM.h" 14 #include "llvm/ADT/ArrayRef.h" 15 #include "llvm/ADT/DenseSet.h" 16 #include "llvm/IR/LLVMContext.h" 17 #include "llvm/LTO/legacy/LTOModule.h" 18 #include "llvm/Object/Archive.h" 19 #include "llvm/Object/COFF.h" 20 #include "llvm/Support/StringSaver.h" 21 #include <memory> 22 #include <set> 23 #include <vector> 24 25 namespace lld { 26 namespace coff { 27 28 using llvm::LTOModule; 29 using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN; 30 using llvm::COFF::MachineTypes; 31 using llvm::object::Archive; 32 using llvm::object::COFFObjectFile; 33 using llvm::object::COFFSymbolRef; 34 using llvm::object::coff_import_header; 35 using llvm::object::coff_section; 36 37 class Chunk; 38 class Defined; 39 class DefinedImportData; 40 class DefinedImportThunk; 41 class Lazy; 42 class SectionChunk; 43 struct Symbol; 44 class SymbolBody; 45 class Undefined; 46 47 // The root class of input files. 48 class InputFile { 49 public: 50 enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind }; 51 Kind kind() const { return FileKind; } 52 virtual ~InputFile() {} 53 54 // Returns the filename. 55 StringRef getName() { return MB.getBufferIdentifier(); } 56 57 // Reads a file (the constructor doesn't do that). 58 virtual void parse() = 0; 59 60 // Returns the CPU type this file was compiled to. 61 virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; } 62 63 // An archive file name if this file is created from an archive. 64 StringRef ParentName; 65 66 // Returns .drectve section contents if exist. 67 StringRef getDirectives() { return StringRef(Directives).trim(); } 68 69 protected: 70 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} 71 72 MemoryBufferRef MB; 73 std::string Directives; 74 75 private: 76 const Kind FileKind; 77 }; 78 79 // .lib or .a file. 80 class ArchiveFile : public InputFile { 81 public: 82 explicit ArchiveFile(MemoryBufferRef M); 83 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; } 84 void parse() override; 85 86 // Enqueues an archive member load for the given symbol. If we've already 87 // enqueued a load for the same archive member, this function does nothing, 88 // which ensures that we don't load the same member more than once. 89 void addMember(const Archive::Symbol *Sym); 90 91 private: 92 std::unique_ptr<Archive> File; 93 std::string Filename; 94 llvm::DenseSet<uint64_t> Seen; 95 }; 96 97 // .obj or .o file. This may be a member of an archive file. 98 class ObjectFile : public InputFile { 99 public: 100 explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {} 101 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; } 102 void parse() override; 103 MachineTypes getMachineType() override; 104 std::vector<Chunk *> &getChunks() { return Chunks; } 105 std::vector<SectionChunk *> &getDebugChunks() { return DebugChunks; } 106 std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; } 107 108 // Returns a SymbolBody object for the SymbolIndex'th symbol in the 109 // underlying object file. 110 SymbolBody *getSymbolBody(uint32_t SymbolIndex) { 111 return SparseSymbolBodies[SymbolIndex]; 112 } 113 114 // Returns the underying COFF file. 115 COFFObjectFile *getCOFFObj() { return COFFObj.get(); } 116 117 // True if this object file is compatible with SEH. 118 // COFF-specific and x86-only. 119 bool SEHCompat = false; 120 121 // The list of safe exception handlers listed in .sxdata section. 122 // COFF-specific and x86-only. 123 std::set<SymbolBody *> SEHandlers; 124 125 private: 126 void initializeChunks(); 127 void initializeSymbols(); 128 void initializeSEH(); 129 130 SymbolBody *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst); 131 SymbolBody *createUndefined(COFFSymbolRef Sym); 132 133 std::unique_ptr<COFFObjectFile> COFFObj; 134 llvm::BumpPtrAllocator Alloc; 135 const coff_section *SXData = nullptr; 136 137 // List of all chunks defined by this file. This includes both section 138 // chunks and non-section chunks for common symbols. 139 std::vector<Chunk *> Chunks; 140 141 // CodeView debug info sections. 142 std::vector<SectionChunk *> DebugChunks; 143 144 // This vector contains the same chunks as Chunks, but they are 145 // indexed such that you can get a SectionChunk by section index. 146 // Nonexistent section indices are filled with null pointers. 147 // (Because section number is 1-based, the first slot is always a 148 // null pointer.) 149 std::vector<Chunk *> SparseChunks; 150 151 // List of all symbols referenced or defined by this file. 152 std::vector<SymbolBody *> SymbolBodies; 153 154 // This vector contains the same symbols as SymbolBodies, but they 155 // are indexed such that you can get a SymbolBody by symbol 156 // index. Nonexistent indices (which are occupied by auxiliary 157 // symbols in the real symbol table) are filled with null pointers. 158 std::vector<SymbolBody *> SparseSymbolBodies; 159 }; 160 161 // This type represents import library members that contain DLL names 162 // and symbols exported from the DLLs. See Microsoft PE/COFF spec. 7 163 // for details about the format. 164 class ImportFile : public InputFile { 165 public: 166 explicit ImportFile(MemoryBufferRef M) 167 : InputFile(ImportKind, M), StringAlloc(StringAllocAux) {} 168 static bool classof(const InputFile *F) { return F->kind() == ImportKind; } 169 170 DefinedImportData *ImpSym = nullptr; 171 DefinedImportThunk *ThunkSym = nullptr; 172 std::string DLLName; 173 174 private: 175 void parse() override; 176 177 llvm::BumpPtrAllocator Alloc; 178 llvm::BumpPtrAllocator StringAllocAux; 179 llvm::StringSaver StringAlloc; 180 181 public: 182 StringRef ExternalName; 183 const coff_import_header *Hdr; 184 Chunk *Location = nullptr; 185 }; 186 187 // Used for LTO. 188 class BitcodeFile : public InputFile { 189 public: 190 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {} 191 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } 192 std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; } 193 MachineTypes getMachineType() override; 194 std::unique_ptr<LTOModule> takeModule() { return std::move(M); } 195 196 static llvm::LLVMContext Context; 197 198 private: 199 void parse() override; 200 201 std::vector<SymbolBody *> SymbolBodies; 202 llvm::BumpPtrAllocator Alloc; 203 std::unique_ptr<LTOModule> M; 204 }; 205 } // namespace coff 206 207 std::string toString(coff::InputFile *File); 208 } // namespace lld 209 210 #endif 211