Coverage Report

Created: 2017-10-03 07:32

/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.3k
  const Symbol *symbol() const {
57
12.3k
    return const_cast<SymbolBody *>(this)->symbol();
58
12.3k
  }
59
60
47.0k
  Kind kind() const { return static_cast<Kind>(SymbolKind); }
61
62
9.21k
  bool isUndefined() const { return SymbolKind == UndefinedKind; }
63
46
  bool isDefined() const { return SymbolKind <= DefinedLast; }
64
36
  bool isCommon() const { return SymbolKind == DefinedCommonKind; }
65
5.95k
  bool isLazy() const {
66
5.86k
    return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
67
5.95k
  }
68
6.11k
  bool isShared() const { return SymbolKind == SharedKind; }
69
7.27k
  bool isInCurrentDSO() const {
70
7.27k
    return !isUndefined() && 
!isShared()6.11k
&&
!isLazy()4.72k
;
71
7.27k
  }
72
28.1k
  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.65k
  bool isPreemptible() const { return IsPreemptible; }
80
14.0k
  StringRef getName() const { return Name; }
81
481
  uint8_t getVisibility() const { return StOther & 0x3; }
82
  void parseSymbolVersion();
83
  void copyFrom(SymbolBody *Other);
84
85
301
  bool isInGot() const { return GotIndex != -1U; }
86
1.14k
  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.72k
  bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
144
12.4k
  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
145
151
  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
146
2.70k
  bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
147
76
  bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
148
1.21k
  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.3k
  static bool classof(const SymbolBody *S) {
167
11.3k
    return S->kind() == SymbolBody::DefinedCommonKind;
168
11.3k
  }
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.64k
        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.9k
  static bool classof(const SymbolBody *S) {
196
21.9k
    return S->kind() == SymbolBody::DefinedRegularKind;
197
21.9k
  }
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.49k
  static bool classof(const SymbolBody *S) {
216
4.49k
    return S->kind() == SymbolBody::SharedKind;
217
4.49k
  }
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
  }
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
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
  }
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, 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
  }
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.12k
  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
  // False if LTO shouldn't inline whatever this symbol points to. If a symbol
369
  // is overwritten after LTO, LTO shouldn't inline the symbol because it
370
  // doesn't know the final contents of the symbol.
371
  unsigned CanInline : 1;
372
373
  // True if this symbol is specified by --trace-symbol option.
374
  unsigned Traced : 1;
375
376
  // This symbol version was found in a version script.
377
  unsigned InVersionScript : 1;
378
379
  // The file from which this symbol was created.
380
  InputFile *File = nullptr;
381
382
  bool includeInDynsym() const;
383
  uint8_t computeBinding() const;
384
1.80k
  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
385
386
  // This field is used to store the Symbol's SymbolBody. This instantiation of
387
  // AlignedCharArrayUnion gives us a struct with a char array field that is
388
  // large and aligned enough to store any derived class of SymbolBody.
389
  llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
390
                              SharedSymbol, LazyArchive, LazyObject>
391
      Body;
392
393
41.1k
  SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }
394
3.83k
  const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
395
};
396
397
void printTraceSymbol(Symbol *Sym);
398
399
template <typename T, typename... ArgT>
400
5.75k
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
5.75k
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
5.75k
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
5.75k
                "Body not aligned enough");
404
5.75k
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
5.75k
         "Not a SymbolBody");
406
5.75k
  S->File = File;
407
5.75k
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
5.75k
409
5.75k
  // Print out a log message if --trace-symbol was specified.
410
5.75k
  // This is for debugging.
411
5.75k
  if (S->Traced)
412
52
    printTraceSymbol(S);
413
5.75k
}
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
400
841
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
841
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
841
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
841
                "Body not aligned enough");
404
841
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
841
         "Not a SymbolBody");
406
841
  S->File = File;
407
841
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
841
409
841
  // Print out a log message if --trace-symbol was specified.
410
841
  // This is for debugging.
411
841
  if (S->Traced)
412
16
    printTraceSymbol(S);
413
841
}
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
400
3.60k
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
3.60k
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
3.60k
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
3.60k
                "Body not aligned enough");
404
3.60k
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
3.60k
         "Not a SymbolBody");
406
3.60k
  S->File = File;
407
3.60k
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
3.60k
409
3.60k
  // Print out a log message if --trace-symbol was specified.
410
3.60k
  // This is for debugging.
411
3.60k
  if (S->Traced)
412
20
    printTraceSymbol(S);
413
3.60k
}
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
400
69
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
69
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
69
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
69
                "Body not aligned enough");
404
69
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
69
         "Not a SymbolBody");
406
69
  S->File = File;
407
69
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
69
409
69
  // Print out a log message if --trace-symbol was specified.
410
69
  // This is for debugging.
411
69
  if (S->Traced)
412
2
    printTraceSymbol(S);
413
69
}
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
400
10
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
10
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
10
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
10
                "Body not aligned enough");
404
10
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
10
         "Not a SymbolBody");
406
10
  S->File = File;
407
10
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
10
409
10
  // Print out a log message if --trace-symbol was specified.
410
10
  // This is for debugging.
411
10
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
10
}
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
400
14
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
14
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
14
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
14
                "Body not aligned enough");
404
14
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
14
         "Not a SymbolBody");
406
14
  S->File = File;
407
14
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
14
409
14
  // Print out a log message if --trace-symbol was specified.
410
14
  // This is for debugging.
411
14
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
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
400
83
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
83
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
83
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
83
                "Body not aligned enough");
404
83
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
83
         "Not a SymbolBody");
406
83
  S->File = File;
407
83
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
83
409
83
  // Print out a log message if --trace-symbol was specified.
410
83
  // This is for debugging.
411
83
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
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
400
63
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
63
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
63
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
63
                "Body not aligned enough");
404
63
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
63
         "Not a SymbolBody");
406
63
  S->File = File;
407
63
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
63
409
63
  // Print out a log message if --trace-symbol was specified.
410
63
  // This is for debugging.
411
63
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
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
400
362
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
362
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
362
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
362
                "Body not aligned enough");
404
362
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
362
         "Not a SymbolBody");
406
362
  S->File = File;
407
362
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
362
409
362
  // Print out a log message if --trace-symbol was specified.
410
362
  // This is for debugging.
411
362
  if (S->Traced)
412
9
    printTraceSymbol(S);
413
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
400
17
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
17
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
17
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
17
                "Body not aligned enough");
404
17
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
17
         "Not a SymbolBody");
406
17
  S->File = File;
407
17
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
17
409
17
  // Print out a log message if --trace-symbol was specified.
410
17
  // This is for debugging.
411
17
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
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
400
201
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
201
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
201
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
201
                "Body not aligned enough");
404
201
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
201
         "Not a SymbolBody");
406
201
  S->File = File;
407
201
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
201
409
201
  // Print out a log message if --trace-symbol was specified.
410
201
  // This is for debugging.
411
201
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
201
}
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
400
108
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
108
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
108
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
108
                "Body not aligned enough");
404
108
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
108
         "Not a SymbolBody");
406
108
  S->File = File;
407
108
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
108
409
108
  // Print out a log message if --trace-symbol was specified.
410
108
  // This is for debugging.
411
108
  if (S->Traced)
412
5
    printTraceSymbol(S);
413
108
}
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
400
200
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
200
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
200
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
200
                "Body not aligned enough");
404
200
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
200
         "Not a SymbolBody");
406
200
  S->File = File;
407
200
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
200
409
200
  // Print out a log message if --trace-symbol was specified.
410
200
  // This is for debugging.
411
200
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
200
}
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
400
185
void replaceBody(Symbol *S, InputFile *File, ArgT &&... Arg) {
401
185
  static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
402
185
  static_assert(alignof(T) <= alignof(decltype(S->Body)),
403
185
                "Body not aligned enough");
404
185
  assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
405
185
         "Not a SymbolBody");
406
185
  S->File = File;
407
185
  new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
408
185
409
185
  // Print out a log message if --trace-symbol was specified.
410
185
  // This is for debugging.
411
185
  if (S->Traced)
412
0
    printTraceSymbol(S);
413
185
}
414
415
28.4k
inline Symbol *SymbolBody::symbol() {
416
28.4k
  assert(!isLocal());
417
28.4k
  return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
418
28.4k
                                    offsetof(Symbol, Body));
419
28.4k
}
420
} // namespace elf
421
422
std::string toString(const elf::SymbolBody &B);
423
} // namespace lld
424
425
#endif