Coverage Report

Created: 2019-05-19 14:56

/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
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Symbol table is a bag of all known symbols. We put all symbols of
10
// all input files to the symbol table. The symbol table is basically
11
// a hash table with the logic to resolve symbol name conflicts using
12
// the symbol types.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#include "SymbolTable.h"
17
#include "Config.h"
18
#include "LinkerScript.h"
19
#include "Symbols.h"
20
#include "SyntheticSections.h"
21
#include "lld/Common/ErrorHandler.h"
22
#include "lld/Common/Memory.h"
23
#include "lld/Common/Strings.h"
24
#include "llvm/ADT/STLExtras.h"
25
26
using namespace llvm;
27
using namespace llvm::object;
28
using namespace llvm::ELF;
29
30
using namespace lld;
31
using namespace lld::elf;
32
33
SymbolTable *elf::Symtab;
34
35
// This function is where all the optimizations of link-time
36
// optimization happens. When LTO is in use, some input files are
37
// not in native object file format but in the LLVM bitcode format.
38
// This function compiles bitcode files into a few big native files
39
// using LLVM functions and replaces bitcode symbols with the results.
40
// Because all bitcode files that the program consists of are passed
41
// to the compiler at once, it can do whole-program optimization.
42
2.55k
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
43
2.55k
  // Compile bitcode files and replace bitcode symbols.
44
2.55k
  LTO.reset(new BitcodeCompiler);
45
2.55k
  for (BitcodeFile *F : BitcodeFiles)
46
247
    LTO->add(*F);
47
2.55k
48
2.55k
  for (InputFile *File : LTO->compile()) {
49
208
    DenseSet<CachedHashStringRef> DummyGroups;
50
208
    auto *Obj = cast<ObjFile<ELFT>>(File);
51
208
    Obj->parse(DummyGroups);
52
208
    for (Symbol *Sym : Obj->getGlobalSymbols())
53
258
      Sym->parseSymbolVersion();
54
208
    ObjectFiles.push_back(File);
55
208
  }
56
2.55k
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
42
319
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
43
319
  // Compile bitcode files and replace bitcode symbols.
44
319
  LTO.reset(new BitcodeCompiler);
45
319
  for (BitcodeFile *F : BitcodeFiles)
46
1
    LTO->add(*F);
47
319
48
319
  for (InputFile *File : LTO->compile()) {
49
1
    DenseSet<CachedHashStringRef> DummyGroups;
50
1
    auto *Obj = cast<ObjFile<ELFT>>(File);
51
1
    Obj->parse(DummyGroups);
52
1
    for (Symbol *Sym : Obj->getGlobalSymbols())
53
1
      Sym->parseSymbolVersion();
54
1
    ObjectFiles.push_back(File);
55
1
  }
56
319
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
42
133
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
43
133
  // Compile bitcode files and replace bitcode symbols.
44
133
  LTO.reset(new BitcodeCompiler);
45
133
  for (BitcodeFile *F : BitcodeFiles)
46
0
    LTO->add(*F);
47
133
48
133
  for (InputFile *File : LTO->compile()) {
49
0
    DenseSet<CachedHashStringRef> DummyGroups;
50
0
    auto *Obj = cast<ObjFile<ELFT>>(File);
51
0
    Obj->parse(DummyGroups);
52
0
    for (Symbol *Sym : Obj->getGlobalSymbols())
53
0
      Sym->parseSymbolVersion();
54
0
    ObjectFiles.push_back(File);
55
0
  }
56
133
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
42
1.98k
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
43
1.98k
  // Compile bitcode files and replace bitcode symbols.
44
1.98k
  LTO.reset(new BitcodeCompiler);
45
1.98k
  for (BitcodeFile *F : BitcodeFiles)
46
246
    LTO->add(*F);
47
1.98k
48
1.98k
  for (InputFile *File : LTO->compile()) {
49
207
    DenseSet<CachedHashStringRef> DummyGroups;
50
207
    auto *Obj = cast<ObjFile<ELFT>>(File);
51
207
    Obj->parse(DummyGroups);
52
207
    for (Symbol *Sym : Obj->getGlobalSymbols())
53
257
      Sym->parseSymbolVersion();
54
207
    ObjectFiles.push_back(File);
55
207
  }
56
1.98k
}
void lld::elf::SymbolTable::addCombinedLTOObject<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
42
115
template <class ELFT> void SymbolTable::addCombinedLTOObject() {
43
115
  // Compile bitcode files and replace bitcode symbols.
44
115
  LTO.reset(new BitcodeCompiler);
45
115
  for (BitcodeFile *F : BitcodeFiles)
46
0
    LTO->add(*F);
47
115
48
115
  for (InputFile *File : LTO->compile()) {
49
0
    DenseSet<CachedHashStringRef> DummyGroups;
50
0
    auto *Obj = cast<ObjFile<ELFT>>(File);
51
0
    Obj->parse(DummyGroups);
52
0
    for (Symbol *Sym : Obj->getGlobalSymbols())
53
0
      Sym->parseSymbolVersion();
54
0
    ObjectFiles.push_back(File);
55
0
  }
56
115
}
57
58
// Set a flag for --trace-symbol so that we can print out a log message
59
// if a new symbol with the same name is inserted into the symbol table.
60
34
void SymbolTable::trace(StringRef Name) {
61
34
  SymMap.insert({CachedHashStringRef(Name), -1});
62
34
}
63
64
13
void SymbolTable::wrap(Symbol *Sym, Symbol *Real, Symbol *Wrap) {
65
13
  // Swap symbols as instructed by -wrap.
66
13
  int &Idx1 = SymMap[CachedHashStringRef(Sym->getName())];
67
13
  int &Idx2 = SymMap[CachedHashStringRef(Real->getName())];
68
13
  int &Idx3 = SymMap[CachedHashStringRef(Wrap->getName())];
69
13
70
13
  Idx2 = Idx1;
71
13
  Idx1 = Idx3;
72
13
73
13
  // Now renaming is complete. No one refers Real symbol. We could leave
74
13
  // Real as-is, but if Real is written to the symbol table, that may
75
13
  // contain irrelevant values. So, we copy all values from Sym to Real.
76
13
  StringRef S = Real->getName();
77
13
  memcpy(Real, Sym, sizeof(SymbolUnion));
78
13
  Real->setName(S);
79
13
}
80
81
19.4k
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
82
19.4k
  if (VA == STV_DEFAULT)
83
19.3k
    return VB;
84
85
  if (VB == STV_DEFAULT)
85
38
    return VA;
86
47
  return std::min(VA, VB);
87
47
}
88
89
// Find an existing symbol or create a new one.
90
20.3k
Symbol *SymbolTable::insert(StringRef Name) {
91
20.3k
  // <name>@@<version> means the symbol is the default version. In that
92
20.3k
  // case <name>@@<version> will be used to resolve references to <name>.
93
20.3k
  //
94
20.3k
  // Since this is a hot path, the following string search code is
95
20.3k
  // optimized for speed. StringRef::find(char) is much faster than
96
20.3k
  // StringRef::find(StringRef).
97
20.3k
  size_t Pos = Name.find('@');
98
20.3k
  if (Pos != StringRef::npos && 
Pos + 1 < Name.size()103
&&
Name[Pos + 1] == '@'102
)
99
22
    Name = Name.take_front(Pos);
100
20.3k
101
20.3k
  auto P = SymMap.insert({CachedHashStringRef(Name), (int)SymVector.size()});
102
20.3k
  int &SymIndex = P.first->second;
103
20.3k
  bool IsNew = P.second;
104
20.3k
  bool Traced = false;
105
20.3k
106
20.3k
  if (SymIndex == -1) {
107
28
    SymIndex = SymVector.size();
108
28
    IsNew = true;
109
28
    Traced = true;
110
28
  }
111
20.3k
112
20.3k
  if (!IsNew)
113
2.32k
    return SymVector[SymIndex];
114
18.0k
115
18.0k
  Symbol *Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
116
18.0k
  SymVector.push_back(Sym);
117
18.0k
118
18.0k
  Sym->SymbolKind = Symbol::PlaceholderKind;
119
18.0k
  Sym->VersionId = Config->DefaultSymbolVersion;
120
18.0k
  Sym->Visibility = STV_DEFAULT;
121
18.0k
  Sym->IsUsedInRegularObj = false;
122
18.0k
  Sym->ExportDynamic = false;
123
18.0k
  Sym->CanInline = true;
124
18.0k
  Sym->Traced = Traced;
125
18.0k
  Sym->ScriptDefined = false;
126
18.0k
  return Sym;
127
18.0k
}
128
129
19.6k
Symbol *SymbolTable::addSymbol(const Symbol &New) {
130
19.6k
  Symbol *Old = Symtab->insert(New.getName());
131
19.6k
  resolveSymbol(Old, New);
132
19.6k
  return Old;
133
19.6k
}
134
135
352
static void addUndefined(Symbol *Old, const Undefined &New) {
136
352
  // An undefined symbol with non default visibility must be satisfied
137
352
  // in the same DSO.
138
352
  if (Old->isShared() && 
New.Visibility != STV_DEFAULT41
) {
139
2
    replaceSymbol(Old, New);
140
2
    return;
141
2
  }
142
350
143
350
  if (Old->isShared() || 
Old->isLazy()311
||
144
350
      
(283
Old->isUndefined()283
&&
New.Binding != STB_WEAK80
))
145
145
    Old->Binding = New.Binding;
146
350
147
350
  if (Old->isLazy()) {
148
28
    // An undefined weak will not fetch archive members. See comment on Lazy in
149
28
    // Symbols.h for the details.
150
28
    if (New.Binding == STB_WEAK) {
151
3
      Old->Type = New.Type;
152
3
      return;
153
3
    }
154
25
155
25
    // Do extra check for --warn-backrefs.
156
25
    //
157
25
    // --warn-backrefs is an option to prevent an undefined reference from
158
25
    // fetching an archive member written earlier in the command line. It can be
159
25
    // used to keep compatibility with GNU linkers to some degree.
160
25
    // I'll explain the feature and why you may find it useful in this comment.
161
25
    //
162
25
    // lld's symbol resolution semantics is more relaxed than traditional Unix
163
25
    // linkers. For example,
164
25
    //
165
25
    //   ld.lld foo.a bar.o
166
25
    //
167
25
    // succeeds even if bar.o contains an undefined symbol that has to be
168
25
    // resolved by some object file in foo.a. Traditional Unix linkers don't
169
25
    // allow this kind of backward reference, as they visit each file only once
170
25
    // from left to right in the command line while resolving all undefined
171
25
    // symbols at the moment of visiting.
172
25
    //
173
25
    // In the above case, since there's no undefined symbol when a linker visits
174
25
    // foo.a, no files are pulled out from foo.a, and because the linker forgets
175
25
    // about foo.a after visiting, it can't resolve undefined symbols in bar.o
176
25
    // that could have been resolved otherwise.
177
25
    //
178
25
    // That lld accepts more relaxed form means that (besides it'd make more
179
25
    // sense) you can accidentally write a command line or a build file that
180
25
    // works only with lld, even if you have a plan to distribute it to wider
181
25
    // users who may be using GNU linkers. With --warn-backrefs, you can detect
182
25
    // a library order that doesn't work with other Unix linkers.
183
25
    //
184
25
    // The option is also useful to detect cyclic dependencies between static
185
25
    // archives. Again, lld accepts
186
25
    //
187
25
    //   ld.lld foo.a bar.a
188
25
    //
189
25
    // even if foo.a and bar.a depend on each other. With --warn-backrefs, it is
190
25
    // handled as an error.
191
25
    //
192
25
    // Here is how the option works. We assign a group ID to each file. A file
193
25
    // with a smaller group ID can pull out object files from an archive file
194
25
    // with an equal or greater group ID. Otherwise, it is a reverse dependency
195
25
    // and an error.
196
25
    //
197
25
    // A file outside --{start,end}-group gets a fresh ID when instantiated. All
198
25
    // files within the same --{start,end}-group get the same group ID. E.g.
199
25
    //
200
25
    //   ld.lld A B --start-group C D --end-group E
201
25
    //
202
25
    // A forms group 0. B form group 1. C and D (including their member object
203
25
    // files) form group 2. E forms group 3. I think that you can see how this
204
25
    // group assignment rule simulates the traditional linker's semantics.
205
25
    bool Backref = Config->WarnBackrefs && 
New.File10
&&
206
25
                   
Old->File->GroupId < New.File->GroupId10
;
207
25
    Symtab->fetchLazy(Old);
208
25
209
25
    // We don't report backward references to weak symbols as they can be
210
25
    // overridden later.
211
25
    if (Backref && 
!Old->isWeak()5
)
212
4
      warn("backward reference detected: " + New.getName() + " in " +
213
4
           toString(New.File) + " refers to " + toString(Old->File));
214
25
  }
215
350
}
216
217
// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
218
// foo@@VER. We want to effectively ignore foo, so give precedence to
219
// foo@@VER.
220
// FIXME: If users can transition to using
221
// .symver foo,foo@@@VER
222
// we can delete this hack.
223
96
static int compareVersion(StringRef OldName, StringRef NewName) {
224
96
  bool A = OldName.contains("@@");
225
96
  bool B = NewName.contains("@@");
226
96
  if (!A && 
B95
)
227
1
    return 1;
228
95
  if (A && 
!B1
)
229
1
    return -1;
230
94
  return 0;
231
94
}
232
233
// Compare two symbols. Return 1 if the new symbol should win, -1 if
234
// the new symbol should lose, or 0 if there is a conflict.
235
966
static int compare(const Symbol *Old, const Symbol *New) {
236
966
  assert(New->isDefined() || New->isCommon());
237
966
238
966
  if (!Old->isDefined() && 
!Old->isCommon()892
)
239
870
    return 1;
240
96
241
96
  if (int Cmp = compareVersion(Old->getName(), New->getName()))
242
2
    return Cmp;
243
94
244
94
  if (New->isWeak())
245
18
    return -1;
246
76
247
76
  if (Old->isWeak())
248
22
    return 1;
249
54
250
54
  if (Old->isCommon() && 
New->isCommon()16
) {
251
14
    if (Config->WarnCommon)
252
3
      warn("multiple common of " + Old->getName());
253
14
    return 0;
254
14
  }
255
40
256
40
  if (Old->isCommon()) {
257
2
    if (Config->WarnCommon)
258
1
      warn("common " + Old->getName() + " is overridden");
259
2
    return 1;
260
2
  }
261
38
262
38
  if (New->isCommon()) {
263
2
    if (Config->WarnCommon)
264
1
      warn("common " + Old->getName() + " is overridden");
265
2
    return -1;
266
2
  }
267
36
268
36
  auto *OldSym = cast<Defined>(Old);
269
36
  auto *NewSym = cast<Defined>(New);
270
36
271
36
  if (New->File && 
isa<BitcodeFile>(New->File)31
)
272
1
    return 0;
273
35
274
35
  if (!OldSym->Section && 
!NewSym->Section5
&&
OldSym->Value == NewSym->Value5
&&
275
35
      
NewSym->Binding == STB_GLOBAL4
)
276
4
    return -1;
277
31
278
31
  return 0;
279
31
}
280
281
31
static void addCommon(Symbol *Old, const CommonSymbol &New) {
282
31
  int Cmp = compare(Old, &New);
283
31
  if (Cmp < 0)
284
6
    return;
285
25
286
25
  if (Cmp > 0) {
287
11
    replaceSymbol(Old, New);
288
11
    return;
289
11
  }
290
14
291
14
  CommonSymbol *OldSym = cast<CommonSymbol>(Old);
292
14
293
14
  OldSym->Alignment = std::max(OldSym->Alignment, New.Alignment);
294
14
  if (OldSym->Size < New.Size) {
295
12
    OldSym->File = New.File;
296
12
    OldSym->Size = New.Size;
297
12
  }
298
14
}
299
300
static void reportDuplicate(Symbol *Sym, InputFile *NewFile,
301
32
                            InputSectionBase *ErrSec, uint64_t ErrOffset) {
302
32
  if (Config->AllowMultipleDefinition)
303
4
    return;
304
28
305
28
  Defined *D = cast<Defined>(Sym);
306
28
  if (!D->Section || 
!ErrSec26
) {
307
2
    error("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
308
2
          toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
309
2
    return;
310
2
  }
311
26
312
26
  // Construct and print an error message in the form of:
313
26
  //
314
26
  //   ld.lld: error: duplicate symbol: foo
315
26
  //   >>> defined at bar.c:30
316
26
  //   >>>            bar.o (/home/alice/src/bar.o)
317
26
  //   >>> defined at baz.c:563
318
26
  //   >>>            baz.o in archive libbaz.a
319
26
  auto *Sec1 = cast<InputSectionBase>(D->Section);
320
26
  std::string Src1 = Sec1->getSrcMsg(*Sym, D->Value);
321
26
  std::string Obj1 = Sec1->getObjMsg(D->Value);
322
26
  std::string Src2 = ErrSec->getSrcMsg(*Sym, ErrOffset);
323
26
  std::string Obj2 = ErrSec->getObjMsg(ErrOffset);
324
26
325
26
  std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
326
26
  if (!Src1.empty())
327
10
    Msg += Src1 + "\n>>>            ";
328
26
  Msg += Obj1 + "\n>>> defined at ";
329
26
  if (!Src2.empty())
330
10
    Msg += Src2 + "\n>>>            ";
331
26
  Msg += Obj2;
332
26
  error(Msg);
333
26
}
334
335
935
static void addDefined(Symbol *Old, const Defined &New) {
336
935
  int Cmp = compare(Old, &New);
337
935
  if (Cmp > 0)
338
884
    replaceSymbol(Old, New);
339
51
  else if (Cmp == 0)
340
32
    reportDuplicate(Old, New.File,
341
32
                    dyn_cast_or_null<InputSectionBase>(New.Section), New.Value);
342
935
}
343
344
421
static void addShared(Symbol *Old, const SharedSymbol &New) {
345
421
  if (Old->Visibility == STV_DEFAULT && 
(416
Old->isUndefined()416
||
Old->isLazy()37
)) {
346
381
    // An undefined symbol with non default visibility must be satisfied
347
381
    // in the same DSO.
348
381
    uint8_t Binding = Old->Binding;
349
381
    replaceSymbol(Old, New);
350
381
    Old->Binding = Binding;
351
381
  }
352
421
}
353
354
659k
Symbol *SymbolTable::find(StringRef Name) {
355
659k
  auto It = SymMap.find(CachedHashStringRef(Name));
356
659k
  if (It == SymMap.end())
357
656k
    return nullptr;
358
3.31k
  if (It->second == -1)
359
1
    return nullptr;
360
3.31k
  return SymVector[It->second];
361
3.31k
}
362
363
116
template <class LazyT> static void addLazy(Symbol *Old, const LazyT &New) {
364
116
  if (!Old->isUndefined())
365
35
    return;
366
81
367
81
  // An undefined weak will not fetch archive members. See comment on Lazy in
368
81
  // Symbols.h for the details.
369
81
  if (Old->isWeak()) {
370
15
    uint8_t Type = Old->Type;
371
15
    replaceSymbol(Old, New);
372
15
    Old->Type = Type;
373
15
    Old->Binding = STB_WEAK;
374
15
    return;
375
15
  }
376
66
377
66
  if (InputFile *F = New.fetch())
378
65
    parseFile(F);
379
66
}
SymbolTable.cpp:void addLazy<lld::elf::LazyArchive>(lld::elf::Symbol*, lld::elf::LazyArchive const&)
Line
Count
Source
363
101
template <class LazyT> static void addLazy(Symbol *Old, const LazyT &New) {
364
101
  if (!Old->isUndefined())
365
32
    return;
366
69
367
69
  // An undefined weak will not fetch archive members. See comment on Lazy in
368
69
  // Symbols.h for the details.
369
69
  if (Old->isWeak()) {
370
14
    uint8_t Type = Old->Type;
371
14
    replaceSymbol(Old, New);
372
14
    Old->Type = Type;
373
14
    Old->Binding = STB_WEAK;
374
14
    return;
375
14
  }
376
55
377
55
  if (InputFile *F = New.fetch())
378
55
    parseFile(F);
379
55
}
SymbolTable.cpp:void addLazy<lld::elf::LazyObject>(lld::elf::Symbol*, lld::elf::LazyObject const&)
Line
Count
Source
363
15
template <class LazyT> static void addLazy(Symbol *Old, const LazyT &New) {
364
15
  if (!Old->isUndefined())
365
3
    return;
366
12
367
12
  // An undefined weak will not fetch archive members. See comment on Lazy in
368
12
  // Symbols.h for the details.
369
12
  if (Old->isWeak()) {
370
1
    uint8_t Type = Old->Type;
371
1
    replaceSymbol(Old, New);
372
1
    Old->Type = Type;
373
1
    Old->Binding = STB_WEAK;
374
1
    return;
375
1
  }
376
11
377
11
  if (InputFile *F = New.fetch())
378
10
    parseFile(F);
379
11
}
380
381
101
static void addLazyArchive(Symbol *Old, const LazyArchive &New) {
382
101
  addLazy(Old, New);
383
101
}
384
385
15
static void addLazyObject(Symbol *Old, const LazyObject &New) {
386
15
  addLazy(Old, New);
387
15
}
388
389
43
void SymbolTable::fetchLazy(Symbol *Sym) {
390
43
  if (auto *S = dyn_cast<LazyArchive>(Sym)) {
391
34
    if (InputFile *File = S->fetch())
392
32
      parseFile(File);
393
34
    return;
394
34
  }
395
9
396
9
  auto *S = cast<LazyObject>(Sym);
397
9
  if (InputFile *File = cast<LazyObjFile>(S->File)->fetch())
398
8
    parseFile(File);
399
9
}
400
401
// Initialize DemangledSyms with a map from demangled symbols to symbol
402
// objects. Used to handle "extern C++" directive in version scripts.
403
//
404
// The map will contain all demangled symbols. That can be very large,
405
// and in LLD we generally want to avoid do anything for each symbol.
406
// Then, why are we doing this? Here's why.
407
//
408
// Users can use "extern C++ {}" directive to match against demangled
409
// C++ symbols. For example, you can write a pattern such as
410
// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
411
// other than trying to match a pattern against all demangled symbols.
412
// So, if "extern C++" feature is used, we need to demangle all known
413
// symbols.
414
29
StringMap<std::vector<Symbol *>> &SymbolTable::getDemangledSyms() {
415
29
  if (!DemangledSyms) {
416
22
    DemangledSyms.emplace();
417
45
    for (Symbol *Sym : SymVector) {
418
45
      if (!Sym->isDefined() && 
!Sym->isCommon()1
)
419
1
        continue;
420
44
      if (Optional<std::string> S = demangleItanium(Sym->getName()))
421
43
        (*DemangledSyms)[*S].push_back(Sym);
422
1
      else
423
1
        (*DemangledSyms)[Sym->getName()].push_back(Sym);
424
44
    }
425
22
  }
426
29
  return *DemangledSyms;
427
29
}
428
429
100
std::vector<Symbol *> SymbolTable::findByVersion(SymbolVersion Ver) {
430
100
  if (Ver.IsExternCpp)
431
12
    return getDemangledSyms().lookup(Ver.Name);
432
88
  if (Symbol *B = find(Ver.Name))
433
77
    if (B->isDefined() || 
B->isCommon()3
)
434
74
      return {B};
435
14
  return {};
436
14
}
437
438
27
std::vector<Symbol *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
439
27
  std::vector<Symbol *> Res;
440
27
  StringMatcher M(Ver.Name);
441
27
442
27
  if (Ver.IsExternCpp) {
443
17
    for (auto &P : getDemangledSyms())
444
42
      if (M.match(P.first()))
445
19
        Res.insert(Res.end(), P.second.begin(), P.second.end());
446
17
    return Res;
447
17
  }
448
10
449
10
  for (Symbol *Sym : SymVector)
450
35
    if ((Sym->isDefined() || 
Sym->isCommon()0
) && M.match(Sym->getName()))
451
23
      Res.push_back(Sym);
452
10
  return Res;
453
10
}
454
455
// If there's only one anonymous version definition in a version
456
// script file, the script does not actually define any symbol version,
457
// but just specifies symbols visibilities.
458
2.47k
void SymbolTable::handleAnonymousVersion() {
459
2.47k
  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
460
25
    assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
461
2.47k
  for (SymbolVersion &Ver : Config->VersionScriptGlobals)
462
25
    assignWildcardVersion(Ver, VER_NDX_GLOBAL);
463
2.47k
  for (SymbolVersion &Ver : Config->VersionScriptLocals)
464
8
    assignExactVersion(Ver, VER_NDX_LOCAL, "local");
465
2.47k
  for (SymbolVersion &Ver : Config->VersionScriptLocals)
466
8
    assignWildcardVersion(Ver, VER_NDX_LOCAL);
467
2.47k
}
468
469
// Handles -dynamic-list.
470
2.47k
void SymbolTable::handleDynamicList() {
471
2.47k
  for (SymbolVersion &Ver : Config->DynamicList) {
472
26
    std::vector<Symbol *> Syms;
473
26
    if (Ver.HasWildcard)
474
1
      Syms = findAllByVersion(Ver);
475
25
    else
476
25
      Syms = findByVersion(Ver);
477
26
478
26
    for (Symbol *B : Syms) {
479
21
      if (!Config->Shared)
480
18
        B->ExportDynamic = true;
481
3
      else if (B->includeInDynsym())
482
2
        B->IsPreemptible = true;
483
21
    }
484
26
  }
485
2.47k
}
486
487
// Set symbol versions to symbols. This function handles patterns
488
// containing no wildcard characters.
489
void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
490
101
                                     StringRef VersionName) {
491
101
  if (Ver.HasWildcard)
492
26
    return;
493
75
494
75
  // Get a list of symbols which we need to assign the version to.
495
75
  std::vector<Symbol *> Syms = findByVersion(Ver);
496
75
  if (Syms.empty()) {
497
14
    if (!Config->UndefinedVersion)
498
3
      error("version script assignment of '" + VersionName + "' to symbol '" +
499
3
            Ver.Name + "' failed: symbol not defined");
500
14
    return;
501
14
  }
502
61
503
61
  // Assign the version.
504
62
  
for (Symbol *Sym : Syms)61
{
505
62
    // Skip symbols containing version info because symbol versions
506
62
    // specified by symbol names take precedence over version scripts.
507
62
    // See parseSymbolVersion().
508
62
    if (Sym->getName().contains('@'))
509
4
      continue;
510
58
511
58
    if (Sym->VersionId != Config->DefaultSymbolVersion &&
512
58
        
Sym->VersionId != VersionId2
)
513
1
      error("duplicate symbol '" + Ver.Name + "' in version script");
514
58
    Sym->VersionId = VersionId;
515
58
  }
516
61
}
517
518
101
void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
519
101
  if (!Ver.HasWildcard)
520
75
    return;
521
26
522
26
  // Exact matching takes precendence over fuzzy matching,
523
26
  // so we set a version to a symbol only if no version has been assigned
524
26
  // to the symbol. This behavior is compatible with GNU.
525
26
  for (Symbol *B : findAllByVersion(Ver))
526
40
    if (B->VersionId == Config->DefaultSymbolVersion)
527
36
      B->VersionId = VersionId;
528
26
}
529
530
// This function processes version scripts by updating VersionId
531
// member of symbols.
532
2.47k
void SymbolTable::scanVersionScript() {
533
2.47k
  // Handle edge cases first.
534
2.47k
  handleAnonymousVersion();
535
2.47k
  handleDynamicList();
536
2.47k
537
2.47k
  // Now we have version definitions, so we need to set version ids to symbols.
538
2.47k
  // Each version definition has a glob pattern, and all symbols that match
539
2.47k
  // with the pattern get that version.
540
2.47k
541
2.47k
  // First, we assign versions to exact matching symbols,
542
2.47k
  // i.e. version definitions not containing any glob meta-characters.
543
2.47k
  for (VersionDefinition &V : Config->VersionDefinitions)
544
87
    for (SymbolVersion &Ver : V.Globals)
545
68
      assignExactVersion(Ver, V.Id, V.Name);
546
2.47k
547
2.47k
  // Next, we assign versions to fuzzy matching symbols,
548
2.47k
  // i.e. version definitions containing glob meta-characters.
549
2.47k
  // Note that because the last match takes precedence over previous matches,
550
2.47k
  // we iterate over the definitions in the reverse order.
551
2.47k
  for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
552
87
    for (SymbolVersion &Ver : V.Globals)
553
68
      assignWildcardVersion(Ver, V.Id);
554
2.47k
555
2.47k
  // Symbol themselves might know their versions because symbols
556
2.47k
  // can contain versions in the form of <name>@<version>.
557
2.47k
  // Let them parse and update their names to exclude version suffix.
558
2.47k
  for (Symbol *Sym : SymVector)
559
16.5k
    Sym->parseSymbolVersion();
560
2.47k
}
561
562
// Merge symbol properties.
563
//
564
// When we have many symbols of the same name, we choose one of them,
565
// and that's the result of symbol resolution. However, symbols that
566
// were not chosen still affect some symbol properties.
567
20.3k
void elf::mergeSymbolProperties(Symbol *Old, const Symbol &New) {
568
20.3k
  // Merge symbol properties.
569
20.3k
  Old->ExportDynamic = Old->ExportDynamic || 
New.ExportDynamic19.6k
;
570
20.3k
  Old->IsUsedInRegularObj = Old->IsUsedInRegularObj || 
New.IsUsedInRegularObj18.4k
;
571
20.3k
572
20.3k
  // DSO symbols do not affect visibility in the output.
573
20.3k
  if (!New.isShared())
574
19.4k
    Old->Visibility = getMinVisibility(Old->Visibility, New.Visibility);
575
20.3k
}
576
577
19.6k
void elf::resolveSymbol(Symbol *Old, const Symbol &New) {
578
19.6k
  mergeSymbolProperties(Old, New);
579
19.6k
580
19.6k
  if (Old->isPlaceholder()) {
581
17.8k
    replaceSymbol(Old, New);
582
17.8k
    return;
583
17.8k
  }
584
1.85k
585
1.85k
  switch (New.kind()) {
586
1.85k
  case Symbol::UndefinedKind:
587
352
    addUndefined(Old, cast<Undefined>(New));
588
352
    break;
589
1.85k
  case Symbol::CommonKind:
590
31
    addCommon(Old, cast<CommonSymbol>(New));
591
31
    break;
592
1.85k
  case Symbol::DefinedKind:
593
935
    addDefined(Old, cast<Defined>(New));
594
935
    break;
595
1.85k
  case Symbol::LazyArchiveKind:
596
101
    addLazyArchive(Old, cast<LazyArchive>(New));
597
101
    break;
598
1.85k
  case Symbol::LazyObjectKind:
599
15
    addLazyObject(Old, cast<LazyObject>(New));
600
15
    break;
601
1.85k
  case Symbol::SharedKind:
602
421
    addShared(Old, cast<SharedSymbol>(New));
603
421
    break;
604
1.85k
  case Symbol::PlaceholderKind:
605
0
    llvm_unreachable("bad symbol kind");
606
1.85k
  }
607
1.85k
}
608
609
template void SymbolTable::addCombinedLTOObject<ELF32LE>();
610
template void SymbolTable::addCombinedLTOObject<ELF32BE>();
611
template void SymbolTable::addCombinedLTOObject<ELF64LE>();
612
template void SymbolTable::addCombinedLTOObject<ELF64BE>();