]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/InputFiles.h
MFV r313781:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / InputFiles.h
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/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"
20 #include <memory>
21 #include <mutex>
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_section;
35
36 class Chunk;
37 class Defined;
38 class DefinedImportData;
39 class DefinedImportThunk;
40 class Lazy;
41 class SymbolBody;
42 class Undefined;
43
44 // The root class of input files.
45 class InputFile {
46 public:
47   enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
48   Kind kind() const { return FileKind; }
49   virtual ~InputFile() {}
50
51   // Returns the filename.
52   StringRef getName() { return MB.getBufferIdentifier(); }
53
54   // Returns symbols defined by this file.
55   virtual std::vector<SymbolBody *> &getSymbols() = 0;
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   // 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();
67
68   // Sets a parent filename if this file is created from an archive.
69   void setParentName(StringRef N) { ParentName = N; }
70
71   // Returns .drectve section contents if exist.
72   StringRef getDirectives() { return StringRef(Directives).trim(); }
73
74   // Each file has a unique index. The index number is used to
75   // resolve ties in symbol resolution.
76   int Index;
77   static int NextIndex;
78
79 protected:
80   InputFile(Kind K, MemoryBufferRef M)
81       : Index(NextIndex++), MB(M), FileKind(K) {}
82
83   MemoryBufferRef MB;
84   std::string Directives;
85
86 private:
87   const Kind FileKind;
88   StringRef ParentName;
89 };
90
91 // .lib or .a file.
92 class ArchiveFile : public InputFile {
93 public:
94   explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
95   static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
96   void parse() override;
97
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);
102
103   llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; }
104
105   // All symbols returned by ArchiveFiles are of Lazy type.
106   std::vector<SymbolBody *> &getSymbols() override {
107     llvm_unreachable("internal fatal");
108   }
109
110 private:
111   std::unique_ptr<Archive> File;
112   std::string Filename;
113   std::vector<Lazy> LazySymbols;
114   std::map<uint64_t, std::atomic_flag> Seen;
115 };
116
117 // .obj or .o file. This may be a member of an archive file.
118 class ObjectFile : public InputFile {
119 public:
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; }
126
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];
131   }
132
133   // Returns the underying COFF file.
134   COFFObjectFile *getCOFFObj() { return COFFObj.get(); }
135
136   // True if this object file is compatible with SEH.
137   // COFF-specific and x86-only.
138   bool SEHCompat = false;
139
140   // The list of safe exception handlers listed in .sxdata section.
141   // COFF-specific and x86-only.
142   std::set<SymbolBody *> SEHandlers;
143
144 private:
145   void initializeChunks();
146   void initializeSymbols();
147   void initializeSEH();
148
149   Defined *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst);
150   Undefined *createUndefined(COFFSymbolRef Sym);
151
152   std::unique_ptr<COFFObjectFile> COFFObj;
153   llvm::BumpPtrAllocator Alloc;
154   const coff_section *SXData = nullptr;
155
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;
159
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
164   // null pointer.)
165   std::vector<Chunk *> SparseChunks;
166
167   // List of all symbols referenced or defined by this file.
168   std::vector<SymbolBody *> SymbolBodies;
169
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;
175 };
176
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 {
181 public:
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; }
186
187   DefinedImportData *ImpSym = nullptr;
188   DefinedImportThunk *ThunkSym = nullptr;
189   std::string DLLName;
190
191 private:
192   void parse() override;
193
194   std::vector<SymbolBody *> SymbolBodies;
195   llvm::BumpPtrAllocator Alloc;
196   llvm::BumpPtrAllocator StringAllocAux;
197   llvm::StringSaver StringAlloc;
198 };
199
200 // Used for LTO.
201 class BitcodeFile : public InputFile {
202 public:
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); }
208
209   static llvm::LLVMContext Context;
210
211 private:
212   void parse() override;
213
214   std::vector<SymbolBody *> SymbolBodies;
215   llvm::BumpPtrAllocator Alloc;
216   std::unique_ptr<LTOModule> M;
217   static std::mutex Mu;
218 };
219
220 } // namespace coff
221 } // namespace lld
222
223 #endif