Coverage Report

Created: 2018-06-18 20:01

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/SymbolTable.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- SymbolTable.cpp ----------------------------------------------------===//
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
// Symbol table is a bag of all known symbols. We put all symbols of
11
// all input files to the symbol table. The symbol table is basically
12
// a hash table with the logic to resolve symbol name conflicts using
13
// the symbol types.
14
//
15
//===----------------------------------------------------------------------===//
16
17
#include "SymbolTable.h"
18
#include "Config.h"
19
#include "LinkerScript.h"
20
#include "Symbols.h"
21
#include "SyntheticSections.h"
22
#include "lld/Common/ErrorHandler.h"
23
#include "lld/Common/Memory.h"
24
#include "lld/Common/Strings.h"
25
#include "llvm/ADT/STLExtras.h"
26
27
using namespace llvm;
28
using namespace llvm::object;
29
using namespace llvm::ELF;
30
31
using namespace lld;
32
using namespace lld::elf;
33
34
SymbolTable *elf::Symtab;
35
36
9
static InputFile *getFirstElf() {
37
9
  if (!ObjectFiles.empty())
38
7
    return ObjectFiles[0];
39
2
  if (!SharedFiles.empty())
40
2
    return SharedFiles[0];
41
0
  return nullptr;
42
0
}
43
44
// All input object files must be for the same architecture
45
// (e.g. it does not make sense to link x86 object files with
46
// MIPS object files.) This function checks for that error.
47
3.12k
static bool isCompatible(InputFile *F) {
48
3.12k
  if (!F->isElf() && 
!isa<BitcodeFile>(F)350
)
49
128
    return true;
50
2.99k
51
2.99k
  if (F->EKind == Config->EKind && 
F->EMachine == Config->EMachine2.98k
) {
52
2.98k
    if (Config->EMachine != EM_MIPS)
53
2.72k
      return true;
54
262
    if (isMipsN32Abi(F) == Config->MipsN32Abi)
55
260
      return true;
56
15
  }
57
15
58
15
  if (!Config->Emulation.empty())
59
6
    error(toString(F) + " is incompatible with " + Config->Emulation);
60
9
  else
61
9
    error(toString(F) + " is incompatible with " + toString(getFirstElf()));
62
15
  return false;
63
15
}
64
65
// Add symbols in File to the symbol table.
66
3.12k
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67
3.12k
  if (!isCompatible(File))
68
15
    return;
69
3.11k
70
3.11k
  // Binary file
71
3.11k
  if (auto *F = dyn_cast<BinaryFile>(File)) {
72
5
    BinaryFiles.push_back(F);
73
5
    F->parse();
74
5
    return;
75
5
  }
76
3.10k
77
3.10k
  // .a file
78
3.10k
  if (auto *F = dyn_cast<ArchiveFile>(File)) {
79
98
    F->parse<ELFT>();
80
98
    return;
81
98
  }
82
3.00k
83
3.00k
  // Lazy object file
84
3.00k
  if (auto *F = dyn_cast<LazyObjFile>(File)) {
85
25
    LazyObjFiles.push_back(F);
86
25
    F->parse<ELFT>();
87
25
    return;
88
25
  }
89
2.98k
90
2.98k
  if (Config->Trace)
91
7
    message(toString(File));
92
2.98k
93
2.98k
  // .so file
94
2.98k
  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95
327
    // DSOs are uniquified not by filename but by soname.
96
327
    F->parseSoName();
97
327
    if (errorCount() || 
!SoNames.insert(F->SoName).second325
)
98
4
      return;
99
323
    SharedFiles.push_back(F);
100
323
    F->parseRest();
101
323
    return;
102
323
  }
103
2.65k
104
2.65k
  // LLVM bitcode file
105
2.65k
  if (auto *F = dyn_cast<BitcodeFile>(File)) {
106
221
    BitcodeFiles.push_back(F);
107
221
    F->parse<ELFT>(ComdatGroups);
108
221
    return;
109
221
  }
110
2.43k
111
2.43k
  // Regular object file
112
2.43k
  ObjectFiles.push_back(File);
113
2.43k
  cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
114
2.43k
}
void lld::elf::SymbolTable::addFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::InputFile*)
Line
Count
Source
66
365
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67
365
  if (!isCompatible(File))
68
7
    return;
69
358
70
358
  // Binary file
71
358
  if (auto *F = dyn_cast<BinaryFile>(File)) {
72
0
    BinaryFiles.push_back(F);
73
0
    F->parse();
74
0
    return;
75
0
  }
76
358
77
358
  // .a file
78
358
  if (auto *F = dyn_cast<ArchiveFile>(File)) {
79
3
    F->parse<ELFT>();
80
3
    return;
81
3
  }
82
355
83
355
  // Lazy object file
84
355
  if (auto *F = dyn_cast<LazyObjFile>(File)) {
85
0
    LazyObjFiles.push_back(F);
86
0
    F->parse<ELFT>();
87
0
    return;
88
0
  }
89
355
90
355
  if (Config->Trace)
91
0
    message(toString(File));
92
355
93
355
  // .so file
94
355
  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95
56
    // DSOs are uniquified not by filename but by soname.
96
56
    F->parseSoName();
97
56
    if (errorCount() || 
!SoNames.insert(F->SoName).second55
)
98
2
      return;
99
54
    SharedFiles.push_back(F);
100
54
    F->parseRest();
101
54
    return;
102
54
  }
103
299
104
299
  // LLVM bitcode file
105
299
  if (auto *F = dyn_cast<BitcodeFile>(File)) {
106
0
    BitcodeFiles.push_back(F);
107
0
    F->parse<ELFT>(ComdatGroups);
108
0
    return;
109
0
  }
110
299
111
299
  // Regular object file
112
299
  ObjectFiles.push_back(File);
113
299
  cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
114
299
}
void lld::elf::SymbolTable::addFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::InputFile*)
Line
Count
Source
66
184
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67
184
  if (!isCompatible(File))
68
2
    return;
69
182
70
182
  // Binary file
71
182
  if (auto *F = dyn_cast<BinaryFile>(File)) {
72
0
    BinaryFiles.push_back(F);
73
0
    F->parse();
74
0
    return;
75
0
  }
76
182
77
182
  // .a file
78
182
  if (auto *F = dyn_cast<ArchiveFile>(File)) {
79
0
    F->parse<ELFT>();
80
0
    return;
81
0
  }
82
182
83
182
  // Lazy object file
84
182
  if (auto *F = dyn_cast<LazyObjFile>(File)) {
85
0
    LazyObjFiles.push_back(F);
86
0
    F->parse<ELFT>();
87
0
    return;
88
0
  }
89
182
90
182
  if (Config->Trace)
91
0
    message(toString(File));
92
182
93
182
  // .so file
94
182
  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95
24
    // DSOs are uniquified not by filename but by soname.
96
24
    F->parseSoName();
97
24
    if (errorCount() || !SoNames.insert(F->SoName).second)
98
0
      return;
99
24
    SharedFiles.push_back(F);
100
24
    F->parseRest();
101
24
    return;
102
24
  }
103
158
104
158
  // LLVM bitcode file
105
158
  if (auto *F = dyn_cast<BitcodeFile>(File)) {
106
0
    BitcodeFiles.push_back(F);
107
0
    F->parse<ELFT>(ComdatGroups);
108
0
    return;
109
0
  }
110
158
111
158
  // Regular object file
112
158
  ObjectFiles.push_back(File);
113
158
  cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
114
158
}
void lld::elf::SymbolTable::addFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::InputFile*)
Line
Count
Source
66
2.46k
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67
2.46k
  if (!isCompatible(File))
68
3
    return;
69
2.46k
70
2.46k
  // Binary file
71
2.46k
  if (auto *F = dyn_cast<BinaryFile>(File)) {
72
5
    BinaryFiles.push_back(F);
73
5
    F->parse();
74
5
    return;
75
5
  }
76
2.46k
77
2.46k
  // .a file
78
2.46k
  if (auto *F = dyn_cast<ArchiveFile>(File)) {
79
94
    F->parse<ELFT>();
80
94
    return;
81
94
  }
82
2.36k
83
2.36k
  // Lazy object file
84
2.36k
  if (auto *F = dyn_cast<LazyObjFile>(File)) {
85
25
    LazyObjFiles.push_back(F);
86
25
    F->parse<ELFT>();
87
25
    return;
88
25
  }
89
2.34k
90
2.34k
  if (Config->Trace)
91
7
    message(toString(File));
92
2.34k
93
2.34k
  // .so file
94
2.34k
  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95
230
    // DSOs are uniquified not by filename but by soname.
96
230
    F->parseSoName();
97
230
    if (errorCount() || 
!SoNames.insert(F->SoName).second229
)
98
2
      return;
99
228
    SharedFiles.push_back(F);
100
228
    F->parseRest();
101
228
    return;
102
228
  }
103
2.11k
104
2.11k
  // LLVM bitcode file
105
2.11k
  if (auto *F = dyn_cast<BitcodeFile>(File)) {
106
221
    BitcodeFiles.push_back(F);
107
221
    F->parse<ELFT>(ComdatGroups);
108
221
    return;
109
221
  }
110
1.89k
111
1.89k
  // Regular object file
112
1.89k
  ObjectFiles.push_back(File);
113
1.89k
  cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
114
1.89k
}
void lld::elf::SymbolTable::addFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::InputFile*)
Line
Count
Source
66
108
template <class ELFT> void SymbolTable::addFile(InputFile *File) {
67
108
  if (!isCompatible(File))
68
3
    return;
69
105
70
105
  // Binary file
71
105
  if (auto *F = dyn_cast<BinaryFile>(File)) {
72
0
    BinaryFiles.push_back(F);
73
0
    F->parse();
74
0
    return;
75
0
  }
76
105
77
105
  // .a file
78
105
  if (auto *F = dyn_cast<ArchiveFile>(File)) {
79
1
    F->parse<ELFT>();
80
1
    return;
81
1
  }
82
104
83
104
  // Lazy object file
84
104
  if (auto *F = dyn_cast<LazyObjFile>(File)) {
85
0
    LazyObjFiles.push_back(F);
86
0
    F->parse<ELFT>();
87
0
    return;
88
0
  }
89
104
90
104
  if (Config->Trace)
91
0
    message(toString(File));
92
104
93
104
  // .so file
94
104
  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
95
17
    // DSOs are uniquified not by filename but by soname.
96
17
    F->parseSoName();
97
17
    if (errorCount() || !SoNames.insert(F->SoName).second)
98
0
      return;
99
17
    SharedFiles.push_back(F);
100
17
    F->parseRest();
101
17
    return;
102
17
  }
103
87
104
87
  // LLVM bitcode file
105
87
  if (auto *F = dyn_cast<BitcodeFile>(File)) {
106
0
    BitcodeFiles.push_back(F);
107
0
    F->parse<ELFT>(ComdatGroups);
108
0
    return;
109
0
  }
110
87
111
87
  // Regular object file
112
87
  ObjectFiles.push_back(File);
113
87
  cast<ObjFile<ELFT>>(File)->parse(ComdatGroups);
114
87
}
115
116
// This function is where all the optimizations of link-time
117
// optimization happens. When LTO is in use, some input files are
118
// not in native object file format but in the LLVM bitcode format.
119
// This function compiles bitcode files into a few big native files
120
// using LLVM functions and replaces bitcode symbols with the results.
121
// Because all bitcode files that the program consists of are passed
122
// to the compiler at once, it can do whole-program optimization.
123
2.15k
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
124
2.15k
  if (BitcodeFiles.empty())
125
2.00k
    return;
126
149
127
149
  // Compile bitcode files and replace bitcode symbols.
128
149
  LTO.reset(new BitcodeCompiler);
129
149
  for (BitcodeFile *F : BitcodeFiles)
130
219
    LTO->add(*F);
131
149
132
184
  for (InputFile *File : LTO->compile()) {
133
184
    DenseSet<CachedHashStringRef> DummyGroups;
134
184
    auto *Obj = cast<ObjFile<ELFT>>(File);
135
184
    Obj->parse(DummyGroups);
136
184
    for (Symbol *Sym : Obj->getGlobalSymbols())
137
231
      Sym->parseSymbolVersion();
138
184
    ObjectFiles.push_back(File);
139
184
  }
140
149
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
123
256
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
124
256
  if (BitcodeFiles.empty())
125
256
    return;
126
0
127
0
  // Compile bitcode files and replace bitcode symbols.
128
0
  LTO.reset(new BitcodeCompiler);
129
0
  for (BitcodeFile *F : BitcodeFiles)
130
0
    LTO->add(*F);
131
0
132
0
  for (InputFile *File : LTO->compile()) {
133
0
    DenseSet<CachedHashStringRef> DummyGroups;
134
0
    auto *Obj = cast<ObjFile<ELFT>>(File);
135
0
    Obj->parse(DummyGroups);
136
0
    for (Symbol *Sym : Obj->getGlobalSymbols())
137
0
      Sym->parseSymbolVersion();
138
0
    ObjectFiles.push_back(File);
139
0
  }
140
0
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
123
119
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
124
119
  if (BitcodeFiles.empty())
125
119
    return;
126
0
127
0
  // Compile bitcode files and replace bitcode symbols.
128
0
  LTO.reset(new BitcodeCompiler);
129
0
  for (BitcodeFile *F : BitcodeFiles)
130
0
    LTO->add(*F);
131
0
132
0
  for (InputFile *File : LTO->compile()) {
133
0
    DenseSet<CachedHashStringRef> DummyGroups;
134
0
    auto *Obj = cast<ObjFile<ELFT>>(File);
135
0
    Obj->parse(DummyGroups);
136
0
    for (Symbol *Sym : Obj->getGlobalSymbols())
137
0
      Sym->parseSymbolVersion();
138
0
    ObjectFiles.push_back(File);
139
0
  }
140
0
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
123
1.70k
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
124
1.70k
  if (BitcodeFiles.empty())
125
1.55k
    return;
126
149
127
149
  // Compile bitcode files and replace bitcode symbols.
128
149
  LTO.reset(new BitcodeCompiler);
129
149
  for (BitcodeFile *F : BitcodeFiles)
130
219
    LTO->add(*F);
131
149
132
184
  for (InputFile *File : LTO->compile()) {
133
184
    DenseSet<CachedHashStringRef> DummyGroups;
134
184
    auto *Obj = cast<ObjFile<ELFT>>(File);
135
184
    Obj->parse(DummyGroups);
136
184
    for (Symbol *Sym : Obj->getGlobalSymbols())
137
231
      Sym->parseSymbolVersion();
138
184
    ObjectFiles.push_back(File);
139
184
  }
140
149
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
123
76
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
124
76
  if (BitcodeFiles.empty())
125
76
    return;
126
0
127
0
  // Compile bitcode files and replace bitcode symbols.
128
0
  LTO.reset(new BitcodeCompiler);
129
0
  for (BitcodeFile *F : BitcodeFiles)
130
0
    LTO->add(*F);
131
0
132
0
  for (InputFile *File : LTO->compile()) {
133
0
    DenseSet<CachedHashStringRef> DummyGroups;
134
0
    auto *Obj = cast<ObjFile<ELFT>>(File);
135
0
    Obj->parse(DummyGroups);
136
0
    for (Symbol *Sym : Obj->getGlobalSymbols())
137
0
      Sym->parseSymbolVersion();
138
0
    ObjectFiles.push_back(File);
139
0
  }
140
0
}
141
142
Defined *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility,
143
172
                                  uint8_t Binding) {
144
172
  Symbol *Sym =
145
172
      addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr);
146
172
  return cast<Defined>(Sym);
147
172
}
148
149
// Set a flag for --trace-symbol so that we can print out a log message
150
// if a new symbol with the same name is inserted into the symbol table.
151
33
void SymbolTable::trace(StringRef Name) {
152
33
  SymMap.insert({CachedHashStringRef(Name), -1});
153
33
}
154
155
// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
156
// Used to implement --wrap.
157
11
template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
158
11
  Symbol *Sym = find(Name);
159
11
  if (!Sym)
160
2
    return;
161
9
  Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
162
9
  Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
163
9
  WrappedSymbols.push_back({Sym, Real, Wrap});
164
9
165
9
  // We want to tell LTO not to inline symbols to be overwritten
166
9
  // because LTO doesn't know the final symbol contents after renaming.
167
9
  Real->CanInline = false;
168
9
  Sym->CanInline = false;
169
9
170
9
  // Tell LTO not to eliminate these symbols.
171
9
  Sym->IsUsedInRegularObj = true;
172
9
  Wrap->IsUsedInRegularObj = true;
173
9
}
Unexecuted instantiation: void lld::elf::SymbolTable::addSymbolWrap<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef)
Unexecuted instantiation: void lld::elf::SymbolTable::addSymbolWrap<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef)
void lld::elf::SymbolTable::addSymbolWrap<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef)
Line
Count
Source
157
11
template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
158
11
  Symbol *Sym = find(Name);
159
11
  if (!Sym)
160
2
    return;
161
9
  Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
162
9
  Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
163
9
  WrappedSymbols.push_back({Sym, Real, Wrap});
164
9
165
9
  // We want to tell LTO not to inline symbols to be overwritten
166
9
  // because LTO doesn't know the final symbol contents after renaming.
167
9
  Real->CanInline = false;
168
9
  Sym->CanInline = false;
169
9
170
9
  // Tell LTO not to eliminate these symbols.
171
9
  Sym->IsUsedInRegularObj = true;
172
9
  Wrap->IsUsedInRegularObj = true;
173
9
}
Unexecuted instantiation: void lld::elf::SymbolTable::addSymbolWrap<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef)
174
175
// Apply symbol renames created by -wrap. The renames are created
176
// before LTO in addSymbolWrap() to have a chance to inform LTO (if
177
// LTO is running) not to include these symbols in IPO. Now that the
178
// symbols are finalized, we can perform the replacement.
179
2.13k
void SymbolTable::applySymbolWrap() {
180
2.13k
  // This function rotates 3 symbols:
181
2.13k
  //
182
2.13k
  // __real_sym becomes sym
183
2.13k
  // sym        becomes __wrap_sym
184
2.13k
  // __wrap_sym becomes __real_sym
185
2.13k
  //
186
2.13k
  // The last part is special in that we don't want to change what references to
187
2.13k
  // __wrap_sym point to, we just want have __real_sym in the symbol table.
188
2.13k
189
2.13k
  for (WrappedSymbol &W : WrappedSymbols) {
190
9
    // First, make a copy of __real_sym.
191
9
    Symbol *Real = nullptr;
192
9
    if (W.Real->isDefined()) {
193
6
      Real = reinterpret_cast<Symbol *>(make<SymbolUnion>());
194
6
      memcpy(Real, W.Real, sizeof(SymbolUnion));
195
6
    }
196
9
197
9
    // Replace __real_sym with sym and sym with __wrap_sym.
198
9
    memcpy(W.Real, W.Sym, sizeof(SymbolUnion));
199
9
    memcpy(W.Sym, W.Wrap, sizeof(SymbolUnion));
200
9
201
9
    // We now have two copies of __wrap_sym. Drop one.
202
9
    W.Wrap->IsUsedInRegularObj = false;
203
9
204
9
    if (Real)
205
6
      SymVector.push_back(Real);
206
9
  }
207
2.13k
}
208
209
18.5k
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
210
18.5k
  if (VA == STV_DEFAULT)
211
18.4k
    return VB;
212
87
  if (VB == STV_DEFAULT)
213
40
    return VA;
214
47
  return std::min(VA, VB);
215
47
}
216
217
// Find an existing symbol or create and insert a new one.
218
18.7k
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
219
18.7k
  // <name>@@<version> means the symbol is the default version. In that
220
18.7k
  // case <name>@@<version> will be used to resolve references to <name>.
221
18.7k
  //
222
18.7k
  // Since this is a hot path, the following string search code is
223
18.7k
  // optimized for speed. StringRef::find(char) is much faster than
224
18.7k
  // StringRef::find(StringRef).
225
18.7k
  size_t Pos = Name.find('@');
226
18.7k
  if (Pos != StringRef::npos && 
Pos + 1 < Name.size()102
&&
Name[Pos + 1] == '@'102
)
227
22
    Name = Name.take_front(Pos);
228
18.7k
229
18.7k
  auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
230
18.7k
  int &SymIndex = P.first->second;
231
18.7k
  bool IsNew = P.second;
232
18.7k
  bool Traced = false;
233
18.7k
234
18.7k
  if (SymIndex == -1) {
235
28
    SymIndex = SymVector.size();
236
28
    IsNew = Traced = true;
237
28
  }
238
18.7k
239
18.7k
  Symbol *Sym;
240
18.7k
  if (IsNew) {
241
16.8k
    Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
242
16.8k
    Sym->Visibility = STV_DEFAULT;
243
16.8k
    Sym->IsUsedInRegularObj = false;
244
16.8k
    Sym->ExportDynamic = false;
245
16.8k
    Sym->CanInline = true;
246
16.8k
    Sym->Traced = Traced;
247
16.8k
    Sym->VersionId = Config->DefaultSymbolVersion;
248
16.8k
    SymVector.push_back(Sym);
249
16.8k
  } else {
250
1.88k
    Sym = SymVector[SymIndex];
251
1.88k
  }
252
18.7k
  return {Sym, IsNew};
253
18.7k
}
254
255
// Find an existing symbol or create and insert a new one, then apply the given
256
// attributes.
257
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
258
                                              uint8_t Visibility,
259
                                              bool CanOmitFromDynSym,
260
18.5k
                                              InputFile *File) {
261
18.5k
  Symbol *S;
262
18.5k
  bool WasInserted;
263
18.5k
  std::tie(S, WasInserted) = insert(Name);
264
18.5k
265
18.5k
  // Merge in the new symbol's visibility.
266
18.5k
  S->Visibility = getMinVisibility(S->Visibility, Visibility);
267
18.5k
268
18.5k
  if (!CanOmitFromDynSym && 
(17.7k
Config->Shared17.7k
||
Config->ExportDynamic14.7k
))
269
3.05k
    S->ExportDynamic = true;
270
18.5k
271
18.5k
  if (!File || 
File->kind() == InputFile::ObjKind16.5k
)
272
17.3k
    S->IsUsedInRegularObj = true;
273
18.5k
274
18.5k
  if (!WasInserted && 
S->Type != Symbol::UnknownType1.78k
&&
275
18.5k
      
((Type == STT_TLS) != S->isTls())1.70k
) {
276
1
    error("TLS attribute mismatch: " + toString(*S) + "\n>>> defined in " +
277
1
          toString(S->File) + "\n>>> defined in " + toString(File));
278
1
  }
279
18.5k
280
18.5k
  return {S, WasInserted};
281
18.5k
}
282
283
92
template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
284
92
  return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT,
285
92
                            /*Type*/ 0,
286
92
                            /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
287
92
}
Unexecuted instantiation: lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef)
Unexecuted instantiation: lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef)
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef)
Line
Count
Source
283
88
template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
284
88
  return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT,
285
88
                            /*Type*/ 0,
286
88
                            /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
287
88
}
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef)
Line
Count
Source
283
4
template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
284
4
  return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT,
285
4
                            /*Type*/ 0,
286
4
                            /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
287
4
}
288
289
17.1k
static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
290
291
template <class ELFT>
292
Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding,
293
                                  uint8_t StOther, uint8_t Type,
294
1.50k
                                  bool CanOmitFromDynSym, InputFile *File) {
295
1.50k
  Symbol *S;
296
1.50k
  bool WasInserted;
297
1.50k
  uint8_t Visibility = getVisibility(StOther);
298
1.50k
  std::tie(S, WasInserted) =
299
1.50k
      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
300
1.50k
301
1.50k
  // An undefined symbol with non default visibility must be satisfied
302
1.50k
  // in the same DSO.
303
1.50k
  if (WasInserted || 
(285
isa<SharedSymbol>(S)285
&&
Visibility != STV_DEFAULT35
)) {
304
1.22k
    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
305
1.22k
    return S;
306
1.22k
  }
307
283
308
283
  if (S->isShared() || 
S->isLazy()250
||
(227
S->isUndefined()227
&&
Binding != STB_WEAK57
))
309
111
    S->Binding = Binding;
310
283
311
283
  if (!Config->GcSections && 
Binding != STB_WEAK274
)
312
259
    if (auto *SS = dyn_cast<SharedSymbol>(S))
313
27
      SS->getFile<ELFT>().IsNeeded = true;
314
283
315
283
  if (S->isLazy()) {
316
23
    // An undefined weak will not fetch archive members. See comment on Lazy in
317
23
    // Symbols.h for the details.
318
23
    if (Binding == STB_WEAK) {
319
3
      S->Type = Type;
320
3
      return S;
321
3
    }
322
20
323
20
    // Do extra check for --warn-backrefs.
324
20
    //
325
20
    // --warn-backrefs is an option to prevent an undefined reference from
326
20
    // fetching an archive member written earlier in the command line. It can be
327
20
    // used to keep compatibility with GNU linkers to some degree.
328
20
    // I'll explain the feature and why you may find it useful in this comment.
329
20
    //
330
20
    // lld's symbol resolution semantics is more relaxed than traditional Unix
331
20
    // linkers. For example,
332
20
    //
333
20
    //   ld.lld foo.a bar.o
334
20
    //
335
20
    // succeeds even if bar.o contains an undefined symbol that has to be
336
20
    // resolved by some object file in foo.a. Traditional Unix linkers don't
337
20
    // allow this kind of backward reference, as they visit each file only once
338
20
    // from left to right in the command line while resolving all undefined
339
20
    // symbols at the moment of visiting.
340
20
    //
341
20
    // In the above case, since there's no undefined symbol when a linker visits
342
20
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
343
20
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
344
20
    // that could have been resolved otherwise.
345
20
    //
346
20
    // That lld accepts more relaxed form means that (besides it'd make more
347
20
    // sense) you can accidentally write a command line or a build file that
348
20
    // works only with lld, even if you have a plan to distribute it to wider
349
20
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
350
20
    // a library order that doesn't work with other Unix linkers.
351
20
    //
352
20
    // The option is also useful to detect cyclic dependencies between static
353
20
    // archives. Again, lld accepts
354
20
    //
355
20
    //   ld.lld foo.a bar.a
356
20
    //
357
20
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
358
20
    // handled as an error.
359
20
    //
360
20
    // Here is how the option works. We assign a group ID to each file. A file
361
20
    // with a smaller group ID can pull out object files from an archive file
362
20
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
363
20
    // and an error.
364
20
    //
365
20
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
366
20
    // files within the same --{start,end}-group get the same group ID. E.g.
367
20
    //
368
20
    //   ld.lld A B --start-group C D --end-group E
369
20
    //
370
20
    // A forms group 0. B form group 1. C and D (including their member object
371
20
    // files) form group 2. E forms group 3. I think that you can see how this
372
20
    // group assignment rule simulates the traditional linker's semantics.
373
20
    bool Backref =
374
20
        Config->WarnBackrefs && 
File10
&&
S->File->GroupId < File->GroupId10
;
375
20
    fetchLazy<ELFT>(S);
376
20
377
20
    // We don't report backward references to weak symbols as they can be
378
20
    // overridden later.
379
20
    if (Backref && 
S->Binding != STB_WEAK5
)
380
4
      warn("backward reference detected: " + Name + " in " + toString(File) +
381
4
           " refers to " + toString(S->File));
382
20
  }
383
283
  
return S280
;
384
283
}
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, unsigned char, unsigned char, unsigned char, bool, lld::elf::InputFile*)
Line
Count
Source
294
180
                                  bool CanOmitFromDynSym, InputFile *File) {
295
180
  Symbol *S;
296
180
  bool WasInserted;
297
180
  uint8_t Visibility = getVisibility(StOther);
298
180
  std::tie(S, WasInserted) =
299
180
      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
300
180
301
180
  // An undefined symbol with non default visibility must be satisfied
302
180
  // in the same DSO.
303
180
  if (WasInserted || 
(44
isa<SharedSymbol>(S)44
&&
Visibility != STV_DEFAULT12
)) {
304
136
    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
305
136
    return S;
306
136
  }
307
44
308
44
  if (S->isShared() || 
S->isLazy()32
||
(31
S->isUndefined()31
&&
Binding != STB_WEAK0
))
309
13
    S->Binding = Binding;
310
44
311
44
  if (!Config->GcSections && Binding != STB_WEAK)
312
43
    if (auto *SS = dyn_cast<SharedSymbol>(S))
313
11
      SS->getFile<ELFT>().IsNeeded = true;
314
44
315
44
  if (S->isLazy()) {
316
1
    // An undefined weak will not fetch archive members. See comment on Lazy in
317
1
    // Symbols.h for the details.
318
1
    if (Binding == STB_WEAK) {
319
0
      S->Type = Type;
320
0
      return S;
321
0
    }
322
1
323
1
    // Do extra check for --warn-backrefs.
324
1
    //
325
1
    // --warn-backrefs is an option to prevent an undefined reference from
326
1
    // fetching an archive member written earlier in the command line. It can be
327
1
    // used to keep compatibility with GNU linkers to some degree.
328
1
    // I'll explain the feature and why you may find it useful in this comment.
329
1
    //
330
1
    // lld's symbol resolution semantics is more relaxed than traditional Unix
331
1
    // linkers. For example,
332
1
    //
333
1
    //   ld.lld foo.a bar.o
334
1
    //
335
1
    // succeeds even if bar.o contains an undefined symbol that has to be
336
1
    // resolved by some object file in foo.a. Traditional Unix linkers don't
337
1
    // allow this kind of backward reference, as they visit each file only once
338
1
    // from left to right in the command line while resolving all undefined
339
1
    // symbols at the moment of visiting.
340
1
    //
341
1
    // In the above case, since there's no undefined symbol when a linker visits
342
1
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
343
1
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
344
1
    // that could have been resolved otherwise.
345
1
    //
346
1
    // That lld accepts more relaxed form means that (besides it'd make more
347
1
    // sense) you can accidentally write a command line or a build file that
348
1
    // works only with lld, even if you have a plan to distribute it to wider
349
1
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
350
1
    // a library order that doesn't work with other Unix linkers.
351
1
    //
352
1
    // The option is also useful to detect cyclic dependencies between static
353
1
    // archives. Again, lld accepts
354
1
    //
355
1
    //   ld.lld foo.a bar.a
356
1
    //
357
1
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
358
1
    // handled as an error.
359
1
    //
360
1
    // Here is how the option works. We assign a group ID to each file. A file
361
1
    // with a smaller group ID can pull out object files from an archive file
362
1
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
363
1
    // and an error.
364
1
    //
365
1
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
366
1
    // files within the same --{start,end}-group get the same group ID. E.g.
367
1
    //
368
1
    //   ld.lld A B --start-group C D --end-group E
369
1
    //
370
1
    // A forms group 0. B form group 1. C and D (including their member object
371
1
    // files) form group 2. E forms group 3. I think that you can see how this
372
1
    // group assignment rule simulates the traditional linker's semantics.
373
1
    bool Backref =
374
1
        Config->WarnBackrefs && 
File0
&&
S->File->GroupId < File->GroupId0
;
375
1
    fetchLazy<ELFT>(S);
376
1
377
1
    // We don't report backward references to weak symbols as they can be
378
1
    // overridden later.
379
1
    if (Backref && 
S->Binding != STB_WEAK0
)
380
0
      warn("backward reference detected: " + Name + " in " + toString(File) +
381
0
           " refers to " + toString(S->File));
382
1
  }
383
44
  return S;
384
44
}
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, unsigned char, unsigned char, unsigned char, bool, lld::elf::InputFile*)
Line
Count
Source
294
94
                                  bool CanOmitFromDynSym, InputFile *File) {
295
94
  Symbol *S;
296
94
  bool WasInserted;
297
94
  uint8_t Visibility = getVisibility(StOther);
298
94
  std::tie(S, WasInserted) =
299
94
      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
300
94
301
94
  // An undefined symbol with non default visibility must be satisfied
302
94
  // in the same DSO.
303
94
  if (WasInserted || 
(12
isa<SharedSymbol>(S)12
&&
Visibility != STV_DEFAULT0
)) {
304
82
    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
305
82
    return S;
306
82
  }
307
12
308
12
  if (S->isShared() || S->isLazy() || (S->isUndefined() && 
Binding != STB_WEAK0
))
309
0
    S->Binding = Binding;
310
12
311
12
  if (!Config->GcSections && Binding != STB_WEAK)
312
12
    if (auto *SS = dyn_cast<SharedSymbol>(S))
313
0
      SS->getFile<ELFT>().IsNeeded = true;
314
12
315
12
  if (S->isLazy()) {
316
0
    // An undefined weak will not fetch archive members. See comment on Lazy in
317
0
    // Symbols.h for the details.
318
0
    if (Binding == STB_WEAK) {
319
0
      S->Type = Type;
320
0
      return S;
321
0
    }
322
0
323
0
    // Do extra check for --warn-backrefs.
324
0
    //
325
0
    // --warn-backrefs is an option to prevent an undefined reference from
326
0
    // fetching an archive member written earlier in the command line. It can be
327
0
    // used to keep compatibility with GNU linkers to some degree.
328
0
    // I'll explain the feature and why you may find it useful in this comment.
329
0
    //
330
0
    // lld's symbol resolution semantics is more relaxed than traditional Unix
331
0
    // linkers. For example,
332
0
    //
333
0
    //   ld.lld foo.a bar.o
334
0
    //
335
0
    // succeeds even if bar.o contains an undefined symbol that has to be
336
0
    // resolved by some object file in foo.a. Traditional Unix linkers don't
337
0
    // allow this kind of backward reference, as they visit each file only once
338
0
    // from left to right in the command line while resolving all undefined
339
0
    // symbols at the moment of visiting.
340
0
    //
341
0
    // In the above case, since there's no undefined symbol when a linker visits
342
0
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
343
0
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
344
0
    // that could have been resolved otherwise.
345
0
    //
346
0
    // That lld accepts more relaxed form means that (besides it'd make more
347
0
    // sense) you can accidentally write a command line or a build file that
348
0
    // works only with lld, even if you have a plan to distribute it to wider
349
0
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
350
0
    // a library order that doesn't work with other Unix linkers.
351
0
    //
352
0
    // The option is also useful to detect cyclic dependencies between static
353
0
    // archives. Again, lld accepts
354
0
    //
355
0
    //   ld.lld foo.a bar.a
356
0
    //
357
0
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
358
0
    // handled as an error.
359
0
    //
360
0
    // Here is how the option works. We assign a group ID to each file. A file
361
0
    // with a smaller group ID can pull out object files from an archive file
362
0
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
363
0
    // and an error.
364
0
    //
365
0
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
366
0
    // files within the same --{start,end}-group get the same group ID. E.g.
367
0
    //
368
0
    //   ld.lld A B --start-group C D --end-group E
369
0
    //
370
0
    // A forms group 0. B form group 1. C and D (including their member object
371
0
    // files) form group 2. E forms group 3. I think that you can see how this
372
0
    // group assignment rule simulates the traditional linker's semantics.
373
0
    bool Backref =
374
0
        Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
375
0
    fetchLazy<ELFT>(S);
376
0
377
0
    // We don't report backward references to weak symbols as they can be
378
0
    // overridden later.
379
0
    if (Backref && S->Binding != STB_WEAK)
380
0
      warn("backward reference detected: " + Name + " in " + toString(File) +
381
0
           " refers to " + toString(S->File));
382
0
  }
383
12
  return S;
384
12
}
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, unsigned char, unsigned char, unsigned char, bool, lld::elf::InputFile*)
Line
Count
Source
294
1.16k
                                  bool CanOmitFromDynSym, InputFile *File) {
295
1.16k
  Symbol *S;
296
1.16k
  bool WasInserted;
297
1.16k
  uint8_t Visibility = getVisibility(StOther);
298
1.16k
  std::tie(S, WasInserted) =
299
1.16k
      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
300
1.16k
301
1.16k
  // An undefined symbol with non default visibility must be satisfied
302
1.16k
  // in the same DSO.
303
1.16k
  if (WasInserted || 
(224
isa<SharedSymbol>(S)224
&&
Visibility != STV_DEFAULT23
)) {
304
946
    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
305
946
    return S;
306
946
  }
307
222
308
222
  if (S->isShared() || 
S->isLazy()201
||
(179
S->isUndefined()179
&&
Binding != STB_WEAK56
))
309
97
    S->Binding = Binding;
310
222
311
222
  if (!Config->GcSections && 
Binding != STB_WEAK213
)
312
199
    if (auto *SS = dyn_cast<SharedSymbol>(S))
313
16
      SS->getFile<ELFT>().IsNeeded = true;
314
222
315
222
  if (S->isLazy()) {
316
22
    // An undefined weak will not fetch archive members. See comment on Lazy in
317
22
    // Symbols.h for the details.
318
22
    if (Binding == STB_WEAK) {
319
3
      S->Type = Type;
320
3
      return S;
321
3
    }
322
19
323
19
    // Do extra check for --warn-backrefs.
324
19
    //
325
19
    // --warn-backrefs is an option to prevent an undefined reference from
326
19
    // fetching an archive member written earlier in the command line. It can be
327
19
    // used to keep compatibility with GNU linkers to some degree.
328
19
    // I'll explain the feature and why you may find it useful in this comment.
329
19
    //
330
19
    // lld's symbol resolution semantics is more relaxed than traditional Unix
331
19
    // linkers. For example,
332
19
    //
333
19
    //   ld.lld foo.a bar.o
334
19
    //
335
19
    // succeeds even if bar.o contains an undefined symbol that has to be
336
19
    // resolved by some object file in foo.a. Traditional Unix linkers don't
337
19
    // allow this kind of backward reference, as they visit each file only once
338
19
    // from left to right in the command line while resolving all undefined
339
19
    // symbols at the moment of visiting.
340
19
    //
341
19
    // In the above case, since there's no undefined symbol when a linker visits
342
19
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
343
19
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
344
19
    // that could have been resolved otherwise.
345
19
    //
346
19
    // That lld accepts more relaxed form means that (besides it'd make more
347
19
    // sense) you can accidentally write a command line or a build file that
348
19
    // works only with lld, even if you have a plan to distribute it to wider
349
19
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
350
19
    // a library order that doesn't work with other Unix linkers.
351
19
    //
352
19
    // The option is also useful to detect cyclic dependencies between static
353
19
    // archives. Again, lld accepts
354
19
    //
355
19
    //   ld.lld foo.a bar.a
356
19
    //
357
19
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
358
19
    // handled as an error.
359
19
    //
360
19
    // Here is how the option works. We assign a group ID to each file. A file
361
19
    // with a smaller group ID can pull out object files from an archive file
362
19
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
363
19
    // and an error.
364
19
    //
365
19
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
366
19
    // files within the same --{start,end}-group get the same group ID. E.g.
367
19
    //
368
19
    //   ld.lld A B --start-group C D --end-group E
369
19
    //
370
19
    // A forms group 0. B form group 1. C and D (including their member object
371
19
    // files) form group 2. E forms group 3. I think that you can see how this
372
19
    // group assignment rule simulates the traditional linker's semantics.
373
19
    bool Backref =
374
19
        Config->WarnBackrefs && 
File10
&&
S->File->GroupId < File->GroupId10
;
375
19
    fetchLazy<ELFT>(S);
376
19
377
19
    // We don't report backward references to weak symbols as they can be
378
19
    // overridden later.
379
19
    if (Backref && 
S->Binding != STB_WEAK5
)
380
4
      warn("backward reference detected: " + Name + " in " + toString(File) +
381
4
           " refers to " + toString(S->File));
382
19
  }
383
222
  
return S219
;
384
222
}
lld::elf::Symbol* lld::elf::SymbolTable::addUndefined<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, unsigned char, unsigned char, unsigned char, bool, lld::elf::InputFile*)
Line
Count
Source
294
64
                                  bool CanOmitFromDynSym, InputFile *File) {
295
64
  Symbol *S;
296
64
  bool WasInserted;
297
64
  uint8_t Visibility = getVisibility(StOther);
298
64
  std::tie(S, WasInserted) =
299
64
      insert(Name, Type, Visibility, CanOmitFromDynSym, File);
300
64
301
64
  // An undefined symbol with non default visibility must be satisfied
302
64
  // in the same DSO.
303
64
  if (WasInserted || 
(5
isa<SharedSymbol>(S)5
&&
Visibility != STV_DEFAULT0
)) {
304
59
    replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type);
305
59
    return S;
306
59
  }
307
5
308
5
  if (S->isShared() || S->isLazy() || (S->isUndefined() && 
Binding != STB_WEAK1
))
309
1
    S->Binding = Binding;
310
5
311
5
  if (!Config->GcSections && Binding != STB_WEAK)
312
5
    if (auto *SS = dyn_cast<SharedSymbol>(S))
313
0
      SS->getFile<ELFT>().IsNeeded = true;
314
5
315
5
  if (S->isLazy()) {
316
0
    // An undefined weak will not fetch archive members. See comment on Lazy in
317
0
    // Symbols.h for the details.
318
0
    if (Binding == STB_WEAK) {
319
0
      S->Type = Type;
320
0
      return S;
321
0
    }
322
0
323
0
    // Do extra check for --warn-backrefs.
324
0
    //
325
0
    // --warn-backrefs is an option to prevent an undefined reference from
326
0
    // fetching an archive member written earlier in the command line. It can be
327
0
    // used to keep compatibility with GNU linkers to some degree.
328
0
    // I'll explain the feature and why you may find it useful in this comment.
329
0
    //
330
0
    // lld's symbol resolution semantics is more relaxed than traditional Unix
331
0
    // linkers. For example,
332
0
    //
333
0
    //   ld.lld foo.a bar.o
334
0
    //
335
0
    // succeeds even if bar.o contains an undefined symbol that has to be
336
0
    // resolved by some object file in foo.a. Traditional Unix linkers don't
337
0
    // allow this kind of backward reference, as they visit each file only once
338
0
    // from left to right in the command line while resolving all undefined
339
0
    // symbols at the moment of visiting.
340
0
    //
341
0
    // In the above case, since there's no undefined symbol when a linker visits
342
0
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
343
0
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
344
0
    // that could have been resolved otherwise.
345
0
    //
346
0
    // That lld accepts more relaxed form means that (besides it'd make more
347
0
    // sense) you can accidentally write a command line or a build file that
348
0
    // works only with lld, even if you have a plan to distribute it to wider
349
0
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
350
0
    // a library order that doesn't work with other Unix linkers.
351
0
    //
352
0
    // The option is also useful to detect cyclic dependencies between static
353
0
    // archives. Again, lld accepts
354
0
    //
355
0
    //   ld.lld foo.a bar.a
356
0
    //
357
0
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
358
0
    // handled as an error.
359
0
    //
360
0
    // Here is how the option works. We assign a group ID to each file. A file
361
0
    // with a smaller group ID can pull out object files from an archive file
362
0
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
363
0
    // and an error.
364
0
    //
365
0
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
366
0
    // files within the same --{start,end}-group get the same group ID. E.g.
367
0
    //
368
0
    //   ld.lld A B --start-group C D --end-group E
369
0
    //
370
0
    // A forms group 0. B form group 1. C and D (including their member object
371
0
    // files) form group 2. E forms group 3. I think that you can see how this
372
0
    // group assignment rule simulates the traditional linker's semantics.
373
0
    bool Backref =
374
0
        Config->WarnBackrefs && File && S->File->GroupId < File->GroupId;
375
0
    fetchLazy<ELFT>(S);
376
0
377
0
    // We don't report backward references to weak symbols as they can be
378
0
    // overridden later.
379
0
    if (Backref && S->Binding != STB_WEAK)
380
0
      warn("backward reference detected: " + Name + " in " + toString(File) +
381
0
           " refers to " + toString(S->File));
382
0
  }
383
5
  return S;
384
5
}
385
386
// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
387
// foo@@VER. We want to effectively ignore foo, so give precedence to
388
// foo@@VER.
389
// FIXME: If users can transition to using
390
// .symver foo,foo@@@VER
391
// we can delete this hack.
392
94
static int compareVersion(Symbol *S, StringRef Name) {
393
94
  bool A = Name.contains("@@");
394
94
  bool B = S->getName().contains("@@");
395
94
  if (A && 
!B1
)
396
1
    return 1;
397
93
  if (!A && B)
398
1
    return -1;
399
92
  return 0;
400
92
}
401
402
// We have a new defined symbol with the specified binding. Return 1 if the new
403
// symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
404
// strong defined symbols.
405
static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
406
15.6k
                          StringRef Name) {
407
15.6k
  if (WasInserted)
408
14.9k
    return 1;
409
771
  if (!S->isDefined())
410
677
    return 1;
411
94
  if (int R = compareVersion(S, Name))
412
2
    return R;
413
92
  if (Binding == STB_WEAK)
414
18
    return -1;
415
74
  if (S->isWeak())
416
21
    return 1;
417
53
  return 0;
418
53
}
419
420
// We have a new non-common defined symbol with the specified binding. Return 1
421
// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
422
// is a conflict. If the new symbol wins, also update the binding.
423
static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
424
                                   bool IsAbsolute, uint64_t Value,
425
15.5k
                                   StringRef Name) {
426
15.5k
  if (int Cmp = compareDefined(S, WasInserted, Binding, Name))
427
15.5k
    return Cmp;
428
37
  if (auto *R = dyn_cast<Defined>(S)) {
429
37
    if (R->Section && 
isa<BssSection>(R->Section)31
) {
430
2
      // Non-common symbols take precedence over common symbols.
431
2
      if (Config->WarnCommon)
432
1
        warn("common " + S->getName() + " is overridden");
433
2
      return 1;
434
2
    }
435
35
    if (R->Section == nullptr && 
Binding == STB_GLOBAL6
&&
IsAbsolute6
&&
436
35
        
R->Value == Value5
)
437
4
      return -1;
438
31
  }
439
31
  return 0;
440
31
}
441
442
Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
443
                               uint8_t Binding, uint8_t StOther, uint8_t Type,
444
120
                               InputFile &File) {
445
120
  Symbol *S;
446
120
  bool WasInserted;
447
120
  std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
448
120
                                    /*CanOmitFromDynSym*/ false, &File);
449
120
450
120
  int Cmp = compareDefined(S, WasInserted, Binding, N);
451
120
  if (Cmp < 0)
452
4
    return S;
453
116
454
116
  if (Cmp > 0) {
455
100
    auto *Bss = make<BssSection>("COMMON", Size, Alignment);
456
100
    Bss->File = &File;
457
100
    Bss->Live = !Config->GcSections;
458
100
    InputSections.push_back(Bss);
459
100
460
100
    replaceSymbol<Defined>(S, &File, N, Binding, StOther, Type, 0, Size, Bss);
461
100
    return S;
462
100
  }
463
16
464
16
  auto *D = cast<Defined>(S);
465
16
  auto *Bss = dyn_cast_or_null<BssSection>(D->Section);
466
16
  if (!Bss) {
467
2
    // Non-common symbols take precedence over common symbols.
468
2
    if (Config->WarnCommon)
469
1
      warn("common " + S->getName() + " is overridden");
470
2
    return S;
471
2
  }
472
14
473
14
  if (Config->WarnCommon)
474
3
    warn("multiple common of " + D->getName());
475
14
476
14
  Bss->Alignment = std::max(Bss->Alignment, Alignment);
477
14
  if (Size > Bss->Size) {
478
12
    D->File = Bss->File = &File;
479
12
    D->Size = Bss->Size = Size;
480
12
  }
481
14
  return S;
482
14
}
483
484
2
static void reportDuplicate(Symbol *Sym, InputFile *NewFile) {
485
2
  if (!Config->AllowMultipleDefinition)
486
2
    error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
487
2
          toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
488
2
}
489
490
static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
491
30
                            InputSectionBase *ErrSec, uint64_t ErrOffset) {
492
30
  if (Config->AllowMultipleDefinition)
493
4
    return;
494
26
495
26
  Defined *D = cast<Defined>(Sym);
496
26
  if (!D->Section || 
!ErrSec25
) {
497
1
    reportDuplicate(Sym, NewFile);
498
1
    return;
499
1
  }
500
25
501
25
  // Construct and print an error message in the form of:
502
25
  //
503
25
  //   ld.lld: error: duplicate symbol: foo
504
25
  //   >>> defined at bar.c:30
505
25
  //   >>>            bar.o (/home/alice/src/bar.o)
506
25
  //   >>> defined at baz.c:563
507
25
  //   >>>            baz.o in archive libbaz.a
508
25
  auto *Sec1 = cast<InputSectionBase>(D->Section);
509
25
  std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
510
25
  std::string Obj1 = Sec1->getObjMsg(D->Value);
511
25
  std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
512
25
  std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
513
25
514
25
  std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
515
25
  if (!Src1.empty())
516
10
    Msg += Src1 + "\n>>>            ";
517
25
  Msg += Obj1 + "\n>>> defined at ";
518
25
  if (!Src2.empty())
519
10
    Msg += Src2 + "\n>>>            ";
520
25
  Msg += Obj2;
521
25
  error(Msg);
522
25
}
523
524
Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
525
                                uint64_t Value, uint64_t Size, uint8_t Binding,
526
15.3k
                                SectionBase *Section, InputFile *File) {
527
15.3k
  Symbol *S;
528
15.3k
  bool WasInserted;
529
15.3k
  std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
530
15.3k
                                    /*CanOmitFromDynSym*/ false, File);
531
15.3k
  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr,
532
15.3k
                                    Value, Name);
533
15.3k
  if (Cmp > 0)
534
15.2k
    replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size,
535
15.2k
                           Section);
536
42
  else if (Cmp == 0)
537
30
    reportDuplicate(S, File, dyn_cast_or_null<InputSectionBase>(Section),
538
30
                    Value);
539
15.3k
  return S;
540
15.3k
}
541
542
template <typename ELFT>
543
void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
544
                            const typename ELFT::Sym &Sym, uint32_t Alignment,
545
841
                            uint32_t VerdefIndex) {
546
841
  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
547
841
  // as the visibility, which will leave the visibility in the symbol table
548
841
  // unchanged.
549
841
  Symbol *S;
550
841
  bool WasInserted;
551
841
  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
552
841
                                    /*CanOmitFromDynSym*/ true, &File);
553
841
  // Make sure we preempt DSO symbols with default visibility.
554
841
  if (Sym.getVisibility() == STV_DEFAULT)
555
829
    S->ExportDynamic = true;
556
841
557
841
  // An undefined symbol with non default visibility must be satisfied
558
841
  // in the same DSO.
559
841
  if (WasInserted ||
560
841
      
(384
(384
S->isUndefined()384
||
S->isLazy()38
) &&
S->Visibility == STV_DEFAULT348
)) {
561
801
    uint8_t Binding = S->Binding;
562
801
    bool WasUndefined = S->isUndefined();
563
801
    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
564
801
                                Sym.getType(), Sym.st_value, Sym.st_size,
565
801
                                Alignment, VerdefIndex);
566
801
    if (!WasInserted) {
567
344
      S->Binding = Binding;
568
344
      if (!S->isWeak() && 
!Config->GcSections329
&&
WasUndefined322
)
569
320
        File.IsNeeded = true;
570
344
    }
571
801
  }
572
841
}
void lld::elf::SymbolTable::addShared<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >&, llvm::object::ELFType<(llvm::support::endianness)1, false>::Sym const&, unsigned int, unsigned int)
Line
Count
Source
545
115
                            uint32_t VerdefIndex) {
546
115
  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
547
115
  // as the visibility, which will leave the visibility in the symbol table
548
115
  // unchanged.
549
115
  Symbol *S;
550
115
  bool WasInserted;
551
115
  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
552
115
                                    /*CanOmitFromDynSym*/ true, &File);
553
115
  // Make sure we preempt DSO symbols with default visibility.
554
115
  if (Sym.getVisibility() == STV_DEFAULT)
555
115
    S->ExportDynamic = true;
556
115
557
115
  // An undefined symbol with non default visibility must be satisfied
558
115
  // in the same DSO.
559
115
  if (WasInserted ||
560
115
      
(65
(65
S->isUndefined()65
||
S->isLazy()6
) &&
S->Visibility == STV_DEFAULT59
)) {
561
109
    uint8_t Binding = S->Binding;
562
109
    bool WasUndefined = S->isUndefined();
563
109
    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
564
109
                                Sym.getType(), Sym.st_value, Sym.st_size,
565
109
                                Alignment, VerdefIndex);
566
109
    if (!WasInserted) {
567
59
      S->Binding = Binding;
568
59
      if (!S->isWeak() && 
!Config->GcSections54
&&
WasUndefined54
)
569
54
        File.IsNeeded = true;
570
59
    }
571
109
  }
572
115
}
void lld::elf::SymbolTable::addShared<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >&, llvm::object::ELFType<(llvm::support::endianness)0, false>::Sym const&, unsigned int, unsigned int)
Line
Count
Source
545
100
                            uint32_t VerdefIndex) {
546
100
  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
547
100
  // as the visibility, which will leave the visibility in the symbol table
548
100
  // unchanged.
549
100
  Symbol *S;
550
100
  bool WasInserted;
551
100
  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
552
100
                                    /*CanOmitFromDynSym*/ true, &File);
553
100
  // Make sure we preempt DSO symbols with default visibility.
554
100
  if (Sym.getVisibility() == STV_DEFAULT)
555
100
    S->ExportDynamic = true;
556
100
557
100
  // An undefined symbol with non default visibility must be satisfied
558
100
  // in the same DSO.
559
100
  if (WasInserted ||
560
100
      
(28
(28
S->isUndefined()28
||
S->isLazy()0
) &&
S->Visibility == STV_DEFAULT28
)) {
561
100
    uint8_t Binding = S->Binding;
562
100
    bool WasUndefined = S->isUndefined();
563
100
    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
564
100
                                Sym.getType(), Sym.st_value, Sym.st_size,
565
100
                                Alignment, VerdefIndex);
566
100
    if (!WasInserted) {
567
28
      S->Binding = Binding;
568
28
      if (!S->isWeak() && !Config->GcSections && WasUndefined)
569
28
        File.IsNeeded = true;
570
28
    }
571
100
  }
572
100
}
void lld::elf::SymbolTable::addShared<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >&, llvm::object::ELFType<(llvm::support::endianness)1, true>::Sym const&, unsigned int, unsigned int)
Line
Count
Source
545
515
                            uint32_t VerdefIndex) {
546
515
  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
547
515
  // as the visibility, which will leave the visibility in the symbol table
548
515
  // unchanged.
549
515
  Symbol *S;
550
515
  bool WasInserted;
551
515
  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
552
515
                                    /*CanOmitFromDynSym*/ true, &File);
553
515
  // Make sure we preempt DSO symbols with default visibility.
554
515
  if (Sym.getVisibility() == STV_DEFAULT)
555
503
    S->ExportDynamic = true;
556
515
557
515
  // An undefined symbol with non default visibility must be satisfied
558
515
  // in the same DSO.
559
515
  if (WasInserted ||
560
515
      
(271
(271
S->isUndefined()271
||
S->isLazy()32
) &&
S->Visibility == STV_DEFAULT241
)) {
561
481
    uint8_t Binding = S->Binding;
562
481
    bool WasUndefined = S->isUndefined();
563
481
    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
564
481
                                Sym.getType(), Sym.st_value, Sym.st_size,
565
481
                                Alignment, VerdefIndex);
566
481
    if (!WasInserted) {
567
237
      S->Binding = Binding;
568
237
      if (!S->isWeak() && 
!Config->GcSections227
&&
WasUndefined220
)
569
218
        File.IsNeeded = true;
570
237
    }
571
481
  }
572
515
}
void lld::elf::SymbolTable::addShared<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, lld::elf::SharedFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >&, llvm::object::ELFType<(llvm::support::endianness)0, true>::Sym const&, unsigned int, unsigned int)
Line
Count
Source
545
111
                            uint32_t VerdefIndex) {
546
111
  // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
547
111
  // as the visibility, which will leave the visibility in the symbol table
548
111
  // unchanged.
549
111
  Symbol *S;
550
111
  bool WasInserted;
551
111
  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
552
111
                                    /*CanOmitFromDynSym*/ true, &File);
553
111
  // Make sure we preempt DSO symbols with default visibility.
554
111
  if (Sym.getVisibility() == STV_DEFAULT)
555
111
    S->ExportDynamic = true;
556
111
557
111
  // An undefined symbol with non default visibility must be satisfied
558
111
  // in the same DSO.
559
111
  if (WasInserted ||
560
111
      
(20
(20
S->isUndefined()20
||
S->isLazy()0
) &&
S->Visibility == STV_DEFAULT20
)) {
561
111
    uint8_t Binding = S->Binding;
562
111
    bool WasUndefined = S->isUndefined();
563
111
    replaceSymbol<SharedSymbol>(S, File, Name, Sym.getBinding(), Sym.st_other,
564
111
                                Sym.getType(), Sym.st_value, Sym.st_size,
565
111
                                Alignment, VerdefIndex);
566
111
    if (!WasInserted) {
567
20
      S->Binding = Binding;
568
20
      if (!S->isWeak() && !Config->GcSections && WasUndefined)
569
20
        File.IsNeeded = true;
570
20
    }
571
111
  }
572
111
}
573
574
Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
575
                                uint8_t StOther, uint8_t Type,
576
257
                                bool CanOmitFromDynSym, BitcodeFile &F) {
577
257
  Symbol *S;
578
257
  bool WasInserted;
579
257
  std::tie(S, WasInserted) =
580
257
      insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, &F);
581
257
  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding,
582
257
                                    /*IsAbs*/ false, /*Value*/ 0, Name);
583
257
  if (Cmp > 0)
584
249
    replaceSymbol<Defined>(S, &F, Name, Binding, StOther, Type, 0, 0, nullptr);
585
8
  else if (Cmp == 0)
586
1
    reportDuplicate(S, &F);
587
257
  return S;
588
257
}
589
590
436k
Symbol *SymbolTable::find(StringRef Name) {
591
436k
  auto It = SymMap.find(CachedHashStringRef(Name));
592
436k
  if (It == SymMap.end())
593
433k
    return nullptr;
594
2.80k
  if (It->second == -1)
595
0
    return nullptr;
596
2.80k
  return SymVector[It->second];
597
2.80k
}
598
599
// This is used to handle lazy symbols. May replace existent
600
// symbol with lazy version or request to Fetch it.
601
template <class ELFT, typename LazyT, typename... ArgT>
602
static void replaceOrFetchLazy(StringRef Name, InputFile &File,
603
                               llvm::function_ref<InputFile *()> Fetch,
604
203
                               ArgT &&... Arg) {
605
203
  Symbol *S;
606
203
  bool WasInserted;
607
203
  std::tie(S, WasInserted) = Symtab->insert(Name);
608
203
  if (WasInserted) {
609
102
    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
610
102
                         std::forward<ArgT>(Arg)...);
611
102
    return;
612
102
  }
613
101
  if (!S->isUndefined())
614
33
    return;
615
68
616
68
  // An undefined weak will not fetch archive members. See comment on Lazy in
617
68
  // Symbols.h for the details.
618
68
  if (S->isWeak()) {
619
15
    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
620
15
    S->Binding = STB_WEAK;
621
15
    return;
622
15
  }
623
53
624
53
  if (InputFile *F = Fetch())
625
52
    Symtab->addFile<ELFT>(F);
626
53
}
SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, false>, lld::elf::LazyArchive, llvm::object::Archive::Symbol const&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
604
4
                               ArgT &&... Arg) {
605
4
  Symbol *S;
606
4
  bool WasInserted;
607
4
  std::tie(S, WasInserted) = Symtab->insert(Name);
608
4
  if (WasInserted) {
609
3
    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
610
3
                         std::forward<ArgT>(Arg)...);
611
3
    return;
612
3
  }
613
1
  if (!S->isUndefined())
614
0
    return;
615
1
616
1
  // An undefined weak will not fetch archive members. See comment on Lazy in
617
1
  // Symbols.h for the details.
618
1
  if (S->isWeak()) {
619
1
    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
620
1
    S->Binding = STB_WEAK;
621
1
    return;
622
1
  }
623
0
624
0
  if (InputFile *F = Fetch())
625
0
    Symtab->addFile<ELFT>(F);
626
0
}
Unexecuted instantiation: SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, false>, lld::elf::LazyArchive, llvm::object::Archive::Symbol const&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::object::Archive::Symbol const&&&)
SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, true>, lld::elf::LazyArchive, llvm::object::Archive::Symbol const&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
604
167
                               ArgT &&... Arg) {
605
167
  Symbol *S;
606
167
  bool WasInserted;
607
167
  std::tie(S, WasInserted) = Symtab->insert(Name);
608
167
  if (WasInserted) {
609
83
    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
610
83
                         std::forward<ArgT>(Arg)...);
611
83
    return;
612
83
  }
613
84
  if (!S->isUndefined())
614
30
    return;
615
54
616
54
  // An undefined weak will not fetch archive members. See comment on Lazy in
617
54
  // Symbols.h for the details.
618
54
  if (S->isWeak()) {
619
12
    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
620
12
    S->Binding = STB_WEAK;
621
12
    return;
622
12
  }
623
42
624
42
  if (InputFile *F = Fetch())
625
42
    Symtab->addFile<ELFT>(F);
626
42
}
SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, true>, lld::elf::LazyArchive, llvm::object::Archive::Symbol const&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::object::Archive::Symbol const&&&)
Line
Count
Source
604
1
                               ArgT &&... Arg) {
605
1
  Symbol *S;
606
1
  bool WasInserted;
607
1
  std::tie(S, WasInserted) = Symtab->insert(Name);
608
1
  if (WasInserted) {
609
0
    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
610
0
                         std::forward<ArgT>(Arg)...);
611
0
    return;
612
0
  }
613
1
  if (!S->isUndefined())
614
0
    return;
615
1
616
1
  // An undefined weak will not fetch archive members. See comment on Lazy in
617
1
  // Symbols.h for the details.
618
1
  if (S->isWeak()) {
619
1
    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
620
1
    S->Binding = STB_WEAK;
621
1
    return;
622
1
  }
623
0
624
0
  if (InputFile *F = Fetch())
625
0
    Symtab->addFile<ELFT>(F);
626
0
}
Unexecuted instantiation: SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, false>, lld::elf::LazyObject, llvm::StringRef&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::StringRef&&&)
Unexecuted instantiation: SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, false>, lld::elf::LazyObject, llvm::StringRef&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::StringRef&&&)
SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, true>, lld::elf::LazyObject, llvm::StringRef&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::StringRef&&&)
Line
Count
Source
604
31
                               ArgT &&... Arg) {
605
31
  Symbol *S;
606
31
  bool WasInserted;
607
31
  std::tie(S, WasInserted) = Symtab->insert(Name);
608
31
  if (WasInserted) {
609
16
    replaceSymbol<LazyT>(S, File, Symbol::UnknownType,
610
16
                         std::forward<ArgT>(Arg)...);
611
16
    return;
612
16
  }
613
15
  if (!S->isUndefined())
614
3
    return;
615
12
616
12
  // An undefined weak will not fetch archive members. See comment on Lazy in
617
12
  // Symbols.h for the details.
618
12
  if (S->isWeak()) {
619
1
    replaceSymbol<LazyT>(S, File, S->Type, std::forward<ArgT>(Arg)...);
620
1
    S->Binding = STB_WEAK;
621
1
    return;
622
1
  }
623
11
624
11
  if (InputFile *F = Fetch())
625
10
    Symtab->addFile<ELFT>(F);
626
11
}
Unexecuted instantiation: SymbolTable.cpp:void replaceOrFetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, true>, lld::elf::LazyObject, llvm::StringRef&>(llvm::StringRef, lld::elf::InputFile&, llvm::function_ref<lld::elf::InputFile* ()>, llvm::StringRef&&&)
627
628
template <class ELFT>
629
void SymbolTable::addLazyArchive(StringRef Name, ArchiveFile &F,
630
172
                                 const object::Archive::Symbol Sym) {
631
172
  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() 
{ return F.fetch(Sym); }42
,
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)::'lambda'()::operator()() const
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)::'lambda'()::operator()() const
void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)::'lambda'()::operator()() const
Line
Count
Source
631
42
  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)::'lambda'()::operator()() const
632
172
                                        Sym);
633
172
}
void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)
Line
Count
Source
630
4
                                 const object::Archive::Symbol Sym) {
631
4
  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
632
4
                                        Sym);
633
4
}
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)
void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)
Line
Count
Source
630
167
                                 const object::Archive::Symbol Sym) {
631
167
  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
632
167
                                        Sym);
633
167
}
void lld::elf::SymbolTable::addLazyArchive<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, lld::elf::ArchiveFile&, llvm::object::Archive::Symbol)
Line
Count
Source
630
1
                                 const object::Archive::Symbol Sym) {
631
1
  replaceOrFetchLazy<ELFT, LazyArchive>(Name, F, [&]() { return F.fetch(Sym); },
632
1
                                        Sym);
633
1
}
634
635
template <class ELFT>
636
31
void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
637
31
  replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() 
{ return Obj.fetch(); }11
,
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, lld::elf::LazyObjFile&)::'lambda'()::operator()() const
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, lld::elf::LazyObjFile&)::'lambda'()::operator()() const
void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, lld::elf::LazyObjFile&)::'lambda'()::operator()() const
Line
Count
Source
637
11
  replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, lld::elf::LazyObjFile&)::'lambda'()::operator()() const
638
31
                                       Name);
639
31
}
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::StringRef, lld::elf::LazyObjFile&)
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::StringRef, lld::elf::LazyObjFile&)
void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::StringRef, lld::elf::LazyObjFile&)
Line
Count
Source
636
31
void SymbolTable::addLazyObject(StringRef Name, LazyObjFile &Obj) {
637
31
  replaceOrFetchLazy<ELFT, LazyObject>(Name, Obj, [&]() { return Obj.fetch(); },
638
31
                                       Name);
639
31
}
Unexecuted instantiation: void lld::elf::SymbolTable::addLazyObject<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::StringRef, lld::elf::LazyObjFile&)
640
641
36
template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
642
36
  if (auto *S = dyn_cast<LazyArchive>(Sym)) {
643
28
    if (InputFile *File = S->fetch())
644
28
      addFile<ELFT>(File);
645
28
    return;
646
28
  }
647
8
648
8
  auto *S = cast<LazyObject>(Sym);
649
8
  if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
650
7
    addFile<ELFT>(File);
651
8
}
void lld::elf::SymbolTable::fetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::Symbol*)
Line
Count
Source
641
2
template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
642
2
  if (auto *S = dyn_cast<LazyArchive>(Sym)) {
643
2
    if (InputFile *File = S->fetch())
644
2
      addFile<ELFT>(File);
645
2
    return;
646
2
  }
647
0
648
0
  auto *S = cast<LazyObject>(Sym);
649
0
  if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
650
0
    addFile<ELFT>(File);
651
0
}
Unexecuted instantiation: void lld::elf::SymbolTable::fetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::Symbol*)
void lld::elf::SymbolTable::fetchLazy<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::Symbol*)
Line
Count
Source
641
34
template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
642
34
  if (auto *S = dyn_cast<LazyArchive>(Sym)) {
643
26
    if (InputFile *File = S->fetch())
644
26
      addFile<ELFT>(File);
645
26
    return;
646
26
  }
647
8
648
8
  auto *S = cast<LazyObject>(Sym);
649
8
  if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
650
7
    addFile<ELFT>(File);
651
8
}
Unexecuted instantiation: void lld::elf::SymbolTable::fetchLazy<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::Symbol*)
652
653
// Initialize DemangledSyms with a map from demangled symbols to symbol
654
// objects. Used to handle "extern C++" directive in version scripts.
655
//
656
// The map will contain all demangled symbols. That can be very large,
657
// and in LLD we generally want to avoid do anything for each symbol.
658
// Then, why are we doing this? Here's why.
659
//
660
// Users can use "extern C++ {}" directive to match against demangled
661
// C++ symbols. For example, you can write a pattern such as
662
// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
663
// other than trying to match a pattern against all demangled symbols.
664
// So, if "extern C++" feature is used, we need to demangle all known
665
// symbols.
666
27
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
667
27
  if (!DemangledSyms) {
668
20
    DemangledSyms.emplace();
669
43
    for (Symbol *Sym : SymVector) {
670
43
      if (!Sym->isDefined())
671
0
        continue;
672
43
      if (Optional<std::string> S = demangleItanium(Sym->getName()))
673
43
        (*DemangledSyms)[*S].push_back(Sym);
674
0
      else
675
0
        (*DemangledSyms)[Sym->getName()].push_back(Sym);
676
43
    }
677
20
  }
678
27
  return *DemangledSyms;
679
27
}
680
681
97
std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
682
97
  if (Ver.IsExternCpp)
683
10
    return getDemangledSyms().lookup(Ver.Name);
684
87
  if (Symbol *B = find(Ver.Name))
685
77
    if (B->isDefined())
686
74
      return {B};
687
13
  return {};
688
13
}
689
690
27
std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
691
27
  std::vector<Symbol *> Res;
692
27
  StringMatcher M(Ver.Name);
693
27
694
27
  if (Ver.IsExternCpp) {
695
17
    for (auto &P : getDemangledSyms())
696
42
      if (M.match(P.first()))
697
19
        Res.insert(Res.end(), P.second.begin(), P.second.end());
698
17
    return Res;
699
17
  }
700
10
701
10
  for (Symbol *Sym : SymVector)
702
35
    if (Sym->isDefined() && M.match(Sym->getName()))
703
23
      Res.push_back(Sym);
704
10
  return Res;
705
10
}
706
707
// If there's only one anonymous version definition in a version
708
// script file, the script does not actually define any symbol version,
709
// but just specifies symbols visibilities.
710
2.08k
void SymbolTable::handleAnonymousVersion() {
711
2.08k
  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
712
24
    assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
713
2.08k
  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
714
24
    assignWildcardVersion(Ver, VER_NDX_GLOBAL);
715
2.08k
  for (SymbolVersion &Ver : Config->VersionScriptLocals)
716
8
    assignExactVersion(Ver, VER_NDX_LOCAL, "local");
717
2.08k
  for (SymbolVersion &Ver : Config->VersionScriptLocals)
718
8
    assignWildcardVersion(Ver, VER_NDX_LOCAL);
719
2.08k
}
720
721
// Handles -dynamic-list.
722
2.08k
void SymbolTable::handleDynamicList() {
723
2.08k
  for (SymbolVersion &Ver : Config->DynamicList) {
724
26
    std::vector<Symbol *> Syms;
725
26
    if (Ver.HasWildcard)
726
1
      Syms = findAllByVersion(Ver);
727
25
    else
728
25
      Syms = findByVersion(Ver);
729
26
730
26
    for (Symbol *B : Syms) {
731
21
      if (!Config->Shared)
732
18
        B->ExportDynamic = true;
733
3
      else if (B->includeInDynsym())
734
2
        B->IsPreemptible = true;
735
21
    }
736
26
  }
737
2.08k
}
738
739
// Set symbol versions to symbols. This function handles patterns
740
// containing no wildcard characters.
741
void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
742
98
                                     StringRef VersionName) {
743
98
  if (Ver.HasWildcard)
744
26
    return;
745
72
746
72
  // Get a list of symbols which we need to assign the version to.
747
72
  std::vector<Symbol *> Syms = findByVersion(Ver);
748
72
  if (Syms.empty()) {
749
12
    if (!Config->UndefinedVersion)
750
3
      error("version script assignment of '" + VersionName + "' to symbol '" +
751
3
            Ver.Name + "' failed: symbol not defined");
752
12
    return;
753
12
  }
754
60
755
60
  // Assign the version.
756
61
  
for (Symbol *Sym : Syms)60
{
757
61
    // Skip symbols containing version info because symbol versions
758
61
    // specified by symbol names take precedence over version scripts.
759
61
    // See parseSymbolVersion().
760
61
    if (Sym->getName().contains('@'))
761
4
      continue;
762
57
763
57
    if (Sym->VersionId != Config->DefaultSymbolVersion &&
764
57
        
Sym->VersionId != VersionId2
)
765
1
      error("duplicate symbol '" + Ver.Name + "' in version script");
766
57
    Sym->VersionId = VersionId;
767
57
  }
768
60
}
769
770
98
void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
771
98
  if (!Ver.HasWildcard)
772
72
    return;
773
26
774
26
  // Exact matching takes precendence over fuzzy matching,
775
26
  // so we set a version to a symbol only if no version has been assigned
776
26
  // to the symbol. This behavior is compatible with GNU.
777
26
  for (Symbol *B : findAllByVersion(Ver))
778
40
    if (B->VersionId == Config->DefaultSymbolVersion)
779
36
      B->VersionId = VersionId;
780
26
}
781
782
// This function processes version scripts by updating VersionId
783
// member of symbols.
784
2.08k
void SymbolTable::scanVersionScript() {
785
2.08k
  // Handle edge cases first.
786
2.08k
  handleAnonymousVersion();
787
2.08k
  handleDynamicList();
788
2.08k
789
2.08k
  // Now we have version definitions, so we need to set version ids to symbols.
790
2.08k
  // Each version definition has a glob pattern, and all symbols that match
791
2.08k
  // with the pattern get that version.
792
2.08k
793
2.08k
  // First, we assign versions to exact matching symbols,
794
2.08k
  // i.e. version definitions not containing any glob meta-characters.
795
2.08k
  for (VersionDefinition &V : Config->VersionDefinitions)
796
84
    for (SymbolVersion &Ver : V.Globals)
797
66
      assignExactVersion(Ver, V.Id, V.Name);
798
2.08k
799
2.08k
  // Next, we assign versions to fuzzy matching symbols,
800
2.08k
  // i.e. version definitions containing glob meta-characters.
801
2.08k
  // Note that because the last match takes precedence over previous matches,
802
2.08k
  // we iterate over the definitions in the reverse order.
803
2.08k
  for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
804
84
    for (SymbolVersion &Ver : V.Globals)
805
66
      assignWildcardVersion(Ver, V.Id);
806
2.08k
807
2.08k
  // Symbol themselves might know their versions because symbols
808
2.08k
  // can contain versions in the form of <name>@<version>.
809
2.08k
  // Let them parse and update their names to exclude version suffix.
810
2.08k
  for (Symbol *Sym : SymVector)
811
15.5k
    Sym->parseSymbolVersion();
812
2.08k
}
813
814
template void SymbolTable::addFile<ELF32LE>(InputFile *);
815
template void SymbolTable::addFile<ELF32BE>(InputFile *);
816
template void SymbolTable::addFile<ELF64LE>(InputFile *);
817
template void SymbolTable::addFile<ELF64BE>(InputFile *);
818
819
template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef);
820
template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef);
821
template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef);
822
template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef);
823
824
template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
825
template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
826
template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
827
template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef);
828
829
template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t,
830
                                                    uint8_t, bool, InputFile *);
831
template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t,
832
                                                    uint8_t, bool, InputFile *);
833
template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t,
834
                                                    uint8_t, bool, InputFile *);
835
template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t,
836
                                                    uint8_t, bool, InputFile *);
837
838
template void SymbolTable::addCombinedLTOObject<ELF32LE>();
839
template void SymbolTable::addCombinedLTOObject<ELF32BE>();
840
template void SymbolTable::addCombinedLTOObject<ELF64LE>();
841
template void SymbolTable::addCombinedLTOObject<ELF64BE>();
842
843
template void
844
SymbolTable::addLazyArchive<ELF32LE>(StringRef, ArchiveFile &,
845
                                     const object::Archive::Symbol);
846
template void
847
SymbolTable::addLazyArchive<ELF32BE>(StringRef, ArchiveFile &,
848
                                     const object::Archive::Symbol);
849
template void
850
SymbolTable::addLazyArchive<ELF64LE>(StringRef, ArchiveFile &,
851
                                     const object::Archive::Symbol);
852
template void
853
SymbolTable::addLazyArchive<ELF64BE>(StringRef, ArchiveFile &,
854
                                     const object::Archive::Symbol);
855
856
template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjFile &);
857
template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjFile &);
858
template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjFile &);
859
template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjFile &);
860
861
template void SymbolTable::fetchLazy<ELF32LE>(Symbol *);
862
template void SymbolTable::fetchLazy<ELF32BE>(Symbol *);
863
template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
864
template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
865
866
template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
867
                                              const typename ELF32LE::Sym &,
868
                                              uint32_t Alignment, uint32_t);
869
template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &,
870
                                              const typename ELF32BE::Sym &,
871
                                              uint32_t Alignment, uint32_t);
872
template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
873
                                              const typename ELF64LE::Sym &,
874
                                              uint32_t Alignment, uint32_t);
875
template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
876
                                              const typename ELF64BE::Sym &,
877
                                              uint32_t Alignment, uint32_t);