]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/InputFiles.h
Merge llvm, clang, lld and lldb trunk r291274, and resolve conflicts.
[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/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