Coverage Report

Created: 2019-01-18 03:29

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/Symbols.h
Line
Count
Source (jump to first uncovered line)
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 "lld/Common/LLVM.h"
16
#include "lld/Common/Memory.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 ObjFile;
35
class SymbolTable;
36
37
// The base class for real symbol classes.
38
class Symbol {
39
public:
40
  enum Kind {
41
    // The order of these is significant. We start with the regular defined
42
    // symbols as those are the most prevalent and the zero tag is the cheapest
43
    // to set. Among the defined kinds, the lower the kind is preferred over
44
    // the higher kind when testing whether one symbol should take precedence
45
    // over another.
46
    DefinedRegularKind = 0,
47
    DefinedCommonKind,
48
    DefinedLocalImportKind,
49
    DefinedImportThunkKind,
50
    DefinedImportDataKind,
51
    DefinedAbsoluteKind,
52
    DefinedSyntheticKind,
53
54
    UndefinedKind,
55
    LazyKind,
56
57
    LastDefinedCOFFKind = DefinedCommonKind,
58
    LastDefinedKind = DefinedSyntheticKind,
59
  };
60
61
34.2k
  Kind kind() const { return static_cast<Kind>(SymbolKind); }
62
63
  // Returns true if this is an external symbol.
64
0
  bool isExternal() { return IsExternal; }
65
66
  // Returns the symbol name.
67
  StringRef getName();
68
69
  void replaceKeepingName(Symbol *Other, size_t Size);
70
71
  // Returns the file from which this symbol was created.
72
  InputFile *getFile();
73
74
  // Indicates that this symbol will be included in the final image. Only valid
75
  // after calling markLive.
76
  bool isLive() const;
77
78
protected:
79
  friend SymbolTable;
80
  explicit Symbol(Kind K, StringRef N = "")
81
      : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
82
        WrittenToSymtab(false), PendingArchiveLoad(false), IsGCRoot(false),
83
10.1k
        IsRuntimePseudoReloc(false), Name(N) {}
84
85
  const unsigned SymbolKind : 8;
86
  unsigned IsExternal : 1;
87
88
  // This bit is used by the \c DefinedRegular subclass.
89
  unsigned IsCOMDAT : 1;
90
91
public:
92
  // This bit is used by Writer::createSymbolAndStringTable() to prevent
93
  // symbols from being written to the symbol table more than once.
94
  unsigned WrittenToSymtab : 1;
95
96
  // True if this symbol was referenced by a regular (non-bitcode) object.
97
  unsigned IsUsedInRegularObj : 1;
98
99
  // True if we've seen both a lazy and an undefined symbol with this symbol
100
  // name, which means that we have enqueued an archive member load and should
101
  // not load any more archive members to resolve the same symbol.
102
  unsigned PendingArchiveLoad : 1;
103
104
  /// True if we've already added this symbol to the list of GC roots.
105
  unsigned IsGCRoot : 1;
106
107
  unsigned IsRuntimePseudoReloc : 1;
108
109
protected:
110
  StringRef Name;
111
};
112
113
// The base class for any defined symbols, including absolute symbols,
114
// etc.
115
class Defined : public Symbol {
116
public:
117
9.39k
  Defined(Kind K, StringRef N) : Symbol(K, N) {}
118
119
6.33k
  static bool classof(const Symbol *S) { return S->kind() <= LastDefinedKind; }
120
121
  // Returns the RVA (relative virtual address) of this symbol. The
122
  // writer sets and uses RVAs.
123
  uint64_t getRVA();
124
125
  // Returns the chunk containing this symbol. Absolute symbols and __ImageBase
126
  // do not have chunks, so this may return null.
127
  Chunk *getChunk();
128
};
129
130
// Symbols defined via a COFF object file or bitcode file.  For COFF files, this
131
// stores a coff_symbol_generic*, and names of internal symbols are lazily
132
// loaded through that. For bitcode files, Sym is nullptr and the name is stored
133
// as a StringRef.
134
class DefinedCOFF : public Defined {
135
  friend Symbol;
136
137
public:
138
  DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S)
139
3.90k
      : Defined(K, N), File(F), Sym(S) {}
140
141
762
  static bool classof(const Symbol *S) {
142
762
    return S->kind() <= LastDefinedCOFFKind;
143
762
  }
144
145
0
  InputFile *getFile() { return File; }
146
147
  COFFSymbolRef getCOFFSymbol();
148
149
  InputFile *File;
150
151
protected:
152
  const coff_symbol_generic *Sym;
153
};
154
155
// Regular defined symbols read from object file symbol tables.
156
class DefinedRegular : public DefinedCOFF {
157
public:
158
  DefinedRegular(InputFile *F, StringRef N, bool IsCOMDAT,
159
                 bool IsExternal = false,
160
                 const coff_symbol_generic *S = nullptr,
161
                 SectionChunk *C = nullptr)
162
3.89k
      : DefinedCOFF(DefinedRegularKind, F, N, S), Data(C ? &C->Repl : nullptr) {
163
3.89k
    this->IsExternal = IsExternal;
164
3.89k
    this->IsCOMDAT = IsCOMDAT;
165
3.89k
  }
166
167
3.44k
  static bool classof(const Symbol *S) {
168
3.44k
    return S->kind() == DefinedRegularKind;
169
3.44k
  }
170
171
2.65k
  uint64_t getRVA() const { return (*Data)->getRVA() + Sym->Value; }
172
25
  bool isCOMDAT() const { return IsCOMDAT; }
173
6.41k
  SectionChunk *getChunk() const { return *Data; }
174
126
  uint32_t getValue() const { return Sym->Value; }
175
176
  SectionChunk **Data;
177
};
178
179
class DefinedCommon : public DefinedCOFF {
180
public:
181
  DefinedCommon(InputFile *F, StringRef N, uint64_t Size,
182
                const coff_symbol_generic *S = nullptr,
183
                CommonChunk *C = nullptr)
184
12
      : DefinedCOFF(DefinedCommonKind, F, N, S), Data(C), Size(Size) {
185
12
    this->IsExternal = true;
186
12
  }
187
188
4
  static bool classof(const Symbol *S) {
189
4
    return S->kind() == DefinedCommonKind;
190
4
  }
191
192
15
  uint64_t getRVA() { return Data->getRVA(); }
193
25
  CommonChunk *getChunk() { return Data; }
194
195
private:
196
  friend SymbolTable;
197
0
  uint64_t getSize() const { return Size; }
198
  CommonChunk *Data;
199
  uint64_t Size;
200
};
201
202
// Absolute symbols.
203
class DefinedAbsolute : public Defined {
204
public:
205
  DefinedAbsolute(StringRef N, COFFSymbolRef S)
206
21
      : Defined(DefinedAbsoluteKind, N), VA(S.getValue()) {
207
21
    IsExternal = S.isExternal();
208
21
  }
209
210
  DefinedAbsolute(StringRef N, uint64_t V)
211
4.52k
      : Defined(DefinedAbsoluteKind, N), VA(V) {}
212
213
320
  static bool classof(const Symbol *S) {
214
320
    return S->kind() == DefinedAbsoluteKind;
215
320
  }
216
217
66
  uint64_t getRVA() { return VA - Config->ImageBase; }
218
31
  void setVA(uint64_t V) { VA = V; }
219
220
  // Section index relocations against absolute symbols resolve to
221
  // this 16 bit number, and it is the largest valid section index
222
  // plus one. This variable keeps it.
223
  static uint16_t NumOutputSections;
224
225
private:
226
  uint64_t VA;
227
};
228
229
// This symbol is used for linker-synthesized symbols like __ImageBase and
230
// __safe_se_handler_table.
231
class DefinedSynthetic : public Defined {
232
public:
233
  explicit DefinedSynthetic(StringRef Name, Chunk *C)
234
747
      : Defined(DefinedSyntheticKind, Name), C(C) {}
235
236
55
  static bool classof(const Symbol *S) {
237
55
    return S->kind() == DefinedSyntheticKind;
238
55
  }
239
240
  // A null chunk indicates that this is __ImageBase. Otherwise, this is some
241
  // other synthesized chunk, like SEHTableChunk.
242
131
  uint32_t getRVA() { return C ? 
C->getRVA()97
:
034
; }
243
246
  Chunk *getChunk() { return C; }
244
245
private:
246
  Chunk *C;
247
};
248
249
// This class represents a symbol defined in an archive file. It is
250
// created from an archive file header, and it knows how to load an
251
// object file from an archive to replace itself with a defined
252
// symbol. If the resolver finds both Undefined and Lazy for
253
// the same name, it will ask the Lazy to load a file.
254
class Lazy : public Symbol {
255
public:
256
  Lazy(ArchiveFile *F, const Archive::Symbol S)
257
332
      : Symbol(LazyKind, S.getName()), File(F), Sym(S) {}
258
259
1.57k
  static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
260
261
  ArchiveFile *File;
262
263
private:
264
  friend SymbolTable;
265
266
private:
267
  const Archive::Symbol Sym;
268
};
269
270
// Undefined symbols.
271
class Undefined : public Symbol {
272
public:
273
446
  explicit Undefined(StringRef N) : Symbol(UndefinedKind, N) {}
274
275
9.19k
  static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
276
277
  // An undefined symbol can have a fallback symbol which gives an
278
  // undefined symbol a second chance if it would remain undefined.
279
  // If it remains undefined, it'll be replaced with whatever the
280
  // Alias pointer points to.
281
  Symbol *WeakAlias = nullptr;
282
283
  // If this symbol is external weak, try to resolve it to a defined
284
  // symbol by searching the chain of fallback symbols. Returns the symbol if
285
  // successful, otherwise returns null.
286
  Defined *getWeakAlias();
287
};
288
289
// Windows-specific classes.
290
291
// This class represents a symbol imported from a DLL. This has two
292
// names for internal use and external use. The former is used for
293
// name resolution, and the latter is used for the import descriptor
294
// table in an output. The former has "__imp_" prefix.
295
class DefinedImportData : public Defined {
296
public:
297
  DefinedImportData(StringRef N, ImportFile *F)
298
98
      : Defined(DefinedImportDataKind, N), File(F) {
299
98
  }
300
301
1.43k
  static bool classof(const Symbol *S) {
302
1.43k
    return S->kind() == DefinedImportDataKind;
303
1.43k
  }
304
305
123
  uint64_t getRVA() { return File->Location->getRVA(); }
306
46
  Chunk *getChunk() { return File->Location; }
307
93
  void setLocation(Chunk *AddressTable) { File->Location = AddressTable; }
308
309
147
  StringRef getDLLName() { return File->DLLName; }
310
168
  StringRef getExternalName() { return File->ExternalName; }
311
87
  uint16_t getOrdinal() { return File->Hdr->OrdinalHint; }
312
313
  ImportFile *File;
314
};
315
316
// This class represents a symbol for a jump table entry which jumps
317
// to a function in a DLL. Linker are supposed to create such symbols
318
// without "__imp_" prefix for all function symbols exported from
319
// DLLs, so that you can call DLL functions as regular functions with
320
// a regular name. A function pointer is given as a DefinedImportData.
321
class DefinedImportThunk : public Defined {
322
public:
323
  DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine);
324
325
1.41k
  static bool classof(const Symbol *S) {
326
1.41k
    return S->kind() == DefinedImportThunkKind;
327
1.41k
  }
328
329
110
  uint64_t getRVA() { return Data->getRVA(); }
330
268
  Chunk *getChunk() { return Data; }
331
332
  DefinedImportData *WrappedSym;
333
334
private:
335
  Chunk *Data;
336
};
337
338
// If you have a symbol "foo" in your object file, a symbol name
339
// "__imp_foo" becomes automatically available as a pointer to "foo".
340
// This class is for such automatically-created symbols.
341
// Yes, this is an odd feature. We didn't intend to implement that.
342
// This is here just for compatibility with MSVC.
343
class DefinedLocalImport : public Defined {
344
public:
345
  DefinedLocalImport(StringRef N, Defined *S)
346
9
      : Defined(DefinedLocalImportKind, N), Data(make<LocalImportChunk>(S)) {}
347
348
0
  static bool classof(const Symbol *S) {
349
0
    return S->kind() == DefinedLocalImportKind;
350
0
  }
351
352
13
  uint64_t getRVA() { return Data->getRVA(); }
353
32
  Chunk *getChunk() { return Data; }
354
355
private:
356
  LocalImportChunk *Data;
357
};
358
359
3.03k
inline uint64_t Defined::getRVA() {
360
3.03k
  switch (kind()) {
361
3.03k
  case DefinedAbsoluteKind:
362
66
    return cast<DefinedAbsolute>(this)->getRVA();
363
3.03k
  case DefinedSyntheticKind:
364
131
    return cast<DefinedSynthetic>(this)->getRVA();
365
3.03k
  case DefinedImportDataKind:
366
123
    return cast<DefinedImportData>(this)->getRVA();
367
3.03k
  case DefinedImportThunkKind:
368
110
    return cast<DefinedImportThunk>(this)->getRVA();
369
3.03k
  case DefinedLocalImportKind:
370
13
    return cast<DefinedLocalImport>(this)->getRVA();
371
3.03k
  case DefinedCommonKind:
372
15
    return cast<DefinedCommon>(this)->getRVA();
373
3.03k
  case DefinedRegularKind:
374
2.58k
    return cast<DefinedRegular>(this)->getRVA();
375
3.03k
  case LazyKind:
376
0
  case UndefinedKind:
377
0
    llvm_unreachable("Cannot get the address for an undefined symbol.");
378
0
  }
379
0
  llvm_unreachable("unknown symbol kind");
380
0
}
381
382
6.37k
inline Chunk *Defined::getChunk() {
383
6.37k
  switch (kind()) {
384
6.37k
  case DefinedRegularKind:
385
4.71k
    return cast<DefinedRegular>(this)->getChunk();
386
6.37k
  case DefinedAbsoluteKind:
387
1.14k
    return nullptr;
388
6.37k
  case DefinedSyntheticKind:
389
246
    return cast<DefinedSynthetic>(this)->getChunk();
390
6.37k
  case DefinedImportDataKind:
391
46
    return cast<DefinedImportData>(this)->getChunk();
392
6.37k
  case DefinedImportThunkKind:
393
185
    return cast<DefinedImportThunk>(this)->getChunk();
394
6.37k
  case DefinedLocalImportKind:
395
23
    return cast<DefinedLocalImport>(this)->getChunk();
396
6.37k
  case DefinedCommonKind:
397
24
    return cast<DefinedCommon>(this)->getChunk();
398
6.37k
  case LazyKind:
399
0
  case UndefinedKind:
400
0
    llvm_unreachable("Cannot get the chunk of an undefined symbol.");
401
0
  }
402
0
  llvm_unreachable("unknown symbol kind");
403
0
}
404
405
// A buffer class that is large enough to hold any Symbol-derived
406
// object. We allocate memory using this class and instantiate a symbol
407
// using the placement new.
408
union SymbolUnion {
409
  alignas(DefinedRegular) char A[sizeof(DefinedRegular)];
410
  alignas(DefinedCommon) char B[sizeof(DefinedCommon)];
411
  alignas(DefinedAbsolute) char C[sizeof(DefinedAbsolute)];
412
  alignas(DefinedSynthetic) char D[sizeof(DefinedSynthetic)];
413
  alignas(Lazy) char E[sizeof(Lazy)];
414
  alignas(Undefined) char F[sizeof(Undefined)];
415
  alignas(DefinedImportData) char G[sizeof(DefinedImportData)];
416
  alignas(DefinedImportThunk) char H[sizeof(DefinedImportThunk)];
417
  alignas(DefinedLocalImport) char I[sizeof(DefinedLocalImport)];
418
};
419
420
template <typename T, typename... ArgT>
421
7.52k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
7.52k
  static_assert(std::is_trivially_destructible<T>(),
423
7.52k
                "Symbol types must be trivially destructible");
424
7.52k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
7.52k
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
7.52k
                "SymbolUnion not aligned enough");
427
7.52k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
7.52k
         "Not a Symbol");
429
7.52k
  new (S) T(std::forward<ArgT>(Arg)...);
430
7.52k
}
void lld::coff::replaceSymbol<lld::coff::Undefined, llvm::StringRef>(lld::coff::Symbol*, llvm::StringRef&&)
Line
Count
Source
421
78
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
78
  static_assert(std::is_trivially_destructible<T>(),
423
78
                "Symbol types must be trivially destructible");
424
78
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
78
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
78
                "SymbolUnion not aligned enough");
427
78
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
78
         "Not a Symbol");
429
78
  new (S) T(std::forward<ArgT>(Arg)...);
430
78
}
void lld::coff::replaceSymbol<lld::coff::DefinedLocalImport, llvm::StringRef&, lld::coff::Defined*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::Defined*&&&)
Line
Count
Source
421
9
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
9
  static_assert(std::is_trivially_destructible<T>(),
423
9
                "Symbol types must be trivially destructible");
424
9
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
9
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
9
                "SymbolUnion not aligned enough");
427
9
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
9
         "Not a Symbol");
429
9
  new (S) T(std::forward<ArgT>(Arg)...);
430
9
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, int>(lld::coff::Symbol*, llvm::StringRef&&&, int&&)
Line
Count
Source
421
2
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
2
  static_assert(std::is_trivially_destructible<T>(),
423
2
                "Symbol types must be trivially destructible");
424
2
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
2
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
2
                "SymbolUnion not aligned enough");
427
2
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
2
         "Not a Symbol");
429
2
  new (S) T(std::forward<ArgT>(Arg)...);
430
2
}
void lld::coff::replaceSymbol<lld::coff::Undefined, llvm::StringRef&>(lld::coff::Symbol*, llvm::StringRef&&&)
Line
Count
Source
421
368
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
368
  static_assert(std::is_trivially_destructible<T>(),
423
368
                "Symbol types must be trivially destructible");
424
368
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
368
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
368
                "SymbolUnion not aligned enough");
427
368
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
368
         "Not a Symbol");
429
368
  new (S) T(std::forward<ArgT>(Arg)...);
430
368
}
void lld::coff::replaceSymbol<lld::coff::Lazy, lld::coff::ArchiveFile*&, llvm::object::Archive::Symbol const&>(lld::coff::Symbol*, lld::coff::ArchiveFile*&&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
421
332
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
332
  static_assert(std::is_trivially_destructible<T>(),
423
332
                "Symbol types must be trivially destructible");
424
332
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
332
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
332
                "SymbolUnion not aligned enough");
427
332
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
332
         "Not a Symbol");
429
332
  new (S) T(std::forward<ArgT>(Arg)...);
430
332
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, llvm::object::COFFSymbolRef&>(lld::coff::Symbol*, llvm::StringRef&&&, llvm::object::COFFSymbolRef&&&)
Line
Count
Source
421
17
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
17
  static_assert(std::is_trivially_destructible<T>(),
423
17
                "Symbol types must be trivially destructible");
424
17
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
17
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
17
                "SymbolUnion not aligned enough");
427
17
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
17
         "Not a Symbol");
429
17
  new (S) T(std::forward<ArgT>(Arg)...);
430
17
}
void lld::coff::replaceSymbol<lld::coff::DefinedAbsolute, llvm::StringRef&, unsigned long long&>(lld::coff::Symbol*, llvm::StringRef&&&, unsigned long long&&&)
Line
Count
Source
421
4.52k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
4.52k
  static_assert(std::is_trivially_destructible<T>(),
423
4.52k
                "Symbol types must be trivially destructible");
424
4.52k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
4.52k
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
4.52k
                "SymbolUnion not aligned enough");
427
4.52k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
4.52k
         "Not a Symbol");
429
4.52k
  new (S) T(std::forward<ArgT>(Arg)...);
430
4.52k
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef&, lld::coff::Chunk*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::Chunk*&&&)
Line
Count
Source
421
523
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
523
  static_assert(std::is_trivially_destructible<T>(),
423
523
                "Symbol types must be trivially destructible");
424
523
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
523
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
523
                "SymbolUnion not aligned enough");
427
523
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
523
         "Not a Symbol");
429
523
  new (S) T(std::forward<ArgT>(Arg)...);
430
523
}
void lld::coff::replaceSymbol<lld::coff::DefinedRegular, lld::coff::InputFile*&, llvm::StringRef&, bool, bool, llvm::object::coff_symbol_generic const*&, lld::coff::SectionChunk*&>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, bool&&, bool&&, llvm::object::coff_symbol_generic const*&&&, lld::coff::SectionChunk*&&&)
Line
Count
Source
421
1.02k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
1.02k
  static_assert(std::is_trivially_destructible<T>(),
423
1.02k
                "Symbol types must be trivially destructible");
424
1.02k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
1.02k
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
1.02k
                "SymbolUnion not aligned enough");
427
1.02k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
1.02k
         "Not a Symbol");
429
1.02k
  new (S) T(std::forward<ArgT>(Arg)...);
430
1.02k
}
void lld::coff::replaceSymbol<lld::coff::DefinedRegular, lld::coff::InputFile*&, llvm::StringRef&, bool, bool, llvm::object::coff_symbol_generic const*&, std::nullptr_t>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, bool&&, bool&&, llvm::object::coff_symbol_generic const*&&&, std::nullptr_t&&)
Line
Count
Source
421
287
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
287
  static_assert(std::is_trivially_destructible<T>(),
423
287
                "Symbol types must be trivially destructible");
424
287
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
287
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
287
                "SymbolUnion not aligned enough");
427
287
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
287
         "Not a Symbol");
429
287
  new (S) T(std::forward<ArgT>(Arg)...);
430
287
}
void lld::coff::replaceSymbol<lld::coff::DefinedCommon, lld::coff::InputFile*&, llvm::StringRef&, unsigned long long&, llvm::object::coff_symbol_generic const*&, lld::coff::CommonChunk*&>(lld::coff::Symbol*, lld::coff::InputFile*&&&, llvm::StringRef&&&, unsigned long long&&&, llvm::object::coff_symbol_generic const*&&&, lld::coff::CommonChunk*&&&)
Line
Count
Source
421
12
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
12
  static_assert(std::is_trivially_destructible<T>(),
423
12
                "Symbol types must be trivially destructible");
424
12
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
12
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
12
                "SymbolUnion not aligned enough");
427
12
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
12
         "Not a Symbol");
429
12
  new (S) T(std::forward<ArgT>(Arg)...);
430
12
}
void lld::coff::replaceSymbol<lld::coff::DefinedImportData, llvm::StringRef&, lld::coff::ImportFile*&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::ImportFile*&&&)
Line
Count
Source
421
98
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
98
  static_assert(std::is_trivially_destructible<T>(),
423
98
                "Symbol types must be trivially destructible");
424
98
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
98
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
98
                "SymbolUnion not aligned enough");
427
98
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
98
         "Not a Symbol");
429
98
  new (S) T(std::forward<ArgT>(Arg)...);
430
98
}
void lld::coff::replaceSymbol<lld::coff::DefinedImportThunk, llvm::StringRef&, lld::coff::DefinedImportData*&, unsigned short&>(lld::coff::Symbol*, llvm::StringRef&&&, lld::coff::DefinedImportData*&&&, unsigned short&&&)
Line
Count
Source
421
88
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
88
  static_assert(std::is_trivially_destructible<T>(),
423
88
                "Symbol types must be trivially destructible");
424
88
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
88
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
88
                "SymbolUnion not aligned enough");
427
88
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
88
         "Not a Symbol");
429
88
  new (S) T(std::forward<ArgT>(Arg)...);
430
88
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::RVATableChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::RVATableChunk*&&&)
Line
Count
Source
421
19
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
19
  static_assert(std::is_trivially_destructible<T>(),
423
19
                "Symbol types must be trivially destructible");
424
19
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
19
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
19
                "SymbolUnion not aligned enough");
427
19
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
19
         "Not a Symbol");
429
19
  new (S) T(std::forward<ArgT>(Arg)...);
430
19
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::PseudoRelocTableChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::PseudoRelocTableChunk*&&&)
Line
Count
Source
421
39
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
39
  static_assert(std::is_trivially_destructible<T>(),
423
39
                "Symbol types must be trivially destructible");
424
39
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
39
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
39
                "SymbolUnion not aligned enough");
427
39
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
39
         "Not a Symbol");
429
39
  new (S) T(std::forward<ArgT>(Arg)...);
430
39
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::EmptyChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::EmptyChunk*&&&)
Line
Count
Source
421
39
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
39
  static_assert(std::is_trivially_destructible<T>(),
423
39
                "Symbol types must be trivially destructible");
424
39
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
39
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
39
                "SymbolUnion not aligned enough");
427
39
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
39
         "Not a Symbol");
429
39
  new (S) T(std::forward<ArgT>(Arg)...);
430
39
}
void lld::coff::replaceSymbol<lld::coff::DefinedSynthetic, llvm::StringRef, lld::coff::AbsolutePointerChunk*&>(lld::coff::Symbol*, llvm::StringRef&&, lld::coff::AbsolutePointerChunk*&&&)
Line
Count
Source
421
78
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
422
78
  static_assert(std::is_trivially_destructible<T>(),
423
78
                "Symbol types must be trivially destructible");
424
78
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
425
78
  static_assert(alignof(T) <= alignof(SymbolUnion),
426
78
                "SymbolUnion not aligned enough");
427
78
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
428
78
         "Not a Symbol");
429
78
  new (S) T(std::forward<ArgT>(Arg)...);
430
78
}
431
} // namespace coff
432
433
std::string toString(coff::Symbol &B);
434
} // namespace lld
435
436
#endif