1 //===- InputFiles.h ---------------------------------------------*- C++ -*-===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLD_COFF_INPUT_FILES_H
11 #define LLD_COFF_INPUT_FILES_H
13 #include "lld/Core/LLVM.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/LTO/legacy/LTOModule.h"
17 #include "llvm/Object/Archive.h"
18 #include "llvm/Object/COFF.h"
19 #include "llvm/Support/StringSaver.h"
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_section;
38 class DefinedImportData;
39 class DefinedImportThunk;
44 // The root class of input files.
47 enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
48 Kind kind() const { return FileKind; }
49 virtual ~InputFile() {}
51 // Returns the filename.
52 StringRef getName() { return MB.getBufferIdentifier(); }
54 // Returns symbols defined by this file.
55 virtual std::vector<SymbolBody *> &getSymbols() = 0;
57 // Reads a file (the constructor doesn't do that).
58 virtual void parse() = 0;
60 // Returns the CPU type this file was compiled to.
61 virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; }
63 // Returns a short, human-friendly filename. If this is a member of
64 // an archive file, a returned value includes parent's filename.
65 // Used for logging or debugging.
66 std::string getShortName();
68 // Sets a parent filename if this file is created from an archive.
69 void setParentName(StringRef N) { ParentName = N; }
71 // Returns .drectve section contents if exist.
72 StringRef getDirectives() { return StringRef(Directives).trim(); }
74 // Each file has a unique index. The index number is used to
75 // resolve ties in symbol resolution.
80 InputFile(Kind K, MemoryBufferRef M)
81 : Index(NextIndex++), MB(M), FileKind(K) {}
84 std::string Directives;
92 class ArchiveFile : public InputFile {
94 explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
95 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
96 void parse() override;
98 // Returns a memory buffer for a given symbol. An empty memory buffer
99 // is returned if we have already returned the same memory buffer.
100 // (So that we don't instantiate same members more than once.)
101 MemoryBufferRef getMember(const Archive::Symbol *Sym);
103 llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; }
105 // All symbols returned by ArchiveFiles are of Lazy type.
106 std::vector<SymbolBody *> &getSymbols() override {
107 llvm_unreachable("internal fatal");
111 std::unique_ptr<Archive> File;
112 std::string Filename;
113 std::vector<Lazy> LazySymbols;
114 std::map<uint64_t, std::atomic_flag> Seen;
117 // .obj or .o file. This may be a member of an archive file.
118 class ObjectFile : public InputFile {
120 explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
121 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
122 void parse() override;
123 MachineTypes getMachineType() override;
124 std::vector<Chunk *> &getChunks() { return Chunks; }
125 std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
127 // Returns a SymbolBody object for the SymbolIndex'th symbol in the
128 // underlying object file.
129 SymbolBody *getSymbolBody(uint32_t SymbolIndex) {
130 return SparseSymbolBodies[SymbolIndex];
133 // Returns the underying COFF file.
134 COFFObjectFile *getCOFFObj() { return COFFObj.get(); }
136 // True if this object file is compatible with SEH.
137 // COFF-specific and x86-only.
138 bool SEHCompat = false;
140 // The list of safe exception handlers listed in .sxdata section.
141 // COFF-specific and x86-only.
142 std::set<SymbolBody *> SEHandlers;
145 void initializeChunks();
146 void initializeSymbols();
147 void initializeSEH();
149 Defined *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst);
150 Undefined *createUndefined(COFFSymbolRef Sym);
152 std::unique_ptr<COFFObjectFile> COFFObj;
153 llvm::BumpPtrAllocator Alloc;
154 const coff_section *SXData = nullptr;
156 // List of all chunks defined by this file. This includes both section
157 // chunks and non-section chunks for common symbols.
158 std::vector<Chunk *> Chunks;
160 // This vector contains the same chunks as Chunks, but they are
161 // indexed such that you can get a SectionChunk by section index.
162 // Nonexistent section indices are filled with null pointers.
163 // (Because section number is 1-based, the first slot is always a
165 std::vector<Chunk *> SparseChunks;
167 // List of all symbols referenced or defined by this file.
168 std::vector<SymbolBody *> SymbolBodies;
170 // This vector contains the same symbols as SymbolBodies, but they
171 // are indexed such that you can get a SymbolBody by symbol
172 // index. Nonexistent indices (which are occupied by auxiliary
173 // symbols in the real symbol table) are filled with null pointers.
174 std::vector<SymbolBody *> SparseSymbolBodies;
177 // This type represents import library members that contain DLL names
178 // and symbols exported from the DLLs. See Microsoft PE/COFF spec. 7
179 // for details about the format.
180 class ImportFile : public InputFile {
182 explicit ImportFile(MemoryBufferRef M)
183 : InputFile(ImportKind, M), StringAlloc(StringAllocAux) {}
184 static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
185 std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
187 DefinedImportData *ImpSym = nullptr;
188 DefinedImportThunk *ThunkSym = nullptr;
192 void parse() override;
194 std::vector<SymbolBody *> SymbolBodies;
195 llvm::BumpPtrAllocator Alloc;
196 llvm::BumpPtrAllocator StringAllocAux;
197 llvm::StringSaver StringAlloc;
201 class BitcodeFile : public InputFile {
203 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
204 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
205 std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
206 MachineTypes getMachineType() override;
207 std::unique_ptr<LTOModule> takeModule() { return std::move(M); }
209 static llvm::LLVMContext Context;
212 void parse() override;
214 std::vector<SymbolBody *> SymbolBodies;
215 llvm::BumpPtrAllocator Alloc;
216 std::unique_ptr<LTOModule> M;
217 static std::mutex Mu;