]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/Symbols.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / Symbols.h
1 //===- Symbols.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_SYMBOLS_H
11 #define LLD_COFF_SYMBOLS_H
12
13 #include "Chunks.h"
14 #include "Config.h"
15 #include "Memory.h"
16 #include "lld/Core/LLVM.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/Object/Archive.h"
19 #include "llvm/Object/COFF.h"
20 #include <atomic>
21 #include <memory>
22 #include <vector>
23
24 namespace lld {
25 namespace coff {
26
27 using llvm::object::Archive;
28 using llvm::object::COFFSymbolRef;
29 using llvm::object::coff_import_header;
30 using llvm::object::coff_symbol_generic;
31
32 class ArchiveFile;
33 class InputFile;
34 class ObjectFile;
35 struct Symbol;
36 class SymbolTable;
37
38 // The base class for real symbol classes.
39 class SymbolBody {
40 public:
41   enum Kind {
42     // The order of these is significant. We start with the regular defined
43     // symbols as those are the most prevelant and the zero tag is the cheapest
44     // to set. Among the defined kinds, the lower the kind is preferred over
45     // the higher kind when testing wether one symbol should take precedence
46     // over another.
47     DefinedRegularKind = 0,
48     DefinedCommonKind,
49     DefinedLocalImportKind,
50     DefinedImportThunkKind,
51     DefinedImportDataKind,
52     DefinedAbsoluteKind,
53     DefinedRelativeKind,
54
55     UndefinedKind,
56     LazyKind,
57
58     LastDefinedCOFFKind = DefinedCommonKind,
59     LastDefinedKind = DefinedRelativeKind,
60   };
61
62   Kind kind() const { return static_cast<Kind>(SymbolKind); }
63
64   // Returns true if this is an external symbol.
65   bool isExternal() { return IsExternal; }
66
67   // Returns the symbol name.
68   StringRef getName();
69
70   // Returns the file from which this symbol was created.
71   InputFile *getFile();
72
73   Symbol *symbol();
74   const Symbol *symbol() const {
75     return const_cast<SymbolBody *>(this)->symbol();
76   }
77
78 protected:
79   friend SymbolTable;
80   explicit SymbolBody(Kind K, StringRef N = "")
81       : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
82         WrittenToSymtab(false), Name(N) {}
83
84   const unsigned SymbolKind : 8;
85   unsigned IsExternal : 1;
86
87   // This bit is used by the \c DefinedRegular subclass.
88   unsigned IsCOMDAT : 1;
89
90 public:
91   // This bit is used by Writer::createSymbolAndStringTable() to prevent
92   // symbols from being written to the symbol table more than once.
93   unsigned WrittenToSymtab : 1;
94
95 protected:
96   StringRef Name;
97 };
98
99 // The base class for any defined symbols, including absolute symbols,
100 // etc.
101 class Defined : public SymbolBody {
102 public:
103   Defined(Kind K, StringRef N) : SymbolBody(K, N) {}
104
105   static bool classof(const SymbolBody *S) {
106     return S->kind() <= LastDefinedKind;
107   }
108
109   // Returns the RVA (relative virtual address) of this symbol. The
110   // writer sets and uses RVAs.
111   uint64_t getRVA();
112
113   // Returns the RVA relative to the beginning of the output section.
114   // Used to implement SECREL relocation type.
115   uint64_t getSecrel();
116
117   // Returns the output section index.
118   // Used to implement SECTION relocation type.
119   uint64_t getSectionIndex();
120
121   // Returns true if this symbol points to an executable (e.g. .text) section.
122   // Used to implement ARM relocations.
123   bool isExecutable();
124 };
125
126 // Symbols defined via a COFF object file or bitcode file.  For COFF files, this
127 // stores a coff_symbol_generic*, and names of internal symbols are lazily
128 // loaded through that. For bitcode files, Sym is nullptr and the name is stored
129 // as a StringRef.
130 class DefinedCOFF : public Defined {
131   friend SymbolBody;
132 public:
133   DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S)
134       : Defined(K, N), File(F), Sym(S) {}
135
136   static bool classof(const SymbolBody *S) {
137     return S->kind() <= LastDefinedCOFFKind;
138   }
139
140   InputFile *getFile() { return File; }
141
142   COFFSymbolRef getCOFFSymbol();
143
144   InputFile *File;
145
146 protected:
147   const coff_symbol_generic *Sym;
148 };
149
150 // Regular defined symbols read from object file symbol tables.
151 class DefinedRegular : public DefinedCOFF {
152 public:
153   DefinedRegular(InputFile *F, StringRef N, bool IsCOMDAT,
154                  bool IsExternal = false,
155                  const coff_symbol_generic *S = nullptr,
156                  SectionChunk *C = nullptr)
157       : DefinedCOFF(DefinedRegularKind, F, N, S), Data(C ? &C->Repl : nullptr) {
158     this->IsExternal = IsExternal;
159     this->IsCOMDAT = IsCOMDAT;
160   }
161
162   static bool classof(const SymbolBody *S) {
163     return S->kind() == DefinedRegularKind;
164   }
165
166   uint64_t getRVA() { return (*Data)->getRVA() + Sym->Value; }
167   bool isCOMDAT() { return IsCOMDAT; }
168   SectionChunk *getChunk() { return *Data; }
169   uint32_t getValue() { return Sym->Value; }
170
171 private:
172   SectionChunk **Data;
173 };
174
175 class DefinedCommon : public DefinedCOFF {
176 public:
177   DefinedCommon(InputFile *F, StringRef N, uint64_t Size,
178                 const coff_symbol_generic *S = nullptr,
179                 CommonChunk *C = nullptr)
180       : DefinedCOFF(DefinedCommonKind, F, N, S), Data(C), Size(Size) {
181     this->IsExternal = true;
182   }
183
184   static bool classof(const SymbolBody *S) {
185     return S->kind() == DefinedCommonKind;
186   }
187
188   uint64_t getRVA() { return Data->getRVA(); }
189
190 private:
191   friend SymbolTable;
192   uint64_t getSize() const { return Size; }
193   CommonChunk *Data;
194   uint64_t Size;
195 };
196
197 // Absolute symbols.
198 class DefinedAbsolute : public Defined {
199 public:
200   DefinedAbsolute(StringRef N, COFFSymbolRef S)
201       : Defined(DefinedAbsoluteKind, N), VA(S.getValue()) {
202     IsExternal = S.isExternal();
203   }
204
205   DefinedAbsolute(StringRef N, uint64_t V)
206       : Defined(DefinedAbsoluteKind, N), VA(V) {}
207
208   static bool classof(const SymbolBody *S) {
209     return S->kind() == DefinedAbsoluteKind;
210   }
211
212   uint64_t getRVA() { return VA - Config->ImageBase; }
213   void setVA(uint64_t V) { VA = V; }
214
215 private:
216   uint64_t VA;
217 };
218
219 // This is a kind of absolute symbol but relative to the image base.
220 // Unlike absolute symbols, relocations referring this kind of symbols
221 // are subject of the base relocation. This type is used rarely --
222 // mainly for __ImageBase.
223 class DefinedRelative : public Defined {
224 public:
225   explicit DefinedRelative(StringRef Name, uint64_t V = 0)
226       : Defined(DefinedRelativeKind, Name), RVA(V) {}
227
228   static bool classof(const SymbolBody *S) {
229     return S->kind() == DefinedRelativeKind;
230   }
231
232   uint64_t getRVA() { return RVA; }
233   void setRVA(uint64_t V) { RVA = V; }
234
235 private:
236   uint64_t RVA;
237 };
238
239 // This class represents a symbol defined in an archive file. It is
240 // created from an archive file header, and it knows how to load an
241 // object file from an archive to replace itself with a defined
242 // symbol. If the resolver finds both Undefined and Lazy for
243 // the same name, it will ask the Lazy to load a file.
244 class Lazy : public SymbolBody {
245 public:
246   Lazy(ArchiveFile *F, const Archive::Symbol S)
247       : SymbolBody(LazyKind, S.getName()), File(F), Sym(S) {}
248
249   static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }
250
251   ArchiveFile *File;
252
253 private:
254   friend SymbolTable;
255
256 private:
257   const Archive::Symbol Sym;
258 };
259
260 // Undefined symbols.
261 class Undefined : public SymbolBody {
262 public:
263   explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
264
265   static bool classof(const SymbolBody *S) {
266     return S->kind() == UndefinedKind;
267   }
268
269   // An undefined symbol can have a fallback symbol which gives an
270   // undefined symbol a second chance if it would remain undefined.
271   // If it remains undefined, it'll be replaced with whatever the
272   // Alias pointer points to.
273   SymbolBody *WeakAlias = nullptr;
274
275   // If this symbol is external weak, try to resolve it to a defined
276   // symbol by searching the chain of fallback symbols. Returns the symbol if
277   // successful, otherwise returns null.
278   Defined *getWeakAlias();
279 };
280
281 // Windows-specific classes.
282
283 // This class represents a symbol imported from a DLL. This has two
284 // names for internal use and external use. The former is used for
285 // name resolution, and the latter is used for the import descriptor
286 // table in an output. The former has "__imp_" prefix.
287 class DefinedImportData : public Defined {
288 public:
289   DefinedImportData(StringRef N, ImportFile *F)
290       : Defined(DefinedImportDataKind, N), File(F) {
291   }
292
293   static bool classof(const SymbolBody *S) {
294     return S->kind() == DefinedImportDataKind;
295   }
296
297   uint64_t getRVA() { return File->Location->getRVA(); }
298   StringRef getDLLName() { return File->DLLName; }
299   StringRef getExternalName() { return File->ExternalName; }
300   void setLocation(Chunk *AddressTable) { File->Location = AddressTable; }
301   uint16_t getOrdinal() { return File->Hdr->OrdinalHint; }
302
303   ImportFile *File;
304 };
305
306 // This class represents a symbol for a jump table entry which jumps
307 // to a function in a DLL. Linker are supposed to create such symbols
308 // without "__imp_" prefix for all function symbols exported from
309 // DLLs, so that you can call DLL functions as regular functions with
310 // a regular name. A function pointer is given as a DefinedImportData.
311 class DefinedImportThunk : public Defined {
312 public:
313   DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine);
314
315   static bool classof(const SymbolBody *S) {
316     return S->kind() == DefinedImportThunkKind;
317   }
318
319   uint64_t getRVA() { return Data->getRVA(); }
320   Chunk *getChunk() { return Data; }
321
322   DefinedImportData *WrappedSym;
323
324 private:
325   Chunk *Data;
326 };
327
328 // If you have a symbol "__imp_foo" in your object file, a symbol name
329 // "foo" becomes automatically available as a pointer to "__imp_foo".
330 // This class is for such automatically-created symbols.
331 // Yes, this is an odd feature. We didn't intend to implement that.
332 // This is here just for compatibility with MSVC.
333 class DefinedLocalImport : public Defined {
334 public:
335   DefinedLocalImport(StringRef N, Defined *S)
336       : Defined(DefinedLocalImportKind, N), Data(make<LocalImportChunk>(S)) {}
337
338   static bool classof(const SymbolBody *S) {
339     return S->kind() == DefinedLocalImportKind;
340   }
341
342   uint64_t getRVA() { return Data->getRVA(); }
343   Chunk *getChunk() { return Data; }
344
345 private:
346   LocalImportChunk *Data;
347 };
348
349 inline uint64_t Defined::getRVA() {
350   switch (kind()) {
351   case DefinedAbsoluteKind:
352     return cast<DefinedAbsolute>(this)->getRVA();
353   case DefinedRelativeKind:
354     return cast<DefinedRelative>(this)->getRVA();
355   case DefinedImportDataKind:
356     return cast<DefinedImportData>(this)->getRVA();
357   case DefinedImportThunkKind:
358     return cast<DefinedImportThunk>(this)->getRVA();
359   case DefinedLocalImportKind:
360     return cast<DefinedLocalImport>(this)->getRVA();
361   case DefinedCommonKind:
362     return cast<DefinedCommon>(this)->getRVA();
363   case DefinedRegularKind:
364     return cast<DefinedRegular>(this)->getRVA();
365   case LazyKind:
366   case UndefinedKind:
367     llvm_unreachable("Cannot get the address for an undefined symbol.");
368   }
369   llvm_unreachable("unknown symbol kind");
370 }
371
372 // A real symbol object, SymbolBody, is usually stored within a Symbol. There's
373 // always one Symbol for each symbol name. The resolver updates the SymbolBody
374 // stored in the Body field of this object as it resolves symbols. Symbol also
375 // holds computed properties of symbol names.
376 struct Symbol {
377   // True if this symbol was referenced by a regular (non-bitcode) object.
378   unsigned IsUsedInRegularObj : 1;
379
380   // True if we've seen both a lazy and an undefined symbol with this symbol
381   // name, which means that we have enqueued an archive member load and should
382   // not load any more archive members to resolve the same symbol.
383   unsigned PendingArchiveLoad : 1;
384
385   // This field is used to store the Symbol's SymbolBody. This instantiation of
386   // AlignedCharArrayUnion gives us a struct with a char array field that is
387   // large and aligned enough to store any derived class of SymbolBody.
388   llvm::AlignedCharArrayUnion<
389       DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedRelative, Lazy,
390       Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport>
391       Body;
392
393   SymbolBody *body() {
394     return reinterpret_cast<SymbolBody *>(Body.buffer);
395   }
396   const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
397 };
398
399 template <typename T, typename... ArgT>
400 void replaceBody(Symbol *S, ArgT &&... Arg) {
401   static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402   static_assert(alignof(T) <= alignof(decltype(S->Body)),
403                 "Body not aligned enough");
404   assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405          "Not a SymbolBody");
406   new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
407 }
408
409 inline Symbol *SymbolBody::symbol() {
410   assert(isExternal());
411   return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
412                                     offsetof(Symbol, Body));
413 }
414 } // namespace coff
415
416 std::string toString(coff::SymbolBody &B);
417 } // namespace lld
418
419 #endif