1c94d393aSSam Clegg //===- SymbolTable.cpp ----------------------------------------------------===// 2c94d393aSSam Clegg // 3c94d393aSSam Clegg // The LLVM Linker 4c94d393aSSam Clegg // 5c94d393aSSam Clegg // This file is distributed under the University of Illinois Open Source 6c94d393aSSam Clegg // License. See LICENSE.TXT for details. 7c94d393aSSam Clegg // 8c94d393aSSam Clegg //===----------------------------------------------------------------------===// 9c94d393aSSam Clegg 10c94d393aSSam Clegg #include "SymbolTable.h" 11c94d393aSSam Clegg #include "Config.h" 125fa274beSSam Clegg #include "InputChunks.h" 13*e915a71fSHeejin Ahn #include "InputEvent.h" 1493102974SSam Clegg #include "InputGlobal.h" 15b8621596SSam Clegg #include "WriterUtils.h" 16c94d393aSSam Clegg #include "lld/Common/ErrorHandler.h" 172017d52bSRui Ueyama #include "lld/Common/Memory.h" 187d67dd11SRui Ueyama #include "llvm/ADT/SetVector.h" 19c94d393aSSam Clegg 20c94d393aSSam Clegg #define DEBUG_TYPE "lld" 21c94d393aSSam Clegg 22c94d393aSSam Clegg using namespace llvm; 2320db381bSSam Clegg using namespace llvm::wasm; 2445218f4aSSam Clegg using namespace llvm::object; 25c94d393aSSam Clegg using namespace lld; 26c94d393aSSam Clegg using namespace lld::wasm; 27c94d393aSSam Clegg 28c94d393aSSam Clegg SymbolTable *lld::wasm::Symtab; 29c94d393aSSam Clegg 30c94d393aSSam Clegg void SymbolTable::addFile(InputFile *File) { 31c94d393aSSam Clegg log("Processing: " + toString(File)); 32c94d393aSSam Clegg File->parse(); 33c94d393aSSam Clegg 34c729c1b4SSam Clegg // LLVM bitcode file 35c729c1b4SSam Clegg if (auto *F = dyn_cast<BitcodeFile>(File)) 36c729c1b4SSam Clegg BitcodeFiles.push_back(F); 37c729c1b4SSam Clegg else if (auto *F = dyn_cast<ObjFile>(File)) 38c94d393aSSam Clegg ObjectFiles.push_back(F); 39c94d393aSSam Clegg } 40c94d393aSSam Clegg 41c729c1b4SSam Clegg // This function is where all the optimizations of link-time 42c729c1b4SSam Clegg // optimization happens. When LTO is in use, some input files are 43c729c1b4SSam Clegg // not in native object file format but in the LLVM bitcode format. 44c729c1b4SSam Clegg // This function compiles bitcode files into a few big native files 45c729c1b4SSam Clegg // using LLVM functions and replaces bitcode symbols with the results. 46c729c1b4SSam Clegg // Because all bitcode files that the program consists of are passed 47c729c1b4SSam Clegg // to the compiler at once, it can do whole-program optimization. 48c729c1b4SSam Clegg void SymbolTable::addCombinedLTOObject() { 49c729c1b4SSam Clegg if (BitcodeFiles.empty()) 50c729c1b4SSam Clegg return; 51c729c1b4SSam Clegg 52c729c1b4SSam Clegg // Compile bitcode files and replace bitcode symbols. 53c729c1b4SSam Clegg LTO.reset(new BitcodeCompiler); 54c729c1b4SSam Clegg for (BitcodeFile *F : BitcodeFiles) 55c729c1b4SSam Clegg LTO->add(*F); 56c729c1b4SSam Clegg 57c729c1b4SSam Clegg for (StringRef Filename : LTO->compile()) { 58c729c1b4SSam Clegg auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp")); 59c729c1b4SSam Clegg Obj->parse(); 60c729c1b4SSam Clegg ObjectFiles.push_back(Obj); 61c729c1b4SSam Clegg } 62c729c1b4SSam Clegg } 63c729c1b4SSam Clegg 64c94d393aSSam Clegg void SymbolTable::reportRemainingUndefines() { 6574fe0ba1SSam Clegg for (Symbol *Sym : SymVector) { 66c729c1b4SSam Clegg if (!Sym->isUndefined() || Sym->isWeak()) 67c729c1b4SSam Clegg continue; 68c729c1b4SSam Clegg if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0) 69c729c1b4SSam Clegg continue; 70c729c1b4SSam Clegg if (!Sym->IsUsedInRegularObj) 71c729c1b4SSam Clegg continue; 7247e2b6b2SSam Clegg error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym)); 73c94d393aSSam Clegg } 74c94d393aSSam Clegg } 75c94d393aSSam Clegg 76c94d393aSSam Clegg Symbol *SymbolTable::find(StringRef Name) { 7767d6908fSRui Ueyama return SymMap.lookup(CachedHashStringRef(Name)); 78c94d393aSSam Clegg } 79c94d393aSSam Clegg 804c2cbfe6SSam Clegg std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) { 814c2cbfe6SSam Clegg bool Inserted = false; 82a80d94d5SSam Clegg Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; 834c2cbfe6SSam Clegg if (!Sym) { 84dfb0b2c7SSam Clegg Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 85c729c1b4SSam Clegg Sym->IsUsedInRegularObj = false; 8674fe0ba1SSam Clegg SymVector.emplace_back(Sym); 874c2cbfe6SSam Clegg Inserted = true; 884c2cbfe6SSam Clegg } 894c2cbfe6SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 904c2cbfe6SSam Clegg Sym->IsUsedInRegularObj = true; 914c2cbfe6SSam Clegg return {Sym, Inserted}; 92c94d393aSSam Clegg } 93c94d393aSSam Clegg 94e3498ec5SRui Ueyama static void reportTypeError(const Symbol *Existing, const InputFile *File, 953876d89aSSam Clegg llvm::wasm::WasmSymbolType Type) { 96e3498ec5SRui Ueyama error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + 97e3498ec5SRui Ueyama toString(Existing->getWasmType()) + " in " + 983876d89aSSam Clegg toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + 993876d89aSSam Clegg " in " + toString(File)); 100e3498ec5SRui Ueyama } 101e3498ec5SRui Ueyama 1026f4286fbSHeejin Ahn // Check the type of new symbol matches that of the symbol is replacing. 1036f4286fbSHeejin Ahn // For functions this can also involve verifying that the signatures match. 104cefbf9acSSam Clegg static void checkFunctionType(Symbol *Existing, const InputFile *File, 105e3498ec5SRui Ueyama const WasmSignature *NewSig) { 10665d6380cSSam Clegg auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); 10765d6380cSSam Clegg if (!ExistingFunction) { 1083876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION); 109e3498ec5SRui Ueyama return; 110e3498ec5SRui Ueyama } 111e3498ec5SRui Ueyama 112cefbf9acSSam Clegg if (!NewSig) 113cefbf9acSSam Clegg return; 114cefbf9acSSam Clegg 115*e915a71fSHeejin Ahn const WasmSignature *OldSig = ExistingFunction->Signature; 116cefbf9acSSam Clegg if (!OldSig) { 117*e915a71fSHeejin Ahn ExistingFunction->Signature = NewSig; 118cefbf9acSSam Clegg return; 119cefbf9acSSam Clegg } 120cefbf9acSSam Clegg 121cefbf9acSSam Clegg if (*NewSig != *OldSig) 122ffd0aaf8SSam Clegg warn("function signature mismatch: " + Existing->getName() + 123e3498ec5SRui Ueyama "\n>>> defined as " + toString(*OldSig) + " in " + 124e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined as " + 125ffd0aaf8SSam Clegg toString(*NewSig) + " in " + toString(File)); 126e3498ec5SRui Ueyama } 127e3498ec5SRui Ueyama 128e3498ec5SRui Ueyama static void checkGlobalType(const Symbol *Existing, const InputFile *File, 129e3498ec5SRui Ueyama const WasmGlobalType *NewType) { 130e3498ec5SRui Ueyama if (!isa<GlobalSymbol>(Existing)) { 1313876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_GLOBAL); 132b8621596SSam Clegg return; 133b8621596SSam Clegg } 134b8621596SSam Clegg 135e3498ec5SRui Ueyama const WasmGlobalType *OldType = cast<GlobalSymbol>(Existing)->getGlobalType(); 136e3498ec5SRui Ueyama if (*NewType != *OldType) { 137e3498ec5SRui Ueyama error("Global type mismatch: " + Existing->getName() + "\n>>> defined as " + 138e3498ec5SRui Ueyama toString(*OldType) + " in " + toString(Existing->getFile()) + 139e3498ec5SRui Ueyama "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); 140c94d393aSSam Clegg } 14124b3dcd4SSam Clegg } 14224b3dcd4SSam Clegg 143*e915a71fSHeejin Ahn static void checkEventType(const Symbol *Existing, const InputFile *File, 144*e915a71fSHeejin Ahn const WasmEventType *NewType, 145*e915a71fSHeejin Ahn const WasmSignature *NewSig) { 146*e915a71fSHeejin Ahn auto ExistingEvent = dyn_cast<EventSymbol>(Existing); 147*e915a71fSHeejin Ahn if (!isa<EventSymbol>(Existing)) { 148*e915a71fSHeejin Ahn reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); 149*e915a71fSHeejin Ahn return; 150*e915a71fSHeejin Ahn } 151*e915a71fSHeejin Ahn 152*e915a71fSHeejin Ahn const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType(); 153*e915a71fSHeejin Ahn const WasmSignature *OldSig = ExistingEvent->Signature; 154*e915a71fSHeejin Ahn if (NewType->Attribute != OldType->Attribute) 155*e915a71fSHeejin Ahn error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + 156*e915a71fSHeejin Ahn toString(*OldType) + " in " + toString(Existing->getFile()) + 157*e915a71fSHeejin Ahn "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); 158*e915a71fSHeejin Ahn if (*NewSig != *OldSig) 159*e915a71fSHeejin Ahn warn("Event signature mismatch: " + Existing->getName() + 160*e915a71fSHeejin Ahn "\n>>> defined as " + toString(*OldSig) + " in " + 161*e915a71fSHeejin Ahn toString(Existing->getFile()) + "\n>>> defined as " + 162*e915a71fSHeejin Ahn toString(*NewSig) + " in " + toString(File)); 163*e915a71fSHeejin Ahn } 164*e915a71fSHeejin Ahn 165e3498ec5SRui Ueyama static void checkDataType(const Symbol *Existing, const InputFile *File) { 166e3498ec5SRui Ueyama if (!isa<DataSymbol>(Existing)) 1673876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); 168e3498ec5SRui Ueyama } 169e3498ec5SRui Ueyama 170dfb0b2c7SSam Clegg DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, 171ebda41f8SNicholas Wilson uint32_t Flags, 172ebda41f8SNicholas Wilson InputFunction *Function) { 173e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); 174b961abc8SRui Ueyama assert(!find(Name)); 175ebda41f8SNicholas Wilson SyntheticFunctions.emplace_back(Function); 1764c2cbfe6SSam Clegg return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name, 1774c2cbfe6SSam Clegg Flags, nullptr, Function); 17850686856SSam Clegg } 17950686856SSam Clegg 18000245539SSam Clegg DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, 18100245539SSam Clegg uint32_t Flags) { 182e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); 183b961abc8SRui Ueyama assert(!find(Name)); 1844c2cbfe6SSam Clegg return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags); 185c94d393aSSam Clegg } 186c94d393aSSam Clegg 18793102974SSam Clegg DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, 18893102974SSam Clegg InputGlobal *Global) { 189e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global 190e7245b42SNicola Zaghen << "\n"); 191b961abc8SRui Ueyama assert(!find(Name)); 192ebda41f8SNicholas Wilson SyntheticGlobals.emplace_back(Global); 1934c2cbfe6SSam Clegg return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags, 1944c2cbfe6SSam Clegg nullptr, Global); 19593102974SSam Clegg } 19693102974SSam Clegg 197e3498ec5SRui Ueyama static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, 198e3498ec5SRui Ueyama uint32_t NewFlags) { 199c03c9040SRui Ueyama // If existing symbol is undefined, replace it. 200e3498ec5SRui Ueyama if (!Existing->isDefined()) { 201e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " 202e3498ec5SRui Ueyama << Existing->getName() << "\n"); 203c03c9040SRui Ueyama return true; 204c03c9040SRui Ueyama } 205c03c9040SRui Ueyama 206c03c9040SRui Ueyama // Now we have two defined symbols. If the new one is weak, we can ignore it. 207c03c9040SRui Ueyama if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { 208e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); 209c03c9040SRui Ueyama return false; 210c03c9040SRui Ueyama } 211c03c9040SRui Ueyama 212c03c9040SRui Ueyama // If the existing symbol is weak, we should replace it. 213e3498ec5SRui Ueyama if (Existing->isWeak()) { 214e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); 215c03c9040SRui Ueyama return true; 216c03c9040SRui Ueyama } 217c03c9040SRui Ueyama 218c03c9040SRui Ueyama // Neither symbol is week. They conflict. 219e3498ec5SRui Ueyama error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + 220e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined in " + 221e3498ec5SRui Ueyama toString(NewFile)); 222c03c9040SRui Ueyama return true; 223b8621596SSam Clegg } 22493e559b1SSam Clegg 22593e559b1SSam Clegg Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, 226e3498ec5SRui Ueyama InputFile *File, 227e3498ec5SRui Ueyama InputFunction *Function) { 2288b0b48f3SSam Clegg LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" 2298b0b48f3SSam Clegg << (Function ? toString(Function->Signature) : "none") 2308b0b48f3SSam Clegg << "]\n"); 23193e559b1SSam Clegg Symbol *S; 23293e559b1SSam Clegg bool WasInserted; 2334c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 234c729c1b4SSam Clegg 235e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 236e3498ec5SRui Ueyama replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 237e3498ec5SRui Ueyama return S; 238e3498ec5SRui Ueyama } 239e3498ec5SRui Ueyama 240c729c1b4SSam Clegg if (Function) 241e3498ec5SRui Ueyama checkFunctionType(S, File, &Function->Signature); 242e3498ec5SRui Ueyama 2438b0b48f3SSam Clegg if (shouldReplace(S, File, Flags)) { 2448b0b48f3SSam Clegg // If the new defined function doesn't have signture (i.e. bitcode 2458b0b48f3SSam Clegg // functions) but the old symbols does then preserve the old signature 2468b0b48f3SSam Clegg const WasmSignature *OldSig = nullptr; 2478b0b48f3SSam Clegg if (auto* F = dyn_cast<FunctionSymbol>(S)) 248*e915a71fSHeejin Ahn OldSig = F->Signature; 2498b0b48f3SSam Clegg auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 250*e915a71fSHeejin Ahn if (!NewSym->Signature) 251*e915a71fSHeejin Ahn NewSym->Signature = OldSig; 2528b0b48f3SSam Clegg } 25393e559b1SSam Clegg return S; 25493e559b1SSam Clegg } 25593e559b1SSam Clegg 25600245539SSam Clegg Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, 257e3498ec5SRui Ueyama InputFile *File, InputSegment *Segment, 25893102974SSam Clegg uint32_t Address, uint32_t Size) { 259e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address 260e7245b42SNicola Zaghen << "\n"); 26193e559b1SSam Clegg Symbol *S; 26293e559b1SSam Clegg bool WasInserted; 2634c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 264c729c1b4SSam Clegg 265e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 266e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 267e3498ec5SRui Ueyama return S; 268e3498ec5SRui Ueyama } 269e3498ec5SRui Ueyama 270e3498ec5SRui Ueyama checkDataType(S, File); 271e3498ec5SRui Ueyama 272e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 273e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 274c94d393aSSam Clegg return S; 275c94d393aSSam Clegg } 276c94d393aSSam Clegg 27793102974SSam Clegg Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, 278e3498ec5SRui Ueyama InputFile *File, InputGlobal *Global) { 279e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); 2804c2cbfe6SSam Clegg 28193102974SSam Clegg Symbol *S; 28293102974SSam Clegg bool WasInserted; 2834c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 284c729c1b4SSam Clegg 285e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 286e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 28793102974SSam Clegg return S; 28893102974SSam Clegg } 28993102974SSam Clegg 290e3498ec5SRui Ueyama checkGlobalType(S, File, &Global->getType()); 291e3498ec5SRui Ueyama 292e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 293e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 294e3498ec5SRui Ueyama return S; 295e3498ec5SRui Ueyama } 296e3498ec5SRui Ueyama 297*e915a71fSHeejin Ahn Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, 298*e915a71fSHeejin Ahn InputFile *File, InputEvent *Event) { 299*e915a71fSHeejin Ahn LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); 300*e915a71fSHeejin Ahn 301*e915a71fSHeejin Ahn Symbol *S; 302*e915a71fSHeejin Ahn bool WasInserted; 303*e915a71fSHeejin Ahn std::tie(S, WasInserted) = insert(Name, File); 304*e915a71fSHeejin Ahn 305*e915a71fSHeejin Ahn if (WasInserted || S->isLazy()) { 306*e915a71fSHeejin Ahn replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); 307*e915a71fSHeejin Ahn return S; 308*e915a71fSHeejin Ahn } 309*e915a71fSHeejin Ahn 310*e915a71fSHeejin Ahn checkEventType(S, File, &Event->getType(), &Event->Signature); 311*e915a71fSHeejin Ahn 312*e915a71fSHeejin Ahn if (shouldReplace(S, File, Flags)) 313*e915a71fSHeejin Ahn replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); 314*e915a71fSHeejin Ahn return S; 315*e915a71fSHeejin Ahn } 316*e915a71fSHeejin Ahn 317e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, 318e3498ec5SRui Ueyama InputFile *File, 319e3498ec5SRui Ueyama const WasmSignature *Sig) { 3208b0b48f3SSam Clegg LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << 3218b0b48f3SSam Clegg " [" << (Sig ? toString(*Sig) : "none") << "]\n"); 322c03c9040SRui Ueyama 323c94d393aSSam Clegg Symbol *S; 324c94d393aSSam Clegg bool WasInserted; 3254c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 326c729c1b4SSam Clegg 327e3498ec5SRui Ueyama if (WasInserted) 328e3498ec5SRui Ueyama replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); 329e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 330b961abc8SRui Ueyama Lazy->fetch(); 331cefbf9acSSam Clegg else 332e3498ec5SRui Ueyama checkFunctionType(S, File, Sig); 333cefbf9acSSam Clegg 334c03c9040SRui Ueyama return S; 335c03c9040SRui Ueyama } 336c03c9040SRui Ueyama 337e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, 338e3498ec5SRui Ueyama InputFile *File) { 339e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); 34093102974SSam Clegg 341e3498ec5SRui Ueyama Symbol *S; 342e3498ec5SRui Ueyama bool WasInserted; 3434c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 344f989a92dSSam Clegg 345e3498ec5SRui Ueyama if (WasInserted) 346e3498ec5SRui Ueyama replaceSymbol<UndefinedData>(S, Name, Flags, File); 347e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 348b961abc8SRui Ueyama Lazy->fetch(); 349e3498ec5SRui Ueyama else if (S->isDefined()) 350e3498ec5SRui Ueyama checkDataType(S, File); 351c94d393aSSam Clegg return S; 352c94d393aSSam Clegg } 353c94d393aSSam Clegg 354e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, 355e3498ec5SRui Ueyama InputFile *File, 356e3498ec5SRui Ueyama const WasmGlobalType *Type) { 357e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); 358e3498ec5SRui Ueyama 359e3498ec5SRui Ueyama Symbol *S; 360e3498ec5SRui Ueyama bool WasInserted; 3614c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, File); 362c729c1b4SSam Clegg 363e3498ec5SRui Ueyama if (WasInserted) 364e3498ec5SRui Ueyama replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); 365e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 366b961abc8SRui Ueyama Lazy->fetch(); 367e3498ec5SRui Ueyama else if (S->isDefined()) 368e3498ec5SRui Ueyama checkGlobalType(S, File, Type); 369e3498ec5SRui Ueyama return S; 370e3498ec5SRui Ueyama } 371e3498ec5SRui Ueyama 372e3498ec5SRui Ueyama void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { 373e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); 374c94d393aSSam Clegg StringRef Name = Sym->getName(); 375c03c9040SRui Ueyama 376c94d393aSSam Clegg Symbol *S; 377c94d393aSSam Clegg bool WasInserted; 3784c2cbfe6SSam Clegg std::tie(S, WasInserted) = insert(Name, nullptr); 379c03c9040SRui Ueyama 380c94d393aSSam Clegg if (WasInserted) { 381e3498ec5SRui Ueyama replaceSymbol<LazySymbol>(S, Name, File, *Sym); 382c03c9040SRui Ueyama return; 383c03c9040SRui Ueyama } 384c03c9040SRui Ueyama 385c03c9040SRui Ueyama // If there is an existing undefined symbol, load a new one from the archive. 386c03c9040SRui Ueyama if (S->isUndefined()) { 387e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); 388e3498ec5SRui Ueyama File->addMember(Sym); 389c94d393aSSam Clegg } 390c94d393aSSam Clegg } 391e0f6fcd0SSam Clegg 392c4d9aa1bSNicholas Wilson bool SymbolTable::addComdat(StringRef Name) { 393c4d9aa1bSNicholas Wilson return Comdats.insert(CachedHashStringRef(Name)).second; 394e0f6fcd0SSam Clegg } 395