xref: /freebsd-src/contrib/llvm-project/lld/MachO/SymbolTable.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1*5ffd83dbSDimitry Andric //===- SymbolTable.cpp ----------------------------------------------------===//
2*5ffd83dbSDimitry Andric //
3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5ffd83dbSDimitry Andric //
7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
8*5ffd83dbSDimitry Andric 
9*5ffd83dbSDimitry Andric #include "SymbolTable.h"
10*5ffd83dbSDimitry Andric #include "InputFiles.h"
11*5ffd83dbSDimitry Andric #include "Symbols.h"
12*5ffd83dbSDimitry Andric #include "lld/Common/ErrorHandler.h"
13*5ffd83dbSDimitry Andric #include "lld/Common/Memory.h"
14*5ffd83dbSDimitry Andric 
15*5ffd83dbSDimitry Andric using namespace llvm;
16*5ffd83dbSDimitry Andric using namespace lld;
17*5ffd83dbSDimitry Andric using namespace lld::macho;
18*5ffd83dbSDimitry Andric 
19*5ffd83dbSDimitry Andric Symbol *SymbolTable::find(StringRef name) {
20*5ffd83dbSDimitry Andric   auto it = symMap.find(llvm::CachedHashStringRef(name));
21*5ffd83dbSDimitry Andric   if (it == symMap.end())
22*5ffd83dbSDimitry Andric     return nullptr;
23*5ffd83dbSDimitry Andric   return symVector[it->second];
24*5ffd83dbSDimitry Andric }
25*5ffd83dbSDimitry Andric 
26*5ffd83dbSDimitry Andric std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {
27*5ffd83dbSDimitry Andric   auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
28*5ffd83dbSDimitry Andric 
29*5ffd83dbSDimitry Andric   // Name already present in the symbol table.
30*5ffd83dbSDimitry Andric   if (!p.second)
31*5ffd83dbSDimitry Andric     return {symVector[p.first->second], false};
32*5ffd83dbSDimitry Andric 
33*5ffd83dbSDimitry Andric   // Name is a new symbol.
34*5ffd83dbSDimitry Andric   Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
35*5ffd83dbSDimitry Andric   symVector.push_back(sym);
36*5ffd83dbSDimitry Andric   return {sym, true};
37*5ffd83dbSDimitry Andric }
38*5ffd83dbSDimitry Andric 
39*5ffd83dbSDimitry Andric Symbol *SymbolTable::addDefined(StringRef name, InputSection *isec,
40*5ffd83dbSDimitry Andric                                 uint32_t value) {
41*5ffd83dbSDimitry Andric   Symbol *s;
42*5ffd83dbSDimitry Andric   bool wasInserted;
43*5ffd83dbSDimitry Andric   std::tie(s, wasInserted) = insert(name);
44*5ffd83dbSDimitry Andric 
45*5ffd83dbSDimitry Andric   if (!wasInserted && isa<Defined>(s))
46*5ffd83dbSDimitry Andric     error("duplicate symbol: " + name);
47*5ffd83dbSDimitry Andric 
48*5ffd83dbSDimitry Andric   replaceSymbol<Defined>(s, name, isec, value);
49*5ffd83dbSDimitry Andric   return s;
50*5ffd83dbSDimitry Andric }
51*5ffd83dbSDimitry Andric 
52*5ffd83dbSDimitry Andric Symbol *SymbolTable::addUndefined(StringRef name) {
53*5ffd83dbSDimitry Andric   Symbol *s;
54*5ffd83dbSDimitry Andric   bool wasInserted;
55*5ffd83dbSDimitry Andric   std::tie(s, wasInserted) = insert(name);
56*5ffd83dbSDimitry Andric 
57*5ffd83dbSDimitry Andric   if (wasInserted)
58*5ffd83dbSDimitry Andric     replaceSymbol<Undefined>(s, name);
59*5ffd83dbSDimitry Andric   else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s))
60*5ffd83dbSDimitry Andric     lazy->fetchArchiveMember();
61*5ffd83dbSDimitry Andric   return s;
62*5ffd83dbSDimitry Andric }
63*5ffd83dbSDimitry Andric 
64*5ffd83dbSDimitry Andric Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) {
65*5ffd83dbSDimitry Andric   Symbol *s;
66*5ffd83dbSDimitry Andric   bool wasInserted;
67*5ffd83dbSDimitry Andric   std::tie(s, wasInserted) = insert(name);
68*5ffd83dbSDimitry Andric 
69*5ffd83dbSDimitry Andric   if (wasInserted || isa<Undefined>(s))
70*5ffd83dbSDimitry Andric     replaceSymbol<DylibSymbol>(s, file, name);
71*5ffd83dbSDimitry Andric   return s;
72*5ffd83dbSDimitry Andric }
73*5ffd83dbSDimitry Andric 
74*5ffd83dbSDimitry Andric Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file,
75*5ffd83dbSDimitry Andric                              const llvm::object::Archive::Symbol &sym) {
76*5ffd83dbSDimitry Andric   Symbol *s;
77*5ffd83dbSDimitry Andric   bool wasInserted;
78*5ffd83dbSDimitry Andric   std::tie(s, wasInserted) = insert(name);
79*5ffd83dbSDimitry Andric 
80*5ffd83dbSDimitry Andric   if (wasInserted)
81*5ffd83dbSDimitry Andric     replaceSymbol<LazySymbol>(s, file, sym);
82*5ffd83dbSDimitry Andric   else if (isa<Undefined>(s))
83*5ffd83dbSDimitry Andric     file->fetch(sym);
84*5ffd83dbSDimitry Andric   return s;
85*5ffd83dbSDimitry Andric }
86*5ffd83dbSDimitry Andric 
87*5ffd83dbSDimitry Andric SymbolTable *macho::symtab;
88