1 //===- SymbolTable.cpp ----------------------------------------------------===// 2 // 3 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SymbolTable.h" 10 #include "Config.h" 11 #include "Driver.h" 12 #include "LTO.h" 13 #include "PDB.h" 14 #include "Symbols.h" 15 #include "lld/Common/ErrorHandler.h" 16 #include "lld/Common/Memory.h" 17 #include "lld/Common/Timer.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <utility> 22 23 using namespace llvm; 24 25 namespace lld { 26 namespace coff { 27 28 static Timer LTOTimer("LTO", Timer::root()); 29 30 SymbolTable *Symtab; 31 32 void SymbolTable::addFile(InputFile *File) { 33 log("Reading " + toString(File)); 34 File->parse(); 35 36 MachineTypes MT = File->getMachineType(); 37 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { 38 Config->Machine = MT; 39 } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { 40 error(toString(File) + ": machine type " + machineToStr(MT) + 41 " conflicts with " + machineToStr(Config->Machine)); 42 return; 43 } 44 45 if (auto *F = dyn_cast<ObjFile>(File)) { 46 ObjFile::Instances.push_back(F); 47 } else if (auto *F = dyn_cast<BitcodeFile>(File)) { 48 BitcodeFile::Instances.push_back(F); 49 } else if (auto *F = dyn_cast<ImportFile>(File)) { 50 ImportFile::Instances.push_back(F); 51 } 52 53 Driver->parseDirectives(File); 54 } 55 56 static void errorOrWarn(const Twine &S) { 57 if (Config->ForceUnresolved) 58 warn(S); 59 else 60 error(S); 61 } 62 63 // Returns the symbol in SC whose value is <= Addr that is closest to Addr. 64 // This is generally the global variable or function whose definition contains 65 // Addr. 66 static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) { 67 DefinedRegular *Candidate = nullptr; 68 69 for (Symbol *S : SC->File->getSymbols()) { 70 auto *D = dyn_cast_or_null<DefinedRegular>(S); 71 if (!D || D->getChunk() != SC || D->getValue() > Addr || 72 (Candidate && D->getValue() < Candidate->getValue())) 73 continue; 74 75 Candidate = D; 76 } 77 78 return Candidate; 79 } 80 81 std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) { 82 struct Location { 83 Symbol *Sym; 84 std::pair<StringRef, uint32_t> FileLine; 85 }; 86 std::vector<Location> Locations; 87 88 for (Chunk *C : File->getChunks()) { 89 auto *SC = dyn_cast<SectionChunk>(C); 90 if (!SC) 91 continue; 92 for (const coff_relocation &R : SC->getRelocs()) { 93 if (R.SymbolTableIndex != SymIndex) 94 continue; 95 std::pair<StringRef, uint32_t> FileLine = 96 getFileLine(SC, R.VirtualAddress); 97 Symbol *Sym = getSymbol(SC, R.VirtualAddress); 98 if (!FileLine.first.empty() || Sym) 99 Locations.push_back({Sym, FileLine}); 100 } 101 } 102 103 if (Locations.empty()) 104 return "\n>>> referenced by " + toString(File); 105 106 std::string Out; 107 llvm::raw_string_ostream OS(Out); 108 for (Location Loc : Locations) { 109 OS << "\n>>> referenced by "; 110 if (!Loc.FileLine.first.empty()) 111 OS << Loc.FileLine.first << ":" << Loc.FileLine.second 112 << "\n>>> "; 113 OS << toString(File); 114 if (Loc.Sym) 115 OS << ":(" << toString(*Loc.Sym) << ')'; 116 } 117 return OS.str(); 118 } 119 120 void SymbolTable::loadMinGWAutomaticImports() { 121 for (auto &I : SymMap) { 122 Symbol *Sym = I.second; 123 auto *Undef = dyn_cast<Undefined>(Sym); 124 if (!Undef) 125 continue; 126 if (!Sym->IsUsedInRegularObj) 127 continue; 128 129 StringRef Name = Undef->getName(); 130 131 if (Name.startswith("__imp_")) 132 continue; 133 // If we have an undefined symbol, but we have a Lazy representing a 134 // symbol we could load from file, make sure to load that. 135 Lazy *L = dyn_cast_or_null<Lazy>(find(("__imp_" + Name).str())); 136 if (!L || L->PendingArchiveLoad) 137 continue; 138 139 log("Loading lazy " + L->getName() + " from " + L->File->getName() + 140 " for automatic import"); 141 L->PendingArchiveLoad = true; 142 L->File->addMember(&L->Sym); 143 } 144 } 145 146 bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) { 147 if (Name.startswith("__imp_")) 148 return false; 149 Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str())); 150 if (!Imp) 151 return false; 152 153 // Replace the reference directly to a variable with a reference 154 // to the import address table instead. This obviously isn't right, 155 // but we mark the symbol as IsRuntimePseudoReloc, and a later pass 156 // will add runtime pseudo relocations for every relocation against 157 // this Symbol. The runtime pseudo relocation framework expects the 158 // reference itself to point at the IAT entry. 159 size_t ImpSize = 0; 160 if (isa<DefinedImportData>(Imp)) { 161 log("Automatically importing " + Name + " from " + 162 cast<DefinedImportData>(Imp)->getDLLName()); 163 ImpSize = sizeof(DefinedImportData); 164 } else if (isa<DefinedRegular>(Imp)) { 165 log("Automatically importing " + Name + " from " + 166 toString(cast<DefinedRegular>(Imp)->File)); 167 ImpSize = sizeof(DefinedRegular); 168 } else { 169 warn("unable to automatically import " + Name + " from " + Imp->getName() + 170 " from " + toString(cast<DefinedRegular>(Imp)->File) + 171 "; unexpected symbol type"); 172 return false; 173 } 174 Sym->replaceKeepingName(Imp, ImpSize); 175 Sym->IsRuntimePseudoReloc = true; 176 177 // There may exist symbols named .refptr.<name> which only consist 178 // of a single pointer to <name>. If it turns out <name> is 179 // automatically imported, we don't need to keep the .refptr.<name> 180 // pointer at all, but redirect all accesses to it to the IAT entry 181 // for __imp_<name> instead, and drop the whole .refptr.<name> chunk. 182 DefinedRegular *Refptr = 183 dyn_cast_or_null<DefinedRegular>(find((".refptr." + Name).str())); 184 if (Refptr && Refptr->getChunk()->getSize() == Config->Wordsize) { 185 SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Refptr->getChunk()); 186 if (SC && SC->getRelocs().size() == 1 && *SC->symbols().begin() == Sym) { 187 log("Replacing .refptr." + Name + " with " + Imp->getName()); 188 Refptr->getChunk()->Live = false; 189 Refptr->replaceKeepingName(Imp, ImpSize); 190 } 191 } 192 return true; 193 } 194 195 void SymbolTable::reportRemainingUndefines() { 196 SmallPtrSet<Symbol *, 8> Undefs; 197 DenseMap<Symbol *, Symbol *> LocalImports; 198 199 for (auto &I : SymMap) { 200 Symbol *Sym = I.second; 201 auto *Undef = dyn_cast<Undefined>(Sym); 202 if (!Undef) 203 continue; 204 if (!Sym->IsUsedInRegularObj) 205 continue; 206 207 StringRef Name = Undef->getName(); 208 209 // A weak alias may have been resolved, so check for that. 210 if (Defined *D = Undef->getWeakAlias()) { 211 // We want to replace Sym with D. However, we can't just blindly 212 // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an 213 // internal symbol, and internal symbols are stored as "unparented" 214 // Symbols. For that reason we need to check which type of symbol we 215 // are dealing with and copy the correct number of bytes. 216 if (isa<DefinedRegular>(D)) 217 memcpy(Sym, D, sizeof(DefinedRegular)); 218 else if (isa<DefinedAbsolute>(D)) 219 memcpy(Sym, D, sizeof(DefinedAbsolute)); 220 else 221 memcpy(Sym, D, sizeof(SymbolUnion)); 222 continue; 223 } 224 225 // If we can resolve a symbol by removing __imp_ prefix, do that. 226 // This odd rule is for compatibility with MSVC linker. 227 if (Name.startswith("__imp_")) { 228 Symbol *Imp = find(Name.substr(strlen("__imp_"))); 229 if (Imp && isa<Defined>(Imp)) { 230 auto *D = cast<Defined>(Imp); 231 replaceSymbol<DefinedLocalImport>(Sym, Name, D); 232 LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk()); 233 LocalImports[Sym] = D; 234 continue; 235 } 236 } 237 238 // We don't want to report missing Microsoft precompiled headers symbols. 239 // A proper message will be emitted instead in PDBLinker::aquirePrecompObj 240 if (Name.contains("_PchSym_")) 241 continue; 242 243 if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name)) 244 continue; 245 246 // Remaining undefined symbols are not fatal if /force is specified. 247 // They are replaced with dummy defined symbols. 248 if (Config->ForceUnresolved) 249 replaceSymbol<DefinedAbsolute>(Sym, Name, 0); 250 Undefs.insert(Sym); 251 } 252 253 if (Undefs.empty() && LocalImports.empty()) 254 return; 255 256 for (Symbol *B : Config->GCRoot) { 257 if (Undefs.count(B)) 258 errorOrWarn("<root>: undefined symbol: " + toString(*B)); 259 if (Config->WarnLocallyDefinedImported) 260 if (Symbol *Imp = LocalImports.lookup(B)) 261 warn("<root>: locally defined symbol imported: " + toString(*Imp) + 262 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); 263 } 264 265 for (ObjFile *File : ObjFile::Instances) { 266 size_t SymIndex = (size_t)-1; 267 for (Symbol *Sym : File->getSymbols()) { 268 ++SymIndex; 269 if (!Sym) 270 continue; 271 if (Undefs.count(Sym)) 272 errorOrWarn("undefined symbol: " + toString(*Sym) + 273 getSymbolLocations(File, SymIndex)); 274 if (Config->WarnLocallyDefinedImported) 275 if (Symbol *Imp = LocalImports.lookup(Sym)) 276 warn(toString(File) + 277 ": locally defined symbol imported: " + toString(*Imp) + 278 " (defined in " + toString(Imp->getFile()) + ") [LNK4217]"); 279 } 280 } 281 } 282 283 std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { 284 bool Inserted = false; 285 Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; 286 if (!Sym) { 287 Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 288 Sym->IsUsedInRegularObj = false; 289 Sym->PendingArchiveLoad = false; 290 Inserted = true; 291 } 292 return {Sym, Inserted}; 293 } 294 295 std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) { 296 std::pair<Symbol *, bool> Result = insert(Name); 297 if (!File || !isa<BitcodeFile>(File)) 298 Result.first->IsUsedInRegularObj = true; 299 return Result; 300 } 301 302 Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F, 303 bool IsWeakAlias) { 304 Symbol *S; 305 bool WasInserted; 306 std::tie(S, WasInserted) = insert(Name, F); 307 if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) { 308 replaceSymbol<Undefined>(S, Name); 309 return S; 310 } 311 if (auto *L = dyn_cast<Lazy>(S)) { 312 if (!S->PendingArchiveLoad) { 313 S->PendingArchiveLoad = true; 314 L->File->addMember(&L->Sym); 315 } 316 } 317 return S; 318 } 319 320 void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) { 321 StringRef Name = Sym.getName(); 322 Symbol *S; 323 bool WasInserted; 324 std::tie(S, WasInserted) = insert(Name); 325 if (WasInserted) { 326 replaceSymbol<Lazy>(S, F, Sym); 327 return; 328 } 329 auto *U = dyn_cast<Undefined>(S); 330 if (!U || U->WeakAlias || S->PendingArchiveLoad) 331 return; 332 S->PendingArchiveLoad = true; 333 F->addMember(&Sym); 334 } 335 336 void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { 337 std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " + 338 toString(Existing->getFile()) + " and in " + 339 toString(NewFile); 340 341 if (Config->ForceMultiple) 342 warn(Msg); 343 else 344 error(Msg); 345 } 346 347 Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) { 348 Symbol *S; 349 bool WasInserted; 350 std::tie(S, WasInserted) = insert(N, nullptr); 351 S->IsUsedInRegularObj = true; 352 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) 353 replaceSymbol<DefinedAbsolute>(S, N, Sym); 354 else if (!isa<DefinedCOFF>(S)) 355 reportDuplicate(S, nullptr); 356 return S; 357 } 358 359 Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) { 360 Symbol *S; 361 bool WasInserted; 362 std::tie(S, WasInserted) = insert(N, nullptr); 363 S->IsUsedInRegularObj = true; 364 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) 365 replaceSymbol<DefinedAbsolute>(S, N, VA); 366 else if (!isa<DefinedCOFF>(S)) 367 reportDuplicate(S, nullptr); 368 return S; 369 } 370 371 Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) { 372 Symbol *S; 373 bool WasInserted; 374 std::tie(S, WasInserted) = insert(N, nullptr); 375 S->IsUsedInRegularObj = true; 376 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) 377 replaceSymbol<DefinedSynthetic>(S, N, C); 378 else if (!isa<DefinedCOFF>(S)) 379 reportDuplicate(S, nullptr); 380 return S; 381 } 382 383 Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, 384 const coff_symbol_generic *Sym, 385 SectionChunk *C) { 386 Symbol *S; 387 bool WasInserted; 388 std::tie(S, WasInserted) = insert(N, F); 389 if (WasInserted || !isa<DefinedRegular>(S)) 390 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false, 391 /*IsExternal*/ true, Sym, C); 392 else 393 reportDuplicate(S, F); 394 return S; 395 } 396 397 std::pair<DefinedRegular *, bool> 398 SymbolTable::addComdat(InputFile *F, StringRef N, 399 const coff_symbol_generic *Sym) { 400 Symbol *S; 401 bool WasInserted; 402 std::tie(S, WasInserted) = insert(N, F); 403 if (WasInserted || !isa<DefinedRegular>(S)) { 404 replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true, 405 /*IsExternal*/ true, Sym, nullptr); 406 return {cast<DefinedRegular>(S), true}; 407 } 408 auto *ExistingSymbol = cast<DefinedRegular>(S); 409 if (!ExistingSymbol->isCOMDAT()) 410 reportDuplicate(S, F); 411 return {ExistingSymbol, false}; 412 } 413 414 Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size, 415 const coff_symbol_generic *Sym, CommonChunk *C) { 416 Symbol *S; 417 bool WasInserted; 418 std::tie(S, WasInserted) = insert(N, F); 419 if (WasInserted || !isa<DefinedCOFF>(S)) 420 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C); 421 else if (auto *DC = dyn_cast<DefinedCommon>(S)) 422 if (Size > DC->getSize()) 423 replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C); 424 return S; 425 } 426 427 Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) { 428 Symbol *S; 429 bool WasInserted; 430 std::tie(S, WasInserted) = insert(N, nullptr); 431 S->IsUsedInRegularObj = true; 432 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { 433 replaceSymbol<DefinedImportData>(S, N, F); 434 return S; 435 } 436 437 reportDuplicate(S, F); 438 return nullptr; 439 } 440 441 Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID, 442 uint16_t Machine) { 443 Symbol *S; 444 bool WasInserted; 445 std::tie(S, WasInserted) = insert(Name, nullptr); 446 S->IsUsedInRegularObj = true; 447 if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) { 448 replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine); 449 return S; 450 } 451 452 reportDuplicate(S, ID->File); 453 return nullptr; 454 } 455 456 std::vector<Chunk *> SymbolTable::getChunks() { 457 std::vector<Chunk *> Res; 458 for (ObjFile *File : ObjFile::Instances) { 459 ArrayRef<Chunk *> V = File->getChunks(); 460 Res.insert(Res.end(), V.begin(), V.end()); 461 } 462 return Res; 463 } 464 465 Symbol *SymbolTable::find(StringRef Name) { 466 return SymMap.lookup(CachedHashStringRef(Name)); 467 } 468 469 Symbol *SymbolTable::findUnderscore(StringRef Name) { 470 if (Config->Machine == I386) 471 return find(("_" + Name).str()); 472 return find(Name); 473 } 474 475 StringRef SymbolTable::findByPrefix(StringRef Prefix) { 476 for (auto Pair : SymMap) { 477 StringRef Name = Pair.first.val(); 478 if (Name.startswith(Prefix)) 479 return Name; 480 } 481 return ""; 482 } 483 484 StringRef SymbolTable::findMangle(StringRef Name) { 485 if (Symbol *Sym = find(Name)) 486 if (!isa<Undefined>(Sym)) 487 return Name; 488 if (Config->Machine != I386) 489 return findByPrefix(("?" + Name + "@@Y").str()); 490 if (!Name.startswith("_")) 491 return ""; 492 // Search for x86 stdcall function. 493 StringRef S = findByPrefix((Name + "@").str()); 494 if (!S.empty()) 495 return S; 496 // Search for x86 fastcall function. 497 S = findByPrefix(("@" + Name.substr(1) + "@").str()); 498 if (!S.empty()) 499 return S; 500 // Search for x86 vectorcall function. 501 S = findByPrefix((Name.substr(1) + "@@").str()); 502 if (!S.empty()) 503 return S; 504 // Search for x86 C++ non-member function. 505 return findByPrefix(("?" + Name.substr(1) + "@@Y").str()); 506 } 507 508 void SymbolTable::mangleMaybe(Symbol *B) { 509 auto *U = dyn_cast<Undefined>(B); 510 if (!U || U->WeakAlias) 511 return; 512 StringRef Alias = findMangle(U->getName()); 513 if (!Alias.empty()) { 514 log(U->getName() + " aliased to " + Alias); 515 U->WeakAlias = addUndefined(Alias); 516 } 517 } 518 519 Symbol *SymbolTable::addUndefined(StringRef Name) { 520 return addUndefined(Name, nullptr, false); 521 } 522 523 std::vector<StringRef> SymbolTable::compileBitcodeFiles() { 524 LTO.reset(new BitcodeCompiler); 525 for (BitcodeFile *F : BitcodeFile::Instances) 526 LTO->add(*F); 527 return LTO->compile(); 528 } 529 530 void SymbolTable::addCombinedLTOObjects() { 531 if (BitcodeFile::Instances.empty()) 532 return; 533 534 ScopedTimer T(LTOTimer); 535 for (StringRef Object : compileBitcodeFiles()) { 536 auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp")); 537 Obj->parse(); 538 ObjFile::Instances.push_back(Obj); 539 } 540 } 541 542 } // namespace coff 543 } // namespace lld 544