Coverage Report

Created: 2017-09-19 22:28

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/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
// All symbols are handled as SymbolBodies regardless of their types.
11
// This file defines various types of SymbolBodies.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLD_ELF_SYMBOLS_H
16
#define LLD_ELF_SYMBOLS_H
17
18
#include "InputSection.h"
19
#include "Strings.h"
20
21
#include "lld/Core/LLVM.h"
22
#include "llvm/Object/Archive.h"
23
#include "llvm/Object/ELF.h"
24
25
namespace lld {
26
namespace elf {
27
28
class ArchiveFile;
29
class BitcodeFile;
30
class BssSection;
31
class InputFile;
32
class LazyObjFile;
33
template <class ELFT> class ObjFile;
34
class OutputSection;
35
template <class ELFT> class SharedFile;
36
37
struct Symbol;
38
39
// The base class for real symbol classes.
40
class SymbolBody {
41
public:
42
  enum Kind {
43
    DefinedFirst,
44
    DefinedRegularKind = DefinedFirst,
45
    SharedKind,
46
    DefinedCommonKind,
47
    DefinedLast = DefinedCommonKind,
48
    UndefinedKind,
49
    LazyArchiveKind,
50
    LazyObjectKind,
51
  };
52
53
0
  SymbolBody(Kind K) : SymbolKind(K) {}
54
55
  Symbol *symbol();
56
12.2k
  const Symbol *symbol() const {
57
12.2k
    return const_cast<SymbolBody *>(this)->symbol();
58
12.2k
  }
59
60
46.7k
  Kind kind() const { return static_cast<Kind>(SymbolKind); }
61
62
9.17k
  bool isUndefined() const { return SymbolKind == UndefinedKind; }
63
46
  bool isDefined() const { return SymbolKind <= DefinedLast; }
64
36
  bool isCommon() const { return SymbolKind == DefinedCommonKind; }
65
5.92k
  bool isLazy() const {
66
5.83k
    return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
67
5.92k
  }
68
6.09k
  bool isShared() const { return SymbolKind == SharedKind; }
69
7.24k
  bool isInCurrentDSO() const {
70
7.24k
    return !isUndefined() && 
!isShared()6.09k
&&
!isLazy()4.70k
;
71
7.24k
  }
72
27.8k
  bool isLocal() const { return IsLocal; }
73
74
  // True is this is an undefined weak symbol. This only works once
75
  // all input files have been added.
76
  bool isUndefWeak() const;
77
78
  InputFile *getFile() const;
79
7.57k
  bool isPreemptible() const { return IsPreemptible; }
80
13.7k
  StringRef getName() const { return Name; }
81
480
  uint8_t getVisibility() const { return StOther & 0x3; }
82
  void parseSymbolVersion();
83
  void copy(SymbolBody *Other);
84
85
299
  bool isInGot() const { return GotIndex != -1U; }
86
1.13k
  bool isInPlt() const { return PltIndex != -1U; }
87
88
  uint64_t getVA(int64_t Addend = 0) const;
89
90
  uint64_t getGotOffset() const;
91
  uint64_t getGotVA() const;
92
  uint64_t getGotPltOffset() const;
93
  uint64_t getGotPltVA() const;
94
  uint64_t getPltVA() const;
95
  template <class ELFT> typename ELFT::uint getSize() const;
96
  OutputSection *getOutputSection() const;
97
98
  uint32_t DynsymIndex = 0;
99
  uint32_t GotIndex = -1;
100
  uint32_t GotPltIndex = -1;
101
  uint32_t PltIndex = -1;
102
  uint32_t GlobalDynIndex = -1;
103
104
protected:
105
  SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
106
             uint8_t Type);
107
108
  const unsigned SymbolKind : 8;
109
110
public:
111
  // True the symbol should point to its PLT entry.
112
  // For SharedSymbol only.
113
  unsigned NeedsPltAddr : 1;
114
115
  // True if this is a local symbol.
116
  unsigned IsLocal : 1;
117
118
  // True if this symbol has an entry in the global part of MIPS GOT.
119
  unsigned IsInGlobalMipsGot : 1;
120
121
  // True if this symbol is referenced by 32-bit GOT relocations.
122
  unsigned Is32BitMipsGot : 1;
123
124
  // True if this symbol is in the Iplt sub-section of the Plt.
125
  unsigned IsInIplt : 1;
126
127
  // True if this symbol is in the Igot sub-section of the .got.plt or .got.
128
  unsigned IsInIgot : 1;
129
130
  unsigned IsPreemptible : 1;
131
132
  // The following fields have the same meaning as the ELF symbol attributes.
133
  uint8_t Type;    // symbol type
134
  uint8_t StOther; // st_other field value
135
136
  // The Type field may also have this value. It means that we have not yet seen
137
  // a non-Lazy symbol with this name, so we don't know what its type is. The
138
  // Type field is normally set to this value for Lazy symbols unless we saw a
139
  // weak undefined symbol first, in which case we need to remember the original
140
  // symbol's type in order to check for TLS mismatches.
141
  enum { UnknownType = 255 };
142
143
8.62k
  bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
144
12.3k
  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
145
151
  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
146
2.68k
  bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
147
76
  bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
148
1.19k
  bool isFile() const { return Type == llvm::ELF::STT_FILE; }
149
150
protected:
151
  StringRefZ Name;
152
};
153
154
// The base class for any defined symbols.
155
class Defined : public SymbolBody {
156
public:
157
  Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type);
158
0
  static bool classof(const SymbolBody *S) { return S->isDefined(); }
159
};
160
161
class DefinedCommon : public Defined {
162
public:
163
  DefinedCommon(StringRef N, uint64_t Size, uint32_t Alignment, uint8_t StOther,
164
                uint8_t Type);
165
166
11.2k
  static bool classof(const SymbolBody *S) {
167
11.2k
    return S->kind() == SymbolBody::DefinedCommonKind;
168
11.2k
  }
169
170
  // True if this symbol is not GC'ed. Liveness is usually a notion of
171
  // input sections and not of symbols, but since common symbols don't
172
  // belong to any input section, their liveness is managed by this bit.
173
  bool Live;
174
175
  // The maximum alignment we have seen for this symbol.
176
  uint32_t Alignment;
177
178
  // The output offset of this common symbol in the output bss.
179
  // Computed by the writer.
180
  uint64_t Size;
181
  BssSection *Section = nullptr;
182
};
183
184
// Regular defined symbols read from object file symbol tables.
185
class DefinedRegular : public Defined {
186
public:
187
  DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
188
                 uint64_t Value, uint64_t Size, SectionBase *Section)
189
      : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type),
190
5.57k
        Value(Value), Size(Size), Section(Section) {}
191
192
  // Return true if the symbol is a PIC function.
193
  template <class ELFT> bool isMipsPIC() const;
194
195
21.8k
  static bool classof(const SymbolBody *S) {
196
21.8k
    return S->kind() == SymbolBody::DefinedRegularKind;
197
21.8k
  }
198
199
  uint64_t Value;
200
  uint64_t Size;
201
  SectionBase *Section;
202
};
203
204
class Undefined : public SymbolBody {
205
public:
206
  Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type);
207
208
268
  static bool classof(const SymbolBody *S) {
209
268
    return S->kind() == UndefinedKind;
210
268
  }
211
};
212
213
class SharedSymbol : public Defined {
214
public:
215
4.46k
  static bool classof(const SymbolBody *S) {
216
4.46k
    return S->kind() == SymbolBody::SharedKind;
217
4.46k
  }
218
219
  SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type,
220
               const void *ElfSym, const void *Verdef)
221
      : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type),
222
525
        Verdef(Verdef), ElfSym(ElfSym) {
223
525
    // IFuncs defined in DSOs are treated as functions by the static linker.
224
525
    if (isGnuIFunc())
225
3
      this->Type = llvm::ELF::STT_FUNC;
226
525
  }
227
228
121
  template <class ELFT> SharedFile<ELFT> *getFile() const {
229
121
    return cast<SharedFile<ELFT>>(SymbolBody::getFile());
230
121
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >* lld::elf::SharedSymbol::getFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
228
29
  template <class ELFT> SharedFile<ELFT> *getFile() const {
229
29
    return cast<SharedFile<ELFT>>(SymbolBody::getFile());
230
29
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >* lld::elf::SharedSymbol::getFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
228
15
  template <class ELFT> SharedFile<ELFT> *getFile() const {
229
15
    return cast<SharedFile<ELFT>>(SymbolBody::getFile());
230
15
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >* lld::elf::SharedSymbol::getFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
228
77
  template <class ELFT> SharedFile<ELFT> *getFile() const {
229
77
    return cast<SharedFile<ELFT>>(SymbolBody::getFile());
230
77
  }
Unexecuted instantiation: lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >* lld::elf::SharedSymbol::getFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
231
232
29
  template <class ELFT> uint64_t getShndx() const {
233
29
    return getSym<ELFT>().st_shndx;
234
29
  }
unsigned long long lld::elf::SharedSymbol::getShndx<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
232
6
  template <class ELFT> uint64_t getShndx() const {
233
6
    return getSym<ELFT>().st_shndx;
234
6
  }
unsigned long long lld::elf::SharedSymbol::getShndx<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
232
18
  template <class ELFT> uint64_t getShndx() const {
233
18
    return getSym<ELFT>().st_shndx;
234
18
  }
Unexecuted instantiation: unsigned long long lld::elf::SharedSymbol::getShndx<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
unsigned long long lld::elf::SharedSymbol::getShndx<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
232
5
  template <class ELFT> uint64_t getShndx() const {
233
5
    return getSym<ELFT>().st_shndx;
234
5
  }
235
236
58
  template <class ELFT> uint64_t getValue() const {
237
58
    return getSym<ELFT>().st_value;
238
58
  }
unsigned long long lld::elf::SharedSymbol::getValue<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
236
12
  template <class ELFT> uint64_t getValue() const {
237
12
    return getSym<ELFT>().st_value;
238
12
  }
Unexecuted instantiation: unsigned long long lld::elf::SharedSymbol::getValue<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
unsigned long long lld::elf::SharedSymbol::getValue<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
236
10
  template <class ELFT> uint64_t getValue() const {
237
10
    return getSym<ELFT>().st_value;
238
10
  }
unsigned long long lld::elf::SharedSymbol::getValue<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
236
36
  template <class ELFT> uint64_t getValue() const {
237
36
    return getSym<ELFT>().st_value;
238
36
  }
239
240
89
  template <class ELFT> uint64_t getSize() const {
241
89
    return getSym<ELFT>().st_size;
242
89
  }
unsigned long long lld::elf::SharedSymbol::getSize<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
240
18
  template <class ELFT> uint64_t getSize() const {
241
18
    return getSym<ELFT>().st_size;
242
18
  }
unsigned long long lld::elf::SharedSymbol::getSize<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
240
15
  template <class ELFT> uint64_t getSize() const {
241
15
    return getSym<ELFT>().st_size;
242
15
  }
unsigned long long lld::elf::SharedSymbol::getSize<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
240
56
  template <class ELFT> uint64_t getSize() const {
241
56
    return getSym<ELFT>().st_size;
242
56
  }
Unexecuted instantiation: unsigned long long lld::elf::SharedSymbol::getSize<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
243
244
  template <class ELFT> uint32_t getAlignment() const;
245
246
  // This field is a pointer to the symbol's version definition.
247
  const void *Verdef;
248
249
  // CopyRelSec and CopyRelSecOff are significant only when NeedsCopy is true.
250
  InputSection *CopyRelSec;
251
252
private:
253
234
  template <class ELFT> const typename ELFT::Sym &getSym() const {
254
234
    return *(const typename ELFT::Sym *)ElfSym;
255
234
  }
llvm::object::ELFType<(llvm::support::endianness)1, false>::Sym const& lld::elf::SharedSymbol::getSym<llvm::object::ELFType<(llvm::support::endianness)1, false> >() const
Line
Count
Source
253
48
  template <class ELFT> const typename ELFT::Sym &getSym() const {
254
48
    return *(const typename ELFT::Sym *)ElfSym;
255
48
  }
llvm::object::ELFType<(llvm::support::endianness)0, false>::Sym const& lld::elf::SharedSymbol::getSym<llvm::object::ELFType<(llvm::support::endianness)0, false> >() const
Line
Count
Source
253
40
  template <class ELFT> const typename ELFT::Sym &getSym() const {
254
40
    return *(const typename ELFT::Sym *)ElfSym;
255
40
  }
llvm::object::ELFType<(llvm::support::endianness)1, true>::Sym const& lld::elf::SharedSymbol::getSym<llvm::object::ELFType<(llvm::support::endianness)1, true> >() const
Line
Count
Source
253
146
  template <class ELFT> const typename ELFT::Sym &getSym() const {
254
146
    return *(const typename ELFT::Sym *)ElfSym;
255
146
  }
Unexecuted instantiation: llvm::object::ELFType<(llvm::support::endianness)0, true>::Sym const& lld::elf::SharedSymbol::getSym<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
256
257
  const void *ElfSym;
258
};
259
260
// This class represents a symbol defined in an archive file. It is
261
// created from an archive file header, and it knows how to load an
262
// object file from an archive to replace itself with a defined
263
// symbol. If the resolver finds both Undefined and Lazy for
264
// the same name, it will ask the Lazy to load a file.
265
class Lazy : public SymbolBody {
266
public:
267
1.11k
  static bool classof(const SymbolBody *S) { return S->isLazy(); }
268
269
  // Returns an object file for this symbol, or a nullptr if the file
270
  // was already returned.
271
  InputFile *fetch();
272
273
protected:
274
  Lazy(SymbolBody::Kind K, StringRef Name, uint8_t Type)
275
93
      : SymbolBody(K, Name, /*IsLocal=*/false, llvm::ELF::STV_DEFAULT, Type) {}
276
};
277
278
// LazyArchive symbols represents symbols in archive files.
279
class LazyArchive : public Lazy {
280
public:
281
  LazyArchive(const llvm::object::Archive::Symbol S, uint8_t Type);
282
283
22
  static bool classof(const SymbolBody *S) {
284
22
    return S->kind() == LazyArchiveKind;
285
22
  }
286
287
  ArchiveFile *getFile();
288
  InputFile *fetch();
289
290
private:
291
  const llvm::object::Archive::Symbol Sym;
292
};
293
294
// LazyObject symbols represents symbols in object files between
295
// --start-lib and --end-lib options.
296
class LazyObject : public Lazy {
297
public:
298
  LazyObject(StringRef Name, uint8_t Type);
299
300
0
  static bool classof(const SymbolBody *S) {
301
0
    return S->kind() == LazyObjectKind;
302
0
  }
303
304
  LazyObjFile *getFile();
305
  InputFile *fetch();
306
};
307
308
// Some linker-generated symbols need to be created as
309
// DefinedRegular symbols.
310
struct ElfSym {
311
  // __bss_start
312
  static DefinedRegular *Bss;
313
314
  // etext and _etext
315
  static DefinedRegular *Etext1;
316
  static DefinedRegular *Etext2;
317
318
  // edata and _edata
319
  static DefinedRegular *Edata1;
320
  static DefinedRegular *Edata2;
321
322
  // end and _end
323
  static DefinedRegular *End1;
324
  static DefinedRegular *End2;
325
326
  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
327
  // be at some offset from the base of the .got section, usually 0 or
328
  // the end of the .got.
329
  static DefinedRegular *GlobalOffsetTable;
330
331
  // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
332
  static DefinedRegular *MipsGp;
333
  static DefinedRegular *MipsGpDisp;
334
  static DefinedRegular *MipsLocalGp;
335
};
336
337
// A real symbol object, SymbolBody, is usually stored within a Symbol. There's
338
// always one Symbol for each symbol name. The resolver updates the SymbolBody
339
// stored in the Body field of this object as it resolves symbols. Symbol also
340
// holds computed properties of symbol names.
341
struct Symbol {
342
  // Symbol binding. This is on the Symbol to track changes during resolution.
343
  // In particular:
344
  // An undefined weak is still weak when it resolves to a shared library.
345
  // An undefined weak will not fetch archive members, but we have to remember
346
  // it is weak.
347
  uint8_t Binding;
348
349
  // Version definition index.
350
  uint16_t VersionId;
351
352
  // Symbol visibility. This is the computed minimum visibility of all
353
  // observed non-DSO symbols.
354
  unsigned Visibility : 2;
355
356
  // True if the symbol was used for linking and thus need to be added to the
357
  // output file's symbol table. This is true for all symbols except for
358
  // unreferenced DSO symbols and bitcode symbols that are unreferenced except
359
  // by other bitcode objects.
360
  unsigned IsUsedInRegularObj : 1;
361
362
  // If this flag is true and the symbol has protected or default visibility, it
363
  // will appear in .dynsym. This flag is set by interposable DSO symbols in
364
  // executables, by most symbols in DSOs and executables built with
365
  // --export-dynamic, and by dynamic lists.
366
  unsigned ExportDynamic : 1;
367
368
  // True if this symbol is specified by --trace-symbol option.
369
  unsigned Traced : 1;
370
371
  // This symbol version was found in a version script.
372
  unsigned InVersionScript : 1;
373
374
  // The file from which this symbol was created.
375
  InputFile *File = nullptr;
376
377
  bool includeInDynsym() const;
378
  uint8_t computeBinding() const;
379
1.78k
  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
380
381
  // This field is used to store the Symbol's SymbolBody. This instantiation of
382
  // AlignedCharArrayUnion gives us a struct with a char array field that is
383
  // large and aligned enough to store any derived class of SymbolBody.
384
  llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
385
                              SharedSymbol, LazyArchive, LazyObject>
386
      Body;
387
388
40.8k
  SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }
389
3.82k
  const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
390
};
391
392
void printTraceSymbol(Symbol *Sym);
393
394
template <typename T, typename... ArgT>
395
5.70k
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
5.70k
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
5.70k
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
5.70k
                "Body not aligned enough");
399
5.70k
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
5.70k
         "Not a SymbolBody");
401
5.70k
  S->File = File;
402
5.70k
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
5.70k
404
5.70k
  // Print out a log message if --trace-symbol was specified.
405
5.70k
  // This is for debugging.
406
5.70k
  if (S->Traced)
407
52
    printTraceSymbol(S);
408
5.70k
}
void lld::elf::replaceBody<lld::elf::LazyObject, llvm::StringRef&, lld::elf::SymbolBody::'unnamed'>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, lld::elf::SymbolBody::'unnamed'&&)
Line
Count
Source
395
14
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
14
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
14
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
14
                "Body not aligned enough");
399
14
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
14
         "Not a SymbolBody");
401
14
  S->File = File;
402
14
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
14
404
14
  // Print out a log message if --trace-symbol was specified.
405
14
  // This is for debugging.
406
14
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
14
}
Unexecuted instantiation: void lld::elf::replaceBody<lld::elf::LazyObject, llvm::StringRef&, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned char&&&)
void lld::elf::replaceBody<lld::elf::SharedSymbol, llvm::StringRef&, unsigned char const&, unsigned char, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false> > const*, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false> > const*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned char const&&&, unsigned char&&, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false> > const*&&, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)1, false> > const*&&&)
Line
Count
Source
395
83
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
83
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
83
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
83
                "Body not aligned enough");
399
83
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
83
         "Not a SymbolBody");
401
83
  S->File = File;
402
83
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
83
404
83
  // Print out a log message if --trace-symbol was specified.
405
83
  // This is for debugging.
406
83
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
83
}
void lld::elf::replaceBody<lld::elf::SharedSymbol, llvm::StringRef&, unsigned char const&, unsigned char, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false> > const*, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false> > const*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned char const&&&, unsigned char&&, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false> > const*&&, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)0, false> > const*&&&)
Line
Count
Source
395
63
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
63
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
63
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
63
                "Body not aligned enough");
399
63
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
63
         "Not a SymbolBody");
401
63
  S->File = File;
402
63
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
63
404
63
  // Print out a log message if --trace-symbol was specified.
405
63
  // This is for debugging.
406
63
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
63
}
void lld::elf::replaceBody<lld::elf::SharedSymbol, llvm::StringRef&, unsigned char const&, unsigned char, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true> > const*, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true> > const*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned char const&&&, unsigned char&&, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true> > const*&&, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)1, true> > const*&&&)
Line
Count
Source
395
362
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
362
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
362
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
362
                "Body not aligned enough");
399
362
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
362
         "Not a SymbolBody");
401
362
  S->File = File;
402
362
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
362
404
362
  // Print out a log message if --trace-symbol was specified.
405
362
  // This is for debugging.
406
362
  if (S->Traced)
407
9
    printTraceSymbol(S);
408
362
}
void lld::elf::replaceBody<lld::elf::SharedSymbol, llvm::StringRef&, unsigned char const&, unsigned char, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true> > const*, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true> > const*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned char const&&&, unsigned char&&, llvm::object::Elf_Sym_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true> > const*&&, llvm::object::Elf_Verdef_Impl<llvm::object::ELFType<(llvm::support::endianness)0, true> > const*&&&)
Line
Count
Source
395
17
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
17
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
17
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
17
                "Body not aligned enough");
399
17
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
17
         "Not a SymbolBody");
401
17
  S->File = File;
402
17
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
17
404
17
  // Print out a log message if --trace-symbol was specified.
405
17
  // This is for debugging.
406
17
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
17
}
void lld::elf::replaceBody<lld::elf::DefinedRegular, llvm::StringRef&, bool, unsigned char&, unsigned char&, int, int, std::nullptr_t>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, bool&&, unsigned char&&&, unsigned char&&&, int&&, int&&, std::nullptr_t&&)
Line
Count
Source
395
191
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
191
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
191
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
191
                "Body not aligned enough");
399
191
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
191
         "Not a SymbolBody");
401
191
  S->File = File;
402
191
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
191
404
191
  // Print out a log message if --trace-symbol was specified.
405
191
  // This is for debugging.
406
191
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
191
}
void lld::elf::replaceBody<lld::elf::DefinedCommon, llvm::StringRef&, unsigned long long&, unsigned int&, unsigned char&, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, unsigned long long&&&, unsigned int&&&, unsigned char&&&, unsigned char&&&)
Line
Count
Source
395
108
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
108
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
108
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
108
                "Body not aligned enough");
399
108
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
108
         "Not a SymbolBody");
401
108
  S->File = File;
402
108
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
108
404
108
  // Print out a log message if --trace-symbol was specified.
405
108
  // This is for debugging.
406
108
  if (S->Traced)
407
5
    printTraceSymbol(S);
408
108
}
LinkerScript.cpp:void lld::elf::replaceBody<lld::elf::DefinedRegular, llvm::StringRef&, bool, unsigned char&, llvm::ELF::$_9, unsigned long long&, int, lld::elf::SectionBase*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, bool&&, unsigned char&&&, llvm::ELF::$_9&&, unsigned long long&&&, int&&, lld::elf::SectionBase*&&&)
Line
Count
Source
395
178
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
178
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
178
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
178
                "Body not aligned enough");
399
178
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
178
         "Not a SymbolBody");
401
178
  S->File = File;
402
178
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
178
404
178
  // Print out a log message if --trace-symbol was specified.
405
178
  // This is for debugging.
406
178
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
178
}
LTO.cpp:void lld::elf::replaceBody<lld::elf::Undefined, llvm::StringRef, bool, llvm::ELF::$_3, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&, bool&&, llvm::ELF::$_3&&, unsigned char&&&)
Line
Count
Source
395
190
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
190
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
190
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
190
                "Body not aligned enough");
399
190
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
190
         "Not a SymbolBody");
401
190
  S->File = File;
402
190
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
190
404
190
  // Print out a log message if --trace-symbol was specified.
405
190
  // This is for debugging.
406
190
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
190
}
void lld::elf::replaceBody<lld::elf::LazyArchive, llvm::object::Archive::Symbol const&, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::object::Archive::Symbol const&&&, unsigned char&&&)
Line
Count
Source
395
10
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
10
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
10
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
10
                "Body not aligned enough");
399
10
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
10
         "Not a SymbolBody");
401
10
  S->File = File;
402
10
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
10
404
10
  // Print out a log message if --trace-symbol was specified.
405
10
  // This is for debugging.
406
10
  if (S->Traced)
407
0
    printTraceSymbol(S);
408
10
}
void lld::elf::replaceBody<lld::elf::LazyArchive, llvm::object::Archive::Symbol const&, lld::elf::SymbolBody::'unnamed'>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::object::Archive::Symbol const&&&, lld::elf::SymbolBody::'unnamed'&&)
Line
Count
Source
395
69
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
69
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
69
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
69
                "Body not aligned enough");
399
69
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
69
         "Not a SymbolBody");
401
69
  S->File = File;
402
69
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
69
404
69
  // Print out a log message if --trace-symbol was specified.
405
69
  // This is for debugging.
406
69
  if (S->Traced)
407
2
    printTraceSymbol(S);
408
69
}
void lld::elf::replaceBody<lld::elf::Undefined, llvm::StringRef&, bool&, unsigned char&, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, bool&&&, unsigned char&&&, unsigned char&&&)
Line
Count
Source
395
839
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
839
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
839
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
839
                "Body not aligned enough");
399
839
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
839
         "Not a SymbolBody");
401
839
  S->File = File;
402
839
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
839
404
839
  // Print out a log message if --trace-symbol was specified.
405
839
  // This is for debugging.
406
839
  if (S->Traced)
407
16
    printTraceSymbol(S);
408
839
}
void lld::elf::replaceBody<lld::elf::DefinedRegular, llvm::StringRef&, bool, unsigned char&, unsigned char&, unsigned long long&, unsigned long long&, lld::elf::SectionBase*&>(lld::elf::Symbol*, lld::elf::InputFile*, llvm::StringRef&&&, bool&&, unsigned char&&&, unsigned char&&&, unsigned long long&&&, unsigned long long&&&, lld::elf::SectionBase*&&&)
Line
Count
Source
395
3.58k
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
396
3.58k
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
397
3.58k
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
398
3.58k
                "Body not aligned enough");
399
3.58k
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
400
3.58k
         "Not a SymbolBody");
401
3.58k
  S->File = File;
402
3.58k
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
403
3.58k
404
3.58k
  // Print out a log message if --trace-symbol was specified.
405
3.58k
  // This is for debugging.
406
3.58k
  if (S->Traced)
407
20
    printTraceSymbol(S);
408
3.58k
}
409
410
28.2k
inline Symbol *SymbolBody::symbol() {
411
28.2k
  assert(!isLocal());
412
28.2k
  return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
413
28.2k
                                    offsetof(Symbol, Body));
414
28.2k
}
415
} // namespace elf
416
417
std::string toString(const elf::SymbolBody &B);
418
} // namespace lld
419
420
#endif