blob: c7983196db36c88d45de926e39f56537a02b5fa0 [file] [log] [blame]
Sam Cleggc94d3932017-11-17 18:14:09 +00001//===- 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#include "SymbolTable.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000011#include "Config.h"
Sam Clegg5fa274b2018-01-10 01:13:34 +000012#include "InputChunks.h"
Heejin Ahne915a712018-12-08 06:17:43 +000013#include "InputEvent.h"
Sam Clegg93102972018-02-23 05:08:53 +000014#include "InputGlobal.h"
Sam Cleggb8621592017-11-30 01:40:08 +000015#include "WriterUtils.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000016#include "lld/Common/ErrorHandler.h"
Rui Ueyama2017d522017-11-28 20:39:17 +000017#include "lld/Common/Memory.h"
Rui Ueyama7d67dd12018-02-13 22:30:52 +000018#include "llvm/ADT/SetVector.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000019
20#define DEBUG_TYPE "lld"
21
22using namespace llvm;
Sam Clegg20db3812018-01-10 00:52:20 +000023using namespace llvm::wasm;
Sam Clegg45218f42018-11-27 01:08:16 +000024using namespace llvm::object;
Sam Cleggc94d3932017-11-17 18:14:09 +000025using namespace lld;
26using namespace lld::wasm;
27
28SymbolTable *lld::wasm::Symtab;
29
30void SymbolTable::addFile(InputFile *File) {
31 log("Processing: " + toString(File));
32 File->parse();
33
Sam Cleggc729c1b2018-05-30 18:07:52 +000034 // LLVM bitcode file
35 if (auto *F = dyn_cast<BitcodeFile>(File))
36 BitcodeFiles.push_back(F);
37 else if (auto *F = dyn_cast<ObjFile>(File))
Sam Cleggc94d3932017-11-17 18:14:09 +000038 ObjectFiles.push_back(F);
39}
40
Sam Cleggc729c1b2018-05-30 18:07:52 +000041// This function is where all the optimizations of link-time
42// optimization happens. When LTO is in use, some input files are
43// not in native object file format but in the LLVM bitcode format.
44// This function compiles bitcode files into a few big native files
45// using LLVM functions and replaces bitcode symbols with the results.
46// Because all bitcode files that the program consists of are passed
47// to the compiler at once, it can do whole-program optimization.
48void SymbolTable::addCombinedLTOObject() {
49 if (BitcodeFiles.empty())
50 return;
51
52 // Compile bitcode files and replace bitcode symbols.
53 LTO.reset(new BitcodeCompiler);
54 for (BitcodeFile *F : BitcodeFiles)
55 LTO->add(*F);
56
57 for (StringRef Filename : LTO->compile()) {
58 auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"));
59 Obj->parse();
60 ObjectFiles.push_back(Obj);
61 }
62}
63
Sam Cleggc94d3932017-11-17 18:14:09 +000064void SymbolTable::reportRemainingUndefines() {
Sam Clegg74fe0ba2017-12-07 01:51:24 +000065 for (Symbol *Sym : SymVector) {
Sam Cleggc729c1b2018-05-30 18:07:52 +000066 if (!Sym->isUndefined() || Sym->isWeak())
67 continue;
68 if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0)
69 continue;
70 if (!Sym->IsUsedInRegularObj)
71 continue;
Sam Clegg47e2b6b2018-08-04 00:04:06 +000072 error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
Sam Cleggc94d3932017-11-17 18:14:09 +000073 }
Sam Cleggc94d3932017-11-17 18:14:09 +000074}
75
76Symbol *SymbolTable::find(StringRef Name) {
Rui Ueyama67d69082018-02-28 23:03:06 +000077 return SymMap.lookup(CachedHashStringRef(Name));
Sam Cleggc94d3932017-11-17 18:14:09 +000078}
79
Sam Clegg4c2cbfe2018-08-02 20:39:19 +000080std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
81 bool Inserted = false;
Sam Clegga80d94d2017-11-27 23:16:06 +000082 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
Sam Clegg4c2cbfe2018-08-02 20:39:19 +000083 if (!Sym) {
84 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
85 Sym->IsUsedInRegularObj = false;
86 SymVector.emplace_back(Sym);
87 Inserted = true;
88 }
89 if (!File || File->kind() == InputFile::ObjectKind)
90 Sym->IsUsedInRegularObj = true;
91 return {Sym, Inserted};
Sam Cleggc94d3932017-11-17 18:14:09 +000092}
93
Rui Ueyamae3498ec2018-02-28 00:09:22 +000094static void reportTypeError(const Symbol *Existing, const InputFile *File,
Sam Clegg3876d89a2018-05-14 22:42:33 +000095 llvm::wasm::WasmSymbolType Type) {
Rui Ueyamae3498ec2018-02-28 00:09:22 +000096 error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " +
97 toString(Existing->getWasmType()) + " in " +
Sam Clegg3876d89a2018-05-14 22:42:33 +000098 toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) +
99 " in " + toString(File));
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000100}
101
Heejin Ahn6f4286f2018-11-19 23:31:28 +0000102// Check the type of new symbol matches that of the symbol is replacing.
103// For functions this can also involve verifying that the signatures match.
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000104static void checkFunctionType(Symbol *Existing, const InputFile *File,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000105 const WasmSignature *NewSig) {
Sam Clegg65d63802018-05-14 23:01:16 +0000106 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
107 if (!ExistingFunction) {
Sam Clegg3876d89a2018-05-14 22:42:33 +0000108 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000109 return;
110 }
111
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000112 if (!NewSig)
113 return;
114
Heejin Ahne915a712018-12-08 06:17:43 +0000115 const WasmSignature *OldSig = ExistingFunction->Signature;
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000116 if (!OldSig) {
Heejin Ahne915a712018-12-08 06:17:43 +0000117 ExistingFunction->Signature = NewSig;
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000118 return;
119 }
120
121 if (*NewSig != *OldSig)
Sam Cleggffd0aaf2018-06-22 15:13:10 +0000122 warn("function signature mismatch: " + Existing->getName() +
123 "\n>>> defined as " + toString(*OldSig) + " in " +
124 toString(Existing->getFile()) + "\n>>> defined as " +
125 toString(*NewSig) + " in " + toString(File));
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000126}
127
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000128static void checkGlobalType(const Symbol *Existing, const InputFile *File,
129 const WasmGlobalType *NewType) {
130 if (!isa<GlobalSymbol>(Existing)) {
Sam Clegg3876d89a2018-05-14 22:42:33 +0000131 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL);
Sam Cleggb8621592017-11-30 01:40:08 +0000132 return;
133 }
134
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000135 const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType();
136 if (*NewType != *OldType) {
137 error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " +
138 toString(*OldType) + " in " + toString(Existing->getFile()) +
139 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
Sam Clegg93102972018-02-23 05:08:53 +0000140 }
Sam Clegg24b3dcd2018-01-28 19:57:01 +0000141}
142
Heejin Ahne915a712018-12-08 06:17:43 +0000143static void checkEventType(const Symbol *Existing, const InputFile *File,
144 const WasmEventType *NewType,
145 const WasmSignature *NewSig) {
146 auto ExistingEvent = dyn_cast<EventSymbol>(Existing);
147 if (!isa<EventSymbol>(Existing)) {
148 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT);
149 return;
150 }
151
152 const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType();
153 const WasmSignature *OldSig = ExistingEvent->Signature;
154 if (NewType->Attribute != OldType->Attribute)
155 error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " +
156 toString(*OldType) + " in " + toString(Existing->getFile()) +
157 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
158 if (*NewSig != *OldSig)
159 warn("Event signature mismatch: " + Existing->getName() +
160 "\n>>> defined as " + toString(*OldSig) + " in " +
161 toString(Existing->getFile()) + "\n>>> defined as " +
162 toString(*NewSig) + " in " + toString(File));
163}
164
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000165static void checkDataType(const Symbol *Existing, const InputFile *File) {
166 if (!isa<DataSymbol>(Existing))
Sam Clegg3876d89a2018-05-14 22:42:33 +0000167 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000168}
169
Sam Cleggdfb0b2c2018-02-14 18:27:59 +0000170DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000171 uint32_t Flags,
172 InputFunction *Function) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000173 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000174 assert(!find(Name));
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000175 SyntheticFunctions.emplace_back(Function);
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000176 return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name,
177 Flags, nullptr, Function);
Sam Clegg50686852018-01-12 18:35:13 +0000178}
179
Sam Clegg00245532018-02-20 23:38:27 +0000180DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
181 uint32_t Flags) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000182 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000183 assert(!find(Name));
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000184 return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);
Sam Cleggc94d3932017-11-17 18:14:09 +0000185}
186
Sam Clegg93102972018-02-23 05:08:53 +0000187DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
188 InputGlobal *Global) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000189 LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global
190 << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000191 assert(!find(Name));
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000192 SyntheticGlobals.emplace_back(Global);
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000193 return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags,
194 nullptr, Global);
Sam Clegg93102972018-02-23 05:08:53 +0000195}
196
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000197static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
198 uint32_t NewFlags) {
Rui Ueyamac03c9042018-02-20 21:08:47 +0000199 // If existing symbol is undefined, replace it.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000200 if (!Existing->isDefined()) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000201 LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
202 << Existing->getName() << "\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000203 return true;
204 }
205
206 // Now we have two defined symbols. If the new one is weak, we can ignore it.
207 if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000208 LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000209 return false;
210 }
211
212 // If the existing symbol is weak, we should replace it.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000213 if (Existing->isWeak()) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000214 LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000215 return true;
216 }
217
218 // Neither symbol is week. They conflict.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000219 error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " +
220 toString(Existing->getFile()) + "\n>>> defined in " +
221 toString(NewFile));
Rui Ueyamac03c9042018-02-20 21:08:47 +0000222 return true;
Sam Clegg93e559b2018-02-20 18:55:06 +0000223}
224
225Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000226 InputFile *File,
227 InputFunction *Function) {
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000228 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
229 << (Function ? toString(Function->Signature) : "none")
230 << "]\n");
Sam Clegg93e559b2018-02-20 18:55:06 +0000231 Symbol *S;
232 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000233 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000234
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000235 if (WasInserted || S->isLazy()) {
236 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
237 return S;
238 }
239
Sam Cleggc729c1b2018-05-30 18:07:52 +0000240 if (Function)
241 checkFunctionType(S, File, &Function->Signature);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000242
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000243 if (shouldReplace(S, File, Flags)) {
244 // If the new defined function doesn't have signture (i.e. bitcode
245 // functions) but the old symbols does then preserve the old signature
246 const WasmSignature *OldSig = nullptr;
247 if (auto* F = dyn_cast<FunctionSymbol>(S))
Heejin Ahne915a712018-12-08 06:17:43 +0000248 OldSig = F->Signature;
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000249 auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
Heejin Ahne915a712018-12-08 06:17:43 +0000250 if (!NewSym->Signature)
251 NewSym->Signature = OldSig;
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000252 }
Sam Clegg93e559b2018-02-20 18:55:06 +0000253 return S;
254}
255
Sam Clegg00245532018-02-20 23:38:27 +0000256Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000257 InputFile *File, InputSegment *Segment,
Sam Clegg93102972018-02-23 05:08:53 +0000258 uint32_t Address, uint32_t Size) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000259 LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address
260 << "\n");
Sam Clegg93e559b2018-02-20 18:55:06 +0000261 Symbol *S;
262 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000263 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000264
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000265 if (WasInserted || S->isLazy()) {
266 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
267 return S;
268 }
269
270 checkDataType(S, File);
271
272 if (shouldReplace(S, File, Flags))
273 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
Sam Cleggc94d3932017-11-17 18:14:09 +0000274 return S;
275}
276
Sam Clegg93102972018-02-23 05:08:53 +0000277Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000278 InputFile *File, InputGlobal *Global) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000279 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000280
Sam Clegg93102972018-02-23 05:08:53 +0000281 Symbol *S;
282 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000283 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000284
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000285 if (WasInserted || S->isLazy()) {
286 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
287 return S;
288 }
289
290 checkGlobalType(S, File, &Global->getType());
291
292 if (shouldReplace(S, File, Flags))
293 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
Sam Clegg93102972018-02-23 05:08:53 +0000294 return S;
295}
296
Heejin Ahne915a712018-12-08 06:17:43 +0000297Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
298 InputFile *File, InputEvent *Event) {
299 LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n");
300
301 Symbol *S;
302 bool WasInserted;
303 std::tie(S, WasInserted) = insert(Name, File);
304
305 if (WasInserted || S->isLazy()) {
306 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
307 return S;
308 }
309
310 checkEventType(S, File, &Event->getType(), &Event->Signature);
311
312 if (shouldReplace(S, File, Flags))
313 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
314 return S;
315}
316
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000317Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,
318 InputFile *File,
319 const WasmSignature *Sig) {
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000320 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
321 " [" << (Sig ? toString(*Sig) : "none") << "]\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000322
Sam Cleggc94d3932017-11-17 18:14:09 +0000323 Symbol *S;
324 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000325 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000326
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000327 if (WasInserted)
328 replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig);
329 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000330 Lazy->fetch();
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000331 else
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000332 checkFunctionType(S, File, Sig);
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000333
Sam Cleggc94d3932017-11-17 18:14:09 +0000334 return S;
335}
336
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000337Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
338 InputFile *File) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000339 LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000340
341 Symbol *S;
342 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000343 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggf989a922018-07-17 19:15:02 +0000344
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000345 if (WasInserted)
346 replaceSymbol<UndefinedData>(S, Name, Flags, File);
347 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000348 Lazy->fetch();
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000349 else if (S->isDefined())
350 checkDataType(S, File);
351 return S;
352}
353
354Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
355 InputFile *File,
356 const WasmGlobalType *Type) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000357 LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000358
359 Symbol *S;
360 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000361 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000362
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000363 if (WasInserted)
364 replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
365 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000366 Lazy->fetch();
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000367 else if (S->isDefined())
368 checkGlobalType(S, File, Type);
369 return S;
370}
371
372void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000373 LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000374 StringRef Name = Sym->getName();
Rui Ueyamac03c9042018-02-20 21:08:47 +0000375
Sam Cleggc94d3932017-11-17 18:14:09 +0000376 Symbol *S;
377 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000378 std::tie(S, WasInserted) = insert(Name, nullptr);
Rui Ueyamac03c9042018-02-20 21:08:47 +0000379
Sam Cleggc94d3932017-11-17 18:14:09 +0000380 if (WasInserted) {
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000381 replaceSymbol<LazySymbol>(S, Name, File, *Sym);
Rui Ueyamac03c9042018-02-20 21:08:47 +0000382 return;
383 }
384
385 // If there is an existing undefined symbol, load a new one from the archive.
386 if (S->isUndefined()) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000387 LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000388 File->addMember(Sym);
Sam Cleggc94d3932017-11-17 18:14:09 +0000389 }
390}
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000391
Nicholas Wilsonc4d9aa12018-03-14 15:45:11 +0000392bool SymbolTable::addComdat(StringRef Name) {
393 return Comdats.insert(CachedHashStringRef(Name)).second;
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000394}