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" 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; 23c94d393aSSam Clegg using namespace lld; 24c94d393aSSam Clegg using namespace lld::wasm; 25c94d393aSSam Clegg 26c94d393aSSam Clegg SymbolTable *lld::wasm::Symtab; 27c94d393aSSam Clegg 28c94d393aSSam Clegg void SymbolTable::addFile(InputFile *File) { 29c94d393aSSam Clegg log("Processing: " + toString(File)); 30c94d393aSSam Clegg File->parse(); 31c94d393aSSam Clegg 32*c729c1b4SSam Clegg // LLVM bitcode file 33*c729c1b4SSam Clegg if (auto *F = dyn_cast<BitcodeFile>(File)) 34*c729c1b4SSam Clegg BitcodeFiles.push_back(F); 35*c729c1b4SSam Clegg else if (auto *F = dyn_cast<ObjFile>(File)) 36c94d393aSSam Clegg ObjectFiles.push_back(F); 37c94d393aSSam Clegg } 38c94d393aSSam Clegg 39*c729c1b4SSam Clegg // This function is where all the optimizations of link-time 40*c729c1b4SSam Clegg // optimization happens. When LTO is in use, some input files are 41*c729c1b4SSam Clegg // not in native object file format but in the LLVM bitcode format. 42*c729c1b4SSam Clegg // This function compiles bitcode files into a few big native files 43*c729c1b4SSam Clegg // using LLVM functions and replaces bitcode symbols with the results. 44*c729c1b4SSam Clegg // Because all bitcode files that the program consists of are passed 45*c729c1b4SSam Clegg // to the compiler at once, it can do whole-program optimization. 46*c729c1b4SSam Clegg void SymbolTable::addCombinedLTOObject() { 47*c729c1b4SSam Clegg if (BitcodeFiles.empty()) 48*c729c1b4SSam Clegg return; 49*c729c1b4SSam Clegg 50*c729c1b4SSam Clegg // Compile bitcode files and replace bitcode symbols. 51*c729c1b4SSam Clegg LTO.reset(new BitcodeCompiler); 52*c729c1b4SSam Clegg for (BitcodeFile *F : BitcodeFiles) 53*c729c1b4SSam Clegg LTO->add(*F); 54*c729c1b4SSam Clegg 55*c729c1b4SSam Clegg for (StringRef Filename : LTO->compile()) { 56*c729c1b4SSam Clegg auto *Obj = make<ObjFile>(MemoryBufferRef(Filename, "lto.tmp")); 57*c729c1b4SSam Clegg Obj->parse(); 58*c729c1b4SSam Clegg ObjectFiles.push_back(Obj); 59*c729c1b4SSam Clegg } 60*c729c1b4SSam Clegg } 61*c729c1b4SSam Clegg 62c94d393aSSam Clegg void SymbolTable::reportRemainingUndefines() { 637d67dd11SRui Ueyama SetVector<Symbol *> Undefs; 6474fe0ba1SSam Clegg for (Symbol *Sym : SymVector) { 65*c729c1b4SSam Clegg if (!Sym->isUndefined() || Sym->isWeak()) 66*c729c1b4SSam Clegg continue; 67*c729c1b4SSam Clegg if (Config->AllowUndefinedSymbols.count(Sym->getName()) != 0) 68*c729c1b4SSam Clegg continue; 69*c729c1b4SSam Clegg if (!Sym->IsUsedInRegularObj) 70*c729c1b4SSam Clegg continue; 71c94d393aSSam Clegg Undefs.insert(Sym); 72c94d393aSSam Clegg } 73c94d393aSSam Clegg 74c94d393aSSam Clegg if (Undefs.empty()) 75c94d393aSSam Clegg return; 76c94d393aSSam Clegg 77c94d393aSSam Clegg for (ObjFile *File : ObjectFiles) 78c94d393aSSam Clegg for (Symbol *Sym : File->getSymbols()) 79c94d393aSSam Clegg if (Undefs.count(Sym)) 80c94d393aSSam Clegg error(toString(File) + ": undefined symbol: " + toString(*Sym)); 81c94d393aSSam Clegg 82c94d393aSSam Clegg for (Symbol *Sym : Undefs) 83c94d393aSSam Clegg if (!Sym->getFile()) 84c94d393aSSam Clegg error("undefined symbol: " + toString(*Sym)); 85c94d393aSSam Clegg } 86c94d393aSSam Clegg 87c94d393aSSam Clegg Symbol *SymbolTable::find(StringRef Name) { 8867d6908fSRui Ueyama return SymMap.lookup(CachedHashStringRef(Name)); 89c94d393aSSam Clegg } 90c94d393aSSam Clegg 91c94d393aSSam Clegg std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { 92a80d94d5SSam Clegg Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; 93c94d393aSSam Clegg if (Sym) 94c94d393aSSam Clegg return {Sym, false}; 95dfb0b2c7SSam Clegg Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 96*c729c1b4SSam Clegg Sym->IsUsedInRegularObj = false; 9774fe0ba1SSam Clegg SymVector.emplace_back(Sym); 98c94d393aSSam Clegg return {Sym, true}; 99c94d393aSSam Clegg } 100c94d393aSSam Clegg 101e3498ec5SRui Ueyama static void reportTypeError(const Symbol *Existing, const InputFile *File, 1023876d89aSSam Clegg llvm::wasm::WasmSymbolType Type) { 103e3498ec5SRui Ueyama error("symbol type mismatch: " + toString(*Existing) + "\n>>> defined as " + 104e3498ec5SRui Ueyama toString(Existing->getWasmType()) + " in " + 1053876d89aSSam Clegg toString(Existing->getFile()) + "\n>>> defined as " + toString(Type) + 1063876d89aSSam Clegg " in " + toString(File)); 107e3498ec5SRui Ueyama } 108e3498ec5SRui Ueyama 109e3498ec5SRui Ueyama static void checkFunctionType(const Symbol *Existing, const InputFile *File, 110e3498ec5SRui Ueyama const WasmSignature *NewSig) { 11165d6380cSSam Clegg auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); 11265d6380cSSam Clegg if (!ExistingFunction) { 1133876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_FUNCTION); 114e3498ec5SRui Ueyama return; 115e3498ec5SRui Ueyama } 116e3498ec5SRui Ueyama 11765d6380cSSam Clegg const WasmSignature *OldSig = ExistingFunction->getFunctionType(); 11865d6380cSSam Clegg if (OldSig && NewSig && *NewSig != *OldSig) { 119752494bfSSam Clegg warn("Function type mismatch: " + Existing->getName() + 120e3498ec5SRui Ueyama "\n>>> defined as " + toString(*OldSig) + " in " + 121e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined as " + 122e3498ec5SRui Ueyama toString(*NewSig) + " in " + toString(File)); 123e3498ec5SRui Ueyama } 124e3498ec5SRui Ueyama } 125e3498ec5SRui Ueyama 126b8621596SSam Clegg // Check the type of new symbol matches that of the symbol is replacing. 127b8621596SSam Clegg // For functions this can also involve verifying that the signatures match. 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 143e3498ec5SRui Ueyama static void checkDataType(const Symbol *Existing, const InputFile *File) { 144e3498ec5SRui Ueyama if (!isa<DataSymbol>(Existing)) 1453876d89aSSam Clegg reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); 146e3498ec5SRui Ueyama } 147e3498ec5SRui Ueyama 148dfb0b2c7SSam Clegg DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, 149ebda41f8SNicholas Wilson uint32_t Flags, 150ebda41f8SNicholas Wilson InputFunction *Function) { 151e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); 152b961abc8SRui Ueyama assert(!find(Name)); 153ebda41f8SNicholas Wilson SyntheticFunctions.emplace_back(Function); 154ebda41f8SNicholas Wilson return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, 155ebda41f8SNicholas Wilson nullptr, Function); 15650686856SSam Clegg } 15750686856SSam Clegg 15800245539SSam Clegg DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, 15900245539SSam Clegg uint32_t Flags) { 160e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n"); 161b961abc8SRui Ueyama assert(!find(Name)); 162b961abc8SRui Ueyama return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags); 163c94d393aSSam Clegg } 164c94d393aSSam Clegg 16593102974SSam Clegg DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, 16693102974SSam Clegg InputGlobal *Global) { 167e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global 168e7245b42SNicola Zaghen << "\n"); 169b961abc8SRui Ueyama assert(!find(Name)); 170ebda41f8SNicholas Wilson SyntheticGlobals.emplace_back(Global); 171b961abc8SRui Ueyama return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr, 172b961abc8SRui Ueyama Global); 17393102974SSam Clegg } 17493102974SSam Clegg 175e3498ec5SRui Ueyama static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, 176e3498ec5SRui Ueyama uint32_t NewFlags) { 177c03c9040SRui Ueyama // If existing symbol is undefined, replace it. 178e3498ec5SRui Ueyama if (!Existing->isDefined()) { 179e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "resolving existing undefined symbol: " 180e3498ec5SRui Ueyama << Existing->getName() << "\n"); 181c03c9040SRui Ueyama return true; 182c03c9040SRui Ueyama } 183c03c9040SRui Ueyama 184c03c9040SRui Ueyama // Now we have two defined symbols. If the new one is weak, we can ignore it. 185c03c9040SRui Ueyama if ((NewFlags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { 186e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "existing symbol takes precedence\n"); 187c03c9040SRui Ueyama return false; 188c03c9040SRui Ueyama } 189c03c9040SRui Ueyama 190c03c9040SRui Ueyama // If the existing symbol is weak, we should replace it. 191e3498ec5SRui Ueyama if (Existing->isWeak()) { 192e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing weak symbol\n"); 193c03c9040SRui Ueyama return true; 194c03c9040SRui Ueyama } 195c03c9040SRui Ueyama 196c03c9040SRui Ueyama // Neither symbol is week. They conflict. 197e3498ec5SRui Ueyama error("duplicate symbol: " + toString(*Existing) + "\n>>> defined in " + 198e3498ec5SRui Ueyama toString(Existing->getFile()) + "\n>>> defined in " + 199e3498ec5SRui Ueyama toString(NewFile)); 200c03c9040SRui Ueyama return true; 201b8621596SSam Clegg } 20293e559b1SSam Clegg 20393e559b1SSam Clegg Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, 204e3498ec5SRui Ueyama InputFile *File, 205e3498ec5SRui Ueyama InputFunction *Function) { 206e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n"); 20793e559b1SSam Clegg Symbol *S; 20893e559b1SSam Clegg bool WasInserted; 20993e559b1SSam Clegg std::tie(S, WasInserted) = insert(Name); 210e3498ec5SRui Ueyama 211*c729c1b4SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 212*c729c1b4SSam Clegg S->IsUsedInRegularObj = true; 213*c729c1b4SSam Clegg 214e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 215e3498ec5SRui Ueyama replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 216e3498ec5SRui Ueyama return S; 217e3498ec5SRui Ueyama } 218e3498ec5SRui Ueyama 219*c729c1b4SSam Clegg if (Function) 220e3498ec5SRui Ueyama checkFunctionType(S, File, &Function->Signature); 221e3498ec5SRui Ueyama 222e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 223e3498ec5SRui Ueyama replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); 22493e559b1SSam Clegg return S; 22593e559b1SSam Clegg } 22693e559b1SSam Clegg 22700245539SSam Clegg Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags, 228e3498ec5SRui Ueyama InputFile *File, InputSegment *Segment, 22993102974SSam Clegg uint32_t Address, uint32_t Size) { 230e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedData:" << Name << " addr:" << Address 231e7245b42SNicola Zaghen << "\n"); 23293e559b1SSam Clegg Symbol *S; 23393e559b1SSam Clegg bool WasInserted; 23493e559b1SSam Clegg std::tie(S, WasInserted) = insert(Name); 235e3498ec5SRui Ueyama 236*c729c1b4SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 237*c729c1b4SSam Clegg S->IsUsedInRegularObj = true; 238*c729c1b4SSam Clegg 239e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 240e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 241e3498ec5SRui Ueyama return S; 242e3498ec5SRui Ueyama } 243e3498ec5SRui Ueyama 244e3498ec5SRui Ueyama checkDataType(S, File); 245e3498ec5SRui Ueyama 246e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 247e3498ec5SRui Ueyama replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); 248c94d393aSSam Clegg return S; 249c94d393aSSam Clegg } 250c94d393aSSam Clegg 25193102974SSam Clegg Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, 252e3498ec5SRui Ueyama InputFile *File, InputGlobal *Global) { 253e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); 25493102974SSam Clegg Symbol *S; 25593102974SSam Clegg bool WasInserted; 25693102974SSam Clegg std::tie(S, WasInserted) = insert(Name); 257e3498ec5SRui Ueyama 258*c729c1b4SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 259*c729c1b4SSam Clegg S->IsUsedInRegularObj = true; 260*c729c1b4SSam Clegg 261e3498ec5SRui Ueyama if (WasInserted || S->isLazy()) { 262e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 26393102974SSam Clegg return S; 26493102974SSam Clegg } 26593102974SSam Clegg 266e3498ec5SRui Ueyama checkGlobalType(S, File, &Global->getType()); 267e3498ec5SRui Ueyama 268e3498ec5SRui Ueyama if (shouldReplace(S, File, Flags)) 269e3498ec5SRui Ueyama replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); 270e3498ec5SRui Ueyama return S; 271e3498ec5SRui Ueyama } 272e3498ec5SRui Ueyama 273e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, 274e3498ec5SRui Ueyama InputFile *File, 275e3498ec5SRui Ueyama const WasmSignature *Sig) { 276e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); 277c03c9040SRui Ueyama 278c94d393aSSam Clegg Symbol *S; 279c94d393aSSam Clegg bool WasInserted; 28020db381bSSam Clegg std::tie(S, WasInserted) = insert(Name); 281c03c9040SRui Ueyama 282*c729c1b4SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 283*c729c1b4SSam Clegg S->IsUsedInRegularObj = true; 284*c729c1b4SSam Clegg 285e3498ec5SRui Ueyama if (WasInserted) 286e3498ec5SRui Ueyama replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); 287e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 288b961abc8SRui Ueyama Lazy->fetch(); 289e3498ec5SRui Ueyama else if (S->isDefined()) 290e3498ec5SRui Ueyama checkFunctionType(S, File, Sig); 291c03c9040SRui Ueyama return S; 292c03c9040SRui Ueyama } 293c03c9040SRui Ueyama 294e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, 295e3498ec5SRui Ueyama InputFile *File) { 296e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedData: " << Name << "\n"); 29793102974SSam Clegg 298e3498ec5SRui Ueyama Symbol *S; 299e3498ec5SRui Ueyama bool WasInserted; 300e3498ec5SRui Ueyama std::tie(S, WasInserted) = insert(Name); 301e3498ec5SRui Ueyama 302e3498ec5SRui Ueyama if (WasInserted) 303e3498ec5SRui Ueyama replaceSymbol<UndefinedData>(S, Name, Flags, File); 304e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 305b961abc8SRui Ueyama Lazy->fetch(); 306e3498ec5SRui Ueyama else if (S->isDefined()) 307e3498ec5SRui Ueyama checkDataType(S, File); 308c94d393aSSam Clegg return S; 309c94d393aSSam Clegg } 310c94d393aSSam Clegg 311e3498ec5SRui Ueyama Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, 312e3498ec5SRui Ueyama InputFile *File, 313e3498ec5SRui Ueyama const WasmGlobalType *Type) { 314e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); 315e3498ec5SRui Ueyama 316e3498ec5SRui Ueyama Symbol *S; 317e3498ec5SRui Ueyama bool WasInserted; 318e3498ec5SRui Ueyama std::tie(S, WasInserted) = insert(Name); 319e3498ec5SRui Ueyama 320*c729c1b4SSam Clegg if (!File || File->kind() == InputFile::ObjectKind) 321*c729c1b4SSam Clegg S->IsUsedInRegularObj = true; 322*c729c1b4SSam Clegg 323e3498ec5SRui Ueyama if (WasInserted) 324e3498ec5SRui Ueyama replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); 325e3498ec5SRui Ueyama else if (auto *Lazy = dyn_cast<LazySymbol>(S)) 326b961abc8SRui Ueyama Lazy->fetch(); 327e3498ec5SRui Ueyama else if (S->isDefined()) 328e3498ec5SRui Ueyama checkGlobalType(S, File, Type); 329e3498ec5SRui Ueyama return S; 330e3498ec5SRui Ueyama } 331e3498ec5SRui Ueyama 332e3498ec5SRui Ueyama void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) { 333e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "addLazy: " << Sym->getName() << "\n"); 334c94d393aSSam Clegg StringRef Name = Sym->getName(); 335c03c9040SRui Ueyama 336c94d393aSSam Clegg Symbol *S; 337c94d393aSSam Clegg bool WasInserted; 338c94d393aSSam Clegg std::tie(S, WasInserted) = insert(Name); 339c03c9040SRui Ueyama 340c94d393aSSam Clegg if (WasInserted) { 341e3498ec5SRui Ueyama replaceSymbol<LazySymbol>(S, Name, File, *Sym); 342c03c9040SRui Ueyama return; 343c03c9040SRui Ueyama } 344c03c9040SRui Ueyama 345c03c9040SRui Ueyama // If there is an existing undefined symbol, load a new one from the archive. 346c03c9040SRui Ueyama if (S->isUndefined()) { 347e7245b42SNicola Zaghen LLVM_DEBUG(dbgs() << "replacing existing undefined\n"); 348e3498ec5SRui Ueyama File->addMember(Sym); 349c94d393aSSam Clegg } 350c94d393aSSam Clegg } 351e0f6fcd0SSam Clegg 352c4d9aa1bSNicholas Wilson bool SymbolTable::addComdat(StringRef Name) { 353c4d9aa1bSNicholas Wilson return Comdats.insert(CachedHashStringRef(Name)).second; 354e0f6fcd0SSam Clegg } 355