blob: c8865d128fb8423f55c0d8b97403bef47347ada4 [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:541//===- Symbols.h ------------------------------------------------*- C++ -*-===//
Rui Ueyama411c63602015-05-28 19:09:302//
Chandler Carruth2946cd72019-01-19 08:50:563// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Rui Ueyama411c63602015-05-28 19:09:306//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLD_COFF_SYMBOLS_H
10#define LLD_COFF_SYMBOLS_H
11
12#include "Chunks.h"
13#include "Config.h"
Rui Ueyama3f851702017-10-02 21:00:4114#include "lld/Common/LLVM.h"
Rui Ueyama2017d522017-11-28 20:39:1715#include "lld/Common/Memory.h"
Rui Ueyama411c63602015-05-28 19:09:3016#include "llvm/ADT/ArrayRef.h"
17#include "llvm/Object/Archive.h"
18#include "llvm/Object/COFF.h"
Rui Ueyamac80c03d2015-07-05 21:54:4219#include <atomic>
Rui Ueyama411c63602015-05-28 19:09:3020#include <memory>
21#include <vector>
22
23namespace lld {
Nico Weber9c0716f2019-07-23 19:00:0124
25std::string toString(coff::Symbol &b);
26
27// There are two different ways to convert an Archive::Symbol to a string:
28// One for Microsoft name mangling and one for Itanium name mangling.
29// Call the functions toCOFFString and toELFString, not just toString.
30std::string toCOFFString(const coff::Archive::Symbol &b);
31
Rui Ueyama411c63602015-05-28 19:09:3032namespace coff {
33
34using llvm::object::Archive;
35using llvm::object::COFFSymbolRef;
Rui Ueyamac9bfe322015-05-29 15:45:3536using llvm::object::coff_import_header;
Rui Ueyamac15139b2015-06-30 00:10:5437using llvm::object::coff_symbol_generic;
Rui Ueyama411c63602015-05-28 19:09:3038
39class ArchiveFile;
40class InputFile;
Rui Ueyamae1b48e02017-07-26 23:05:2441class ObjFile;
Peter Collingbourne79a5e6b2016-12-09 21:55:2442class SymbolTable;
Rui Ueyama411c63602015-05-28 19:09:3043
44// The base class for real symbol classes.
Rui Ueyamaf52496e2017-11-03 21:21:4745class Symbol {
Rui Ueyama411c63602015-05-28 19:09:3046public:
47 enum Kind {
Chandler Carruth64c17c72015-06-29 21:35:4848 // The order of these is significant. We start with the regular defined
Nico Weber1f3ab982019-01-14 19:05:2149 // symbols as those are the most prevalent and the zero tag is the cheapest
Chandler Carruth64c17c72015-06-29 21:35:4850 // to set. Among the defined kinds, the lower the kind is preferred over
Nico Weberc7bad572018-08-27 14:22:2551 // the higher kind when testing whether one symbol should take precedence
Chandler Carruth64c17c72015-06-29 21:35:4852 // over another.
53 DefinedRegularKind = 0,
Rui Ueyamaefb7e1a2015-06-20 07:21:5754 DefinedCommonKind,
Chandler Carruth64c17c72015-06-29 21:35:4855 DefinedLocalImportKind,
56 DefinedImportThunkKind,
57 DefinedImportDataKind,
58 DefinedAbsoluteKind,
Reid Kleckner502d4ce2017-06-26 15:39:5259 DefinedSyntheticKind,
Chandler Carruth64c17c72015-06-29 21:35:4860
Rui Ueyamae2514762015-06-15 19:06:5361 UndefinedKind,
Bob Haarman7dc5e7a02019-09-03 20:32:1662 LazyArchiveKind,
63 LazyObjectKind,
Martin Storsjöa9ff1ce2021-06-16 13:59:4664 LazyDLLSymbolKind,
Chandler Carruth64c17c72015-06-29 21:35:4865
66 LastDefinedCOFFKind = DefinedCommonKind,
Reid Kleckner502d4ce2017-06-26 15:39:5267 LastDefinedKind = DefinedSyntheticKind,
Rui Ueyama411c63602015-05-28 19:09:3068 };
69
Rui Ueyama136d27a2019-07-11 05:40:3070 Kind kind() const { return static_cast<Kind>(symbolKind); }
Rui Ueyama411c63602015-05-28 19:09:3071
Rui Ueyama411c63602015-05-28 19:09:3072 // Returns the symbol name.
Reid Kleckner9b7f6142020-05-03 02:53:4973 StringRef getName() {
74 // COFF symbol names are read lazily for a performance reason.
75 // Non-external symbol names are never used by the linker except for logging
76 // or debugging. Their internal references are resolved not by name but by
77 // symbol index. And because they are not external, no one can refer them by
78 // name. Object files contain lots of non-external symbols, and creating
79 // StringRefs for them (which involves lots of strlen() on the string table)
80 // is a waste of time.
81 if (nameData == nullptr)
82 computeName();
83 return StringRef(nameData, nameSize);
84 }
Rui Ueyama411c63602015-05-28 19:09:3085
Rui Ueyama136d27a2019-07-11 05:40:3086 void replaceKeepingName(Symbol *other, size_t size);
Martin Storsjoeac1b052018-08-27 08:43:3187
Rui Ueyamaa45d45e2016-12-07 23:17:0288 // Returns the file from which this symbol was created.
89 InputFile *getFile();
90
Reid Klecknereacdf042017-07-27 18:25:5991 // Indicates that this symbol will be included in the final image. Only valid
92 // after calling markLive.
93 bool isLive() const;
94
Bob Haarman7dc5e7a02019-09-03 20:32:1695 bool isLazy() const {
Martin Storsjöa9ff1ce2021-06-16 13:59:4696 return symbolKind == LazyArchiveKind || symbolKind == LazyObjectKind ||
97 symbolKind == LazyDLLSymbolKind;
Bob Haarman7dc5e7a02019-09-03 20:32:1698 }
99
Reid Kleckner9b7f6142020-05-03 02:53:49100private:
101 void computeName();
102
Rui Ueyama411c63602015-05-28 19:09:30103protected:
Peter Collingbourne79a5e6b2016-12-09 21:55:24104 friend SymbolTable;
Rui Ueyama136d27a2019-07-11 05:40:30105 explicit Symbol(Kind k, StringRef n = "")
106 : symbolKind(k), isExternal(true), isCOMDAT(false),
107 writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false),
Martin Storsjö3785a412020-10-06 10:54:49108 isRuntimePseudoReloc(false), deferUndefined(false), canInline(true),
109 nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) {}
Rui Ueyama411c63602015-05-28 19:09:30110
Rui Ueyama136d27a2019-07-11 05:40:30111 const unsigned symbolKind : 8;
112 unsigned isExternal : 1;
Chandler Carruth64c17c72015-06-29 21:35:48113
Rui Ueyama7e296ad2019-07-10 09:10:01114public:
Chandler Carruth64c17c72015-06-29 21:35:48115 // This bit is used by the \c DefinedRegular subclass.
Rui Ueyama136d27a2019-07-11 05:40:30116 unsigned isCOMDAT : 1;
Chandler Carruth64c17c72015-06-29 21:35:48117
Peter Collingbournef874bd62017-11-21 01:14:14118 // This bit is used by Writer::createSymbolAndStringTable() to prevent
119 // symbols from being written to the symbol table more than once.
Rui Ueyama136d27a2019-07-11 05:40:30120 unsigned writtenToSymtab : 1;
Peter Collingbournef874bd62017-11-21 01:14:14121
Rui Ueyama616cd992017-10-31 16:10:24122 // True if this symbol was referenced by a regular (non-bitcode) object.
Rui Ueyama136d27a2019-07-11 05:40:30123 unsigned isUsedInRegularObj : 1;
Rui Ueyama616cd992017-10-31 16:10:24124
125 // True if we've seen both a lazy and an undefined symbol with this symbol
126 // name, which means that we have enqueued an archive member load and should
127 // not load any more archive members to resolve the same symbol.
Rui Ueyama136d27a2019-07-11 05:40:30128 unsigned pendingArchiveLoad : 1;
Rui Ueyama616cd992017-10-31 16:10:24129
Reid Kleckner58839892017-11-13 18:38:53130 /// True if we've already added this symbol to the list of GC roots.
Rui Ueyama136d27a2019-07-11 05:40:30131 unsigned isGCRoot : 1;
Reid Kleckner58839892017-11-13 18:38:53132
Rui Ueyama136d27a2019-07-11 05:40:30133 unsigned isRuntimePseudoReloc : 1;
Martin Storsjo2bfa1252018-09-26 06:13:39134
Martin Storsjö3785a412020-10-06 10:54:49135 // True if we want to allow this symbol to be undefined in the early
136 // undefined check pass in SymbolTable::reportUnresolvable(), as it
137 // might be fixed up later.
138 unsigned deferUndefined : 1;
139
140 // False if LTO shouldn't inline whatever this symbol points to. If a symbol
141 // is overwritten after LTO, LTO shouldn't inline the symbol because it
142 // doesn't know the final contents of the symbol.
143 unsigned canInline : 1;
144
Peter Collingbourne99111282016-12-11 22:15:20145protected:
Reid Klecknera30920c2019-04-19 22:51:49146 // Symbol name length. Assume symbol lengths fit in a 32-bit integer.
Rui Ueyama136d27a2019-07-11 05:40:30147 uint32_t nameSize;
Reid Klecknera30920c2019-04-19 22:51:49148
Rui Ueyama136d27a2019-07-11 05:40:30149 const char *nameData;
Rui Ueyama411c63602015-05-28 19:09:30150};
151
152// The base class for any defined symbols, including absolute symbols,
153// etc.
Rui Ueyamaf52496e2017-11-03 21:21:47154class Defined : public Symbol {
Rui Ueyama411c63602015-05-28 19:09:30155public:
Rui Ueyama136d27a2019-07-11 05:40:30156 Defined(Kind k, StringRef n) : Symbol(k, n) {}
Rui Ueyama411c63602015-05-28 19:09:30157
Rui Ueyama136d27a2019-07-11 05:40:30158 static bool classof(const Symbol *s) { return s->kind() <= LastDefinedKind; }
Rui Ueyama411c63602015-05-28 19:09:30159
160 // Returns the RVA (relative virtual address) of this symbol. The
161 // writer sets and uses RVAs.
Chandler Carruth64c17c72015-06-29 21:35:48162 uint64_t getRVA();
Rui Ueyama411c63602015-05-28 19:09:30163
Reid Klecknera1001b82017-06-28 17:06:35164 // Returns the chunk containing this symbol. Absolute symbols and __ImageBase
165 // do not have chunks, so this may return null.
166 Chunk *getChunk();
Chandler Carruth64c17c72015-06-29 21:35:48167};
Rui Ueyama411c63602015-05-28 19:09:30168
Bob Haarmancde5e5b2017-02-02 23:58:14169// Symbols defined via a COFF object file or bitcode file. For COFF files, this
170// stores a coff_symbol_generic*, and names of internal symbols are lazily
171// loaded through that. For bitcode files, Sym is nullptr and the name is stored
Reid Klecknera30920c2019-04-19 22:51:49172// as a decomposed StringRef.
Chandler Carruth64c17c72015-06-29 21:35:48173class DefinedCOFF : public Defined {
Rui Ueyamaf52496e2017-11-03 21:21:47174 friend Symbol;
175
Chandler Carruth64c17c72015-06-29 21:35:48176public:
Rui Ueyama136d27a2019-07-11 05:40:30177 DefinedCOFF(Kind k, InputFile *f, StringRef n, const coff_symbol_generic *s)
178 : Defined(k, n), file(f), sym(s) {}
Chandler Carruth64c17c72015-06-29 21:35:48179
Rui Ueyama136d27a2019-07-11 05:40:30180 static bool classof(const Symbol *s) {
181 return s->kind() <= LastDefinedCOFFKind;
Chandler Carruth64c17c72015-06-29 21:35:48182 }
183
Rui Ueyama136d27a2019-07-11 05:40:30184 InputFile *getFile() { return file; }
Rui Ueyama65813ed2015-07-02 20:33:48185
David Majnemer3a62d3d2015-07-09 17:43:50186 COFFSymbolRef getCOFFSymbol();
187
Rui Ueyama136d27a2019-07-11 05:40:30188 InputFile *file;
Rui Ueyamaa45d45e2016-12-07 23:17:02189
190protected:
Rui Ueyama136d27a2019-07-11 05:40:30191 const coff_symbol_generic *sym;
Rui Ueyama411c63602015-05-28 19:09:30192};
193
194// Regular defined symbols read from object file symbol tables.
Chandler Carruth64c17c72015-06-29 21:35:48195class DefinedRegular : public DefinedCOFF {
Rui Ueyama411c63602015-05-28 19:09:30196public:
Rui Ueyama136d27a2019-07-11 05:40:30197 DefinedRegular(InputFile *f, StringRef n, bool isCOMDAT,
198 bool isExternal = false,
199 const coff_symbol_generic *s = nullptr,
200 SectionChunk *c = nullptr)
201 : DefinedCOFF(DefinedRegularKind, f, n, s), data(c ? &c->repl : nullptr) {
202 this->isExternal = isExternal;
203 this->isCOMDAT = isCOMDAT;
Chandler Carruth64c17c72015-06-29 21:35:48204 }
Rui Ueyama411c63602015-05-28 19:09:30205
Rui Ueyama136d27a2019-07-11 05:40:30206 static bool classof(const Symbol *s) {
207 return s->kind() == DefinedRegularKind;
Rui Ueyama411c63602015-05-28 19:09:30208 }
209
Rui Ueyama136d27a2019-07-11 05:40:30210 uint64_t getRVA() const { return (*data)->getRVA() + sym->Value; }
211 SectionChunk *getChunk() const { return *data; }
212 uint32_t getValue() const { return sym->Value; }
Rui Ueyama411c63602015-05-28 19:09:30213
Rui Ueyama136d27a2019-07-11 05:40:30214 SectionChunk **data;
Rui Ueyamaefb7e1a2015-06-20 07:21:57215};
216
Chandler Carruth64c17c72015-06-29 21:35:48217class DefinedCommon : public DefinedCOFF {
Rui Ueyamaefb7e1a2015-06-20 07:21:57218public:
Rui Ueyama136d27a2019-07-11 05:40:30219 DefinedCommon(InputFile *f, StringRef n, uint64_t size,
220 const coff_symbol_generic *s = nullptr,
221 CommonChunk *c = nullptr)
222 : DefinedCOFF(DefinedCommonKind, f, n, s), data(c), size(size) {
223 this->isExternal = true;
Chandler Carruth64c17c72015-06-29 21:35:48224 }
Rui Ueyamaefb7e1a2015-06-20 07:21:57225
Rui Ueyama136d27a2019-07-11 05:40:30226 static bool classof(const Symbol *s) {
227 return s->kind() == DefinedCommonKind;
Rui Ueyamaefb7e1a2015-06-20 07:21:57228 }
229
Rui Ueyama136d27a2019-07-11 05:40:30230 uint64_t getRVA() { return data->getRVA(); }
231 CommonChunk *getChunk() { return data; }
Rui Ueyama411c63602015-05-28 19:09:30232
233private:
Peter Collingbourne79a5e6b2016-12-09 21:55:24234 friend SymbolTable;
Rui Ueyama136d27a2019-07-11 05:40:30235 uint64_t getSize() const { return size; }
236 CommonChunk *data;
237 uint64_t size;
Rui Ueyama411c63602015-05-28 19:09:30238};
239
240// Absolute symbols.
241class DefinedAbsolute : public Defined {
242public:
Rui Ueyama136d27a2019-07-11 05:40:30243 DefinedAbsolute(StringRef n, COFFSymbolRef s)
244 : Defined(DefinedAbsoluteKind, n), va(s.getValue()) {
245 isExternal = s.isExternal();
Chandler Carruth64c17c72015-06-29 21:35:48246 }
Rui Ueyamaccde19d2015-06-26 03:09:23247
Rui Ueyama136d27a2019-07-11 05:40:30248 DefinedAbsolute(StringRef n, uint64_t v)
249 : Defined(DefinedAbsoluteKind, n), va(v) {}
Rui Ueyama411c63602015-05-28 19:09:30250
Rui Ueyama136d27a2019-07-11 05:40:30251 static bool classof(const Symbol *s) {
252 return s->kind() == DefinedAbsoluteKind;
Rui Ueyama411c63602015-05-28 19:09:30253 }
254
Rui Ueyama136d27a2019-07-11 05:40:30255 uint64_t getRVA() { return va - config->imageBase; }
256 void setVA(uint64_t v) { va = v; }
Martin Storsjö78ce19b2020-01-06 11:54:12257 uint64_t getVA() const { return va; }
Martin Storsjö1737cc72019-12-29 22:32:22258
Rui Ueyamab3107472018-02-17 20:41:38259 // Section index relocations against absolute symbols resolve to
260 // this 16 bit number, and it is the largest valid section index
261 // plus one. This variable keeps it.
Rui Ueyama136d27a2019-07-11 05:40:30262 static uint16_t numOutputSections;
Reid Kleckner84564112017-06-22 23:33:04263
Rui Ueyama411c63602015-05-28 19:09:30264private:
Rui Ueyama136d27a2019-07-11 05:40:30265 uint64_t va;
Rui Ueyama411c63602015-05-28 19:09:30266};
267
Reid Kleckner502d4ce2017-06-26 15:39:52268// This symbol is used for linker-synthesized symbols like __ImageBase and
269// __safe_se_handler_table.
270class DefinedSynthetic : public Defined {
Rui Ueyama3cb895c2015-07-24 22:58:44271public:
Rui Ueyama136d27a2019-07-11 05:40:30272 explicit DefinedSynthetic(StringRef name, Chunk *c)
273 : Defined(DefinedSyntheticKind, name), c(c) {}
Rui Ueyama3cb895c2015-07-24 22:58:44274
Rui Ueyama136d27a2019-07-11 05:40:30275 static bool classof(const Symbol *s) {
276 return s->kind() == DefinedSyntheticKind;
Rui Ueyama3cb895c2015-07-24 22:58:44277 }
278
Reid Kleckner502d4ce2017-06-26 15:39:52279 // A null chunk indicates that this is __ImageBase. Otherwise, this is some
280 // other synthesized chunk, like SEHTableChunk.
Rui Ueyama136d27a2019-07-11 05:40:30281 uint32_t getRVA() { return c ? c->getRVA() : 0; }
282 Chunk *getChunk() { return c; }
Rui Ueyama3cb895c2015-07-24 22:58:44283
284private:
Rui Ueyama136d27a2019-07-11 05:40:30285 Chunk *c;
Rui Ueyama3cb895c2015-07-24 22:58:44286};
287
Rui Ueyama411c63602015-05-28 19:09:30288// This class represents a symbol defined in an archive file. It is
289// created from an archive file header, and it knows how to load an
290// object file from an archive to replace itself with a defined
Bob Haarman7dc5e7a02019-09-03 20:32:16291// symbol. If the resolver finds both Undefined and LazyArchive for
292// the same name, it will ask the LazyArchive to load a file.
293class LazyArchive : public Symbol {
Rui Ueyama411c63602015-05-28 19:09:30294public:
Bob Haarman7dc5e7a02019-09-03 20:32:16295 LazyArchive(ArchiveFile *f, const Archive::Symbol s)
296 : Symbol(LazyArchiveKind, s.getName()), file(f), sym(s) {}
Rui Ueyama411c63602015-05-28 19:09:30297
Bob Haarman7dc5e7a02019-09-03 20:32:16298 static bool classof(const Symbol *s) { return s->kind() == LazyArchiveKind; }
Rui Ueyama411c63602015-05-28 19:09:30299
Amy Huanga1c022c2019-08-22 19:40:07300 MemoryBufferRef getMemberBuffer();
301
Rui Ueyama136d27a2019-07-11 05:40:30302 ArchiveFile *file;
Vlad Tsyrklevich802aab52019-08-30 23:24:41303 const Archive::Symbol sym;
Bob Haarmanfd7569c2019-08-30 16:50:10304};
305
Bob Haarman7dc5e7a02019-09-03 20:32:16306class LazyObject : public Symbol {
307public:
Fangrui Songd496abb2022-01-04 23:11:44308 LazyObject(InputFile *f, StringRef n) : Symbol(LazyObjectKind, n), file(f) {}
Bob Haarman7dc5e7a02019-09-03 20:32:16309 static bool classof(const Symbol *s) { return s->kind() == LazyObjectKind; }
Fangrui Songd496abb2022-01-04 23:11:44310 InputFile *file;
Bob Haarman7dc5e7a02019-09-03 20:32:16311};
312
Martin Storsjöe0e09482021-07-20 20:56:00313// MinGW only.
Martin Storsjöa9ff1ce2021-06-16 13:59:46314class LazyDLLSymbol : public Symbol {
315public:
316 LazyDLLSymbol(DLLFile *f, DLLFile::Symbol *s, StringRef n)
317 : Symbol(LazyDLLSymbolKind, n), file(f), sym(s) {}
318 static bool classof(const Symbol *s) {
319 return s->kind() == LazyDLLSymbolKind;
320 }
321
322 DLLFile *file;
323 DLLFile::Symbol *sym;
324};
325
Rui Ueyama411c63602015-05-28 19:09:30326// Undefined symbols.
Rui Ueyamaf52496e2017-11-03 21:21:47327class Undefined : public Symbol {
Rui Ueyama411c63602015-05-28 19:09:30328public:
Rui Ueyama136d27a2019-07-11 05:40:30329 explicit Undefined(StringRef n) : Symbol(UndefinedKind, n) {}
Rui Ueyama411c63602015-05-28 19:09:30330
Rui Ueyama136d27a2019-07-11 05:40:30331 static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
Rui Ueyama411c63602015-05-28 19:09:30332
333 // An undefined symbol can have a fallback symbol which gives an
334 // undefined symbol a second chance if it would remain undefined.
335 // If it remains undefined, it'll be replaced with whatever the
336 // Alias pointer points to.
Rui Ueyama136d27a2019-07-11 05:40:30337 Symbol *weakAlias = nullptr;
Peter Collingbourne2612a322015-07-04 05:28:41338
339 // If this symbol is external weak, try to resolve it to a defined
340 // symbol by searching the chain of fallback symbols. Returns the symbol if
341 // successful, otherwise returns null.
342 Defined *getWeakAlias();
Rui Ueyama411c63602015-05-28 19:09:30343};
344
345// Windows-specific classes.
346
Rui Ueyama7c4fcdd2015-05-29 15:49:09347// This class represents a symbol imported from a DLL. This has two
348// names for internal use and external use. The former is used for
349// name resolution, and the latter is used for the import descriptor
350// table in an output. The former has "__imp_" prefix.
351class DefinedImportData : public Defined {
352public:
Rui Ueyama136d27a2019-07-11 05:40:30353 DefinedImportData(StringRef n, ImportFile *f)
354 : Defined(DefinedImportDataKind, n), file(f) {
Rui Ueyamab6632d92017-05-22 06:01:37355 }
Rui Ueyama7c4fcdd2015-05-29 15:49:09356
Rui Ueyama136d27a2019-07-11 05:40:30357 static bool classof(const Symbol *s) {
358 return s->kind() == DefinedImportDataKind;
Rui Ueyama7c4fcdd2015-05-29 15:49:09359 }
360
Rui Ueyama136d27a2019-07-11 05:40:30361 uint64_t getRVA() { return file->location->getRVA(); }
362 Chunk *getChunk() { return file->location; }
363 void setLocation(Chunk *addressTable) { file->location = addressTable; }
Reid Klecknera1001b82017-06-28 17:06:35364
Rui Ueyama136d27a2019-07-11 05:40:30365 StringRef getDLLName() { return file->dllName; }
366 StringRef getExternalName() { return file->externalName; }
367 uint16_t getOrdinal() { return file->hdr->OrdinalHint; }
Rui Ueyama7c4fcdd2015-05-29 15:49:09368
Rui Ueyama136d27a2019-07-11 05:40:30369 ImportFile *file;
Andrew Paverd0139c8a2020-11-18 02:02:13370
371 // This is a pointer to the synthetic symbol associated with the load thunk
372 // for this symbol that will be called if the DLL is delay-loaded. This is
373 // needed for Control Flow Guard because if this DefinedImportData symbol is a
374 // valid call target, the corresponding load thunk must also be marked as a
375 // valid call target.
376 DefinedSynthetic *loadThunkSym = nullptr;
Rui Ueyama7c4fcdd2015-05-29 15:49:09377};
378
Rui Ueyama411c63602015-05-28 19:09:30379// This class represents a symbol for a jump table entry which jumps
380// to a function in a DLL. Linker are supposed to create such symbols
381// without "__imp_" prefix for all function symbols exported from
382// DLLs, so that you can call DLL functions as regular functions with
383// a regular name. A function pointer is given as a DefinedImportData.
384class DefinedImportThunk : public Defined {
385public:
Rui Ueyama136d27a2019-07-11 05:40:30386 DefinedImportThunk(StringRef name, DefinedImportData *s, uint16_t machine);
Rui Ueyama411c63602015-05-28 19:09:30387
Rui Ueyama136d27a2019-07-11 05:40:30388 static bool classof(const Symbol *s) {
389 return s->kind() == DefinedImportThunkKind;
Rui Ueyama411c63602015-05-28 19:09:30390 }
391
Rui Ueyama136d27a2019-07-11 05:40:30392 uint64_t getRVA() { return data->getRVA(); }
393 Chunk *getChunk() { return data; }
Rui Ueyama411c63602015-05-28 19:09:30394
Rui Ueyama136d27a2019-07-11 05:40:30395 DefinedImportData *wrappedSym;
Rui Ueyama9aa82f72017-05-24 22:30:06396
Rui Ueyama411c63602015-05-28 19:09:30397private:
Rui Ueyama136d27a2019-07-11 05:40:30398 Chunk *data;
Rui Ueyama411c63602015-05-28 19:09:30399};
400
Martin Storsjod9fd4a02018-08-07 06:42:53401// If you have a symbol "foo" in your object file, a symbol name
402// "__imp_foo" becomes automatically available as a pointer to "foo".
Rui Ueyama88e0f922015-06-25 03:31:47403// This class is for such automatically-created symbols.
404// Yes, this is an odd feature. We didn't intend to implement that.
405// This is here just for compatibility with MSVC.
406class DefinedLocalImport : public Defined {
407public:
Rui Ueyama136d27a2019-07-11 05:40:30408 DefinedLocalImport(StringRef n, Defined *s)
409 : Defined(DefinedLocalImportKind, n), data(make<LocalImportChunk>(s)) {}
Rui Ueyama88e0f922015-06-25 03:31:47410
Rui Ueyama136d27a2019-07-11 05:40:30411 static bool classof(const Symbol *s) {
412 return s->kind() == DefinedLocalImportKind;
Rui Ueyama88e0f922015-06-25 03:31:47413 }
414
Rui Ueyama136d27a2019-07-11 05:40:30415 uint64_t getRVA() { return data->getRVA(); }
416 Chunk *getChunk() { return data; }
Rui Ueyama88e0f922015-06-25 03:31:47417
418private:
Rui Ueyama136d27a2019-07-11 05:40:30419 LocalImportChunk *data;
Rui Ueyama88e0f922015-06-25 03:31:47420};
421
Rui Ueyamacb71c722015-07-13 22:01:27422inline uint64_t Defined::getRVA() {
423 switch (kind()) {
424 case DefinedAbsoluteKind:
425 return cast<DefinedAbsolute>(this)->getRVA();
Reid Kleckner502d4ce2017-06-26 15:39:52426 case DefinedSyntheticKind:
427 return cast<DefinedSynthetic>(this)->getRVA();
Rui Ueyamacb71c722015-07-13 22:01:27428 case DefinedImportDataKind:
429 return cast<DefinedImportData>(this)->getRVA();
430 case DefinedImportThunkKind:
431 return cast<DefinedImportThunk>(this)->getRVA();
432 case DefinedLocalImportKind:
433 return cast<DefinedLocalImport>(this)->getRVA();
434 case DefinedCommonKind:
435 return cast<DefinedCommon>(this)->getRVA();
436 case DefinedRegularKind:
437 return cast<DefinedRegular>(this)->getRVA();
Bob Haarman7dc5e7a02019-09-03 20:32:16438 case LazyArchiveKind:
439 case LazyObjectKind:
Martin Storsjöa9ff1ce2021-06-16 13:59:46440 case LazyDLLSymbolKind:
Rui Ueyamacb71c722015-07-13 22:01:27441 case UndefinedKind:
442 llvm_unreachable("Cannot get the address for an undefined symbol.");
443 }
444 llvm_unreachable("unknown symbol kind");
445}
446
Reid Klecknera1001b82017-06-28 17:06:35447inline Chunk *Defined::getChunk() {
448 switch (kind()) {
449 case DefinedRegularKind:
450 return cast<DefinedRegular>(this)->getChunk();
451 case DefinedAbsoluteKind:
452 return nullptr;
453 case DefinedSyntheticKind:
454 return cast<DefinedSynthetic>(this)->getChunk();
455 case DefinedImportDataKind:
456 return cast<DefinedImportData>(this)->getChunk();
457 case DefinedImportThunkKind:
458 return cast<DefinedImportThunk>(this)->getChunk();
459 case DefinedLocalImportKind:
460 return cast<DefinedLocalImport>(this)->getChunk();
461 case DefinedCommonKind:
462 return cast<DefinedCommon>(this)->getChunk();
Bob Haarman7dc5e7a02019-09-03 20:32:16463 case LazyArchiveKind:
464 case LazyObjectKind:
Martin Storsjöa9ff1ce2021-06-16 13:59:46465 case LazyDLLSymbolKind:
Reid Klecknera1001b82017-06-28 17:06:35466 case UndefinedKind:
467 llvm_unreachable("Cannot get the chunk of an undefined symbol.");
468 }
469 llvm_unreachable("unknown symbol kind");
470}
471
Rui Ueyamaf52496e2017-11-03 21:21:47472// A buffer class that is large enough to hold any Symbol-derived
Rui Ueyama616cd992017-10-31 16:10:24473// object. We allocate memory using this class and instantiate a symbol
474// using the placement new.
475union SymbolUnion {
Rui Ueyama136d27a2019-07-11 05:40:30476 alignas(DefinedRegular) char a[sizeof(DefinedRegular)];
477 alignas(DefinedCommon) char b[sizeof(DefinedCommon)];
478 alignas(DefinedAbsolute) char c[sizeof(DefinedAbsolute)];
479 alignas(DefinedSynthetic) char d[sizeof(DefinedSynthetic)];
Bob Haarman7dc5e7a02019-09-03 20:32:16480 alignas(LazyArchive) char e[sizeof(LazyArchive)];
Rui Ueyama136d27a2019-07-11 05:40:30481 alignas(Undefined) char f[sizeof(Undefined)];
482 alignas(DefinedImportData) char g[sizeof(DefinedImportData)];
483 alignas(DefinedImportThunk) char h[sizeof(DefinedImportThunk)];
484 alignas(DefinedLocalImport) char i[sizeof(DefinedLocalImport)];
Bob Haarman7dc5e7a02019-09-03 20:32:16485 alignas(LazyObject) char j[sizeof(LazyObject)];
Martin Storsjöa9ff1ce2021-06-16 13:59:46486 alignas(LazyDLLSymbol) char k[sizeof(LazyDLLSymbol)];
Peter Collingbourne79a5e6b2016-12-09 21:55:24487};
488
489template <typename T, typename... ArgT>
Rui Ueyama136d27a2019-07-11 05:40:30490void replaceSymbol(Symbol *s, ArgT &&... arg) {
Sam Clegg38f52b22018-02-13 17:32:31491 static_assert(std::is_trivially_destructible<T>(),
492 "Symbol types must be trivially destructible");
Rui Ueyama616cd992017-10-31 16:10:24493 static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
494 static_assert(alignof(T) <= alignof(SymbolUnion),
495 "SymbolUnion not aligned enough");
Rui Ueyama38781a52018-02-14 22:43:43496 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
497 "Not a Symbol");
Martin Storsjö3785a412020-10-06 10:54:49498 bool canInline = s->canInline;
Rui Ueyama136d27a2019-07-11 05:40:30499 new (s) T(std::forward<ArgT>(arg)...);
Martin Storsjö3785a412020-10-06 10:54:49500 s->canInline = canInline;
Peter Collingbourne79a5e6b2016-12-09 21:55:24501}
Rui Ueyama411c63602015-05-28 19:09:30502} // namespace coff
Rui Ueyamace039262017-01-06 10:04:08503
Rui Ueyama411c63602015-05-28 19:09:30504} // namespace lld
505
Rui Ueyama411c63602015-05-28 19:09:30506#endif