Coverage Report

Created: 2018-06-18 20:01

/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
5.03k
  StringRefZ(const char *S) : Data(S), Size(-1) {}
43
19.1k
  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
51.1k
  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.11k
  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
121
122
14.4k
  bool isUndefined() const { return SymbolKind == UndefinedKind; }
123
18.1M
  bool isDefined() const { return SymbolKind == DefinedKind; }
124
449
  bool isShared() const { return SymbolKind == SharedKind; }
125
105k
  bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
126
127
16.8k
  bool isLazy() const {
128
16.8k
    return SymbolKind == LazyArchiveKind || 
SymbolKind == LazyObjectKind16.7k
;
129
16.8k
  }
130
131
  // True if this is an undefined weak symbol.
132
2.24k
  bool isUndefWeak() const { return isWeak() && 
isUndefined()92
; }
133
134
43.3k
  StringRef getName() const {
135
43.3k
    if (NameSize == (uint32_t)-1)
136
2.33k
      NameSize = strlen(NameData);
137
43.3k
    return {NameData, NameSize};
138
43.3k
  }
139
140
  void parseSymbolVersion();
141
142
727
  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
24.1k
        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
35.0k
  bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
193
68.5k
  bool isTls() const { return Type == llvm::ELF::STT_TLS; }
194
193
  bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
195
13.1k
  bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
196
117
  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
19.1k
        Size(Size), Section(Section) {}
207
208
18.1M
  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.13k
      : 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.4k
  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
801
        Alignment(Alignment), Value(Value), Size(Size) {
233
801
    this->VerdefIndex = VerdefIndex;
234
801
    // GNU ifunc is a mechanism to allow user-supplied functions to
235
801
    // resolve PLT slot values at load-time. This is contrary to the
236
801
    // regular symbol resolution scheme in which symbols are resolved just
237
801
    // by name. Using this hook, you can program how symbols are solved
238
801
    // for you program. For example, you can make "memcpy" to be resolved
239
801
    // to a SSE-enabled version of memcpy only when a machine running the
240
801
    // program supports the SSE instruction set.
241
801
    //
242
801
    // Naturally, such symbols should always be called through their PLT
243
801
    // slots. What GNU ifunc symbols point to are resolver functions, and
244
801
    // calling them directly doesn't make sense (unless you are writing a
245
801
    // loader).
246
801
    //
247
801
    // For DSO symbols, we always call them through PLT slots anyway.
248
801
    // So there's no difference between GNU ifunc and regular function
249
801
    // symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
250
801
    if (this->Type == llvm::ELF::STT_GNU_IFUNC)
251
3
      this->Type = llvm::ELF::STT_FUNC;
252
801
  }
253
254
834
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
834
    return *cast<SharedFile<ELFT>>(File);
256
834
  }
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
128
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
128
    return *cast<SharedFile<ELFT>>(File);
256
128
  }
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
565
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
565
    return *cast<SharedFile<ELFT>>(File);
256
565
  }
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
36
  template <class ELFT> SharedFile<ELFT> &getFile() const {
255
36
    return *cast<SharedFile<ELFT>>(File);
256
36
  }
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
100
        Sym(S) {}
285
286
36
  static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
287
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 Symbol {
297
public:
298
  LazyObject(InputFile &File, uint8_t Type, StringRef Name)
299
      : Symbol(LazyObjectKind, &File, Name, llvm::ELF::STB_GLOBAL,
300
17
               llvm::ELF::STV_DEFAULT, Type) {}
301
302
0
  static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
303
};
304
305
// Some linker-generated symbols need to be created as
306
// Defined symbols.
307
struct ElfSym {
308
  // __bss_start
309
  static Defined *Bss;
310
311
  // etext and _etext
312
  static Defined *Etext1;
313
  static Defined *Etext2;
314
315
  // edata and _edata
316
  static Defined *Edata1;
317
  static Defined *Edata2;
318
319
  // end and _end
320
  static Defined *End1;
321
  static Defined *End2;
322
323
  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
324
  // be at some offset from the base of the .got section, usually 0 or
325
  // the end of the .got.
326
  static Defined *GlobalOffsetTable;
327
328
  // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
329
  static Defined *MipsGp;
330
  static Defined *MipsGpDisp;
331
  static Defined *MipsLocalGp;
332
333
  // __rela_iplt_end or __rel_iplt_end
334
  static Defined *RelaIpltEnd;
335
};
336
337
// A buffer class that is large enough to hold any Symbol-derived
338
// object. We allocate memory using this class and instantiate a symbol
339
// using the placement new.
340
union SymbolUnion {
341
  alignas(Defined) char A[sizeof(Defined)];
342
  alignas(Undefined) char C[sizeof(Undefined)];
343
  alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
344
  alignas(LazyArchive) char E[sizeof(LazyArchive)];
345
  alignas(LazyObject) char F[sizeof(LazyObject)];
346
};
347
348
void printTraceSymbol(Symbol *Sym);
349
350
template <typename T, typename... ArgT>
351
18.6k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
18.6k
  static_assert(std::is_trivially_destructible<T>(),
353
18.6k
                "Symbol types must be trivially destructible");
354
18.6k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
18.6k
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
18.6k
                "SymbolUnion not aligned enough");
357
18.6k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
18.6k
         "Not a Symbol");
359
18.6k
360
18.6k
  Symbol Sym = *S;
361
18.6k
362
18.6k
  new (S) T(std::forward<ArgT>(Arg)...);
363
18.6k
364
18.6k
  S->VersionId = Sym.VersionId;
365
18.6k
  S->Visibility = Sym.Visibility;
366
18.6k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
18.6k
  S->ExportDynamic = Sym.ExportDynamic;
368
18.6k
  S->CanInline = Sym.CanInline;
369
18.6k
  S->Traced = Sym.Traced;
370
18.6k
371
18.6k
  // Print out a log message if --trace-symbol was specified.
372
18.6k
  // This is for debugging.
373
18.6k
  if (S->Traced)
374
54
    printTraceSymbol(S);
375
18.6k
}
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
351
42
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
42
  static_assert(std::is_trivially_destructible<T>(),
353
42
                "Symbol types must be trivially destructible");
354
42
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
42
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
42
                "SymbolUnion not aligned enough");
357
42
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
42
         "Not a Symbol");
359
42
360
42
  Symbol Sym = *S;
361
42
362
42
  new (S) T(std::forward<ArgT>(Arg)...);
363
42
364
42
  S->VersionId = Sym.VersionId;
365
42
  S->Visibility = Sym.Visibility;
366
42
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
42
  S->ExportDynamic = Sym.ExportDynamic;
368
42
  S->CanInline = Sym.CanInline;
369
42
  S->Traced = Sym.Traced;
370
42
371
42
  // Print out a log message if --trace-symbol was specified.
372
42
  // This is for debugging.
373
42
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
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
351
244
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
244
  static_assert(std::is_trivially_destructible<T>(),
353
244
                "Symbol types must be trivially destructible");
354
244
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
244
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
244
                "SymbolUnion not aligned enough");
357
244
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
244
         "Not a Symbol");
359
244
360
244
  Symbol Sym = *S;
361
244
362
244
  new (S) T(std::forward<ArgT>(Arg)...);
363
244
364
244
  S->VersionId = Sym.VersionId;
365
244
  S->Visibility = Sym.Visibility;
366
244
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
244
  S->ExportDynamic = Sym.ExportDynamic;
368
244
  S->CanInline = Sym.CanInline;
369
244
  S->Traced = Sym.Traced;
370
244
371
244
  // Print out a log message if --trace-symbol was specified.
372
244
  // This is for debugging.
373
244
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
244
}
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
351
270
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
270
  static_assert(std::is_trivially_destructible<T>(),
353
270
                "Symbol types must be trivially destructible");
354
270
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
270
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
270
                "SymbolUnion not aligned enough");
357
270
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
270
         "Not a Symbol");
359
270
360
270
  Symbol Sym = *S;
361
270
362
270
  new (S) T(std::forward<ArgT>(Arg)...);
363
270
364
270
  S->VersionId = Sym.VersionId;
365
270
  S->Visibility = Sym.Visibility;
366
270
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
270
  S->ExportDynamic = Sym.ExportDynamic;
368
270
  S->CanInline = Sym.CanInline;
369
270
  S->Traced = Sym.Traced;
370
270
371
270
  // Print out a log message if --trace-symbol was specified.
372
270
  // This is for debugging.
373
270
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
270
}
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
351
271
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
271
  static_assert(std::is_trivially_destructible<T>(),
353
271
                "Symbol types must be trivially destructible");
354
271
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
271
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
271
                "SymbolUnion not aligned enough");
357
271
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
271
         "Not a Symbol");
359
271
360
271
  Symbol Sym = *S;
361
271
362
271
  new (S) T(std::forward<ArgT>(Arg)...);
363
271
364
271
  S->VersionId = Sym.VersionId;
365
271
  S->Visibility = Sym.Visibility;
366
271
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
271
  S->ExportDynamic = Sym.ExportDynamic;
368
271
  S->CanInline = Sym.CanInline;
369
271
  S->Traced = Sym.Traced;
370
271
371
271
  // Print out a log message if --trace-symbol was specified.
372
271
  // This is for debugging.
373
271
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
271
}
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
351
108
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
108
  static_assert(std::is_trivially_destructible<T>(),
353
108
                "Symbol types must be trivially destructible");
354
108
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
108
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
108
                "SymbolUnion not aligned enough");
357
108
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
108
         "Not a Symbol");
359
108
360
108
  Symbol Sym = *S;
361
108
362
108
  new (S) T(std::forward<ArgT>(Arg)...);
363
108
364
108
  S->VersionId = Sym.VersionId;
365
108
  S->Visibility = Sym.Visibility;
366
108
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
108
  S->ExportDynamic = Sym.ExportDynamic;
368
108
  S->CanInline = Sym.CanInline;
369
108
  S->Traced = Sym.Traced;
370
108
371
108
  // Print out a log message if --trace-symbol was specified.
372
108
  // This is for debugging.
373
108
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
108
}
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
351
100
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
100
  static_assert(std::is_trivially_destructible<T>(),
353
100
                "Symbol types must be trivially destructible");
354
100
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
100
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
100
                "SymbolUnion not aligned enough");
357
100
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
100
         "Not a Symbol");
359
100
360
100
  Symbol Sym = *S;
361
100
362
100
  new (S) T(std::forward<ArgT>(Arg)...);
363
100
364
100
  S->VersionId = Sym.VersionId;
365
100
  S->Visibility = Sym.Visibility;
366
100
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
100
  S->ExportDynamic = Sym.ExportDynamic;
368
100
  S->CanInline = Sym.CanInline;
369
100
  S->Traced = Sym.Traced;
370
100
371
100
  // Print out a log message if --trace-symbol was specified.
372
100
  // This is for debugging.
373
100
  if (S->Traced)
374
5
    printTraceSymbol(S);
375
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
351
15.2k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
15.2k
  static_assert(std::is_trivially_destructible<T>(),
353
15.2k
                "Symbol types must be trivially destructible");
354
15.2k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
15.2k
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
15.2k
                "SymbolUnion not aligned enough");
357
15.2k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
15.2k
         "Not a Symbol");
359
15.2k
360
15.2k
  Symbol Sym = *S;
361
15.2k
362
15.2k
  new (S) T(std::forward<ArgT>(Arg)...);
363
15.2k
364
15.2k
  S->VersionId = Sym.VersionId;
365
15.2k
  S->Visibility = Sym.Visibility;
366
15.2k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
15.2k
  S->ExportDynamic = Sym.ExportDynamic;
368
15.2k
  S->CanInline = Sym.CanInline;
369
15.2k
  S->Traced = Sym.Traced;
370
15.2k
371
15.2k
  // Print out a log message if --trace-symbol was specified.
372
15.2k
  // This is for debugging.
373
15.2k
  if (S->Traced)
374
20
    printTraceSymbol(S);
375
15.2k
}
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
351
249
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
249
  static_assert(std::is_trivially_destructible<T>(),
353
249
                "Symbol types must be trivially destructible");
354
249
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
249
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
249
                "SymbolUnion not aligned enough");
357
249
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
249
         "Not a Symbol");
359
249
360
249
  Symbol Sym = *S;
361
249
362
249
  new (S) T(std::forward<ArgT>(Arg)...);
363
249
364
249
  S->VersionId = Sym.VersionId;
365
249
  S->Visibility = Sym.Visibility;
366
249
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
249
  S->ExportDynamic = Sym.ExportDynamic;
368
249
  S->CanInline = Sym.CanInline;
369
249
  S->Traced = Sym.Traced;
370
249
371
249
  // Print out a log message if --trace-symbol was specified.
372
249
  // This is for debugging.
373
249
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
249
}
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
351
1.22k
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
1.22k
  static_assert(std::is_trivially_destructible<T>(),
353
1.22k
                "Symbol types must be trivially destructible");
354
1.22k
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
1.22k
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
1.22k
                "SymbolUnion not aligned enough");
357
1.22k
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
1.22k
         "Not a Symbol");
359
1.22k
360
1.22k
  Symbol Sym = *S;
361
1.22k
362
1.22k
  new (S) T(std::forward<ArgT>(Arg)...);
363
1.22k
364
1.22k
  S->VersionId = Sym.VersionId;
365
1.22k
  S->Visibility = Sym.Visibility;
366
1.22k
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
1.22k
  S->ExportDynamic = Sym.ExportDynamic;
368
1.22k
  S->CanInline = Sym.CanInline;
369
1.22k
  S->Traced = Sym.Traced;
370
1.22k
371
1.22k
  // Print out a log message if --trace-symbol was specified.
372
1.22k
  // This is for debugging.
373
1.22k
  if (S->Traced)
374
18
    printTraceSymbol(S);
375
1.22k
}
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
351
86
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
86
  static_assert(std::is_trivially_destructible<T>(),
353
86
                "Symbol types must be trivially destructible");
354
86
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
86
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
86
                "SymbolUnion not aligned enough");
357
86
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
86
         "Not a Symbol");
359
86
360
86
  Symbol Sym = *S;
361
86
362
86
  new (S) T(std::forward<ArgT>(Arg)...);
363
86
364
86
  S->VersionId = Sym.VersionId;
365
86
  S->Visibility = Sym.Visibility;
366
86
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
86
  S->ExportDynamic = Sym.ExportDynamic;
368
86
  S->CanInline = Sym.CanInline;
369
86
  S->Traced = Sym.Traced;
370
86
371
86
  // Print out a log message if --trace-symbol was specified.
372
86
  // This is for debugging.
373
86
  if (S->Traced)
374
2
    printTraceSymbol(S);
375
86
}
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
351
14
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
14
  static_assert(std::is_trivially_destructible<T>(),
353
14
                "Symbol types must be trivially destructible");
354
14
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
14
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
14
                "SymbolUnion not aligned enough");
357
14
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
14
         "Not a Symbol");
359
14
360
14
  Symbol Sym = *S;
361
14
362
14
  new (S) T(std::forward<ArgT>(Arg)...);
363
14
364
14
  S->VersionId = Sym.VersionId;
365
14
  S->Visibility = Sym.Visibility;
366
14
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
14
  S->ExportDynamic = Sym.ExportDynamic;
368
14
  S->CanInline = Sym.CanInline;
369
14
  S->Traced = Sym.Traced;
370
14
371
14
  // Print out a log message if --trace-symbol was specified.
372
14
  // This is for debugging.
373
14
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
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
351
16
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
16
  static_assert(std::is_trivially_destructible<T>(),
353
16
                "Symbol types must be trivially destructible");
354
16
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
16
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
16
                "SymbolUnion not aligned enough");
357
16
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
16
         "Not a Symbol");
359
16
360
16
  Symbol Sym = *S;
361
16
362
16
  new (S) T(std::forward<ArgT>(Arg)...);
363
16
364
16
  S->VersionId = Sym.VersionId;
365
16
  S->Visibility = Sym.Visibility;
366
16
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
16
  S->ExportDynamic = Sym.ExportDynamic;
368
16
  S->CanInline = Sym.CanInline;
369
16
  S->Traced = Sym.Traced;
370
16
371
16
  // Print out a log message if --trace-symbol was specified.
372
16
  // This is for debugging.
373
16
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
16
}
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
351
1
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
1
  static_assert(std::is_trivially_destructible<T>(),
353
1
                "Symbol types must be trivially destructible");
354
1
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
1
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
1
                "SymbolUnion not aligned enough");
357
1
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
1
         "Not a Symbol");
359
1
360
1
  Symbol Sym = *S;
361
1
362
1
  new (S) T(std::forward<ArgT>(Arg)...);
363
1
364
1
  S->VersionId = Sym.VersionId;
365
1
  S->Visibility = Sym.Visibility;
366
1
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
1
  S->ExportDynamic = Sym.ExportDynamic;
368
1
  S->CanInline = Sym.CanInline;
369
1
  S->Traced = Sym.Traced;
370
1
371
1
  // Print out a log message if --trace-symbol was specified.
372
1
  // This is for debugging.
373
1
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
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
351
109
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
109
  static_assert(std::is_trivially_destructible<T>(),
353
109
                "Symbol types must be trivially destructible");
354
109
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
109
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
109
                "SymbolUnion not aligned enough");
357
109
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
109
         "Not a Symbol");
359
109
360
109
  Symbol Sym = *S;
361
109
362
109
  new (S) T(std::forward<ArgT>(Arg)...);
363
109
364
109
  S->VersionId = Sym.VersionId;
365
109
  S->Visibility = Sym.Visibility;
366
109
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
109
  S->ExportDynamic = Sym.ExportDynamic;
368
109
  S->CanInline = Sym.CanInline;
369
109
  S->Traced = Sym.Traced;
370
109
371
109
  // Print out a log message if --trace-symbol was specified.
372
109
  // This is for debugging.
373
109
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
109
}
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
351
100
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
100
  static_assert(std::is_trivially_destructible<T>(),
353
100
                "Symbol types must be trivially destructible");
354
100
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
100
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
100
                "SymbolUnion not aligned enough");
357
100
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
100
         "Not a Symbol");
359
100
360
100
  Symbol Sym = *S;
361
100
362
100
  new (S) T(std::forward<ArgT>(Arg)...);
363
100
364
100
  S->VersionId = Sym.VersionId;
365
100
  S->Visibility = Sym.Visibility;
366
100
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
100
  S->ExportDynamic = Sym.ExportDynamic;
368
100
  S->CanInline = Sym.CanInline;
369
100
  S->Traced = Sym.Traced;
370
100
371
100
  // Print out a log message if --trace-symbol was specified.
372
100
  // This is for debugging.
373
100
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
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
351
481
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
481
  static_assert(std::is_trivially_destructible<T>(),
353
481
                "Symbol types must be trivially destructible");
354
481
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
481
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
481
                "SymbolUnion not aligned enough");
357
481
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
481
         "Not a Symbol");
359
481
360
481
  Symbol Sym = *S;
361
481
362
481
  new (S) T(std::forward<ArgT>(Arg)...);
363
481
364
481
  S->VersionId = Sym.VersionId;
365
481
  S->Visibility = Sym.Visibility;
366
481
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
481
  S->ExportDynamic = Sym.ExportDynamic;
368
481
  S->CanInline = Sym.CanInline;
369
481
  S->Traced = Sym.Traced;
370
481
371
481
  // Print out a log message if --trace-symbol was specified.
372
481
  // This is for debugging.
373
481
  if (S->Traced)
374
9
    printTraceSymbol(S);
375
481
}
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
351
111
void replaceSymbol(Symbol *S, ArgT &&... Arg) {
352
111
  static_assert(std::is_trivially_destructible<T>(),
353
111
                "Symbol types must be trivially destructible");
354
111
  static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355
111
  static_assert(alignof(T) <= alignof(SymbolUnion),
356
111
                "SymbolUnion not aligned enough");
357
111
  assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
358
111
         "Not a Symbol");
359
111
360
111
  Symbol Sym = *S;
361
111
362
111
  new (S) T(std::forward<ArgT>(Arg)...);
363
111
364
111
  S->VersionId = Sym.VersionId;
365
111
  S->Visibility = Sym.Visibility;
366
111
  S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367
111
  S->ExportDynamic = Sym.ExportDynamic;
368
111
  S->CanInline = Sym.CanInline;
369
111
  S->Traced = Sym.Traced;
370
111
371
111
  // Print out a log message if --trace-symbol was specified.
372
111
  // This is for debugging.
373
111
  if (S->Traced)
374
0
    printTraceSymbol(S);
375
111
}
376
377
void warnUnorderableSymbol(const Symbol *Sym);
378
} // namespace elf
379
380
std::string toString(const elf::Symbol &B);
381
} // namespace lld
382
383
#endif