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