Coverage Report

Created: 2018-08-19 14:04

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/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
// This file defines various types of Symbols.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLD_ELF_SYMBOLS_H
15
#define LLD_ELF_SYMBOLS_H
16
17
#include "InputSection.h"
18
#include "lld/Common/LLVM.h"
19
#include "lld/Common/Strings.h"
20
#include "llvm/Object/Archive.h"
21
#include "llvm/Object/ELF.h"
22
23
namespace lld {
24
namespace elf {
25
26
class ArchiveFile;
27
class BitcodeFile;
28
class BssSection;
29
class InputFile;
30
class LazyObjFile;
31
template <class ELFT> class ObjFile;
32
class OutputSection;
33
template <class ELFT> class SharedFile;
34
35
// This is a StringRef-like container that doesn't run strlen().
36
//
37
// ELF string tables contain a lot of null-terminated strings. Most of them
38
// are not necessary for the linker because they are names of local symbols,
39
// and the linker doesn't use local symbol names for name resolution. So, we
40
// use this class to represents strings read from string tables.
41
struct StringRefZ {
42
136k
  StringRefZ(const char *S) : Data(S), Size(-1) {}
43
19.5k
  StringRefZ(StringRef S) : Data(S.data()), Size(S.size()) {}
44
45
  const char *Data;
46
  const uint32_t Size;
47
};
48
49
// The base class for real symbol classes.
50
class Symbol {
51
public:
52
  enum Kind {
53
    DefinedKind,
54
    SharedKind,
55
    UndefinedKind,
56
    LazyArchiveKind,
57
    LazyObjectKind,
58
  };
59
60
117k
  Kind kind() const { return static_cast<Kind>(SymbolKind); }
61
62
  // The file from which this symbol was created.
63
  InputFile *File;
64
65
protected:
66
  const char *NameData;
67
  mutable uint32_t NameSize;
68
69
public:
70
  uint32_t DynsymIndex = 0;
71
  uint32_t GotIndex = -1;
72
  uint32_t PltIndex = -1;
73
  uint32_t GlobalDynIndex = -1;
74
75
  // This field is a index to the symbol's version definition.
76
  uint32_t VerdefIndex = -1;
77
78
  // Version definition index.
79
  uint16_t VersionId;
80
81
  // Symbol binding. This is not overwritten by replaceSymbol to track
82
  // changes during resolution. In particular:
83
  //  - An undefined weak is still weak when it resolves to a shared library.
84
  //  - An undefined weak will not fetch archive members, but we have to
85
  //    remember it is weak.
86
  uint8_t Binding;
87
88
  // The following fields have the same meaning as the ELF symbol attributes.
89
  uint8_t Type;    // symbol type
90
  uint8_t StOther; // st_other field value
91
92
  const uint8_t SymbolKind;
93
94
  // Symbol visibility. This is the computed minimum visibility of all
95
  // observed non-DSO symbols.
96
  unsigned Visibility : 2;
97
98
  // True if the symbol was used for linking and thus need to be added to the
99
  // output file's symbol table. This is true for all symbols except for
100
  // unreferenced DSO symbols and bitcode symbols that are unreferenced except
101
  // by other bitcode objects.
102
  unsigned IsUsedInRegularObj : 1;
103
104
  // If this flag is true and the symbol has protected or default visibility, it
105
  // will appear in .dynsym. This flag is set by interposable DSO symbols in
106
  // executables, by most symbols in DSOs and executables built with
107
  // --export-dynamic, and by dynamic lists.
108
  unsigned ExportDynamic : 1;
109
110
  // False if LTO shouldn't inline whatever this symbol points to. If a symbol
111
  // is overwritten after LTO, LTO shouldn't inline the symbol because it
112
  // doesn't know the final contents of the symbol.
113
  unsigned CanInline : 1;
114
115
  // True if this symbol is specified by --trace-symbol option.
116
  unsigned Traced : 1;
117
118
  bool includeInDynsym() const;
119
  uint8_t computeBinding() const;
120
3.31k
  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
121
122
14.8k
  bool isUndefined() const { return SymbolKind == UndefinedKind; }
123
18.8M
  bool isDefined() const { return SymbolKind == DefinedKind; }
124
464
  bool isShared() const { return SymbolKind == SharedKind; }
125
435k
  bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
126
127
17.2k
  bool isLazy() const {
128
17.2k
    return SymbolKind == LazyArchiveKind || 
SymbolKind == LazyObjectKind17.0k
;
129
17.2k
  }
130
131
  // True if this is an undefined weak symbol.
132
2.42k
  bool isUndefWeak() const { return isWeak() && 
isUndefined()94
; }
133
134
175k
  StringRef getName() const {
135
175k
    if (NameSize == (uint32_t)-1)
136
133k
      NameSize = strlen(NameData);
137
175k
    return {NameData, NameSize};
138
175k
  }
139
140
  void parseSymbolVersion();
141
142
747
  bool isInGot() const { return GotIndex != -1U; }
143
11.9k
  bool isInPlt() const { return PltIndex != -1U; }
144
145
  uint64_t getVA(int64_t Addend = 0) const;
146
147
  uint64_t getGotOffset() const;
148
  uint64_t getGotVA() const;
149
  uint64_t getGotPltOffset() const;
150
  uint64_t getGotPltVA() const;
151
  uint64_t getPltVA() const;
152
  uint64_t getPltOffset() const;
153
  uint64_t getSize() const;
154
  OutputSection *getOutputSection() const;
155
156
protected:
157
  Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
158
         uint8_t StOther, uint8_t Type)
159
      : File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
160
        Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
161
        IsInIplt(false), IsInIgot(false), IsPreemptible(false),
162
155k
        Used(!Config->GcSections), NeedsTocRestore(false) {}
163
164
public:
165
  // True the symbol should point to its PLT entry.
166
  // For SharedSymbol only.
167
  unsigned NeedsPltAddr : 1;
168
169
  // True if this symbol is in the Iplt sub-section of the Plt.
170
  unsigned IsInIplt : 1;
171
172
  // True if this symbol is in the Igot sub-section of the .got.plt or .got.
173
  unsigned IsInIgot : 1;
174
175
  // True if this symbol is preemptible at load time.
176
  unsigned IsPreemptible : 1;
177
178
  // True if an undefined or shared symbol is used from a live section.
179
  unsigned Used : 1;
180
181
  // True if a call to this symbol needs to be followed by a restore of the
182
  // PPC64 toc pointer.
183
  unsigned NeedsTocRestore : 1;
184
185
  // The Type field may also have this value. It means that we have not yet seen
186
  // a non-Lazy symbol with this name, so we don't know what its type is. The
187
  // Type field is normally set to this value for Lazy symbols unless we saw a
188
  // weak undefined symbol first, in which case we need to remember the original
189
  // symbol's type in order to check for TLS mismatches.
190
  enum { UnknownType = 255 };
191
192
166k
  bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
193
135k
  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
194
185
  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
195
13.4k
  bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
196
118
  bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
197
0
  bool isFile() const { return Type == llvm::ELF::STT_FILE; }
198
};
199
200
// Represents a symbol that is defined in the current output file.
201
class Defined : public Symbol {
202
public:
203
  Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
204
          uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section)
205
      : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value),
206
150k
        Size(Size), Section(Section) {}
207
208
18.8M
  static bool classof(const Symbol *S) { return S->isDefined(); }
209
210
  uint64_t Value;
211
  uint64_t Size;
212
  SectionBase *Section;
213
};
214
215
class Undefined : public Symbol {
216
public:
217
  Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
218
            uint8_t Type)
219
4.37k
      : Symbol(UndefinedKind, File, Name, Binding, StOther, Type) {}
220
221
0
  static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
222
};
223
224
class SharedSymbol : public Symbol {
225
public:
226
16.6k
  static bool classof(const Symbol *S) { return S->kind() == SharedKind; }
227
228
  SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
229
               uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
230
               uint32_t Alignment, uint32_t VerdefIndex)
231
      : Symbol(SharedKind, &File, Name, Binding, StOther, Type),
232
813
        Alignment(Alignment), Value(Value), Size(Size) {
233
813
    this->VerdefIndex = VerdefIndex;
234
813
    // GNU ifunc is a mechanism to allow user-supplied functions to
235
813
    // resolve PLT slot values at load-time. This is contrary to the
236
813
    // regular symbol resolution scheme in which symbols are resolved just
237
813
    // by name. Using this hook, you can program how symbols are solved
238
813
    // for you program. For example, you can make "memcpy" to be resolved
239
813
    // to a SSE-enabled version of memcpy only when a machine running the
240
813
    // program supports the SSE instruction set.
241
813
    //
242
813
    // Naturally, such symbols should always be called through their PLT
243
813
    // slots. What GNU ifunc symbols point to are resolver functions, and
244
813
    // calling them directly doesn't make sense (unless you are writing a
245
813
    // loader).
246
813
    //
247
813
    // For DSO symbols, we always call them through PLT slots anyway.
248
813
    // So there's no difference between GNU ifunc and regular function
249
813
    // symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
250
813
    if (this->Type == llvm::ELF::STT_GNU_IFUNC)
251
3
      this->Type = llvm::ELF::STT_FUNC;
252
813
  }
253
254
846
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
846
    return *cast<SharedFile<ELFT>>(File);
256
846
  }
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
254
132
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
132
    return *cast<SharedFile<ELFT>>(File);
256
132
  }
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
254
105
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
105
    return *cast<SharedFile<ELFT>>(File);
256
105
  }
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
254
575
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
575
    return *cast<SharedFile<ELFT>>(File);
256
575
  }
lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >& lld::elf::SharedSymbol::getFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >() const
Line
Count
Source
254
34
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
34
    return *cast<SharedFile<ELFT>>(File);
256
34
  }
257
258
  uint32_t Alignment;
259
260
  uint64_t Value; // st_value
261
  uint64_t Size;  // st_size
262
};
263
264
// LazyArchive and LazyObject represent a symbols that is not yet in the link,
265
// but we know where to find it if needed. If the resolver finds both Undefined
266
// and Lazy for the same name, it will ask the Lazy to load a file.
267
//
268
// A special complication is the handling of weak undefined symbols. They should
269
// not load a file, but we have to remember we have seen both the weak undefined
270
// and the lazy. We represent that with a lazy symbol with a weak binding. This
271
// means that code looking for undefined symbols normally also has to take lazy
272
// symbols into consideration.
273
274
// This class represents a symbol defined in an archive file. It is
275
// created from an archive file header, and it knows how to load an
276
// object file from an archive to replace itself with a defined
277
// symbol.
278
class LazyArchive : public Symbol {
279
public:
280
  LazyArchive(InputFile &File, uint8_t Type,
281
              const llvm::object::Archive::Symbol S)
282
      : Symbol(LazyArchiveKind, &File, S.getName(), llvm::ELF::STB_GLOBAL,
283
               llvm::ELF::STV_DEFAULT, Type),
284
104
        Sym(S) {}
285
286
41
  static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
287
288
  InputFile *fetch();
289
  MemoryBufferRef getMemberBuffer();
290
291
private:
292
  const llvm::object::Archive::Symbol Sym;
293
};
294
295
// LazyObject symbols represents symbols in object files between
296
// --start-lib and --end-lib options.
297
class LazyObject : public Symbol {
298
public:
299
  LazyObject(InputFile &File, uint8_t Type, StringRef Name)
300
      : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
301
21
               llvm::ELF::STV_DEFAULT, Type) {}
302
303
4
  static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
304
};
305
306
// Some linker-generated symbols need to be created as
307
// Defined symbols.
308
struct ElfSym {
309
  // __bss_start
310
  static Defined *Bss;
311
312
  // etext and _etext
313
  static Defined *Etext1;
314
  static Defined *Etext2;
315
316
  // edata and _edata
317
  static Defined *Edata1;
318
  static Defined *Edata2;
319
320
  // end and _end
321
  static Defined *End1;
322
  static Defined *End2;
323
324
  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
325
  // be at some offset from the base of the .got section, usually 0 or
326
  // the end of the .got.
327
  static Defined *GlobalOffsetTable;
328
329
  // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
330
  static Defined *MipsGp;
331
  static Defined *MipsGpDisp;
332
  static Defined *MipsLocalGp;
333
334
  // __rela_iplt_end or __rel_iplt_end
335
  static Defined *RelaIpltEnd;
336
337
  // __global_pointer$ in RISC-V.
338
  static Defined *RISCVGlobalPointer;
339
};
340
341
// A buffer class that is large enough to hold any Symbol-derived
342
// object. We allocate memory using this class and instantiate a symbol
343
// using the placement new.
344
union SymbolUnion {
345
  alignas(Defined) char A[sizeof(Defined)];
346
  alignas(Undefined) char C[sizeof(Undefined)];
347
  alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
348
  alignas(LazyArchive) char E[sizeof(LazyArchive)];
349
  alignas(LazyObject) char F[sizeof(LazyObject)];
350
};
351
352
void printTraceSymbol(Symbol *Sym);
353
354
template <typename T, typename... ArgT>
355
19.1k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
19.1k
  static_assert(std::is_trivially_destructible<T>(),
357
19.1k
                "Symbol types must be trivially destructible");
358
19.1k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
19.1k
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
19.1k
                "SymbolUnion not aligned enough");
361
19.1k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
19.1k
         "Not a Symbol");
363
19.1k
364
19.1k
  Symbol Sym = *S;
365
19.1k
366
19.1k
  new (S) T(std::forward<ArgT>(Arg)...);
367
19.1k
368
19.1k
  S->VersionId = Sym.VersionId;
369
19.1k
  S->Visibility = Sym.Visibility;
370
19.1k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
19.1k
  S->ExportDynamic = Sym.ExportDynamic;
372
19.1k
  S->CanInline = Sym.CanInline;
373
19.1k
  S->Traced = Sym.Traced;
374
19.1k
375
19.1k
  // Print out a log message if --trace-symbol was specified.
376
19.1k
  // This is for debugging.
377
19.1k
  if (S->Traced)
378
54
    printTraceSymbol(S);
379
19.1k
}
void lld::elf::replaceSymbol<lld::elf::Undefined, std::nullptr_t, llvm::StringRef, unsigned char&, unsigned char&, unsigned char&>(lld::elf::Symbol*, std::nullptr_t&&, llvm::StringRef&&, unsigned char&&&, unsigned char&&&, unsigned char&&&)
Line
Count
Source
355
42
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
42
  static_assert(std::is_trivially_destructible<T>(),
357
42
                "Symbol types must be trivially destructible");
358
42
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
42
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
42
                "SymbolUnion not aligned enough");
361
42
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
42
         "Not a Symbol");
363
42
364
42
  Symbol Sym = *S;
365
42
366
42
  new (S) T(std::forward<ArgT>(Arg)...);
367
42
368
42
  S->VersionId = Sym.VersionId;
369
42
  S->Visibility = Sym.Visibility;
370
42
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
42
  S->ExportDynamic = Sym.ExportDynamic;
372
42
  S->CanInline = Sym.CanInline;
373
42
  S->Traced = Sym.Traced;
374
42
375
42
  // Print out a log message if --trace-symbol was specified.
376
42
  // This is for debugging.
377
42
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
42
}
LTO.cpp:void lld::elf::replaceSymbol<lld::elf::Undefined, std::nullptr_t, llvm::StringRef, llvm::ELF::$_3, llvm::ELF::$_4, unsigned char&>(lld::elf::Symbol*, std::nullptr_t&&, llvm::StringRef&&, llvm::ELF::$_3&&, llvm::ELF::$_4&&, unsigned char&&&)
Line
Count
Source
355
259
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
259
  static_assert(std::is_trivially_destructible<T>(),
357
259
                "Symbol types must be trivially destructible");
358
259
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
259
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
259
                "SymbolUnion not aligned enough");
361
259
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
259
         "Not a Symbol");
363
259
364
259
  Symbol Sym = *S;
365
259
366
259
  new (S) T(std::forward<ArgT>(Arg)...);
367
259
368
259
  S->VersionId = Sym.VersionId;
369
259
  S->Visibility = Sym.Visibility;
370
259
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
259
  S->ExportDynamic = Sym.ExportDynamic;
372
259
  S->CanInline = Sym.CanInline;
373
259
  S->Traced = Sym.Traced;
374
259
375
259
  // Print out a log message if --trace-symbol was specified.
376
259
  // This is for debugging.
377
259
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
259
}
LinkerScript.cpp:void lld::elf::replaceSymbol<lld::elf::Defined, std::nullptr_t, llvm::StringRef&, llvm::ELF::$_1, unsigned char&, llvm::ELF::$_2, int, int, std::nullptr_t>(lld::elf::Symbol*, std::nullptr_t&&, llvm::StringRef&&&, llvm::ELF::$_1&&, unsigned char&&&, llvm::ELF::$_2&&, int&&, int&&, std::nullptr_t&&)
Line
Count
Source
355
293
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
293
  static_assert(std::is_trivially_destructible<T>(),
357
293
                "Symbol types must be trivially destructible");
358
293
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
293
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
293
                "SymbolUnion not aligned enough");
361
293
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
293
         "Not a Symbol");
363
293
364
293
  Symbol Sym = *S;
365
293
366
293
  new (S) T(std::forward<ArgT>(Arg)...);
367
293
368
293
  S->VersionId = Sym.VersionId;
369
293
  S->Visibility = Sym.Visibility;
370
293
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
293
  S->ExportDynamic = Sym.ExportDynamic;
372
293
  S->CanInline = Sym.CanInline;
373
293
  S->Traced = Sym.Traced;
374
293
375
293
  // Print out a log message if --trace-symbol was specified.
376
293
  // This is for debugging.
377
293
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
293
}
LinkerScript.cpp:void lld::elf::replaceSymbol<lld::elf::Defined, std::nullptr_t, llvm::StringRef&, llvm::ELF::$_1, unsigned char&, llvm::ELF::$_2, unsigned long long&, int, lld::elf::SectionBase*&>(lld::elf::Symbol*, std::nullptr_t&&, llvm::StringRef&&&, llvm::ELF::$_1&&, unsigned char&&&, llvm::ELF::$_2&&, unsigned long long&&&, int&&, lld::elf::SectionBase*&&&)
Line
Count
Source
355
294
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
294
  static_assert(std::is_trivially_destructible<T>(),
357
294
                "Symbol types must be trivially destructible");
358
294
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
294
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
294
                "SymbolUnion not aligned enough");
361
294
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
294
         "Not a Symbol");
363
294
364
294
  Symbol Sym = *S;
365
294
366
294
  new (S) T(std::forward<ArgT>(Arg)...);
367
294
368
294
  S->VersionId = Sym.VersionId;
369
294
  S->Visibility = Sym.Visibility;
370
294
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
294
  S->ExportDynamic = Sym.ExportDynamic;
372
294
  S->CanInline = Sym.CanInline;
373
294
  S->Traced = Sym.Traced;
374
294
375
294
  // Print out a log message if --trace-symbol was specified.
376
294
  // This is for debugging.
377
294
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
294
}
void lld::elf::replaceSymbol<lld::elf::Defined, lld::elf::InputFile*&, llvm::StringRef, unsigned char&, unsigned char&, unsigned char&, unsigned long long&, unsigned long long&, lld::elf::SectionBase*&>(lld::elf::Symbol*, lld::elf::InputFile*&&&, llvm::StringRef&&, unsigned char&&&, unsigned char&&&, unsigned char&&&, unsigned long long&&&, unsigned long long&&&, lld::elf::SectionBase*&&&)
Line
Count
Source
355
109
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
109
  static_assert(std::is_trivially_destructible<T>(),
357
109
                "Symbol types must be trivially destructible");
358
109
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
109
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
109
                "SymbolUnion not aligned enough");
361
109
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
109
         "Not a Symbol");
363
109
364
109
  Symbol Sym = *S;
365
109
366
109
  new (S) T(std::forward<ArgT>(Arg)...);
367
109
368
109
  S->VersionId = Sym.VersionId;
369
109
  S->Visibility = Sym.Visibility;
370
109
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
109
  S->ExportDynamic = Sym.ExportDynamic;
372
109
  S->CanInline = Sym.CanInline;
373
109
  S->Traced = Sym.Traced;
374
109
375
109
  // Print out a log message if --trace-symbol was specified.
376
109
  // This is for debugging.
377
109
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
109
}
void lld::elf::replaceSymbol<lld::elf::Defined, lld::elf::InputFile*, llvm::StringRef&, unsigned char&, unsigned char&, unsigned char&, int, unsigned long long&, lld::elf::BssSection*&>(lld::elf::Symbol*, lld::elf::InputFile*&&, llvm::StringRef&&&, unsigned char&&&, unsigned char&&&, unsigned char&&&, int&&, unsigned long long&&&, lld::elf::BssSection*&&&)
Line
Count
Source
355
100
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
100
  static_assert(std::is_trivially_destructible<T>(),
357
100
                "Symbol types must be trivially destructible");
358
100
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
100
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
100
                "SymbolUnion not aligned enough");
361
100
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
100
         "Not a Symbol");
363
100
364
100
  Symbol Sym = *S;
365
100
366
100
  new (S) T(std::forward<ArgT>(Arg)...);
367
100
368
100
  S->VersionId = Sym.VersionId;
369
100
  S->Visibility = Sym.Visibility;
370
100
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
100
  S->ExportDynamic = Sym.ExportDynamic;
372
100
  S->CanInline = Sym.CanInline;
373
100
  S->Traced = Sym.Traced;
374
100
375
100
  // Print out a log message if --trace-symbol was specified.
376
100
  // This is for debugging.
377
100
  if (S->Traced)
378
5
    printTraceSymbol(S);
379
100
}
void lld::elf::replaceSymbol<lld::elf::Defined, lld::elf::InputFile*&, llvm::StringRef&, unsigned char&, unsigned char&, unsigned char&, unsigned long long&, unsigned long long&, lld::elf::SectionBase*&>(lld::elf::Symbol*, lld::elf::InputFile*&&&, llvm::StringRef&&&, unsigned char&&&, unsigned char&&&, unsigned char&&&, unsigned long long&&&, unsigned long long&&&, lld::elf::SectionBase*&&&)
Line
Count
Source
355
15.5k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
15.5k
  static_assert(std::is_trivially_destructible<T>(),
357
15.5k
                "Symbol types must be trivially destructible");
358
15.5k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
15.5k
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
15.5k
                "SymbolUnion not aligned enough");
361
15.5k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
15.5k
         "Not a Symbol");
363
15.5k
364
15.5k
  Symbol Sym = *S;
365
15.5k
366
15.5k
  new (S) T(std::forward<ArgT>(Arg)...);
367
15.5k
368
15.5k
  S->VersionId = Sym.VersionId;
369
15.5k
  S->Visibility = Sym.Visibility;
370
15.5k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
15.5k
  S->ExportDynamic = Sym.ExportDynamic;
372
15.5k
  S->CanInline = Sym.CanInline;
373
15.5k
  S->Traced = Sym.Traced;
374
15.5k
375
15.5k
  // Print out a log message if --trace-symbol was specified.
376
15.5k
  // This is for debugging.
377
15.5k
  if (S->Traced)
378
20
    printTraceSymbol(S);
379
15.5k
}
void lld::elf::replaceSymbol<lld::elf::Defined, lld::elf::BitcodeFile*, llvm::StringRef&, unsigned char&, unsigned char&, unsigned char&, int, int, std::nullptr_t>(lld::elf::Symbol*, lld::elf::BitcodeFile*&&, llvm::StringRef&&&, unsigned char&&&, unsigned char&&&, unsigned char&&&, int&&, int&&, std::nullptr_t&&)
Line
Count
Source
355
264
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
264
  static_assert(std::is_trivially_destructible<T>(),
357
264
                "Symbol types must be trivially destructible");
358
264
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
264
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
264
                "SymbolUnion not aligned enough");
361
264
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
264
         "Not a Symbol");
363
264
364
264
  Symbol Sym = *S;
365
264
366
264
  new (S) T(std::forward<ArgT>(Arg)...);
367
264
368
264
  S->VersionId = Sym.VersionId;
369
264
  S->Visibility = Sym.Visibility;
370
264
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
264
  S->ExportDynamic = Sym.ExportDynamic;
372
264
  S->CanInline = Sym.CanInline;
373
264
  S->Traced = Sym.Traced;
374
264
375
264
  // Print out a log message if --trace-symbol was specified.
376
264
  // This is for debugging.
377
264
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
264
}
void lld::elf::replaceSymbol<lld::elf::Undefined, lld::elf::InputFile*&, llvm::StringRef&, unsigned char&, unsigned char&, unsigned char&>(lld::elf::Symbol*, lld::elf::InputFile*&&&, llvm::StringRef&&&, unsigned char&&&, unsigned char&&&, unsigned char&&&)
Line
Count
Source
355
1.28k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
1.28k
  static_assert(std::is_trivially_destructible<T>(),
357
1.28k
                "Symbol types must be trivially destructible");
358
1.28k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
1.28k
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
1.28k
                "SymbolUnion not aligned enough");
361
1.28k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
1.28k
         "Not a Symbol");
363
1.28k
364
1.28k
  Symbol Sym = *S;
365
1.28k
366
1.28k
  new (S) T(std::forward<ArgT>(Arg)...);
367
1.28k
368
1.28k
  S->VersionId = Sym.VersionId;
369
1.28k
  S->Visibility = Sym.Visibility;
370
1.28k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
1.28k
  S->ExportDynamic = Sym.ExportDynamic;
372
1.28k
  S->CanInline = Sym.CanInline;
373
1.28k
  S->Traced = Sym.Traced;
374
1.28k
375
1.28k
  // Print out a log message if --trace-symbol was specified.
376
1.28k
  // This is for debugging.
377
1.28k
  if (S->Traced)
378
18
    printTraceSymbol(S);
379
1.28k
}
void lld::elf::replaceSymbol<lld::elf::LazyArchive, lld::elf::InputFile&, lld::elf::Symbol::'unnamed', llvm::object::Archive::Symbol const&>(lld::elf::Symbol*, lld::elf::InputFile&&&, lld::elf::Symbol::'unnamed'&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
355
90
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
90
  static_assert(std::is_trivially_destructible<T>(),
357
90
                "Symbol types must be trivially destructible");
358
90
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
90
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
90
                "SymbolUnion not aligned enough");
361
90
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
90
         "Not a Symbol");
363
90
364
90
  Symbol Sym = *S;
365
90
366
90
  new (S) T(std::forward<ArgT>(Arg)...);
367
90
368
90
  S->VersionId = Sym.VersionId;
369
90
  S->Visibility = Sym.Visibility;
370
90
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
90
  S->ExportDynamic = Sym.ExportDynamic;
372
90
  S->CanInline = Sym.CanInline;
373
90
  S->Traced = Sym.Traced;
374
90
375
90
  // Print out a log message if --trace-symbol was specified.
376
90
  // This is for debugging.
377
90
  if (S->Traced)
378
2
    printTraceSymbol(S);
379
90
}
void lld::elf::replaceSymbol<lld::elf::LazyArchive, lld::elf::InputFile&, unsigned char&, llvm::object::Archive::Symbol const&>(lld::elf::Symbol*, lld::elf::InputFile&&&, unsigned char&&&, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
355
14
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
14
  static_assert(std::is_trivially_destructible<T>(),
357
14
                "Symbol types must be trivially destructible");
358
14
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
14
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
14
                "SymbolUnion not aligned enough");
361
14
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
14
         "Not a Symbol");
363
14
364
14
  Symbol Sym = *S;
365
14
366
14
  new (S) T(std::forward<ArgT>(Arg)...);
367
14
368
14
  S->VersionId = Sym.VersionId;
369
14
  S->Visibility = Sym.Visibility;
370
14
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
14
  S->ExportDynamic = Sym.ExportDynamic;
372
14
  S->CanInline = Sym.CanInline;
373
14
  S->Traced = Sym.Traced;
374
14
375
14
  // Print out a log message if --trace-symbol was specified.
376
14
  // This is for debugging.
377
14
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
14
}
void lld::elf::replaceSymbol<lld::elf::LazyObject, lld::elf::InputFile&, lld::elf::Symbol::'unnamed', llvm::StringRef&>(lld::elf::Symbol*, lld::elf::InputFile&&&, lld::elf::Symbol::'unnamed'&&, llvm::StringRef&&&)
Line
Count
Source
355
20
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
20
  static_assert(std::is_trivially_destructible<T>(),
357
20
                "Symbol types must be trivially destructible");
358
20
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
20
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
20
                "SymbolUnion not aligned enough");
361
20
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
20
         "Not a Symbol");
363
20
364
20
  Symbol Sym = *S;
365
20
366
20
  new (S) T(std::forward<ArgT>(Arg)...);
367
20
368
20
  S->VersionId = Sym.VersionId;
369
20
  S->Visibility = Sym.Visibility;
370
20
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
20
  S->ExportDynamic = Sym.ExportDynamic;
372
20
  S->CanInline = Sym.CanInline;
373
20
  S->Traced = Sym.Traced;
374
20
375
20
  // Print out a log message if --trace-symbol was specified.
376
20
  // This is for debugging.
377
20
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
20
}
void lld::elf::replaceSymbol<lld::elf::LazyObject, lld::elf::InputFile&, unsigned char&, llvm::StringRef&>(lld::elf::Symbol*, lld::elf::InputFile&&&, unsigned char&&&, llvm::StringRef&&&)
Line
Count
Source
355
1
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
1
  static_assert(std::is_trivially_destructible<T>(),
357
1
                "Symbol types must be trivially destructible");
358
1
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
1
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
1
                "SymbolUnion not aligned enough");
361
1
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
1
         "Not a Symbol");
363
1
364
1
  Symbol Sym = *S;
365
1
366
1
  new (S) T(std::forward<ArgT>(Arg)...);
367
1
368
1
  S->VersionId = Sym.VersionId;
369
1
  S->Visibility = Sym.Visibility;
370
1
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
1
  S->ExportDynamic = Sym.ExportDynamic;
372
1
  S->CanInline = Sym.CanInline;
373
1
  S->Traced = Sym.Traced;
374
1
375
1
  // Print out a log message if --trace-symbol was specified.
376
1
  // This is for debugging.
377
1
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
1
}
void lld::elf::replaceSymbol<lld::elf::SharedSymbol, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >&, llvm::StringRef&, unsigned char, unsigned char const&, unsigned char, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> const&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> const&, unsigned int&, unsigned int&>(lld::elf::Symbol*, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >&&&, llvm::StringRef&&&, unsigned char&&, unsigned char const&&&, unsigned char&&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> const&&&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)1, 1ul> const&&&, unsigned int&&&, unsigned int&&&)
Line
Count
Source
355
113
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
113
  static_assert(std::is_trivially_destructible<T>(),
357
113
                "Symbol types must be trivially destructible");
358
113
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
113
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
113
                "SymbolUnion not aligned enough");
361
113
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
113
         "Not a Symbol");
363
113
364
113
  Symbol Sym = *S;
365
113
366
113
  new (S) T(std::forward<ArgT>(Arg)...);
367
113
368
113
  S->VersionId = Sym.VersionId;
369
113
  S->Visibility = Sym.Visibility;
370
113
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
113
  S->ExportDynamic = Sym.ExportDynamic;
372
113
  S->CanInline = Sym.CanInline;
373
113
  S->Traced = Sym.Traced;
374
113
375
113
  // Print out a log message if --trace-symbol was specified.
376
113
  // This is for debugging.
377
113
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
113
}
void lld::elf::replaceSymbol<lld::elf::SharedSymbol, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >&, llvm::StringRef&, unsigned char, unsigned char const&, unsigned char, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> const&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> const&, unsigned int&, unsigned int&>(lld::elf::Symbol*, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >&&&, llvm::StringRef&&&, unsigned char&&, unsigned char const&&&, unsigned char&&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> const&&&, llvm::support::detail::packed_endian_specific_integral<unsigned int, (llvm::support::endianness)0, 1ul> const&&&, unsigned int&&&, unsigned int&&&)
Line
Count
Source
355
100
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
100
  static_assert(std::is_trivially_destructible<T>(),
357
100
                "Symbol types must be trivially destructible");
358
100
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
100
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
100
                "SymbolUnion not aligned enough");
361
100
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
100
         "Not a Symbol");
363
100
364
100
  Symbol Sym = *S;
365
100
366
100
  new (S) T(std::forward<ArgT>(Arg)...);
367
100
368
100
  S->VersionId = Sym.VersionId;
369
100
  S->Visibility = Sym.Visibility;
370
100
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
100
  S->ExportDynamic = Sym.ExportDynamic;
372
100
  S->CanInline = Sym.CanInline;
373
100
  S->Traced = Sym.Traced;
374
100
375
100
  // Print out a log message if --trace-symbol was specified.
376
100
  // This is for debugging.
377
100
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
100
}
void lld::elf::replaceSymbol<lld::elf::SharedSymbol, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >&, llvm::StringRef&, unsigned char, unsigned char const&, unsigned char, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)1, 1ul> const&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)1, 1ul> const&, unsigned int&, unsigned int&>(lld::elf::Symbol*, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >&&&, llvm::StringRef&&&, unsigned char&&, unsigned char const&&&, unsigned char&&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)1, 1ul> const&&&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)1, 1ul> const&&&, unsigned int&&&, unsigned int&&&)
Line
Count
Source
355
491
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
491
  static_assert(std::is_trivially_destructible<T>(),
357
491
                "Symbol types must be trivially destructible");
358
491
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
491
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
491
                "SymbolUnion not aligned enough");
361
491
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
491
         "Not a Symbol");
363
491
364
491
  Symbol Sym = *S;
365
491
366
491
  new (S) T(std::forward<ArgT>(Arg)...);
367
491
368
491
  S->VersionId = Sym.VersionId;
369
491
  S->Visibility = Sym.Visibility;
370
491
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
491
  S->ExportDynamic = Sym.ExportDynamic;
372
491
  S->CanInline = Sym.CanInline;
373
491
  S->Traced = Sym.Traced;
374
491
375
491
  // Print out a log message if --trace-symbol was specified.
376
491
  // This is for debugging.
377
491
  if (S->Traced)
378
9
    printTraceSymbol(S);
379
491
}
void lld::elf::replaceSymbol<lld::elf::SharedSymbol, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >&, llvm::StringRef&, unsigned char, unsigned char const&, unsigned char, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)0, 1ul> const&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)0, 1ul> const&, unsigned int&, unsigned int&>(lld::elf::Symbol*, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >&&&, llvm::StringRef&&&, unsigned char&&, unsigned char const&&&, unsigned char&&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)0, 1ul> const&&&, llvm::support::detail::packed_endian_specific_integral<unsigned long long, (llvm::support::endianness)0, 1ul> const&&&, unsigned int&&&, unsigned int&&&)
Line
Count
Source
355
109
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
356
109
  static_assert(std::is_trivially_destructible<T>(),
357
109
                "Symbol types must be trivially destructible");
358
109
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
359
109
  static_assert(alignof(T) <= alignof(SymbolUnion),
360
109
                "SymbolUnion not aligned enough");
361
109
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362
109
         "Not a Symbol");
363
109
364
109
  Symbol Sym = *S;
365
109
366
109
  new (S) T(std::forward<ArgT>(Arg)...);
367
109
368
109
  S->VersionId = Sym.VersionId;
369
109
  S->Visibility = Sym.Visibility;
370
109
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
371
109
  S->ExportDynamic = Sym.ExportDynamic;
372
109
  S->CanInline = Sym.CanInline;
373
109
  S->Traced = Sym.Traced;
374
109
375
109
  // Print out a log message if --trace-symbol was specified.
376
109
  // This is for debugging.
377
109
  if (S->Traced)
378
0
    printTraceSymbol(S);
379
109
}
380
381
void warnUnorderableSymbol(const Symbol *Sym);
382
} // namespace elf
383
384
std::string toString(const elf::Symbol &B);
385
} // namespace lld
386
387
#endif