Coverage Report

Created: 2019-01-18 03:29

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