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 "COFFLinkerContext.h" 11 #include "Config.h" 12 #include "Driver.h" 13 #include "LTO.h" 14 #include "PDB.h" 15 #include "Symbols.h" 16 #include "lld/Common/ErrorHandler.h" 17 #include "lld/Common/Memory.h" 18 #include "lld/Common/Timer.h" 19 #include "llvm/DebugInfo/DIContext.h" 20 #include "llvm/IR/LLVMContext.h" 21 #include "llvm/IR/Mangler.h" 22 #include "llvm/LTO/LTO.h" 23 #include "llvm/Object/COFFModuleDefinition.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/GlobPattern.h" 26 #include "llvm/Support/Parallel.h" 27 #include "llvm/Support/TimeProfiler.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <utility> 30 31 using namespace llvm; 32 using namespace llvm::COFF; 33 using namespace llvm::object; 34 using namespace llvm::support; 35 36 namespace lld::coff { 37 38 StringRef ltrim1(StringRef s, const char *chars) { 39 if (!s.empty() && strchr(chars, s[0])) 40 return s.substr(1); 41 return s; 42 } 43 44 static COFFSyncStream errorOrWarn(COFFLinkerContext &ctx) { 45 return {ctx, ctx.config.forceUnresolved ? DiagLevel::Warn : DiagLevel::Err}; 46 } 47 48 // Causes the file associated with a lazy symbol to be linked in. 49 static void forceLazy(Symbol *s) { 50 s->pendingArchiveLoad = true; 51 switch (s->kind()) { 52 case Symbol::Kind::LazyArchiveKind: { 53 auto *l = cast<LazyArchive>(s); 54 l->file->addMember(l->sym); 55 break; 56 } 57 case Symbol::Kind::LazyObjectKind: { 58 InputFile *file = cast<LazyObject>(s)->file; 59 // FIXME: Remove this once we resolve all defineds before all undefineds in 60 // ObjFile::initializeSymbols(). 61 if (!file->lazy) 62 return; 63 file->lazy = false; 64 file->symtab.ctx.driver.addFile(file); 65 break; 66 } 67 case Symbol::Kind::LazyDLLSymbolKind: { 68 auto *l = cast<LazyDLLSymbol>(s); 69 l->file->makeImport(l->sym); 70 break; 71 } 72 default: 73 llvm_unreachable( 74 "symbol passed to forceLazy is not a LazyArchive or LazyObject"); 75 } 76 } 77 78 // Returns the symbol in SC whose value is <= Addr that is closest to Addr. 79 // This is generally the global variable or function whose definition contains 80 // Addr. 81 static Symbol *getSymbol(SectionChunk *sc, uint32_t addr) { 82 DefinedRegular *candidate = nullptr; 83 84 for (Symbol *s : sc->file->getSymbols()) { 85 auto *d = dyn_cast_or_null<DefinedRegular>(s); 86 if (!d || !d->data || d->file != sc->file || d->getChunk() != sc || 87 d->getValue() > addr || 88 (candidate && d->getValue() < candidate->getValue())) 89 continue; 90 91 candidate = d; 92 } 93 94 return candidate; 95 } 96 97 static std::vector<std::string> getSymbolLocations(BitcodeFile *file) { 98 std::string res("\n>>> referenced by "); 99 StringRef source = file->obj->getSourceFileName(); 100 if (!source.empty()) 101 res += source.str() + "\n>>> "; 102 res += toString(file); 103 return {res}; 104 } 105 106 static std::optional<std::pair<StringRef, uint32_t>> 107 getFileLineDwarf(const SectionChunk *c, uint32_t addr) { 108 std::optional<DILineInfo> optionalLineInfo = 109 c->file->getDILineInfo(addr, c->getSectionNumber() - 1); 110 if (!optionalLineInfo) 111 return std::nullopt; 112 const DILineInfo &lineInfo = *optionalLineInfo; 113 if (lineInfo.FileName == DILineInfo::BadString) 114 return std::nullopt; 115 return std::make_pair(saver().save(lineInfo.FileName), lineInfo.Line); 116 } 117 118 static std::optional<std::pair<StringRef, uint32_t>> 119 getFileLine(const SectionChunk *c, uint32_t addr) { 120 // MinGW can optionally use codeview, even if the default is dwarf. 121 std::optional<std::pair<StringRef, uint32_t>> fileLine = 122 getFileLineCodeView(c, addr); 123 // If codeview didn't yield any result, check dwarf in MinGW mode. 124 if (!fileLine && c->file->symtab.ctx.config.mingw) 125 fileLine = getFileLineDwarf(c, addr); 126 return fileLine; 127 } 128 129 // Given a file and the index of a symbol in that file, returns a description 130 // of all references to that symbol from that file. If no debug information is 131 // available, returns just the name of the file, else one string per actual 132 // reference as described in the debug info. 133 // Returns up to maxStrings string descriptions, along with the total number of 134 // locations found. 135 static std::pair<std::vector<std::string>, size_t> 136 getSymbolLocations(ObjFile *file, uint32_t symIndex, size_t maxStrings) { 137 struct Location { 138 Symbol *sym; 139 std::pair<StringRef, uint32_t> fileLine; 140 }; 141 std::vector<Location> locations; 142 size_t numLocations = 0; 143 144 for (Chunk *c : file->getChunks()) { 145 auto *sc = dyn_cast<SectionChunk>(c); 146 if (!sc) 147 continue; 148 for (const coff_relocation &r : sc->getRelocs()) { 149 if (r.SymbolTableIndex != symIndex) 150 continue; 151 numLocations++; 152 if (locations.size() >= maxStrings) 153 continue; 154 155 std::optional<std::pair<StringRef, uint32_t>> fileLine = 156 getFileLine(sc, r.VirtualAddress); 157 Symbol *sym = getSymbol(sc, r.VirtualAddress); 158 if (fileLine) 159 locations.push_back({sym, *fileLine}); 160 else if (sym) 161 locations.push_back({sym, {"", 0}}); 162 } 163 } 164 165 if (maxStrings == 0) 166 return std::make_pair(std::vector<std::string>(), numLocations); 167 168 if (numLocations == 0) 169 return std::make_pair( 170 std::vector<std::string>{"\n>>> referenced by " + toString(file)}, 1); 171 172 std::vector<std::string> symbolLocations(locations.size()); 173 size_t i = 0; 174 for (Location loc : locations) { 175 llvm::raw_string_ostream os(symbolLocations[i++]); 176 os << "\n>>> referenced by "; 177 if (!loc.fileLine.first.empty()) 178 os << loc.fileLine.first << ":" << loc.fileLine.second 179 << "\n>>> "; 180 os << toString(file); 181 if (loc.sym) 182 os << ":(" << toString(file->symtab.ctx, *loc.sym) << ')'; 183 } 184 return std::make_pair(symbolLocations, numLocations); 185 } 186 187 std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) { 188 return getSymbolLocations(file, symIndex, SIZE_MAX).first; 189 } 190 191 static std::pair<std::vector<std::string>, size_t> 192 getSymbolLocations(InputFile *file, uint32_t symIndex, size_t maxStrings) { 193 if (auto *o = dyn_cast<ObjFile>(file)) 194 return getSymbolLocations(o, symIndex, maxStrings); 195 if (auto *b = dyn_cast<BitcodeFile>(file)) { 196 std::vector<std::string> symbolLocations = getSymbolLocations(b); 197 size_t numLocations = symbolLocations.size(); 198 if (symbolLocations.size() > maxStrings) 199 symbolLocations.resize(maxStrings); 200 return std::make_pair(symbolLocations, numLocations); 201 } 202 llvm_unreachable("unsupported file type passed to getSymbolLocations"); 203 return std::make_pair(std::vector<std::string>(), (size_t)0); 204 } 205 206 // For an undefined symbol, stores all files referencing it and the index of 207 // the undefined symbol in each file. 208 struct UndefinedDiag { 209 Symbol *sym; 210 struct File { 211 InputFile *file; 212 uint32_t symIndex; 213 }; 214 std::vector<File> files; 215 }; 216 217 static void reportUndefinedSymbol(COFFLinkerContext &ctx, 218 const UndefinedDiag &undefDiag) { 219 auto diag = errorOrWarn(ctx); 220 diag << "undefined symbol: " << undefDiag.sym; 221 222 const size_t maxUndefReferences = 3; 223 size_t numDisplayedRefs = 0, numRefs = 0; 224 for (const UndefinedDiag::File &ref : undefDiag.files) { 225 auto [symbolLocations, totalLocations] = getSymbolLocations( 226 ref.file, ref.symIndex, maxUndefReferences - numDisplayedRefs); 227 228 numRefs += totalLocations; 229 numDisplayedRefs += symbolLocations.size(); 230 for (const std::string &s : symbolLocations) 231 diag << s; 232 } 233 if (numDisplayedRefs < numRefs) 234 diag << "\n>>> referenced " << numRefs - numDisplayedRefs << " more times"; 235 } 236 237 void SymbolTable::loadMinGWSymbols() { 238 for (auto &i : symMap) { 239 Symbol *sym = i.second; 240 auto *undef = dyn_cast<Undefined>(sym); 241 if (!undef) 242 continue; 243 if (undef->getWeakAlias()) 244 continue; 245 246 StringRef name = undef->getName(); 247 248 if (machine == I386 && ctx.config.stdcallFixup) { 249 // Check if we can resolve an undefined decorated symbol by finding 250 // the intended target as an undecorated symbol (only with a leading 251 // underscore). 252 StringRef origName = name; 253 StringRef baseName = name; 254 // Trim down stdcall/fastcall/vectorcall symbols to the base name. 255 baseName = ltrim1(baseName, "_@"); 256 baseName = baseName.substr(0, baseName.find('@')); 257 // Add a leading underscore, as it would be in cdecl form. 258 std::string newName = ("_" + baseName).str(); 259 Symbol *l; 260 if (newName != origName && (l = find(newName)) != nullptr) { 261 // If we found a symbol and it is lazy; load it. 262 if (l->isLazy() && !l->pendingArchiveLoad) { 263 Log(ctx) << "Loading lazy " << l->getName() << " from " 264 << l->getFile()->getName() << " for stdcall fixup"; 265 forceLazy(l); 266 } 267 // If it's lazy or already defined, hook it up as weak alias. 268 if (l->isLazy() || isa<Defined>(l)) { 269 if (ctx.config.warnStdcallFixup) 270 Warn(ctx) << "Resolving " << origName << " by linking to " 271 << newName; 272 else 273 Log(ctx) << "Resolving " << origName << " by linking to " 274 << newName; 275 undef->setWeakAlias(l); 276 continue; 277 } 278 } 279 } 280 281 if (ctx.config.autoImport) { 282 if (name.starts_with("__imp_")) 283 continue; 284 // If we have an undefined symbol, but we have a lazy symbol we could 285 // load, load it. 286 Symbol *l = find(("__imp_" + name).str()); 287 if (!l || l->pendingArchiveLoad || !l->isLazy()) 288 continue; 289 290 Log(ctx) << "Loading lazy " << l->getName() << " from " 291 << l->getFile()->getName() << " for automatic import"; 292 forceLazy(l); 293 } 294 } 295 } 296 297 Defined *SymbolTable::impSymbol(StringRef name) { 298 if (name.starts_with("__imp_")) 299 return nullptr; 300 return dyn_cast_or_null<Defined>(find(("__imp_" + name).str())); 301 } 302 303 bool SymbolTable::handleMinGWAutomaticImport(Symbol *sym, StringRef name) { 304 Defined *imp = impSymbol(name); 305 if (!imp) 306 return false; 307 308 // Replace the reference directly to a variable with a reference 309 // to the import address table instead. This obviously isn't right, 310 // but we mark the symbol as isRuntimePseudoReloc, and a later pass 311 // will add runtime pseudo relocations for every relocation against 312 // this Symbol. The runtime pseudo relocation framework expects the 313 // reference itself to point at the IAT entry. 314 size_t impSize = 0; 315 if (isa<DefinedImportData>(imp)) { 316 Log(ctx) << "Automatically importing " << name << " from " 317 << cast<DefinedImportData>(imp)->getDLLName(); 318 impSize = sizeof(DefinedImportData); 319 } else if (isa<DefinedRegular>(imp)) { 320 Log(ctx) << "Automatically importing " << name << " from " 321 << toString(cast<DefinedRegular>(imp)->file); 322 impSize = sizeof(DefinedRegular); 323 } else { 324 Warn(ctx) << "unable to automatically import " << name << " from " 325 << imp->getName() << " from " << cast<DefinedRegular>(imp)->file 326 << "; unexpected symbol type"; 327 return false; 328 } 329 sym->replaceKeepingName(imp, impSize); 330 sym->isRuntimePseudoReloc = true; 331 332 // There may exist symbols named .refptr.<name> which only consist 333 // of a single pointer to <name>. If it turns out <name> is 334 // automatically imported, we don't need to keep the .refptr.<name> 335 // pointer at all, but redirect all accesses to it to the IAT entry 336 // for __imp_<name> instead, and drop the whole .refptr.<name> chunk. 337 DefinedRegular *refptr = 338 dyn_cast_or_null<DefinedRegular>(find((".refptr." + name).str())); 339 if (refptr && refptr->getChunk()->getSize() == ctx.config.wordsize) { 340 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(refptr->getChunk()); 341 if (sc && sc->getRelocs().size() == 1 && *sc->symbols().begin() == sym) { 342 Log(ctx) << "Replacing .refptr." << name << " with " << imp->getName(); 343 refptr->getChunk()->live = false; 344 refptr->replaceKeepingName(imp, impSize); 345 } 346 } 347 return true; 348 } 349 350 /// Helper function for reportUnresolvable and resolveRemainingUndefines. 351 /// This function emits an "undefined symbol" diagnostic for each symbol in 352 /// undefs. If localImports is not nullptr, it also emits a "locally 353 /// defined symbol imported" diagnostic for symbols in localImports. 354 /// objFiles and bitcodeFiles (if not nullptr) are used to report where 355 /// undefined symbols are referenced. 356 void SymbolTable::reportProblemSymbols( 357 const SmallPtrSetImpl<Symbol *> &undefs, 358 const DenseMap<Symbol *, Symbol *> *localImports, bool needBitcodeFiles) { 359 // Return early if there is nothing to report (which should be 360 // the common case). 361 if (undefs.empty() && (!localImports || localImports->empty())) 362 return; 363 364 for (Symbol *b : ctx.config.gcroot) { 365 if (undefs.count(b)) 366 errorOrWarn(ctx) << "<root>: undefined symbol: " << b; 367 if (localImports) 368 if (Symbol *imp = localImports->lookup(b)) 369 Warn(ctx) << "<root>: locally defined symbol imported: " << imp 370 << " (defined in " << toString(imp->getFile()) 371 << ") [LNK4217]"; 372 } 373 374 std::vector<UndefinedDiag> undefDiags; 375 DenseMap<Symbol *, int> firstDiag; 376 377 auto processFile = [&](InputFile *file, ArrayRef<Symbol *> symbols) { 378 uint32_t symIndex = (uint32_t)-1; 379 for (Symbol *sym : symbols) { 380 ++symIndex; 381 if (!sym) 382 continue; 383 if (undefs.count(sym)) { 384 auto [it, inserted] = firstDiag.try_emplace(sym, undefDiags.size()); 385 if (inserted) 386 undefDiags.push_back({sym, {{file, symIndex}}}); 387 else 388 undefDiags[it->second].files.push_back({file, symIndex}); 389 } 390 if (localImports) 391 if (Symbol *imp = localImports->lookup(sym)) 392 Warn(ctx) << file << ": locally defined symbol imported: " << imp 393 << " (defined in " << imp->getFile() << ") [LNK4217]"; 394 } 395 }; 396 397 for (ObjFile *file : ctx.objFileInstances) 398 processFile(file, file->getSymbols()); 399 400 if (needBitcodeFiles) 401 for (BitcodeFile *file : bitcodeFileInstances) 402 processFile(file, file->getSymbols()); 403 404 for (const UndefinedDiag &undefDiag : undefDiags) 405 reportUndefinedSymbol(ctx, undefDiag); 406 } 407 408 void SymbolTable::reportUnresolvable() { 409 SmallPtrSet<Symbol *, 8> undefs; 410 for (auto &i : symMap) { 411 Symbol *sym = i.second; 412 auto *undef = dyn_cast<Undefined>(sym); 413 if (!undef || sym->deferUndefined) 414 continue; 415 if (undef->getWeakAlias()) 416 continue; 417 StringRef name = undef->getName(); 418 if (name.starts_with("__imp_")) { 419 Symbol *imp = find(name.substr(strlen("__imp_"))); 420 if (Defined *def = dyn_cast_or_null<Defined>(imp)) { 421 def->isUsedInRegularObj = true; 422 continue; 423 } 424 } 425 if (name.contains("_PchSym_")) 426 continue; 427 if (ctx.config.autoImport && impSymbol(name)) 428 continue; 429 undefs.insert(sym); 430 } 431 432 reportProblemSymbols(undefs, /*localImports=*/nullptr, true); 433 } 434 435 bool SymbolTable::resolveRemainingUndefines() { 436 llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols"); 437 SmallPtrSet<Symbol *, 8> undefs; 438 DenseMap<Symbol *, Symbol *> localImports; 439 bool foundLazy = false; 440 441 for (auto &i : symMap) { 442 Symbol *sym = i.second; 443 auto *undef = dyn_cast<Undefined>(sym); 444 if (!undef) 445 continue; 446 if (!sym->isUsedInRegularObj) 447 continue; 448 449 StringRef name = undef->getName(); 450 451 // A weak alias may have been resolved, so check for that. 452 if (undef->resolveWeakAlias()) 453 continue; 454 455 // If we can resolve a symbol by removing __imp_ prefix, do that. 456 // This odd rule is for compatibility with MSVC linker. 457 if (name.starts_with("__imp_")) { 458 auto findLocalSym = [&](StringRef n) { 459 Symbol *sym = find(n); 460 if (auto undef = dyn_cast_or_null<Undefined>(sym)) { 461 // The unprefixed symbol might come later in symMap, so handle it now 462 // if needed. 463 if (!undef->resolveWeakAlias()) 464 sym = nullptr; 465 } 466 return sym; 467 }; 468 469 StringRef impName = name.substr(strlen("__imp_")); 470 Symbol *imp = findLocalSym(impName); 471 if (!imp && isEC()) { 472 // Try to use the mangled symbol on ARM64EC. 473 std::optional<std::string> mangledName = 474 getArm64ECMangledFunctionName(impName); 475 if (mangledName) 476 imp = findLocalSym(*mangledName); 477 if (!imp && impName.consume_front("aux_")) { 478 // If it's a __imp_aux_ symbol, try skipping the aux_ prefix. 479 imp = findLocalSym(impName); 480 if (!imp && (mangledName = getArm64ECMangledFunctionName(impName))) 481 imp = findLocalSym(*mangledName); 482 } 483 } 484 if (imp && imp->isLazy()) { 485 forceLazy(imp); 486 foundLazy = true; 487 continue; 488 } 489 if (imp && isa<Defined>(imp)) { 490 auto *d = cast<Defined>(imp); 491 replaceSymbol<DefinedLocalImport>(sym, ctx, name, d); 492 localImportChunks.push_back(cast<DefinedLocalImport>(sym)->getChunk()); 493 localImports[sym] = d; 494 continue; 495 } 496 } 497 498 // We don't want to report missing Microsoft precompiled headers symbols. 499 // A proper message will be emitted instead in PDBLinker::aquirePrecompObj 500 if (name.contains("_PchSym_")) 501 continue; 502 503 if (ctx.config.autoImport && handleMinGWAutomaticImport(sym, name)) 504 continue; 505 506 // Remaining undefined symbols are not fatal if /force is specified. 507 // They are replaced with dummy defined symbols. 508 if (ctx.config.forceUnresolved) 509 replaceSymbol<DefinedAbsolute>(sym, ctx, name, 0); 510 undefs.insert(sym); 511 } 512 513 reportProblemSymbols( 514 undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, 515 false); 516 return foundLazy; 517 } 518 519 std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) { 520 bool inserted = false; 521 Symbol *&sym = symMap[CachedHashStringRef(name)]; 522 if (!sym) { 523 sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 524 sym->isUsedInRegularObj = false; 525 sym->pendingArchiveLoad = false; 526 sym->canInline = true; 527 inserted = true; 528 529 if (isEC() && name.starts_with("EXP+")) 530 expSymbols.push_back(sym); 531 } 532 return {sym, inserted}; 533 } 534 535 std::pair<Symbol *, bool> SymbolTable::insert(StringRef name, InputFile *file) { 536 std::pair<Symbol *, bool> result = insert(name); 537 if (!file || !isa<BitcodeFile>(file)) 538 result.first->isUsedInRegularObj = true; 539 return result; 540 } 541 542 void SymbolTable::initializeLoadConfig() { 543 auto sym = 544 dyn_cast_or_null<DefinedRegular>(findUnderscore("_load_config_used")); 545 if (!sym) { 546 if (isEC()) { 547 Warn(ctx) << "EC version of '_load_config_used' is missing"; 548 return; 549 } 550 if (ctx.hybridSymtab) { 551 Warn(ctx) << "native version of '_load_config_used' is missing for " 552 "ARM64X target"; 553 return; 554 } 555 if (ctx.config.guardCF != GuardCFLevel::Off) 556 Warn(ctx) 557 << "Control Flow Guard is enabled but '_load_config_used' is missing"; 558 if (ctx.config.dependentLoadFlags) 559 Warn(ctx) << "_load_config_used not found, /dependentloadflag will have " 560 "no effect"; 561 return; 562 } 563 564 SectionChunk *sc = sym->getChunk(); 565 if (!sc->hasData) { 566 Err(ctx) << "_load_config_used points to uninitialized data"; 567 return; 568 } 569 uint64_t offsetInChunk = sym->getValue(); 570 if (offsetInChunk + 4 > sc->getSize()) { 571 Err(ctx) << "_load_config_used section chunk is too small"; 572 return; 573 } 574 575 ArrayRef<uint8_t> secContents = sc->getContents(); 576 loadConfigSize = 577 *reinterpret_cast<const ulittle32_t *>(&secContents[offsetInChunk]); 578 if (offsetInChunk + loadConfigSize > sc->getSize()) { 579 Err(ctx) << "_load_config_used specifies a size larger than its containing " 580 "section chunk"; 581 return; 582 } 583 584 uint32_t expectedAlign = ctx.config.is64() ? 8 : 4; 585 if (sc->getAlignment() < expectedAlign) 586 Warn(ctx) << "'_load_config_used' is misaligned (expected alignment to be " 587 << expectedAlign << " bytes, got " << sc->getAlignment() 588 << " instead)"; 589 else if (!isAligned(Align(expectedAlign), offsetInChunk)) 590 Warn(ctx) << "'_load_config_used' is misaligned (section offset is 0x" 591 << Twine::utohexstr(sym->getValue()) << " not aligned to " 592 << expectedAlign << " bytes)"; 593 594 loadConfigSym = sym; 595 } 596 597 void SymbolTable::addEntryThunk(Symbol *from, Symbol *to) { 598 entryThunks.push_back({from, to}); 599 } 600 601 void SymbolTable::addExitThunk(Symbol *from, Symbol *to) { 602 exitThunks[from] = to; 603 } 604 605 void SymbolTable::initializeECThunks() { 606 if (!isArm64EC(ctx.config.machine)) 607 return; 608 609 for (auto it : entryThunks) { 610 auto *to = dyn_cast<Defined>(it.second); 611 if (!to) 612 continue; 613 auto *from = dyn_cast<DefinedRegular>(it.first); 614 // We need to be able to add padding to the function and fill it with an 615 // offset to its entry thunks. To ensure that padding the function is 616 // feasible, functions are required to be COMDAT symbols with no offset. 617 if (!from || !from->getChunk()->isCOMDAT() || 618 cast<DefinedRegular>(from)->getValue()) { 619 Err(ctx) << "non COMDAT symbol '" << from->getName() << "' in hybrid map"; 620 continue; 621 } 622 from->getChunk()->setEntryThunk(to); 623 } 624 625 for (ImportFile *file : ctx.importFileInstances) { 626 if (!file->impchkThunk) 627 continue; 628 629 Symbol *sym = exitThunks.lookup(file->thunkSym); 630 if (!sym) 631 sym = exitThunks.lookup(file->impECSym); 632 file->impchkThunk->exitThunk = dyn_cast_or_null<Defined>(sym); 633 } 634 635 // On ARM64EC, the __imp_ symbol references the auxiliary IAT, while the 636 // __imp_aux_ symbol references the regular IAT. However, x86_64 code expects 637 // both to reference the regular IAT, so adjust the symbol if necessary. 638 parallelForEach(ctx.objFileInstances, [&](ObjFile *file) { 639 if (file->getMachineType() != AMD64) 640 return; 641 for (auto &sym : file->getMutableSymbols()) { 642 auto impSym = dyn_cast_or_null<DefinedImportData>(sym); 643 if (impSym && impSym->file->impchkThunk && sym == impSym->file->impECSym) 644 sym = impSym->file->impSym; 645 } 646 }); 647 } 648 649 Symbol *SymbolTable::addUndefined(StringRef name, InputFile *f, 650 bool overrideLazy) { 651 auto [s, wasInserted] = insert(name, f); 652 if (wasInserted || (s->isLazy() && overrideLazy)) { 653 replaceSymbol<Undefined>(s, name); 654 return s; 655 } 656 if (s->isLazy()) 657 forceLazy(s); 658 return s; 659 } 660 661 Symbol *SymbolTable::addGCRoot(StringRef name, bool aliasEC) { 662 Symbol *b = addUndefined(name); 663 if (!b->isGCRoot) { 664 b->isGCRoot = true; 665 ctx.config.gcroot.push_back(b); 666 } 667 668 // On ARM64EC, a symbol may be defined in either its mangled or demangled form 669 // (or both). Define an anti-dependency symbol that binds both forms, similar 670 // to how compiler-generated code references external functions. 671 if (aliasEC && isEC()) { 672 if (std::optional<std::string> mangledName = 673 getArm64ECMangledFunctionName(name)) { 674 auto u = dyn_cast<Undefined>(b); 675 if (u && !u->weakAlias) { 676 Symbol *t = addUndefined(saver().save(*mangledName)); 677 u->setWeakAlias(t, true); 678 } 679 } else if (std::optional<std::string> demangledName = 680 getArm64ECDemangledFunctionName(name)) { 681 Symbol *us = addUndefined(saver().save(*demangledName)); 682 auto u = dyn_cast<Undefined>(us); 683 if (u && !u->weakAlias) 684 u->setWeakAlias(b, true); 685 } 686 } 687 return b; 688 } 689 690 // On ARM64EC, a function symbol may appear in both mangled and demangled forms: 691 // - ARM64EC archives contain only the mangled name, while the demangled symbol 692 // is defined by the object file as an alias. 693 // - x86_64 archives contain only the demangled name (the mangled name is 694 // usually defined by an object referencing the symbol as an alias to a guess 695 // exit thunk). 696 // - ARM64EC import files contain both the mangled and demangled names for 697 // thunks. 698 // If more than one archive defines the same function, this could lead 699 // to different libraries being used for the same function depending on how they 700 // are referenced. Avoid this by checking if the paired symbol is already 701 // defined before adding a symbol to the table. 702 template <typename T> 703 bool checkLazyECPair(SymbolTable *symtab, StringRef name, InputFile *f) { 704 if (name.starts_with("__imp_")) 705 return true; 706 std::string pairName; 707 if (std::optional<std::string> mangledName = 708 getArm64ECMangledFunctionName(name)) 709 pairName = std::move(*mangledName); 710 else if (std::optional<std::string> demangledName = 711 getArm64ECDemangledFunctionName(name)) 712 pairName = std::move(*demangledName); 713 else 714 return true; 715 716 Symbol *sym = symtab->find(pairName); 717 if (!sym) 718 return true; 719 if (sym->pendingArchiveLoad) 720 return false; 721 if (auto u = dyn_cast<Undefined>(sym)) 722 return !u->weakAlias || u->isAntiDep; 723 // If the symbol is lazy, allow it only if it originates from the same 724 // archive. 725 auto lazy = dyn_cast<T>(sym); 726 return lazy && lazy->file == f; 727 } 728 729 void SymbolTable::addLazyArchive(ArchiveFile *f, const Archive::Symbol &sym) { 730 StringRef name = sym.getName(); 731 if (isEC() && !checkLazyECPair<LazyArchive>(this, name, f)) 732 return; 733 auto [s, wasInserted] = insert(name); 734 if (wasInserted) { 735 replaceSymbol<LazyArchive>(s, f, sym); 736 return; 737 } 738 auto *u = dyn_cast<Undefined>(s); 739 if (!u || (u->weakAlias && !u->isECAlias(machine)) || s->pendingArchiveLoad) 740 return; 741 s->pendingArchiveLoad = true; 742 f->addMember(sym); 743 } 744 745 void SymbolTable::addLazyObject(InputFile *f, StringRef n) { 746 assert(f->lazy); 747 if (isEC() && !checkLazyECPair<LazyObject>(this, n, f)) 748 return; 749 auto [s, wasInserted] = insert(n, f); 750 if (wasInserted) { 751 replaceSymbol<LazyObject>(s, f, n); 752 return; 753 } 754 auto *u = dyn_cast<Undefined>(s); 755 if (!u || (u->weakAlias && !u->isECAlias(machine)) || s->pendingArchiveLoad) 756 return; 757 s->pendingArchiveLoad = true; 758 f->lazy = false; 759 ctx.driver.addFile(f); 760 } 761 762 void SymbolTable::addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym, 763 StringRef n) { 764 auto [s, wasInserted] = insert(n); 765 if (wasInserted) { 766 replaceSymbol<LazyDLLSymbol>(s, f, sym, n); 767 return; 768 } 769 auto *u = dyn_cast<Undefined>(s); 770 if (!u || u->weakAlias || s->pendingArchiveLoad) 771 return; 772 s->pendingArchiveLoad = true; 773 f->makeImport(sym); 774 } 775 776 static std::string getSourceLocationBitcode(BitcodeFile *file) { 777 std::string res("\n>>> defined at "); 778 StringRef source = file->obj->getSourceFileName(); 779 if (!source.empty()) 780 res += source.str() + "\n>>> "; 781 res += toString(file); 782 return res; 783 } 784 785 static std::string getSourceLocationObj(ObjFile *file, SectionChunk *sc, 786 uint32_t offset, StringRef name) { 787 std::optional<std::pair<StringRef, uint32_t>> fileLine; 788 if (sc) 789 fileLine = getFileLine(sc, offset); 790 if (!fileLine) 791 fileLine = file->getVariableLocation(name); 792 793 std::string res; 794 llvm::raw_string_ostream os(res); 795 os << "\n>>> defined at "; 796 if (fileLine) 797 os << fileLine->first << ":" << fileLine->second << "\n>>> "; 798 os << toString(file); 799 return res; 800 } 801 802 static std::string getSourceLocation(InputFile *file, SectionChunk *sc, 803 uint32_t offset, StringRef name) { 804 if (!file) 805 return ""; 806 if (auto *o = dyn_cast<ObjFile>(file)) 807 return getSourceLocationObj(o, sc, offset, name); 808 if (auto *b = dyn_cast<BitcodeFile>(file)) 809 return getSourceLocationBitcode(b); 810 return "\n>>> defined at " + toString(file); 811 } 812 813 // Construct and print an error message in the form of: 814 // 815 // lld-link: error: duplicate symbol: foo 816 // >>> defined at bar.c:30 817 // >>> bar.o 818 // >>> defined at baz.c:563 819 // >>> baz.o 820 void SymbolTable::reportDuplicate(Symbol *existing, InputFile *newFile, 821 SectionChunk *newSc, 822 uint32_t newSectionOffset) { 823 COFFSyncStream diag(ctx, ctx.config.forceMultiple ? DiagLevel::Warn 824 : DiagLevel::Err); 825 diag << "duplicate symbol: " << existing; 826 827 DefinedRegular *d = dyn_cast<DefinedRegular>(existing); 828 if (d && isa<ObjFile>(d->getFile())) { 829 diag << getSourceLocation(d->getFile(), d->getChunk(), d->getValue(), 830 existing->getName()); 831 } else { 832 diag << getSourceLocation(existing->getFile(), nullptr, 0, ""); 833 } 834 diag << getSourceLocation(newFile, newSc, newSectionOffset, 835 existing->getName()); 836 } 837 838 Symbol *SymbolTable::addAbsolute(StringRef n, COFFSymbolRef sym) { 839 auto [s, wasInserted] = insert(n, nullptr); 840 s->isUsedInRegularObj = true; 841 if (wasInserted || isa<Undefined>(s) || s->isLazy()) 842 replaceSymbol<DefinedAbsolute>(s, ctx, n, sym); 843 else if (auto *da = dyn_cast<DefinedAbsolute>(s)) { 844 if (da->getVA() != sym.getValue()) 845 reportDuplicate(s, nullptr); 846 } else if (!isa<DefinedCOFF>(s)) 847 reportDuplicate(s, nullptr); 848 return s; 849 } 850 851 Symbol *SymbolTable::addAbsolute(StringRef n, uint64_t va) { 852 auto [s, wasInserted] = insert(n, nullptr); 853 s->isUsedInRegularObj = true; 854 if (wasInserted || isa<Undefined>(s) || s->isLazy()) 855 replaceSymbol<DefinedAbsolute>(s, ctx, n, va); 856 else if (auto *da = dyn_cast<DefinedAbsolute>(s)) { 857 if (da->getVA() != va) 858 reportDuplicate(s, nullptr); 859 } else if (!isa<DefinedCOFF>(s)) 860 reportDuplicate(s, nullptr); 861 return s; 862 } 863 864 Symbol *SymbolTable::addSynthetic(StringRef n, Chunk *c) { 865 auto [s, wasInserted] = insert(n, nullptr); 866 s->isUsedInRegularObj = true; 867 if (wasInserted || isa<Undefined>(s) || s->isLazy()) 868 replaceSymbol<DefinedSynthetic>(s, n, c); 869 else if (!isa<DefinedCOFF>(s)) 870 reportDuplicate(s, nullptr); 871 return s; 872 } 873 874 Symbol *SymbolTable::addRegular(InputFile *f, StringRef n, 875 const coff_symbol_generic *sym, SectionChunk *c, 876 uint32_t sectionOffset, bool isWeak) { 877 auto [s, wasInserted] = insert(n, f); 878 if (wasInserted || !isa<DefinedRegular>(s) || s->isWeak) 879 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ false, 880 /*IsExternal*/ true, sym, c, isWeak); 881 else if (!isWeak) 882 reportDuplicate(s, f, c, sectionOffset); 883 return s; 884 } 885 886 std::pair<DefinedRegular *, bool> 887 SymbolTable::addComdat(InputFile *f, StringRef n, 888 const coff_symbol_generic *sym) { 889 auto [s, wasInserted] = insert(n, f); 890 if (wasInserted || !isa<DefinedRegular>(s)) { 891 replaceSymbol<DefinedRegular>(s, f, n, /*IsCOMDAT*/ true, 892 /*IsExternal*/ true, sym, nullptr); 893 return {cast<DefinedRegular>(s), true}; 894 } 895 auto *existingSymbol = cast<DefinedRegular>(s); 896 if (!existingSymbol->isCOMDAT) 897 reportDuplicate(s, f); 898 return {existingSymbol, false}; 899 } 900 901 Symbol *SymbolTable::addCommon(InputFile *f, StringRef n, uint64_t size, 902 const coff_symbol_generic *sym, CommonChunk *c) { 903 auto [s, wasInserted] = insert(n, f); 904 if (wasInserted || !isa<DefinedCOFF>(s)) 905 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c); 906 else if (auto *dc = dyn_cast<DefinedCommon>(s)) 907 if (size > dc->getSize()) 908 replaceSymbol<DefinedCommon>(s, f, n, size, sym, c); 909 return s; 910 } 911 912 DefinedImportData *SymbolTable::addImportData(StringRef n, ImportFile *f, 913 Chunk *&location) { 914 auto [s, wasInserted] = insert(n, nullptr); 915 s->isUsedInRegularObj = true; 916 if (wasInserted || isa<Undefined>(s) || s->isLazy()) { 917 replaceSymbol<DefinedImportData>(s, n, f, location); 918 return cast<DefinedImportData>(s); 919 } 920 921 reportDuplicate(s, f); 922 return nullptr; 923 } 924 925 Defined *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id, 926 ImportThunkChunk *chunk) { 927 auto [s, wasInserted] = insert(name, nullptr); 928 s->isUsedInRegularObj = true; 929 if (wasInserted || isa<Undefined>(s) || s->isLazy()) { 930 replaceSymbol<DefinedImportThunk>(s, ctx, name, id, chunk); 931 return cast<Defined>(s); 932 } 933 934 reportDuplicate(s, id->file); 935 return nullptr; 936 } 937 938 void SymbolTable::addLibcall(StringRef name) { 939 Symbol *sym = findUnderscore(name); 940 if (!sym) 941 return; 942 943 if (auto *l = dyn_cast<LazyArchive>(sym)) { 944 MemoryBufferRef mb = l->getMemberBuffer(); 945 if (isBitcode(mb)) 946 addUndefined(sym->getName()); 947 } else if (LazyObject *o = dyn_cast<LazyObject>(sym)) { 948 if (isBitcode(o->file->mb)) 949 addUndefined(sym->getName()); 950 } 951 } 952 953 Symbol *SymbolTable::find(StringRef name) const { 954 return symMap.lookup(CachedHashStringRef(name)); 955 } 956 957 Symbol *SymbolTable::findUnderscore(StringRef name) const { 958 if (machine == I386) 959 return find(("_" + name).str()); 960 return find(name); 961 } 962 963 // Return all symbols that start with Prefix, possibly ignoring the first 964 // character of Prefix or the first character symbol. 965 std::vector<Symbol *> SymbolTable::getSymsWithPrefix(StringRef prefix) { 966 std::vector<Symbol *> syms; 967 for (auto pair : symMap) { 968 StringRef name = pair.first.val(); 969 if (name.starts_with(prefix) || name.starts_with(prefix.drop_front()) || 970 name.drop_front().starts_with(prefix) || 971 name.drop_front().starts_with(prefix.drop_front())) { 972 syms.push_back(pair.second); 973 } 974 } 975 return syms; 976 } 977 978 Symbol *SymbolTable::findMangle(StringRef name) { 979 if (Symbol *sym = find(name)) { 980 if (auto *u = dyn_cast<Undefined>(sym)) { 981 // We're specifically looking for weak aliases that ultimately resolve to 982 // defined symbols, hence the call to getWeakAlias() instead of just using 983 // the weakAlias member variable. This matches link.exe's behavior. 984 if (Symbol *weakAlias = u->getWeakAlias()) 985 return weakAlias; 986 } else { 987 return sym; 988 } 989 } 990 991 // Efficient fuzzy string lookup is impossible with a hash table, so iterate 992 // the symbol table once and collect all possibly matching symbols into this 993 // vector. Then compare each possibly matching symbol with each possible 994 // mangling. 995 std::vector<Symbol *> syms = getSymsWithPrefix(name); 996 auto findByPrefix = [&syms](const Twine &t) -> Symbol * { 997 std::string prefix = t.str(); 998 for (auto *s : syms) 999 if (s->getName().starts_with(prefix)) 1000 return s; 1001 return nullptr; 1002 }; 1003 1004 // For non-x86, just look for C++ functions. 1005 if (machine != I386) 1006 return findByPrefix("?" + name + "@@Y"); 1007 1008 if (!name.starts_with("_")) 1009 return nullptr; 1010 // Search for x86 stdcall function. 1011 if (Symbol *s = findByPrefix(name + "@")) 1012 return s; 1013 // Search for x86 fastcall function. 1014 if (Symbol *s = findByPrefix("@" + name.substr(1) + "@")) 1015 return s; 1016 // Search for x86 vectorcall function. 1017 if (Symbol *s = findByPrefix(name.substr(1) + "@@")) 1018 return s; 1019 // Search for x86 C++ non-member function. 1020 return findByPrefix("?" + name.substr(1) + "@@Y"); 1021 } 1022 1023 bool SymbolTable::findUnderscoreMangle(StringRef sym) { 1024 Symbol *s = findMangle(mangle(sym)); 1025 return s && !isa<Undefined>(s); 1026 } 1027 1028 // Symbol names are mangled by prepending "_" on x86. 1029 StringRef SymbolTable::mangle(StringRef sym) { 1030 assert(machine != IMAGE_FILE_MACHINE_UNKNOWN); 1031 if (machine == I386) 1032 return saver().save("_" + sym); 1033 return sym; 1034 } 1035 1036 StringRef SymbolTable::mangleMaybe(Symbol *s) { 1037 // If the plain symbol name has already been resolved, do nothing. 1038 Undefined *unmangled = dyn_cast<Undefined>(s); 1039 if (!unmangled) 1040 return ""; 1041 1042 // Otherwise, see if a similar, mangled symbol exists in the symbol table. 1043 Symbol *mangled = findMangle(unmangled->getName()); 1044 if (!mangled) 1045 return ""; 1046 1047 // If we find a similar mangled symbol, make this an alias to it and return 1048 // its name. 1049 Log(ctx) << unmangled->getName() << " aliased to " << mangled->getName(); 1050 unmangled->setWeakAlias(addUndefined(mangled->getName())); 1051 return mangled->getName(); 1052 } 1053 1054 // Windows specific -- find default entry point name. 1055 // 1056 // There are four different entry point functions for Windows executables, 1057 // each of which corresponds to a user-defined "main" function. This function 1058 // infers an entry point from a user-defined "main" function. 1059 StringRef SymbolTable::findDefaultEntry() { 1060 assert(ctx.config.subsystem != IMAGE_SUBSYSTEM_UNKNOWN && 1061 "must handle /subsystem before calling this"); 1062 1063 if (ctx.config.mingw) 1064 return mangle(ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI 1065 ? "WinMainCRTStartup" 1066 : "mainCRTStartup"); 1067 1068 if (ctx.config.subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) { 1069 if (findUnderscoreMangle("wWinMain")) { 1070 if (!findUnderscoreMangle("WinMain")) 1071 return mangle("wWinMainCRTStartup"); 1072 Warn(ctx) << "found both wWinMain and WinMain; using latter"; 1073 } 1074 return mangle("WinMainCRTStartup"); 1075 } 1076 if (findUnderscoreMangle("wmain")) { 1077 if (!findUnderscoreMangle("main")) 1078 return mangle("wmainCRTStartup"); 1079 Warn(ctx) << "found both wmain and main; using latter"; 1080 } 1081 return mangle("mainCRTStartup"); 1082 } 1083 1084 WindowsSubsystem SymbolTable::inferSubsystem() { 1085 if (ctx.config.dll) 1086 return IMAGE_SUBSYSTEM_WINDOWS_GUI; 1087 if (ctx.config.mingw) 1088 return IMAGE_SUBSYSTEM_WINDOWS_CUI; 1089 // Note that link.exe infers the subsystem from the presence of these 1090 // functions even if /entry: or /nodefaultlib are passed which causes them 1091 // to not be called. 1092 bool haveMain = findUnderscoreMangle("main"); 1093 bool haveWMain = findUnderscoreMangle("wmain"); 1094 bool haveWinMain = findUnderscoreMangle("WinMain"); 1095 bool haveWWinMain = findUnderscoreMangle("wWinMain"); 1096 if (haveMain || haveWMain) { 1097 if (haveWinMain || haveWWinMain) { 1098 Warn(ctx) << "found " << (haveMain ? "main" : "wmain") << " and " 1099 << (haveWinMain ? "WinMain" : "wWinMain") 1100 << "; defaulting to /subsystem:console"; 1101 } 1102 return IMAGE_SUBSYSTEM_WINDOWS_CUI; 1103 } 1104 if (haveWinMain || haveWWinMain) 1105 return IMAGE_SUBSYSTEM_WINDOWS_GUI; 1106 return IMAGE_SUBSYSTEM_UNKNOWN; 1107 } 1108 1109 void SymbolTable::addUndefinedGlob(StringRef arg) { 1110 Expected<GlobPattern> pat = GlobPattern::create(arg); 1111 if (!pat) { 1112 Err(ctx) << "/includeglob: " << toString(pat.takeError()); 1113 return; 1114 } 1115 1116 SmallVector<Symbol *, 0> syms; 1117 forEachSymbol([&syms, &pat](Symbol *sym) { 1118 if (pat->match(sym->getName())) { 1119 syms.push_back(sym); 1120 } 1121 }); 1122 1123 for (Symbol *sym : syms) 1124 addGCRoot(sym->getName()); 1125 } 1126 1127 // Convert stdcall/fastcall style symbols into unsuffixed symbols, 1128 // with or without a leading underscore. (MinGW specific.) 1129 static StringRef killAt(StringRef sym, bool prefix) { 1130 if (sym.empty()) 1131 return sym; 1132 // Strip any trailing stdcall suffix 1133 sym = sym.substr(0, sym.find('@', 1)); 1134 if (!sym.starts_with("@")) { 1135 if (prefix && !sym.starts_with("_")) 1136 return saver().save("_" + sym); 1137 return sym; 1138 } 1139 // For fastcall, remove the leading @ and replace it with an 1140 // underscore, if prefixes are used. 1141 sym = sym.substr(1); 1142 if (prefix) 1143 sym = saver().save("_" + sym); 1144 return sym; 1145 } 1146 1147 static StringRef exportSourceName(ExportSource s) { 1148 switch (s) { 1149 case ExportSource::Directives: 1150 return "source file (directives)"; 1151 case ExportSource::Export: 1152 return "/export"; 1153 case ExportSource::ModuleDefinition: 1154 return "/def"; 1155 default: 1156 llvm_unreachable("unknown ExportSource"); 1157 } 1158 } 1159 1160 // Performs error checking on all /export arguments. 1161 // It also sets ordinals. 1162 void SymbolTable::fixupExports() { 1163 llvm::TimeTraceScope timeScope("Fixup exports"); 1164 // Symbol ordinals must be unique. 1165 std::set<uint16_t> ords; 1166 for (Export &e : exports) { 1167 if (e.ordinal == 0) 1168 continue; 1169 if (!ords.insert(e.ordinal).second) 1170 Fatal(ctx) << "duplicate export ordinal: " << e.name; 1171 } 1172 1173 for (Export &e : exports) { 1174 if (!e.exportAs.empty()) { 1175 e.exportName = e.exportAs; 1176 continue; 1177 } 1178 1179 StringRef sym = 1180 !e.forwardTo.empty() || e.extName.empty() ? e.name : e.extName; 1181 if (machine == I386 && sym.starts_with("_")) { 1182 // In MSVC mode, a fully decorated stdcall function is exported 1183 // as-is with the leading underscore (with type IMPORT_NAME). 1184 // In MinGW mode, a decorated stdcall function gets the underscore 1185 // removed, just like normal cdecl functions. 1186 if (ctx.config.mingw || !sym.contains('@')) { 1187 e.exportName = sym.substr(1); 1188 continue; 1189 } 1190 } 1191 if (isEC() && !e.data && !e.constant) { 1192 if (std::optional<std::string> demangledName = 1193 getArm64ECDemangledFunctionName(sym)) { 1194 e.exportName = saver().save(*demangledName); 1195 continue; 1196 } 1197 } 1198 e.exportName = sym; 1199 } 1200 1201 if (ctx.config.killAt && machine == I386) { 1202 for (Export &e : exports) { 1203 e.name = killAt(e.name, true); 1204 e.exportName = killAt(e.exportName, false); 1205 e.extName = killAt(e.extName, true); 1206 e.symbolName = killAt(e.symbolName, true); 1207 } 1208 } 1209 1210 // Uniquefy by name. 1211 DenseMap<StringRef, std::pair<Export *, unsigned>> map(exports.size()); 1212 std::vector<Export> v; 1213 for (Export &e : exports) { 1214 auto pair = map.insert(std::make_pair(e.exportName, std::make_pair(&e, 0))); 1215 bool inserted = pair.second; 1216 if (inserted) { 1217 pair.first->second.second = v.size(); 1218 v.push_back(e); 1219 continue; 1220 } 1221 Export *existing = pair.first->second.first; 1222 if (e == *existing || e.name != existing->name) 1223 continue; 1224 // If the existing export comes from .OBJ directives, we are allowed to 1225 // overwrite it with /DEF: or /EXPORT without any warning, as MSVC link.exe 1226 // does. 1227 if (existing->source == ExportSource::Directives) { 1228 *existing = e; 1229 v[pair.first->second.second] = e; 1230 continue; 1231 } 1232 if (existing->source == e.source) { 1233 Warn(ctx) << "duplicate " << exportSourceName(existing->source) 1234 << " option: " << e.name; 1235 } else { 1236 Warn(ctx) << "duplicate export: " << e.name << " first seen in " 1237 << exportSourceName(existing->source) << ", now in " 1238 << exportSourceName(e.source); 1239 } 1240 } 1241 exports = std::move(v); 1242 1243 // Sort by name. 1244 llvm::sort(exports, [](const Export &a, const Export &b) { 1245 return a.exportName < b.exportName; 1246 }); 1247 } 1248 1249 void SymbolTable::assignExportOrdinals() { 1250 // Assign unique ordinals if default (= 0). 1251 uint32_t max = 0; 1252 for (Export &e : exports) 1253 max = std::max(max, (uint32_t)e.ordinal); 1254 for (Export &e : exports) 1255 if (e.ordinal == 0) 1256 e.ordinal = ++max; 1257 if (max > std::numeric_limits<uint16_t>::max()) 1258 Fatal(ctx) << "too many exported symbols (got " << max << ", max " 1259 << Twine(std::numeric_limits<uint16_t>::max()) << ")"; 1260 } 1261 1262 void SymbolTable::parseModuleDefs(StringRef path) { 1263 llvm::TimeTraceScope timeScope("Parse def file"); 1264 std::unique_ptr<MemoryBuffer> mb = 1265 CHECK(MemoryBuffer::getFile(path, /*IsText=*/false, 1266 /*RequiresNullTerminator=*/false, 1267 /*IsVolatile=*/true), 1268 "could not open " + path); 1269 COFFModuleDefinition m = check(parseCOFFModuleDefinition( 1270 mb->getMemBufferRef(), machine, ctx.config.mingw)); 1271 1272 // Include in /reproduce: output if applicable. 1273 ctx.driver.takeBuffer(std::move(mb)); 1274 1275 if (ctx.config.outputFile.empty()) 1276 ctx.config.outputFile = std::string(saver().save(m.OutputFile)); 1277 ctx.config.importName = std::string(saver().save(m.ImportName)); 1278 if (m.ImageBase) 1279 ctx.config.imageBase = m.ImageBase; 1280 if (m.StackReserve) 1281 ctx.config.stackReserve = m.StackReserve; 1282 if (m.StackCommit) 1283 ctx.config.stackCommit = m.StackCommit; 1284 if (m.HeapReserve) 1285 ctx.config.heapReserve = m.HeapReserve; 1286 if (m.HeapCommit) 1287 ctx.config.heapCommit = m.HeapCommit; 1288 if (m.MajorImageVersion) 1289 ctx.config.majorImageVersion = m.MajorImageVersion; 1290 if (m.MinorImageVersion) 1291 ctx.config.minorImageVersion = m.MinorImageVersion; 1292 if (m.MajorOSVersion) 1293 ctx.config.majorOSVersion = m.MajorOSVersion; 1294 if (m.MinorOSVersion) 1295 ctx.config.minorOSVersion = m.MinorOSVersion; 1296 1297 for (COFFShortExport e1 : m.Exports) { 1298 Export e2; 1299 // Renamed exports are parsed and set as "ExtName = Name". If Name has 1300 // the form "OtherDll.Func", it shouldn't be a normal exported 1301 // function but a forward to another DLL instead. This is supported 1302 // by both MS and GNU linkers. 1303 if (!e1.ExtName.empty() && e1.ExtName != e1.Name && 1304 StringRef(e1.Name).contains('.')) { 1305 e2.name = saver().save(e1.ExtName); 1306 e2.forwardTo = saver().save(e1.Name); 1307 } else { 1308 e2.name = saver().save(e1.Name); 1309 e2.extName = saver().save(e1.ExtName); 1310 } 1311 e2.exportAs = saver().save(e1.ExportAs); 1312 e2.importName = saver().save(e1.ImportName); 1313 e2.ordinal = e1.Ordinal; 1314 e2.noname = e1.Noname; 1315 e2.data = e1.Data; 1316 e2.isPrivate = e1.Private; 1317 e2.constant = e1.Constant; 1318 e2.source = ExportSource::ModuleDefinition; 1319 exports.push_back(e2); 1320 } 1321 } 1322 1323 Symbol *SymbolTable::addUndefined(StringRef name) { 1324 return addUndefined(name, nullptr, false); 1325 } 1326 1327 void SymbolTable::compileBitcodeFiles() { 1328 if (bitcodeFileInstances.empty()) 1329 return; 1330 1331 llvm::TimeTraceScope timeScope("Compile bitcode"); 1332 ScopedTimer t(ctx.ltoTimer); 1333 lto.reset(new BitcodeCompiler(ctx)); 1334 for (BitcodeFile *f : bitcodeFileInstances) 1335 lto->add(*f); 1336 for (InputFile *newObj : lto->compile()) { 1337 ObjFile *obj = cast<ObjFile>(newObj); 1338 obj->parse(); 1339 ctx.objFileInstances.push_back(obj); 1340 } 1341 } 1342 1343 } // namespace lld::coff 1344