blob: e45dc6bec715b5123ee270905cb35a61d1928746 [file] [log] [blame]
Sam Cleggc94d3932017-11-17 18:14:09 +00001//===- SymbolTable.cpp ----------------------------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Sam Cleggc94d3932017-11-17 18:14:09 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "SymbolTable.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000010#include "Config.h"
Sam Clegg5fa274b2018-01-10 01:13:34 +000011#include "InputChunks.h"
Heejin Ahne915a712018-12-08 06:17:43 +000012#include "InputEvent.h"
Sam Clegg93102972018-02-23 05:08:53 +000013#include "InputGlobal.h"
Sam Cleggb8621592017-11-30 01:40:08 +000014#include "WriterUtils.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000015#include "lld/Common/ErrorHandler.h"
Rui Ueyama2017d522017-11-28 20:39:17 +000016#include "lld/Common/Memory.h"
Rui Ueyama7d67dd12018-02-13 22:30:52 +000017#include "llvm/ADT/SetVector.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000018
19#define DEBUG_TYPE "lld"
20
21using namespace llvm;
Sam Clegg20db3812018-01-10 00:52:20 +000022using namespace llvm::wasm;
Sam Clegg45218f42018-11-27 01:08:16 +000023using namespace llvm::object;
Sam Cleggc94d3932017-11-17 18:14:09 +000024using namespace lld;
25using namespace lld::wasm;
26
27SymbolTable *lld::wasm::Symtab;
28
29void SymbolTable::addFile(InputFile *File) {
30 log("Processing: " + toString(File));
31 File->parse();
32
Sam Cleggc729c1b2018-05-30 18:07:52 +000033 // LLVM bitcode file
34 if (auto *F = dyn_cast<BitcodeFile>(File))
35 BitcodeFiles.push_back(F);
36 else if (auto *F = dyn_cast<ObjFile>(File))
Sam Cleggc94d3932017-11-17 18:14:09 +000037 ObjectFiles.push_back(F);
38}
39
Sam Cleggc729c1b2018-05-30 18:07:52 +000040// This function is where all the optimizations of link-time
41// optimization happens. When LTO is in use, some input files are
42// not in native object file format but in the LLVM bitcode format.
43// This function compiles bitcode files into a few big native files
44// using LLVM functions and replaces bitcode symbols with the results.
45// Because all bitcode files that the program consists of are passed
46// to the compiler at once, it can do whole-program optimization.
47void SymbolTable::addCombinedLTOObject() {
48 if (BitcodeFiles.empty())
49 return;
50
51 // Compile bitcode files and replace bitcode symbols.
52 LTO.reset(new BitcodeCompiler);
53 for (BitcodeFile *F : BitcodeFiles)
54 LTO->add(*F);
55
56 for (StringRef Filename : LTO->compile()) {
57 auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp"));
58 Obj->parse();
59 ObjectFiles.push_back(Obj);
60 }
61}
62
Sam Cleggc94d3932017-11-17 18:14:09 +000063void SymbolTable::reportRemainingUndefines() {
Sam Clegg74fe0ba2017-12-07 01:51:24 +000064 for (Symbol *Sym : SymVector) {
Sam Cleggc729c1b2018-05-30 18:07:52 +000065 if (!Sym->isUndefined() || Sym->isWeak())
66 continue;
67 if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0)
68 continue;
69 if (!Sym->IsUsedInRegularObj)
70 continue;
Sam Clegg47e2b6b2018-08-04 00:04:06 +000071 error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
Sam Cleggc94d3932017-11-17 18:14:09 +000072 }
Sam Cleggc94d3932017-11-17 18:14:09 +000073}
74
75Symbol *SymbolTable::find(StringRef Name) {
Rui Ueyama67d69082018-02-28 23:03:06 +000076 return SymMap.lookup(CachedHashStringRef(Name));
Sam Cleggc94d3932017-11-17 18:14:09 +000077}
78
Sam Clegg4c2cbfe2018-08-02 20:39:19 +000079std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
80 bool Inserted = false;
Sam Clegga80d94d2017-11-27 23:16:06 +000081 Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
Sam Clegg4c2cbfe2018-08-02 20:39:19 +000082 if (!Sym) {
83 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
84 Sym->IsUsedInRegularObj = false;
85 SymVector.emplace_back(Sym);
86 Inserted = true;
87 }
88 if (!File || File->kind() == InputFile::ObjectKind)
89 Sym->IsUsedInRegularObj = true;
90 return {Sym, Inserted};
Sam Cleggc94d3932017-11-17 18:14:09 +000091}
92
Rui Ueyamae3498ec2018-02-28 00:09:22 +000093static void reportTypeError(const Symbol *Existing, const InputFile *File,
Sam Clegg3876d89a2018-05-14 22:42:33 +000094 llvm::wasm::WasmSymbolType Type) {
Rui Ueyamae3498ec2018-02-28 00:09:22 +000095 error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " +
96 toString(Existing->getWasmType()) + " in " +
Sam Clegg3876d89a2018-05-14 22:42:33 +000097 toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) +
98 " in " + toString(File));
Rui Ueyamae3498ec2018-02-28 00:09:22 +000099}
100
Heejin Ahn6f4286f2018-11-19 23:31:28 +0000101// Check the type of new symbol matches that of the symbol is replacing.
102// For functions this can also involve verifying that the signatures match.
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000103static void checkFunctionType(Symbol *Existing, const InputFile *File,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000104 const WasmSignature *NewSig) {
Sam Clegg65d63802018-05-14 23:01:16 +0000105 auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
106 if (!ExistingFunction) {
Sam Clegg3876d89a2018-05-14 22:42:33 +0000107 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000108 return;
109 }
110
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000111 if (!NewSig)
112 return;
113
Heejin Ahne915a712018-12-08 06:17:43 +0000114 const WasmSignature *OldSig = ExistingFunction->Signature;
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000115 if (!OldSig) {
Heejin Ahne915a712018-12-08 06:17:43 +0000116 ExistingFunction->Signature = NewSig;
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000117 return;
118 }
119
120 if (*NewSig != *OldSig)
Sam Cleggffd0aaf2018-06-22 15:13:10 +0000121 warn("function signature mismatch: " + Existing->getName() +
122 "\n>>> defined as " + toString(*OldSig) + " in " +
123 toString(Existing->getFile()) + "\n>>> defined as " +
124 toString(*NewSig) + " in " + toString(File));
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000125}
126
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000127static void checkGlobalType(const Symbol *Existing, const InputFile *File,
128 const WasmGlobalType *NewType) {
129 if (!isa<GlobalSymbol>(Existing)) {
Sam Clegg3876d89a2018-05-14 22:42:33 +0000130 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL);
Sam Cleggb8621592017-11-30 01:40:08 +0000131 return;
132 }
133
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000134 const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType();
135 if (*NewType != *OldType) {
136 error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " +
137 toString(*OldType) + " in " + toString(Existing->getFile()) +
138 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
Sam Clegg93102972018-02-23 05:08:53 +0000139 }
Sam Clegg24b3dcd2018-01-28 19:57:01 +0000140}
141
Heejin Ahne915a712018-12-08 06:17:43 +0000142static void checkEventType(const Symbol *Existing, const InputFile *File,
143 const WasmEventType *NewType,
144 const WasmSignature *NewSig) {
145 auto ExistingEvent = dyn_cast<EventSymbol>(Existing);
146 if (!isa<EventSymbol>(Existing)) {
147 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT);
148 return;
149 }
150
151 const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType();
152 const WasmSignature *OldSig = ExistingEvent->Signature;
153 if (NewType->Attribute != OldType->Attribute)
154 error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " +
155 toString(*OldType) + " in " + toString(Existing->getFile()) +
156 "\n>>> defined as " + toString(*NewType) + " in " + toString(File));
157 if (*NewSig != *OldSig)
158 warn("Event signature mismatch: " + Existing->getName() +
159 "\n>>> defined as " + toString(*OldSig) + " in " +
160 toString(Existing->getFile()) + "\n>>> defined as " +
161 toString(*NewSig) + " in " + toString(File));
162}
163
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000164static void checkDataType(const Symbol *Existing, const InputFile *File) {
165 if (!isa<DataSymbol>(Existing))
Sam Clegg3876d89a2018-05-14 22:42:33 +0000166 reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000167}
168
Sam Cleggdfb0b2c2018-02-14 18:27:59 +0000169DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000170 uint32_t Flags,
171 InputFunction *Function) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000172 LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000173 assert(!find(Name));
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000174 SyntheticFunctions.emplace_back(Function);
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000175 return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name,
176 Flags, nullptr, Function);
Sam Clegg50686852018-01-12 18:35:13 +0000177}
178
Sam Clegg00245532018-02-20 23:38:27 +0000179DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,
180 uint32_t Flags) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000181 LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000182 assert(!find(Name));
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000183 return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);
Sam Cleggc94d3932017-11-17 18:14:09 +0000184}
185
Sam Clegg93102972018-02-23 05:08:53 +0000186DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,
187 InputGlobal *Global) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000188 LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global
189 << "\n");
Rui Ueyamab961abc2018-02-28 22:51:51 +0000190 assert(!find(Name));
Nicholas Wilsonebda41f2018-03-09 16:43:05 +0000191 SyntheticGlobals.emplace_back(Global);
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000192 return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags,
193 nullptr, Global);
Sam Clegg93102972018-02-23 05:08:53 +0000194}
195
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000196static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,
197 uint32_t NewFlags) {
Rui Ueyamac03c9042018-02-20 21:08:47 +0000198 // If existing symbol is undefined, replace it.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000199 if (!Existing->isDefined()) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000200 LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: "
201 << Existing->getName() << "\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000202 return true;
203 }
204
205 // Now we have two defined symbols. If the new one is weak, we can ignore it.
206 if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000207 LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000208 return false;
209 }
210
211 // If the existing symbol is weak, we should replace it.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000212 if (Existing->isWeak()) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000213 LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000214 return true;
215 }
216
217 // Neither symbol is week. They conflict.
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000218 error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " +
219 toString(Existing->getFile()) + "\n>>> defined in " +
220 toString(NewFile));
Rui Ueyamac03c9042018-02-20 21:08:47 +0000221 return true;
Sam Clegg93e559b2018-02-20 18:55:06 +0000222}
223
224Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000225 InputFile *File,
226 InputFunction *Function) {
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000227 LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " ["
228 << (Function ? toString(Function->Signature) : "none")
229 << "]\n");
Sam Clegg93e559b2018-02-20 18:55:06 +0000230 Symbol *S;
231 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000232 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000233
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000234 if (WasInserted || S->isLazy()) {
235 replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
236 return S;
237 }
238
Sam Cleggc729c1b2018-05-30 18:07:52 +0000239 if (Function)
240 checkFunctionType(S, File, &Function->Signature);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000241
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000242 if (shouldReplace(S, File, Flags)) {
243 // If the new defined function doesn't have signture (i.e. bitcode
Sam Clegg37b4ee52019-01-29 22:26:31 +0000244 // functions) but the old symbol does then preserve the old signature
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000245 const WasmSignature *OldSig = nullptr;
246 if (auto* F = dyn_cast<FunctionSymbol>(S))
Heejin Ahne915a712018-12-08 06:17:43 +0000247 OldSig = F->Signature;
Sam Clegg37b4ee52019-01-29 22:26:31 +0000248 if (auto *L = dyn_cast<LazySymbol>(S))
249 OldSig = L->Signature;
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000250 auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function);
Heejin Ahne915a712018-12-08 06:17:43 +0000251 if (!NewSym->Signature)
252 NewSym->Signature = OldSig;
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000253 }
Sam Clegg93e559b2018-02-20 18:55:06 +0000254 return S;
255}
256
Sam Clegg00245532018-02-20 23:38:27 +0000257Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000258 InputFile *File, InputSegment *Segment,
Sam Clegg93102972018-02-23 05:08:53 +0000259 uint32_t Address, uint32_t Size) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000260 LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address
261 << "\n");
Sam Clegg93e559b2018-02-20 18:55:06 +0000262 Symbol *S;
263 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000264 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000265
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000266 if (WasInserted || S->isLazy()) {
267 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
268 return S;
269 }
270
271 checkDataType(S, File);
272
273 if (shouldReplace(S, File, Flags))
274 replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size);
Sam Cleggc94d3932017-11-17 18:14:09 +0000275 return S;
276}
277
Sam Clegg93102972018-02-23 05:08:53 +0000278Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000279 InputFile *File, InputGlobal *Global) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000280 LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n");
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000281
Sam Clegg93102972018-02-23 05:08:53 +0000282 Symbol *S;
283 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000284 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000285
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000286 if (WasInserted || S->isLazy()) {
287 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
288 return S;
289 }
290
291 checkGlobalType(S, File, &Global->getType());
292
293 if (shouldReplace(S, File, Flags))
294 replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global);
Sam Clegg93102972018-02-23 05:08:53 +0000295 return S;
296}
297
Heejin Ahne915a712018-12-08 06:17:43 +0000298Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags,
299 InputFile *File, InputEvent *Event) {
300 LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n");
301
302 Symbol *S;
303 bool WasInserted;
304 std::tie(S, WasInserted) = insert(Name, File);
305
306 if (WasInserted || S->isLazy()) {
307 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
308 return S;
309 }
310
311 checkEventType(S, File, &Event->getType(), &Event->Signature);
312
313 if (shouldReplace(S, File, Flags))
314 replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event);
315 return S;
316}
317
Sam Clegg7cc07532019-02-01 02:29:57 +0000318Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef Module,
319 uint32_t Flags, InputFile *File,
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000320 const WasmSignature *Sig) {
Sam Clegg8b0b48f2018-09-28 16:50:14 +0000321 LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name <<
322 " [" << (Sig ? toString(*Sig) : "none") << "]\n");
Rui Ueyamac03c9042018-02-20 21:08:47 +0000323
Sam Cleggc94d3932017-11-17 18:14:09 +0000324 Symbol *S;
325 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000326 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000327
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000328 if (WasInserted)
Sam Clegg7cc07532019-02-01 02:29:57 +0000329 replaceSymbol<UndefinedFunction>(S, Name, Module, Flags, File, Sig);
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000330 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000331 Lazy->fetch();
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000332 else
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000333 checkFunctionType(S, File, Sig);
Sam Cleggcefbf9a2018-06-28 16:53:53 +0000334
Sam Cleggc94d3932017-11-17 18:14:09 +0000335 return S;
336}
337
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000338Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,
339 InputFile *File) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000340 LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n");
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000341
342 Symbol *S;
343 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000344 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggf989a922018-07-17 19:15:02 +0000345
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000346 if (WasInserted)
347 replaceSymbol<UndefinedData>(S, Name, Flags, File);
348 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000349 Lazy->fetch();
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000350 else if (S->isDefined())
351 checkDataType(S, File);
352 return S;
353}
354
355Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,
356 InputFile *File,
357 const WasmGlobalType *Type) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000358 LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n");
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000359
360 Symbol *S;
361 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000362 std::tie(S, WasInserted) = insert(Name, File);
Sam Cleggc729c1b2018-05-30 18:07:52 +0000363
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000364 if (WasInserted)
365 replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type);
366 else if (auto *Lazy = dyn_cast<LazySymbol>(S))
Rui Ueyamab961abc2018-02-28 22:51:51 +0000367 Lazy->fetch();
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000368 else if (S->isDefined())
369 checkGlobalType(S, File, Type);
370 return S;
371}
372
373void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {
Nicola Zaghene7245b42018-05-15 13:36:20 +0000374 LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000375 StringRef Name = Sym->getName();
Rui Ueyamac03c9042018-02-20 21:08:47 +0000376
Sam Cleggc94d3932017-11-17 18:14:09 +0000377 Symbol *S;
378 bool WasInserted;
Sam Clegg4c2cbfe2018-08-02 20:39:19 +0000379 std::tie(S, WasInserted) = insert(Name, nullptr);
Rui Ueyamac03c9042018-02-20 21:08:47 +0000380
Sam Cleggc94d3932017-11-17 18:14:09 +0000381 if (WasInserted) {
Sam Clegg37b4ee52019-01-29 22:26:31 +0000382 replaceSymbol<LazySymbol>(S, Name, 0, File, *Sym);
Rui Ueyamac03c9042018-02-20 21:08:47 +0000383 return;
384 }
385
Sam Clegg37b4ee52019-01-29 22:26:31 +0000386 if (!S->isUndefined())
387 return;
388
389 // The existing symbol is undefined, load a new one from the archive,
390 // unless the the existing symbol is weak in which case replace the undefined
391 // symbols with a LazySymbol.
392 if (S->isWeak()) {
393 const WasmSignature *OldSig = nullptr;
394 // In the case of an UndefinedFunction we need to preserve the expected
395 // signature.
396 if (auto *F = dyn_cast<UndefinedFunction>(S))
397 OldSig = F->Signature;
398 LLVM_DEBUG(dbgs() << "replacing existing weak undefined symbol\n");
399 auto NewSym = replaceSymbol<LazySymbol>(S, Name, WASM_SYMBOL_BINDING_WEAK,
400 File, *Sym);
401 NewSym->Signature = OldSig;
402 return;
Sam Cleggc94d3932017-11-17 18:14:09 +0000403 }
Sam Clegg37b4ee52019-01-29 22:26:31 +0000404
405 LLVM_DEBUG(dbgs() << "replacing existing undefined\n");
406 File->addMember(Sym);
Sam Cleggc94d3932017-11-17 18:14:09 +0000407}
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000408
Nicholas Wilsonc4d9aa12018-03-14 15:45:11 +0000409bool SymbolTable::addComdat(StringRef Name) {
410 return Comdats.insert(CachedHashStringRef(Name)).second;
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000411}