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