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 "Error.h"
20 #include "LinkerScript.h"
21 #include "SymbolListFile.h"
22 #include "Symbols.h"
23 #include "llvm/Bitcode/ReaderWriter.h"
24 #include "llvm/Support/StringSaver.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 // All input object files must be for the same architecture
34 // (e.g. it does not make sense to link x86 object files with
35 // MIPS object files.) This function checks for that error.
36 template <class ELFT> static bool isCompatible(InputFile *F) {
37   if (!isa<ELFFileBase<ELFT>>(F) && !isa<BitcodeFile>(F))
38     return true;
39   if (F->EKind == Config->EKind && F->EMachine == Config->EMachine)
40     return true;
41   StringRef A = F->getName();
42   StringRef B = Config->Emulation;
43   if (B.empty())
44     B = Config->FirstElf->getName();
45   error(A + " is incompatible with " + B);
46   return false;
47 }
48 
49 // Add symbols in File to the symbol table.
50 template <class ELFT>
51 void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
52   InputFile *FileP = File.get();
53   if (!isCompatible<ELFT>(FileP))
54     return;
55 
56   // Binary file
57   if (auto *F = dyn_cast<BinaryFile>(FileP)) {
58     addFile(F->createELF<ELFT>());
59     return;
60   }
61 
62   // .a file
63   if (auto *F = dyn_cast<ArchiveFile>(FileP)) {
64     ArchiveFiles.emplace_back(cast<ArchiveFile>(File.release()));
65     F->parse<ELFT>();
66     return;
67   }
68 
69   // Lazy object file
70   if (auto *F = dyn_cast<LazyObjectFile>(FileP)) {
71     LazyObjectFiles.emplace_back(cast<LazyObjectFile>(File.release()));
72     F->parse<ELFT>();
73     return;
74   }
75 
76   if (Config->Trace)
77     outs() << getFilename(FileP) << "\n";
78 
79   // .so file
80   if (auto *F = dyn_cast<SharedFile<ELFT>>(FileP)) {
81     // DSOs are uniquified not by filename but by soname.
82     F->parseSoName();
83     if (!SoNames.insert(F->getSoName()).second)
84       return;
85 
86     SharedFiles.emplace_back(cast<SharedFile<ELFT>>(File.release()));
87     F->parseRest();
88     return;
89   }
90 
91   // LLVM bitcode file
92   if (auto *F = dyn_cast<BitcodeFile>(FileP)) {
93     BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
94     F->parse<ELFT>(ComdatGroups);
95     return;
96   }
97 
98   // Regular object file
99   auto *F = cast<ObjectFile<ELFT>>(FileP);
100   ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(File.release()));
101   F->parse(ComdatGroups);
102 }
103 
104 // This function is where all the optimizations of link-time
105 // optimization happens. When LTO is in use, some input files are
106 // not in native object file format but in the LLVM bitcode format.
107 // This function compiles bitcode files into a few big native files
108 // using LLVM functions and replaces bitcode symbols with the results.
109 // Because all bitcode files that consist of a program are passed
110 // to the compiler at once, it can do whole-program optimization.
111 template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() {
112   if (BitcodeFiles.empty())
113     return;
114 
115   // Compile bitcode files.
116   Lto.reset(new BitcodeCompiler);
117   for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)
118     Lto->add(*F);
119   std::vector<std::unique_ptr<InputFile>> IFs = Lto->compile();
120 
121   // Replace bitcode symbols.
122   for (auto &IF : IFs) {
123     ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(IF.release());
124 
125     DenseSet<StringRef> DummyGroups;
126     Obj->parse(DummyGroups);
127     ObjectFiles.emplace_back(Obj);
128   }
129 }
130 
131 template <class ELFT>
132 DefinedRegular<ELFT> *SymbolTable<ELFT>::addAbsolute(StringRef Name,
133                                                      uint8_t Visibility) {
134   return cast<DefinedRegular<ELFT>>(
135       addRegular(Name, STB_GLOBAL, Visibility)->body());
136 }
137 
138 // Add Name as an "ignored" symbol. An ignored symbol is a regular
139 // linker-synthesized defined symbol, but is only defined if needed.
140 template <class ELFT>
141 DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name,
142                                                     uint8_t Visibility) {
143   if (!find(Name))
144     return nullptr;
145   return addAbsolute(Name, Visibility);
146 }
147 
148 // Set a flag for --trace-symbol so that we can print out a log message
149 // if a new symbol with the same name is inserted into the symbol table.
150 template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
151   Symtab.insert({Name, {-1, true}});
152 }
153 
154 // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
155 // Used to implement --wrap.
156 template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) {
157   SymbolBody *B = find(Name);
158   if (!B)
159     return;
160   StringSaver Saver(Alloc);
161   Symbol *Sym = B->symbol();
162   Symbol *Real = addUndefined(Saver.save("__real_" + Name));
163   Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name));
164   // We rename symbols by replacing the old symbol's SymbolBody with the new
165   // symbol's SymbolBody. This causes all SymbolBody pointers referring to the
166   // old symbol to instead refer to the new symbol.
167   memcpy(Real->Body.buffer, Sym->Body.buffer, sizeof(Sym->Body));
168   memcpy(Sym->Body.buffer, Wrap->Body.buffer, sizeof(Wrap->Body));
169 }
170 
171 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
172   if (VA == STV_DEFAULT)
173     return VB;
174   if (VB == STV_DEFAULT)
175     return VA;
176   return std::min(VA, VB);
177 }
178 
179 // Parses a symbol in the form of <name>@<version> or <name>@@<version>.
180 static std::pair<StringRef, uint16_t> getSymbolVersion(StringRef S) {
181   if (Config->VersionDefinitions.empty())
182     return {S, Config->DefaultSymbolVersion};
183 
184   size_t Pos = S.find('@');
185   if (Pos == 0 || Pos == StringRef::npos)
186     return {S, Config->DefaultSymbolVersion};
187 
188   StringRef Name = S.substr(0, Pos);
189   StringRef Verstr = S.substr(Pos + 1);
190   if (Verstr.empty())
191     return {S, Config->DefaultSymbolVersion};
192 
193   // '@@' in a symbol name means the default version.
194   // It is usually the most recent one.
195   bool IsDefault = (Verstr[0] == '@');
196   if (IsDefault)
197     Verstr = Verstr.substr(1);
198 
199   for (VersionDefinition &V : Config->VersionDefinitions) {
200     if (V.Name == Verstr)
201       return {Name, IsDefault ? V.Id : (V.Id | VERSYM_HIDDEN)};
202   }
203 
204   // It is an error if the specified version was not defined.
205   error("symbol " + S + " has undefined version " + Verstr);
206   return {S, Config->DefaultSymbolVersion};
207 }
208 
209 // Find an existing symbol or create and insert a new one.
210 template <class ELFT>
211 std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef &Name) {
212   auto P = Symtab.insert({Name, SymIndex((int)SymVector.size(), false)});
213   SymIndex &V = P.first->second;
214   bool IsNew = P.second;
215 
216   if (V.Idx == -1) {
217     IsNew = true;
218     V = SymIndex((int)SymVector.size(), true);
219   }
220 
221   Symbol *Sym;
222   if (IsNew) {
223     Sym = new (Alloc) Symbol;
224     Sym->Binding = STB_WEAK;
225     Sym->Visibility = STV_DEFAULT;
226     Sym->IsUsedInRegularObj = false;
227     Sym->HasUnnamedAddr = true;
228     Sym->ExportDynamic = false;
229     Sym->Traced = V.Traced;
230     std::tie(Name, Sym->VersionId) = getSymbolVersion(Name);
231     SymVector.push_back(Sym);
232   } else {
233     Sym = SymVector[V.Idx];
234   }
235   return {Sym, IsNew};
236 }
237 
238 // Find an existing symbol or create and insert a new one, then apply the given
239 // attributes.
240 template <class ELFT>
241 std::pair<Symbol *, bool>
242 SymbolTable<ELFT>::insert(StringRef &Name, uint8_t Type, uint8_t Visibility,
243                           bool CanOmitFromDynSym, bool HasUnnamedAddr,
244                           InputFile *File) {
245   bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind;
246   Symbol *S;
247   bool WasInserted;
248   std::tie(S, WasInserted) = insert(Name);
249 
250   // Merge in the new unnamed_addr attribute.
251   S->HasUnnamedAddr &= HasUnnamedAddr;
252   // Merge in the new symbol's visibility.
253   S->Visibility = getMinVisibility(S->Visibility, Visibility);
254   if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
255     S->ExportDynamic = true;
256   if (IsUsedInRegularObj)
257     S->IsUsedInRegularObj = true;
258   if (!WasInserted && S->body()->Type != SymbolBody::UnknownType &&
259       ((Type == STT_TLS) != S->body()->isTls()))
260     error("TLS attribute mismatch for symbol: " +
261           conflictMsg(S->body(), File));
262 
263   return {S, WasInserted};
264 }
265 
266 // Construct a string in the form of "Sym in File1 and File2".
267 // Used to construct an error message.
268 template <typename ELFT>
269 std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Existing,
270                                            InputFile *NewFile) {
271   std::string Sym = Existing->getName();
272   if (Config->Demangle)
273     Sym = demangle(Sym);
274   return Sym + " in " + getFilename(Existing->File) + " and " +
275          getFilename(NewFile);
276 }
277 
278 template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) {
279   return addUndefined(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0,
280                       /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false,
281                       /*File*/ nullptr);
282 }
283 
284 template <class ELFT>
285 Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, uint8_t Binding,
286                                         uint8_t StOther, uint8_t Type,
287                                         bool CanOmitFromDynSym,
288                                         bool HasUnnamedAddr, InputFile *File) {
289   Symbol *S;
290   bool WasInserted;
291   std::tie(S, WasInserted) =
292       insert(Name, Type, StOther & 3, CanOmitFromDynSym, HasUnnamedAddr, File);
293   if (WasInserted) {
294     S->Binding = Binding;
295     replaceBody<Undefined>(S, Name, StOther, Type, File);
296     return S;
297   }
298   if (Binding != STB_WEAK) {
299     if (S->body()->isShared() || S->body()->isLazy())
300       S->Binding = Binding;
301     if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(S->body()))
302       SS->file()->IsUsed = true;
303   }
304   if (auto *L = dyn_cast<Lazy>(S->body())) {
305     // An undefined weak will not fetch archive members, but we have to remember
306     // its type. See also comment in addLazyArchive.
307     if (S->isWeak())
308       L->Type = Type;
309     else if (auto F = L->fetch())
310       addFile(std::move(F));
311   }
312   return S;
313 }
314 
315 // We have a new defined symbol with the specified binding. Return 1 if the new
316 // symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
317 // strong defined symbols.
318 static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding) {
319   if (WasInserted)
320     return 1;
321   SymbolBody *Body = S->body();
322   if (Body->isLazy() || Body->isUndefined() || Body->isShared())
323     return 1;
324   if (Binding == STB_WEAK)
325     return -1;
326   if (S->isWeak())
327     return 1;
328   return 0;
329 }
330 
331 // We have a new non-common defined symbol with the specified binding. Return 1
332 // if the new symbol should win, -1 if the new symbol should lose, or 0 if there
333 // is a conflict. If the new symbol wins, also update the binding.
334 static int compareDefinedNonCommon(Symbol *S, bool WasInserted,
335                                    uint8_t Binding) {
336   if (int Cmp = compareDefined(S, WasInserted, Binding)) {
337     if (Cmp > 0)
338       S->Binding = Binding;
339     return Cmp;
340   }
341   if (isa<DefinedCommon>(S->body())) {
342     // Non-common symbols take precedence over common symbols.
343     if (Config->WarnCommon)
344       warning("common " + S->body()->getName() + " is overridden");
345     return 1;
346   }
347   return 0;
348 }
349 
350 template <class ELFT>
351 Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size,
352                                      uint64_t Alignment, uint8_t Binding,
353                                      uint8_t StOther, uint8_t Type,
354                                      bool HasUnnamedAddr, InputFile *File) {
355   Symbol *S;
356   bool WasInserted;
357   std::tie(S, WasInserted) = insert(
358       N, Type, StOther & 3, /*CanOmitFromDynSym*/ false, HasUnnamedAddr, File);
359   int Cmp = compareDefined(S, WasInserted, Binding);
360   if (Cmp > 0) {
361     S->Binding = Binding;
362     replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File);
363   } else if (Cmp == 0) {
364     auto *C = dyn_cast<DefinedCommon>(S->body());
365     if (!C) {
366       // Non-common symbols take precedence over common symbols.
367       if (Config->WarnCommon)
368         warning("common " + S->body()->getName() + " is overridden");
369       return S;
370     }
371 
372     if (Config->WarnCommon)
373       warning("multiple common of " + S->body()->getName());
374 
375     Alignment = C->Alignment = std::max(C->Alignment, Alignment);
376     if (Size > C->Size)
377       replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File);
378   }
379   return S;
380 }
381 
382 template <class ELFT>
383 void SymbolTable<ELFT>::reportDuplicate(SymbolBody *Existing,
384                                         InputFile *NewFile) {
385   std::string Msg = "duplicate symbol: " + conflictMsg(Existing, NewFile);
386   if (Config->AllowMultipleDefinition)
387     warning(Msg);
388   else
389     error(Msg);
390 }
391 
392 template <typename ELFT>
393 Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, const Elf_Sym &Sym,
394                                       InputSectionBase<ELFT> *Section) {
395   Symbol *S;
396   bool WasInserted;
397   std::tie(S, WasInserted) =
398       insert(Name, Sym.getType(), Sym.getVisibility(),
399              /*CanOmitFromDynSym*/ false, /*HasUnnamedAddr*/ false,
400              Section ? Section->getFile() : nullptr);
401   int Cmp = compareDefinedNonCommon(S, WasInserted, Sym.getBinding());
402   if (Cmp > 0)
403     replaceBody<DefinedRegular<ELFT>>(S, Name, Sym, Section);
404   else if (Cmp == 0)
405     reportDuplicate(S->body(), Section->getFile());
406   return S;
407 }
408 
409 template <typename ELFT>
410 Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t Binding,
411                                       uint8_t StOther) {
412   Symbol *S;
413   bool WasInserted;
414   std::tie(S, WasInserted) =
415       insert(Name, STT_NOTYPE, StOther & 3, /*CanOmitFromDynSym*/ false,
416              /*HasUnnamedAddr*/ false, nullptr);
417   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding);
418   if (Cmp > 0)
419     replaceBody<DefinedRegular<ELFT>>(S, Name, StOther);
420   else if (Cmp == 0)
421     reportDuplicate(S->body(), nullptr);
422   return S;
423 }
424 
425 template <typename ELFT>
426 Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
427                                         OutputSectionBase<ELFT> *Section,
428                                         uintX_t Value, uint8_t StOther) {
429   Symbol *S;
430   bool WasInserted;
431   std::tie(S, WasInserted) = insert(N, STT_NOTYPE, /*Visibility*/ StOther & 0x3,
432                                     /*CanOmitFromDynSym*/ false,
433                                     /*HasUnnamedAddr*/ false, nullptr);
434   int Cmp = compareDefinedNonCommon(S, WasInserted, STB_GLOBAL);
435   if (Cmp > 0)
436     replaceBody<DefinedSynthetic<ELFT>>(S, N, Value, Section);
437   else if (Cmp == 0)
438     reportDuplicate(S->body(), nullptr);
439   return S;
440 }
441 
442 template <typename ELFT>
443 void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name,
444                                   const Elf_Sym &Sym,
445                                   const typename ELFT::Verdef *Verdef) {
446   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
447   // as the visibility, which will leave the visibility in the symbol table
448   // unchanged.
449   Symbol *S;
450   bool WasInserted;
451   std::tie(S, WasInserted) =
452       insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true,
453              /*HasUnnamedAddr*/ false, F);
454   // Make sure we preempt DSO symbols with default visibility.
455   if (Sym.getVisibility() == STV_DEFAULT)
456     S->ExportDynamic = true;
457   if (WasInserted || isa<Undefined>(S->body())) {
458     replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
459     if (!S->isWeak())
460       F->IsUsed = true;
461   }
462 }
463 
464 template <class ELFT>
465 Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, uint8_t Binding,
466                                       uint8_t StOther, uint8_t Type,
467                                       bool CanOmitFromDynSym,
468                                       bool HasUnnamedAddr, BitcodeFile *F) {
469   Symbol *S;
470   bool WasInserted;
471   std::tie(S, WasInserted) =
472       insert(Name, Type, StOther & 3, CanOmitFromDynSym, HasUnnamedAddr, F);
473   int Cmp = compareDefinedNonCommon(S, WasInserted, Binding);
474   if (Cmp > 0)
475     replaceBody<DefinedRegular<ELFT>>(S, Name, StOther, Type, F);
476   else if (Cmp == 0)
477     reportDuplicate(S->body(), F);
478   return S;
479 }
480 
481 template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
482   auto It = Symtab.find(Name);
483   if (It == Symtab.end())
484     return nullptr;
485   SymIndex V = It->second;
486   if (V.Idx == -1)
487     return nullptr;
488   return SymVector[V.Idx]->body();
489 }
490 
491 // Returns a list of defined symbols that match with a given regex.
492 template <class ELFT>
493 std::vector<SymbolBody *> SymbolTable<ELFT>::findAll(const Regex &Re) {
494   std::vector<SymbolBody *> Res;
495   for (Symbol *Sym : SymVector) {
496     SymbolBody *B = Sym->body();
497     StringRef Name = B->getName();
498     if (!B->isUndefined() && const_cast<Regex &>(Re).match(Name))
499       Res.push_back(B);
500   }
501   return Res;
502 }
503 
504 template <class ELFT>
505 void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
506                                        const object::Archive::Symbol Sym) {
507   Symbol *S;
508   bool WasInserted;
509   StringRef Name = Sym.getName();
510   std::tie(S, WasInserted) = insert(Name);
511   if (WasInserted) {
512     replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType);
513     return;
514   }
515   if (!S->body()->isUndefined())
516     return;
517 
518   // Weak undefined symbols should not fetch members from archives. If we were
519   // to keep old symbol we would not know that an archive member was available
520   // if a strong undefined symbol shows up afterwards in the link. If a strong
521   // undefined symbol never shows up, this lazy symbol will get to the end of
522   // the link and must be treated as the weak undefined one. We already marked
523   // this symbol as used when we added it to the symbol table, but we also need
524   // to preserve its type. FIXME: Move the Type field to Symbol.
525   if (S->isWeak()) {
526     replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type);
527     return;
528   }
529   MemoryBufferRef MBRef = F->getMember(&Sym);
530   if (!MBRef.getBuffer().empty())
531     addFile(createObjectFile(MBRef, F->getName()));
532 }
533 
534 template <class ELFT>
535 void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
536   Symbol *S;
537   bool WasInserted;
538   std::tie(S, WasInserted) = insert(Name);
539   if (WasInserted) {
540     replaceBody<LazyObject>(S, Name, Obj, SymbolBody::UnknownType);
541     return;
542   }
543   if (!S->body()->isUndefined())
544     return;
545 
546   // See comment for addLazyArchive above.
547   if (S->isWeak()) {
548     replaceBody<LazyObject>(S, Name, Obj, S->body()->Type);
549   } else {
550     MemoryBufferRef MBRef = Obj.getBuffer();
551     if (!MBRef.getBuffer().empty())
552       addFile(createObjectFile(MBRef));
553   }
554 }
555 
556 // Process undefined (-u) flags by loading lazy symbols named by those flags.
557 template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() {
558   for (StringRef S : Config->Undefined)
559     if (auto *L = dyn_cast_or_null<Lazy>(find(S)))
560       if (std::unique_ptr<InputFile> File = L->fetch())
561         addFile(std::move(File));
562 }
563 
564 // This function takes care of the case in which shared libraries depend on
565 // the user program (not the other way, which is usual). Shared libraries
566 // may have undefined symbols, expecting that the user program provides
567 // the definitions for them. An example is BSD's __progname symbol.
568 // We need to put such symbols to the main program's .dynsym so that
569 // shared libraries can find them.
570 // Except this, we ignore undefined symbols in DSOs.
571 template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() {
572   for (std::unique_ptr<SharedFile<ELFT>> &File : SharedFiles)
573     for (StringRef U : File->getUndefinedSymbols())
574       if (SymbolBody *Sym = find(U))
575         if (Sym->isDefined())
576           Sym->symbol()->ExportDynamic = true;
577 }
578 
579 // This function processes --export-dynamic-symbol and --dynamic-list.
580 template <class ELFT> void SymbolTable<ELFT>::scanDynamicList() {
581   for (StringRef S : Config->DynamicList)
582     if (SymbolBody *B = find(S))
583       B->symbol()->ExportDynamic = true;
584 }
585 
586 static void setVersionId(SymbolBody *Body, StringRef VersionName,
587                          StringRef Name, uint16_t Version) {
588   if (!Body || Body->isUndefined()) {
589     if (Config->NoUndefinedVersion)
590       error("version script assignment of " + VersionName + " to symbol " +
591             Name + " failed: symbol not defined");
592     return;
593   }
594 
595   Symbol *Sym = Body->symbol();
596   if (Sym->VersionId != Config->DefaultSymbolVersion)
597     warning("duplicate symbol " + Name + " in version script");
598   Sym->VersionId = Version;
599 }
600 
601 template <class ELFT>
602 std::map<std::string, SymbolBody *> SymbolTable<ELFT>::getDemangledSyms() {
603   std::map<std::string, SymbolBody *> Result;
604   for (Symbol *Sym : SymVector) {
605     SymbolBody *B = Sym->body();
606     Result[demangle(B->getName())] = B;
607   }
608   return Result;
609 }
610 
611 static bool hasExternCpp() {
612   for (VersionDefinition &V : Config->VersionDefinitions)
613     for (SymbolVersion Sym : V.Globals)
614       if (Sym.IsExternCpp)
615         return true;
616   return false;
617 }
618 
619 static SymbolBody *findDemangled(const std::map<std::string, SymbolBody *> &D,
620                                  StringRef Name) {
621   auto I = D.find(Name);
622   if (I != D.end())
623     return I->second;
624   return nullptr;
625 }
626 
627 static std::vector<SymbolBody *>
628 findAllDemangled(const std::map<std::string, SymbolBody *> &D,
629                  const Regex &Re) {
630   std::vector<SymbolBody *> Res;
631   for (auto &P : D) {
632     SymbolBody *Body = P.second;
633     if (!Body->isUndefined() && const_cast<Regex &>(Re).match(P.first))
634       Res.push_back(Body);
635   }
636   return Res;
637 }
638 
639 // This function processes version scripts by updating VersionId
640 // member of symbols.
641 template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
642   // If there's only one anonymous version definition in a version
643   // script file, the script does not actullay define any symbol version,
644   // but just specifies symbols visibilities. We assume that the script was
645   // in the form of { global: foo; bar; local *; }. So, local is default.
646   // Here, we make specified symbols global.
647   if (!Config->VersionScriptGlobals.empty()) {
648     std::vector<StringRef> Globs;
649     for (SymbolVersion &Sym : Config->VersionScriptGlobals) {
650       if (hasWildcard(Sym.Name)) {
651         Globs.push_back(Sym.Name);
652         continue;
653       }
654       if (SymbolBody *B = find(Sym.Name))
655         B->symbol()->VersionId = VER_NDX_GLOBAL;
656     }
657     if (Globs.empty())
658       return;
659     Regex Re = compileGlobPatterns(Globs);
660     std::vector<SymbolBody *> Syms = findAll(Re);
661     for (SymbolBody *B : Syms)
662       B->symbol()->VersionId = VER_NDX_GLOBAL;
663     return;
664   }
665 
666   if (Config->VersionDefinitions.empty())
667     return;
668 
669   // Now we have version definitions, so we need to set version ids to symbols.
670   // Each version definition has a glob pattern, and all symbols that match
671   // with the pattern get that version.
672 
673   // Users can use "extern C++ {}" directive to match against demangled
674   // C++ symbols. For example, you can write a pattern such as
675   // "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
676   // other than trying to match a regexp against all demangled symbols.
677   // So, if "extern C++" feature is used, we demangle all known symbols.
678   std::map<std::string, SymbolBody *> Demangled;
679   if (hasExternCpp())
680     Demangled = getDemangledSyms();
681 
682   // First, we assign versions to exact matching symbols,
683   // i.e. version definitions not containing any glob meta-characters.
684   for (VersionDefinition &V : Config->VersionDefinitions) {
685     for (SymbolVersion Sym : V.Globals) {
686       if (Sym.HasWildcards)
687         continue;
688       StringRef N = Sym.Name;
689       SymbolBody *B = Sym.IsExternCpp ? findDemangled(Demangled, N) : find(N);
690       setVersionId(B, V.Name, N, V.Id);
691     }
692   }
693 
694   // Next, we assign versions to fuzzy matching symbols,
695   // i.e. version definitions containing glob meta-characters.
696   // Note that because the last match takes precedence over previous matches,
697   // we iterate over the definitions in the reverse order.
698   for (size_t I = Config->VersionDefinitions.size() - 1; I != (size_t)-1; --I) {
699     VersionDefinition &V = Config->VersionDefinitions[I];
700     for (SymbolVersion &Sym : V.Globals) {
701       if (!Sym.HasWildcards)
702         continue;
703       Regex Re = compileGlobPatterns({Sym.Name});
704       std::vector<SymbolBody *> Syms =
705           Sym.IsExternCpp ? findAllDemangled(Demangled, Re) : findAll(Re);
706 
707       // Exact matching takes precendence over fuzzy matching,
708       // so we set a version to a symbol only if no version has been assigned
709       // to the symbol. This behavior is compatible with GNU.
710       for (SymbolBody *B : Syms)
711         if (B->symbol()->VersionId == Config->DefaultSymbolVersion)
712           B->symbol()->VersionId = V.Id;
713     }
714   }
715 }
716 
717 template class elf::SymbolTable<ELF32LE>;
718 template class elf::SymbolTable<ELF32BE>;
719 template class elf::SymbolTable<ELF64LE>;
720 template class elf::SymbolTable<ELF64BE>;
721