1c94d393aSSam Clegg //===- SymbolTable.cpp ----------------------------------------------------===// 2c94d393aSSam Clegg // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c94d393aSSam Clegg // 7c94d393aSSam Clegg //===----------------------------------------------------------------------===// 8c94d393aSSam Clegg 9c94d393aSSam Clegg #include "SymbolTable.h" 10c94d393aSSam Clegg #include "Config.h" 115fa274beSSam Clegg #include "InputChunks.h" 12e915a71fSHeejin Ahn #include "InputEvent.h" 1393102974SSam Clegg #include "InputGlobal.h" 14b8621596SSam Clegg #include "WriterUtils.h" 15c94d393aSSam Clegg #include "lld/Common/ErrorHandler.h" 162017d52bSRui Ueyama #include "lld/Common/Memory.h" 177d67dd11SRui Ueyama #include "llvm/ADT/SetVector.h" 18c94d393aSSam Clegg 19c94d393aSSam Clegg #define DEBUG_TYPE "lld" 20c94d393aSSam Clegg 21c94d393aSSam Clegg using namespace llvm; 2220db381bSSam Clegg using namespace llvm::wasm; 2345218f4aSSam Clegg using namespace llvm::object; 24c94d393aSSam Clegg using namespace lld; 25c94d393aSSam Clegg using namespace lld::wasm; 26c94d393aSSam Clegg 27c94d393aSSam Clegg SymbolTable *lld::wasm::Symtab; 28c94d393aSSam Clegg 29c94d393aSSam Clegg void SymbolTable::addFile(InputFile *File) { 30c94d393aSSam Clegg log("Processing: " + toString(File)); 31c94d393aSSam Clegg File->parse(); 32c94d393aSSam Clegg 33c729c1b4SSam Clegg // LLVM bitcode file 34c729c1b4SSam Clegg if (auto *F = dyn_cast<BitcodeFile>(File)) 35c729c1b4SSam Clegg BitcodeFiles.push_back(F); 36c729c1b4SSam Clegg else if (auto *F = dyn_cast<ObjFile>(File)) 37c94d393aSSam Clegg ObjectFiles.push_back(F); 38c94d393aSSam Clegg } 39c94d393aSSam Clegg 40c729c1b4SSam Clegg // This function is where all the optimizations of link-time 41c729c1b4SSam Clegg // optimization happens. When LTO is in use, some input files are 42c729c1b4SSam Clegg // not in native object file format but in the LLVM bitcode format. 43c729c1b4SSam Clegg // This function compiles bitcode files into a few big native files 44c729c1b4SSam Clegg // using LLVM functions and replaces bitcode symbols with the results. 45c729c1b4SSam Clegg // Because all bitcode files that the program consists of are passed 46c729c1b4SSam Clegg // to the compiler at once, it can do whole-program optimization. 47c729c1b4SSam Clegg void SymbolTable::addCombinedLTOObject() { 48c729c1b4SSam Clegg if (BitcodeFiles.empty()) 49c729c1b4SSam Clegg return; 50c729c1b4SSam Clegg 51c729c1b4SSam Clegg // Compile bitcode files and replace bitcode symbols. 52c729c1b4SSam Clegg LTO.reset(new BitcodeCompiler); 53c729c1b4SSam Clegg for (BitcodeFile *F : BitcodeFiles) 54c729c1b4SSam Clegg LTO->add(*F); 55c729c1b4SSam Clegg 56c729c1b4SSam Clegg for (StringRef Filename : LTO->compile()) { 57c729c1b4SSam Clegg auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp")); 58c729c1b4SSam Clegg Obj->parse(); 59c729c1b4SSam Clegg ObjectFiles.push_back(Obj); 60c729c1b4SSam Clegg } 61c729c1b4SSam Clegg } 62c729c1b4SSam Clegg 63c94d393aSSam Clegg void SymbolTable::reportRemainingUndefines() { 6474fe0ba1SSam Clegg for (Symbol *Sym : SymVector) { 65c729c1b4SSam Clegg if (!Sym->isUndefined() || Sym->isWeak()) 66c729c1b4SSam Clegg continue; 67c729c1b4SSam Clegg if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0) 68c729c1b4SSam Clegg continue; 69c729c1b4SSam Clegg if (!Sym->IsUsedInRegularObj) 70c729c1b4SSam Clegg continue; 7147e2b6b2SSam Clegg error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym)); 72c94d393aSSam Clegg } 73c94d393aSSam Clegg } 74c94d393aSSam Clegg 75c94d393aSSam Clegg Symbol *SymbolTable::find(StringRef Name) { 7667d6908fSRui Ueyama return SymMap.lookup(CachedHashStringRef(Name)); 77c94d393aSSam Clegg } 78c94d393aSSam Clegg 794c2cbfe6SSam Clegg std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) { 804c2cbfe6SSam Clegg bool Inserted = false; 81a80d94d5SSam Clegg Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; 824c2cbfe6SSam Clegg if (!Sym) { 83dfb0b2c7SSam Clegg Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 84c729c1b4SSam Clegg Sym->IsUsedInRegularObj = false; 8574fe0ba1SSam Clegg SymVector.emplace_back(Sym); 864c2cbfe6SSam Clegg Inserted = true; 874c2cbfe6SSam Clegg } 884c2cbfe6SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 894c2cbfe6SSam Clegg Sym->IsUsedInRegularObj = true; 904c2cbfe6SSam Clegg return {Sym, Inserted}; 91c94d393aSSam Clegg } 92c94d393aSSam Clegg 93e3498ec5SRui Ueyama static void reportTypeError(const Symbol *Existing, const InputFile *File, 943876d89aSSam Clegg llvm::wasm::WasmSymbolType Type) { 95e3498ec5SRui Ueyama error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + 96e3498ec5SRui Ueyama toString(Existing->getWasmType()) + " in " + 973876d89aSSam Clegg toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + 983876d89aSSam Clegg " in " + toString(File)); 99e3498ec5SRui Ueyama } 100e3498ec5SRui Ueyama 1016f4286fbSHeejin Ahn // Check the type of new symbol matches that of the symbol is replacing. 1026f4286fbSHeejin Ahn // For functions this can also involve verifying that the signatures match. 103cefbf9acSSam Clegg static void checkFunctionType(Symbol *Existing, const InputFile *File, 104e3498ec5SRui Ueyama const WasmSignature *NewSig) { 10565d6380cSSam Clegg auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); 10665d6380cSSam Clegg if (!ExistingFunction) { 1073876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION); 108e3498ec5SRui Ueyama return; 109e3498ec5SRui Ueyama } 110e3498ec5SRui Ueyama 111cefbf9acSSam Clegg if (!NewSig) 112cefbf9acSSam Clegg return; 113cefbf9acSSam Clegg 114e915a71fSHeejin Ahn const WasmSignature *OldSig = ExistingFunction->Signature; 115cefbf9acSSam Clegg if (!OldSig) { 116e915a71fSHeejin Ahn ExistingFunction->Signature = NewSig; 117cefbf9acSSam Clegg return; 118cefbf9acSSam Clegg } 119cefbf9acSSam Clegg 120cefbf9acSSam Clegg if (*NewSig != *OldSig) 121ffd0aaf8SSam Clegg warn("function signature mismatch: " + Existing->getName() + 122e3498ec5SRui Ueyama "\n>>> defined as " + toString(*OldSig) + " in " + 123e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined as " + 124ffd0aaf8SSam Clegg toString(*NewSig) + " in " + toString(File)); 125e3498ec5SRui Ueyama } 126e3498ec5SRui Ueyama 127e3498ec5SRui Ueyama static void checkGlobalType(const Symbol *Existing, const InputFile *File, 128e3498ec5SRui Ueyama const WasmGlobalType *NewType) { 129e3498ec5SRui Ueyama if (!isa<GlobalSymbol>(Existing)) { 1303876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL); 131b8621596SSam Clegg return; 132b8621596SSam Clegg } 133b8621596SSam Clegg 134e3498ec5SRui Ueyama const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType(); 135e3498ec5SRui Ueyama if (*NewType != *OldType) { 136e3498ec5SRui Ueyama error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " + 137e3498ec5SRui Ueyama toString(*OldType) + " in " + toString(Existing->getFile()) + 138e3498ec5SRui Ueyama "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); 139c94d393aSSam Clegg } 14024b3dcd4SSam Clegg } 14124b3dcd4SSam Clegg 142e915a71fSHeejin Ahn static void checkEventType(const Symbol *Existing, const InputFile *File, 143e915a71fSHeejin Ahn const WasmEventType *NewType, 144e915a71fSHeejin Ahn const WasmSignature *NewSig) { 145e915a71fSHeejin Ahn auto ExistingEvent = dyn_cast<EventSymbol>(Existing); 146e915a71fSHeejin Ahn if (!isa<EventSymbol>(Existing)) { 147e915a71fSHeejin Ahn reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); 148e915a71fSHeejin Ahn return; 149e915a71fSHeejin Ahn } 150e915a71fSHeejin Ahn 151e915a71fSHeejin Ahn const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType(); 152e915a71fSHeejin Ahn const WasmSignature *OldSig = ExistingEvent->Signature; 153e915a71fSHeejin Ahn if (NewType->Attribute != OldType->Attribute) 154e915a71fSHeejin Ahn error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + 155e915a71fSHeejin Ahn toString(*OldType) + " in " + toString(Existing->getFile()) + 156e915a71fSHeejin Ahn "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); 157e915a71fSHeejin Ahn if (*NewSig != *OldSig) 158e915a71fSHeejin Ahn warn("Event signature mismatch: " + Existing->getName() + 159e915a71fSHeejin Ahn "\n>>> defined as " + toString(*OldSig) + " in " + 160e915a71fSHeejin Ahn toString(Existing->getFile()) + "\n>>> defined as " + 161e915a71fSHeejin Ahn toString(*NewSig) + " in " + toString(File)); 162e915a71fSHeejin Ahn } 163e915a71fSHeejin Ahn 164e3498ec5SRui Ueyama static void checkDataType(const Symbol *Existing, const InputFile *File) { 165e3498ec5SRui Ueyama if (!isa<DataSymbol>(Existing)) 1663876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); 167e3498ec5SRui Ueyama } 168e3498ec5SRui Ueyama 169dfb0b2c7SSam Clegg DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, 170ebda41f8SNicholas Wilson uint32_t Flags, 171ebda41f8SNicholas Wilson InputFunction *Function) { 172e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); 173b961abc8SRui Ueyama assert(!find(Name)); 174ebda41f8SNicholas Wilson SyntheticFunctions.emplace_back(Function); 1754c2cbfe6SSam Clegg return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name, 1764c2cbfe6SSam Clegg Flags, nullptr, Function); 17750686856SSam Clegg } 17850686856SSam Clegg 17900245539SSam Clegg DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, 18000245539SSam Clegg uint32_t Flags) { 181e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); 182b961abc8SRui Ueyama assert(!find(Name)); 1834c2cbfe6SSam Clegg return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags); 184c94d393aSSam Clegg } 185c94d393aSSam Clegg 18693102974SSam Clegg DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, 18793102974SSam Clegg InputGlobal *Global) { 188e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global 189e7245b42SNicola Zaghen << "\n"); 190b961abc8SRui Ueyama assert(!find(Name)); 191ebda41f8SNicholas Wilson SyntheticGlobals.emplace_back(Global); 1924c2cbfe6SSam Clegg return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags, 1934c2cbfe6SSam Clegg nullptr, Global); 19493102974SSam Clegg } 19593102974SSam Clegg 196e3498ec5SRui Ueyama static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, 197e3498ec5SRui Ueyama uint32_t NewFlags) { 198c03c9040SRui Ueyama // If existing symbol is undefined, replace it. 199e3498ec5SRui Ueyama if (!Existing->isDefined()) { 200e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " 201e3498ec5SRui Ueyama << Existing->getName() << "\n"); 202c03c9040SRui Ueyama return true; 203c03c9040SRui Ueyama } 204c03c9040SRui Ueyama 205c03c9040SRui Ueyama // Now we have two defined symbols. If the new one is weak, we can ignore it. 206c03c9040SRui Ueyama if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { 207e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); 208c03c9040SRui Ueyama return false; 209c03c9040SRui Ueyama } 210c03c9040SRui Ueyama 211c03c9040SRui Ueyama // If the existing symbol is weak, we should replace it. 212e3498ec5SRui Ueyama if (Existing->isWeak()) { 213e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); 214c03c9040SRui Ueyama return true; 215c03c9040SRui Ueyama } 216c03c9040SRui Ueyama 217c03c9040SRui Ueyama // Neither symbol is week. They conflict. 218e3498ec5SRui Ueyama error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + 219e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined in " + 220e3498ec5SRui Ueyama toString(NewFile)); 221c03c9040SRui Ueyama return true; 222b8621596SSam Clegg } 22393e559b1SSam Clegg 22493e559b1SSam Clegg Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, 225e3498ec5SRui Ueyama InputFile *File, 226e3498ec5SRui Ueyama InputFunction *Function) { 2278b0b48f3SSam Clegg LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" 2288b0b48f3SSam Clegg << (Function ? toString(Function->Signature) : "none") 2298b0b48f3SSam Clegg << "]\n"); 23093e559b1SSam Clegg Symbol *S; 23193e559b1SSam Clegg bool WasInserted; 2324c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 233c729c1b4SSam Clegg 234e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 235e3498ec5SRui Ueyama replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 236e3498ec5SRui Ueyama return S; 237e3498ec5SRui Ueyama } 238e3498ec5SRui Ueyama 239c729c1b4SSam Clegg if (Function) 240e3498ec5SRui Ueyama checkFunctionType(S, File, &Function->Signature); 241e3498ec5SRui Ueyama 2428b0b48f3SSam Clegg if (shouldReplace(S, File, Flags)) { 2438b0b48f3SSam Clegg // If the new defined function doesn't have signture (i.e. bitcode 2448b0b48f3SSam Clegg // functions) but the old symbols does then preserve the old signature 2458b0b48f3SSam Clegg const WasmSignature *OldSig = nullptr; 2468b0b48f3SSam Clegg if (auto* F = dyn_cast<FunctionSymbol>(S)) 247e915a71fSHeejin Ahn OldSig = F->Signature; 2488b0b48f3SSam Clegg auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 249e915a71fSHeejin Ahn if (!NewSym->Signature) 250e915a71fSHeejin Ahn NewSym->Signature = OldSig; 2518b0b48f3SSam Clegg } 25293e559b1SSam Clegg return S; 25393e559b1SSam Clegg } 25493e559b1SSam Clegg 25500245539SSam Clegg Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, 256e3498ec5SRui Ueyama InputFile *File, InputSegment *Segment, 25793102974SSam Clegg uint32_t Address, uint32_t Size) { 258e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address 259e7245b42SNicola Zaghen << "\n"); 26093e559b1SSam Clegg Symbol *S; 26193e559b1SSam Clegg bool WasInserted; 2624c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 263c729c1b4SSam Clegg 264e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 265e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 266e3498ec5SRui Ueyama return S; 267e3498ec5SRui Ueyama } 268e3498ec5SRui Ueyama 269e3498ec5SRui Ueyama checkDataType(S, File); 270e3498ec5SRui Ueyama 271e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 272e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 273c94d393aSSam Clegg return S; 274c94d393aSSam Clegg } 275c94d393aSSam Clegg 27693102974SSam Clegg Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, 277e3498ec5SRui Ueyama InputFile *File, InputGlobal *Global) { 278e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); 2794c2cbfe6SSam Clegg 28093102974SSam Clegg Symbol *S; 28193102974SSam Clegg bool WasInserted; 2824c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 283c729c1b4SSam Clegg 284e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 285e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 28693102974SSam Clegg return S; 28793102974SSam Clegg } 28893102974SSam Clegg 289e3498ec5SRui Ueyama checkGlobalType(S, File, &Global->getType()); 290e3498ec5SRui Ueyama 291e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 292e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 293e3498ec5SRui Ueyama return S; 294e3498ec5SRui Ueyama } 295e3498ec5SRui Ueyama 296e915a71fSHeejin Ahn Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, 297e915a71fSHeejin Ahn InputFile *File, InputEvent *Event) { 298e915a71fSHeejin Ahn LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); 299e915a71fSHeejin Ahn 300e915a71fSHeejin Ahn Symbol *S; 301e915a71fSHeejin Ahn bool WasInserted; 302e915a71fSHeejin Ahn std::tie(S, WasInserted) = insert(Name, File); 303e915a71fSHeejin Ahn 304e915a71fSHeejin Ahn if (WasInserted || S->isLazy()) { 305e915a71fSHeejin Ahn replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); 306e915a71fSHeejin Ahn return S; 307e915a71fSHeejin Ahn } 308e915a71fSHeejin Ahn 309e915a71fSHeejin Ahn checkEventType(S, File, &Event->getType(), &Event->Signature); 310e915a71fSHeejin Ahn 311e915a71fSHeejin Ahn if (shouldReplace(S, File, Flags)) 312e915a71fSHeejin Ahn replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); 313e915a71fSHeejin Ahn return S; 314e915a71fSHeejin Ahn } 315e915a71fSHeejin Ahn 316e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, 317e3498ec5SRui Ueyama InputFile *File, 318e3498ec5SRui Ueyama const WasmSignature *Sig) { 3198b0b48f3SSam Clegg LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << 3208b0b48f3SSam Clegg " [" << (Sig ? toString(*Sig) : "none") << "]\n"); 321c03c9040SRui Ueyama 322c94d393aSSam Clegg Symbol *S; 323c94d393aSSam Clegg bool WasInserted; 3244c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 325c729c1b4SSam Clegg 326e3498ec5SRui Ueyama if (WasInserted) 327e3498ec5SRui Ueyama replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); 328e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 329b961abc8SRui Ueyama Lazy->fetch(); 330cefbf9acSSam Clegg else 331e3498ec5SRui Ueyama checkFunctionType(S, File, Sig); 332cefbf9acSSam Clegg 333c03c9040SRui Ueyama return S; 334c03c9040SRui Ueyama } 335c03c9040SRui Ueyama 336e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, 337e3498ec5SRui Ueyama InputFile *File) { 338e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); 33993102974SSam Clegg 340e3498ec5SRui Ueyama Symbol *S; 341e3498ec5SRui Ueyama bool WasInserted; 3424c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 343f989a92dSSam Clegg 344e3498ec5SRui Ueyama if (WasInserted) 345e3498ec5SRui Ueyama replaceSymbol<UndefinedData>(S, Name, Flags, File); 346e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 347b961abc8SRui Ueyama Lazy->fetch(); 348e3498ec5SRui Ueyama else if (S->isDefined()) 349e3498ec5SRui Ueyama checkDataType(S, File); 350c94d393aSSam Clegg return S; 351c94d393aSSam Clegg } 352c94d393aSSam Clegg 353e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, 354e3498ec5SRui Ueyama InputFile *File, 355e3498ec5SRui Ueyama const WasmGlobalType *Type) { 356e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); 357e3498ec5SRui Ueyama 358e3498ec5SRui Ueyama Symbol *S; 359e3498ec5SRui Ueyama bool WasInserted; 3604c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 361c729c1b4SSam Clegg 362e3498ec5SRui Ueyama if (WasInserted) 363e3498ec5SRui Ueyama replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); 364e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 365b961abc8SRui Ueyama Lazy->fetch(); 366e3498ec5SRui Ueyama else if (S->isDefined()) 367e3498ec5SRui Ueyama checkGlobalType(S, File, Type); 368e3498ec5SRui Ueyama return S; 369e3498ec5SRui Ueyama } 370e3498ec5SRui Ueyama 371e3498ec5SRui Ueyama void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { 372e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); 373c94d393aSSam Clegg StringRef Name = Sym->getName(); 374c03c9040SRui Ueyama 375c94d393aSSam Clegg Symbol *S; 376c94d393aSSam Clegg bool WasInserted; 3774c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, nullptr); 378c03c9040SRui Ueyama 379c94d393aSSam Clegg if (WasInserted) { 380e3498ec5SRui Ueyama replaceSymbol<LazySymbol>(S, Name, File, *Sym); 381c03c9040SRui Ueyama return; 382c03c9040SRui Ueyama } 383c03c9040SRui Ueyama 384c03c9040SRui Ueyama // If there is an existing undefined symbol, load a new one from the archive. 385c03c9040SRui Ueyama if (S->isUndefined()) { 386e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); 387e3498ec5SRui Ueyama File->addMember(Sym); 388c94d393aSSam Clegg } 389c94d393aSSam Clegg } 390e0f6fcd0SSam Clegg 391c4d9aa1bSNicholas Wilson bool SymbolTable::addComdat(StringRef Name) { 392c4d9aa1bSNicholas Wilson return Comdats.insert(CachedHashStringRef(Name)).second; 393e0f6fcd0SSam Clegg } 394