1585 lines · cpp
1//===- InputFiles.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "InputFiles.h"10#include "COFFLinkerContext.h"11#include "Chunks.h"12#include "Config.h"13#include "DebugTypes.h"14#include "Driver.h"15#include "SymbolTable.h"16#include "Symbols.h"17#include "lld/Common/DWARF.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/ADT/Twine.h"20#include "llvm/BinaryFormat/COFF.h"21#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"22#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"23#include "llvm/DebugInfo/CodeView/SymbolRecord.h"24#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"25#include "llvm/DebugInfo/PDB/Native/NativeSession.h"26#include "llvm/DebugInfo/PDB/Native/PDBFile.h"27#include "llvm/IR/Mangler.h"28#include "llvm/LTO/LTO.h"29#include "llvm/Object/Binary.h"30#include "llvm/Object/COFF.h"31#include "llvm/Object/COFFImportFile.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/Endian.h"34#include "llvm/Support/Error.h"35#include "llvm/Support/FileSystem.h"36#include "llvm/Support/Path.h"37#include "llvm/TargetParser/Triple.h"38#include <cstring>39#include <optional>40#include <utility>41 42using namespace llvm;43using namespace llvm::COFF;44using namespace llvm::codeview;45using namespace llvm::object;46using namespace llvm::support::endian;47using namespace lld;48using namespace lld::coff;49 50using llvm::Triple;51using llvm::support::ulittle32_t;52 53// Returns the last element of a path, which is supposed to be a filename.54static StringRef getBasename(StringRef path) {55 return sys::path::filename(path, sys::path::Style::windows);56}57 58// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".59std::string lld::toString(const coff::InputFile *file) {60 if (!file)61 return "<internal>";62 if (file->parentName.empty())63 return std::string(file->getName());64 65 return (getBasename(file->parentName) + "(" + getBasename(file->getName()) +66 ")")67 .str();68}69 70const COFFSyncStream &coff::operator<<(const COFFSyncStream &s,71 const InputFile *f) {72 return s << toString(f);73}74 75/// Checks that Source is compatible with being a weak alias to Target.76/// If Source is Undefined and has no weak alias set, makes it a weak77/// alias to Target.78static void checkAndSetWeakAlias(SymbolTable &symtab, InputFile *f,79 Symbol *source, Symbol *target,80 bool isAntiDep) {81 if (auto *u = dyn_cast<Undefined>(source)) {82 if (u->weakAlias && u->weakAlias != target) {83 // Ignore duplicated anti-dependency symbols.84 if (isAntiDep)85 return;86 if (!u->isAntiDep) {87 // Weak aliases as produced by GCC are named in the form88 // .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name89 // of another symbol emitted near the weak symbol.90 // Just use the definition from the first object file that defined91 // this weak symbol.92 if (symtab.ctx.config.allowDuplicateWeak)93 return;94 symtab.reportDuplicate(source, f);95 }96 }97 u->setWeakAlias(target, isAntiDep);98 }99}100 101static bool ignoredSymbolName(StringRef name) {102 return name == "@feat.00" || name == "@comp.id";103}104 105static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) {106 if (sym.isBigObj()) {107 auto *copy = make<coff_symbol32>(108 *reinterpret_cast<const coff_symbol32 *>(sym.getRawPtr()));109 return reinterpret_cast<coff_symbol_generic *>(copy);110 } else {111 auto *copy = make<coff_symbol16>(112 *reinterpret_cast<const coff_symbol16 *>(sym.getRawPtr()));113 return reinterpret_cast<coff_symbol_generic *>(copy);114 }115}116 117// Skip importing DllMain thunks from import libraries.118static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,119 const Archive::Symbol &sym, bool &skipDllMain) {120 const Archive::Child &c =121 CHECK(sym.getMember(), file->getFileName() +122 ": could not get the member for symbol " +123 toCOFFString(ctx, sym));124 MemoryBufferRef mb =125 CHECK(c.getMemoryBufferRef(),126 file->getFileName() +127 ": could not get the buffer for a child buffer of the archive");128 if (identify_magic(mb.getBuffer()) == file_magic::coff_import_library) {129 if (ctx.config.warnImportedDllMain) {130 // We won't place DllMain symbols in the symbol table if they are131 // coming from a import library. This message can be ignored with the flag132 // '/ignore:importeddllmain'133 Warn(ctx)134 << file->getFileName()135 << ": skipping imported DllMain symbol [importeddllmain]\nNOTE: this "136 "might be a mistake when the DLL/library was produced.";137 }138 skipDllMain = true;139 return true;140 }141 return false;142}143 144ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)145 : InputFile(ctx.symtab, ArchiveKind, m) {}146 147void ArchiveFile::parse() {148 COFFLinkerContext &ctx = symtab.ctx;149 SymbolTable *archiveSymtab = &symtab;150 151 // Parse a MemoryBufferRef as an archive file.152 file = CHECK(Archive::create(mb), this);153 154 // Try to read symbols from ECSYMBOLS section on ARM64EC.155 if (ctx.symtab.isEC()) {156 iterator_range<Archive::symbol_iterator> symbols =157 CHECK(file->ec_symbols(), this);158 if (!symbols.empty()) {159 for (const Archive::Symbol &sym : symbols)160 ctx.symtab.addLazyArchive(this, sym);161 162 // Read both EC and native symbols on ARM64X.163 archiveSymtab = &*ctx.hybridSymtab;164 } else {165 // If the ECSYMBOLS section is missing in the archive, the archive could166 // be either a native-only ARM64 or x86_64 archive. Check the machine type167 // of the object containing a symbol to determine which symbol table to168 // use.169 Archive::symbol_iterator sym = file->symbol_begin();170 if (sym != file->symbol_end()) {171 MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;172 Archive::Child child =173 CHECK(sym->getMember(),174 file->getFileName() +175 ": could not get the buffer for a child of the archive");176 MemoryBufferRef mb = CHECK(177 child.getMemoryBufferRef(),178 file->getFileName() +179 ": could not get the buffer for a child buffer of the archive");180 switch (identify_magic(mb.getBuffer())) {181 case file_magic::coff_object: {182 std::unique_ptr<COFFObjectFile> obj =183 CHECK(COFFObjectFile::create(mb),184 check(child.getName()) + ":" + ": not a valid COFF file");185 machine = MachineTypes(obj->getMachine());186 break;187 }188 case file_magic::coff_import_library:189 machine = MachineTypes(COFFImportFile(mb).getMachine());190 break;191 case file_magic::bitcode: {192 std::unique_ptr<lto::InputFile> obj =193 check(lto::InputFile::create(mb));194 machine = BitcodeFile::getMachineType(obj.get());195 break;196 }197 default:198 break;199 }200 archiveSymtab = &ctx.getSymtab(machine);201 }202 }203 }204 205 bool skipDllMain = false;206 StringRef mangledDllMain, impMangledDllMain;207 208 // The calls below will fail if we haven't set the machine type yet. Instead209 // of failing, it is preferable to skip this "imported DllMain" check if we210 // don't know the machine type at this point.211 if (!file->isEmpty() && ctx.config.machine != IMAGE_FILE_MACHINE_UNKNOWN) {212 mangledDllMain = archiveSymtab->mangle("DllMain");213 impMangledDllMain = uniqueSaver().save("__imp_" + mangledDllMain);214 }215 216 // Read the symbol table to construct Lazy objects.217 for (const Archive::Symbol &sym : file->symbols()) {218 // If an import library provides the DllMain symbol, skip importing it, as219 // we should be using our own DllMain, not another DLL's DllMain.220 if (!mangledDllMain.empty() && (sym.getName() == mangledDllMain ||221 sym.getName() == impMangledDllMain)) {222 if (skipDllMain || fixupDllMain(ctx, file.get(), sym, skipDllMain))223 continue;224 }225 archiveSymtab->addLazyArchive(this, sym);226 }227}228 229// Returns a buffer pointing to a member file containing a given symbol.230void ArchiveFile::addMember(const Archive::Symbol &sym) {231 const Archive::Child &c =232 CHECK(sym.getMember(), "could not get the member for symbol " +233 toCOFFString(symtab.ctx, sym));234 235 // Return an empty buffer if we have already returned the same buffer.236 // FIXME: Remove this once we resolve all defineds before all undefineds in237 // ObjFile::initializeSymbols().238 if (!seen.insert(c.getChildOffset()).second)239 return;240 241 symtab.ctx.driver.enqueueArchiveMember(c, sym, getName());242}243 244std::vector<MemoryBufferRef>245lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {246 std::vector<MemoryBufferRef> v;247 Error err = Error::success();248 249 // Thin archives refer to .o files, so --reproduces needs the .o files too.250 bool addToTar = file->isThin() && ctx.driver.tar;251 252 for (const Archive::Child &c : file->children(err)) {253 MemoryBufferRef mbref =254 CHECK(c.getMemoryBufferRef(),255 file->getFileName() +256 ": could not get the buffer for a child of the archive");257 if (addToTar) {258 ctx.driver.tar->append(relativeToRoot(check(c.getFullName())),259 mbref.getBuffer());260 }261 v.push_back(mbref);262 }263 if (err)264 Fatal(ctx) << file->getFileName()265 << ": Archive::children failed: " << toString(std::move(err));266 return v;267}268 269ObjFile::ObjFile(SymbolTable &symtab, COFFObjectFile *coffObj, bool lazy)270 : InputFile(symtab, ObjectKind, coffObj->getMemoryBufferRef(), lazy),271 coffObj(coffObj) {}272 273ObjFile *ObjFile::create(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy) {274 // Parse a memory buffer as a COFF file.275 Expected<std::unique_ptr<Binary>> bin = createBinary(m);276 if (!bin)277 Fatal(ctx) << "Could not parse " << m.getBufferIdentifier();278 279 auto *obj = dyn_cast<COFFObjectFile>(bin->get());280 if (!obj)281 Fatal(ctx) << m.getBufferIdentifier() << " is not a COFF file";282 283 bin->release();284 return make<ObjFile>(ctx.getSymtab(MachineTypes(obj->getMachine())), obj,285 lazy);286}287 288void ObjFile::parseLazy() {289 // Native object file.290 uint32_t numSymbols = coffObj->getNumberOfSymbols();291 for (uint32_t i = 0; i < numSymbols; ++i) {292 COFFSymbolRef coffSym = check(coffObj->getSymbol(i));293 if (coffSym.isUndefined() || !coffSym.isExternal() ||294 coffSym.isWeakExternal())295 continue;296 StringRef name = check(coffObj->getSymbolName(coffSym));297 if (coffSym.isAbsolute() && ignoredSymbolName(name))298 continue;299 symtab.addLazyObject(this, name);300 if (!lazy)301 return;302 i += coffSym.getNumberOfAuxSymbols();303 }304}305 306struct ECMapEntry {307 ulittle32_t src;308 ulittle32_t dst;309 ulittle32_t type;310};311 312void ObjFile::initializeECThunks() {313 for (SectionChunk *chunk : hybmpChunks) {314 if (chunk->getContents().size() % sizeof(ECMapEntry)) {315 Err(symtab.ctx) << "Invalid .hybmp chunk size "316 << chunk->getContents().size();317 continue;318 }319 320 const uint8_t *end =321 chunk->getContents().data() + chunk->getContents().size();322 for (const uint8_t *iter = chunk->getContents().data(); iter != end;323 iter += sizeof(ECMapEntry)) {324 auto entry = reinterpret_cast<const ECMapEntry *>(iter);325 switch (entry->type) {326 case Arm64ECThunkType::Entry:327 symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst));328 break;329 case Arm64ECThunkType::Exit:330 symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst));331 break;332 case Arm64ECThunkType::GuestExit:333 break;334 default:335 Warn(symtab.ctx) << "Ignoring unknown EC thunk type " << entry->type;336 }337 }338 }339}340 341void ObjFile::parse() {342 // Read section and symbol tables.343 initializeChunks();344 initializeSymbols();345 initializeFlags();346 initializeDependencies();347 initializeECThunks();348}349 350const coff_section *ObjFile::getSection(uint32_t i) {351 auto sec = coffObj->getSection(i);352 if (!sec)353 Fatal(symtab.ctx) << "getSection failed: #" << i << ": " << sec.takeError();354 return *sec;355}356 357// We set SectionChunk pointers in the SparseChunks vector to this value358// temporarily to mark comdat sections as having an unknown resolution. As we359// walk the object file's symbol table, once we visit either a leader symbol or360// an associative section definition together with the parent comdat's leader,361// we set the pointer to either nullptr (to mark the section as discarded) or a362// valid SectionChunk for that section.363static SectionChunk *const pendingComdat = reinterpret_cast<SectionChunk *>(1);364 365void ObjFile::initializeChunks() {366 uint32_t numSections = coffObj->getNumberOfSections();367 sparseChunks.resize(numSections + 1);368 for (uint32_t i = 1; i < numSections + 1; ++i) {369 const coff_section *sec = getSection(i);370 if (sec->Characteristics & IMAGE_SCN_LNK_COMDAT)371 sparseChunks[i] = pendingComdat;372 else373 sparseChunks[i] = readSection(i, nullptr, "");374 }375}376 377SectionChunk *ObjFile::readSection(uint32_t sectionNumber,378 const coff_aux_section_definition *def,379 StringRef leaderName) {380 const coff_section *sec = getSection(sectionNumber);381 382 StringRef name;383 if (Expected<StringRef> e = coffObj->getSectionName(sec))384 name = *e;385 else386 Fatal(symtab.ctx) << "getSectionName failed: #" << sectionNumber << ": "387 << e.takeError();388 389 if (name == ".drectve") {390 ArrayRef<uint8_t> data;391 cantFail(coffObj->getSectionContents(sec, data));392 directives = StringRef((const char *)data.data(), data.size());393 return nullptr;394 }395 396 if (name == ".llvm_addrsig") {397 addrsigSec = sec;398 return nullptr;399 }400 401 if (name == ".llvm.call-graph-profile") {402 callgraphSec = sec;403 return nullptr;404 }405 406 // Those sections are generated by -fembed-bitcode and do not need to be kept407 // in executable files.408 if (name == ".llvmbc" || name == ".llvmcmd")409 return nullptr;410 411 // Object files may have DWARF debug info or MS CodeView debug info412 // (or both).413 //414 // DWARF sections don't need any special handling from the perspective415 // of the linker; they are just a data section containing relocations.416 // We can just link them to complete debug info.417 //418 // CodeView needs linker support. We need to interpret debug info,419 // and then write it to a separate .pdb file.420 421 // Ignore DWARF debug info unless requested to be included.422 if (!symtab.ctx.config.includeDwarfChunks && name.starts_with(".debug_"))423 return nullptr;424 425 if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)426 return nullptr;427 SectionChunk *c;428 if (isArm64EC(getMachineType()))429 c = make<SectionChunkEC>(this, sec);430 else431 c = make<SectionChunk>(this, sec);432 if (def)433 c->checksum = def->CheckSum;434 435 // CodeView sections are stored to a different vector because they are not436 // linked in the regular manner.437 if (c->isCodeView())438 debugChunks.push_back(c);439 else if (name == ".gfids$y")440 guardFidChunks.push_back(c);441 else if (name == ".giats$y")442 guardIATChunks.push_back(c);443 else if (name == ".gljmp$y")444 guardLJmpChunks.push_back(c);445 else if (name == ".gehcont$y")446 guardEHContChunks.push_back(c);447 else if (name == ".sxdata")448 sxDataChunks.push_back(c);449 else if (isArm64EC(getMachineType()) && name == ".hybmp$x")450 hybmpChunks.push_back(c);451 else if (symtab.ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&452 name == ".rdata" && leaderName.starts_with("??_C@"))453 // COFF sections that look like string literal sections (i.e. no454 // relocations, in .rdata, leader symbol name matches the MSVC name mangling455 // for string literals) are subject to string tail merging.456 MergeChunk::addSection(symtab.ctx, c);457 else if (name == ".rsrc" || name.starts_with(".rsrc$"))458 resourceChunks.push_back(c);459 else if (!(sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_INFO))460 chunks.push_back(c);461 462 return c;463}464 465void ObjFile::includeResourceChunks() {466 chunks.insert(chunks.end(), resourceChunks.begin(), resourceChunks.end());467}468 469void ObjFile::readAssociativeDefinition(470 COFFSymbolRef sym, const coff_aux_section_definition *def) {471 readAssociativeDefinition(sym, def, def->getNumber(sym.isBigObj()));472}473 474void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,475 const coff_aux_section_definition *def,476 uint32_t parentIndex) {477 SectionChunk *parent = sparseChunks[parentIndex];478 int32_t sectionNumber = sym.getSectionNumber();479 480 auto diag = [&]() {481 StringRef name = check(coffObj->getSymbolName(sym));482 483 StringRef parentName;484 const coff_section *parentSec = getSection(parentIndex);485 if (Expected<StringRef> e = coffObj->getSectionName(parentSec))486 parentName = *e;487 Err(symtab.ctx) << toString(this) << ": associative comdat " << name488 << " (sec " << sectionNumber489 << ") has invalid reference to section " << parentName490 << " (sec " << parentIndex << ")";491 };492 493 if (parent == pendingComdat) {494 // This can happen if an associative comdat refers to another associative495 // comdat that appears after it (invalid per COFF spec) or to a section496 // without any symbols.497 diag();498 return;499 }500 501 // Check whether the parent is prevailing. If it is, so are we, and we read502 // the section; otherwise mark it as discarded.503 if (parent) {504 SectionChunk *c = readSection(sectionNumber, def, "");505 sparseChunks[sectionNumber] = c;506 if (c) {507 c->selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;508 parent->addAssociative(c);509 }510 } else {511 sparseChunks[sectionNumber] = nullptr;512 }513}514 515void ObjFile::recordPrevailingSymbolForMingw(516 COFFSymbolRef sym, DenseMap<StringRef, uint32_t> &prevailingSectionMap) {517 // For comdat symbols in executable sections, where this is the copy518 // of the section chunk we actually include instead of discarding it,519 // add the symbol to a map to allow using it for implicitly520 // associating .[px]data$<func> sections to it.521 // Use the suffix from the .text$<func> instead of the leader symbol522 // name, for cases where the names differ (i386 mangling/decorations,523 // cases where the leader is a weak symbol named .weak.func.default*).524 int32_t sectionNumber = sym.getSectionNumber();525 SectionChunk *sc = sparseChunks[sectionNumber];526 if (sc && sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE) {527 StringRef name = sc->getSectionName().split('$').second;528 prevailingSectionMap[name] = sectionNumber;529 }530}531 532void ObjFile::maybeAssociateSEHForMingw(533 COFFSymbolRef sym, const coff_aux_section_definition *def,534 const DenseMap<StringRef, uint32_t> &prevailingSectionMap) {535 StringRef name = check(coffObj->getSymbolName(sym));536 if (name.consume_front(".pdata$") || name.consume_front(".xdata$") ||537 name.consume_front(".eh_frame$")) {538 // For MinGW, treat .[px]data$<func> and .eh_frame$<func> as implicitly539 // associative to the symbol <func>.540 auto parentSym = prevailingSectionMap.find(name);541 if (parentSym != prevailingSectionMap.end())542 readAssociativeDefinition(sym, def, parentSym->second);543 }544}545 546Symbol *ObjFile::createRegular(COFFSymbolRef sym) {547 SectionChunk *sc = sparseChunks[sym.getSectionNumber()];548 if (sym.isExternal()) {549 StringRef name = check(coffObj->getSymbolName(sym));550 if (sc)551 return symtab.addRegular(this, name, sym.getGeneric(), sc,552 sym.getValue());553 // For MinGW symbols named .weak.* that point to a discarded section,554 // don't create an Undefined symbol. If nothing ever refers to the symbol,555 // everything should be fine. If something actually refers to the symbol556 // (e.g. the undefined weak alias), linking will fail due to undefined557 // references at the end.558 if (symtab.ctx.config.mingw && name.starts_with(".weak."))559 return nullptr;560 return symtab.addUndefined(name, this, false);561 }562 if (sc) {563 const coff_symbol_generic *symGen = sym.getGeneric();564 if (sym.isSection()) {565 auto *customSymGen = cloneSymbol(sym);566 customSymGen->Value = 0;567 symGen = customSymGen;568 }569 return make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,570 /*IsExternal*/ false, symGen, sc);571 }572 return nullptr;573}574 575void ObjFile::initializeSymbols() {576 uint32_t numSymbols = coffObj->getNumberOfSymbols();577 symbols.resize(numSymbols);578 579 SmallVector<std::pair<Symbol *, const coff_aux_weak_external *>, 8>580 weakAliases;581 std::vector<uint32_t> pendingIndexes;582 pendingIndexes.reserve(numSymbols);583 584 DenseMap<StringRef, uint32_t> prevailingSectionMap;585 std::vector<const coff_aux_section_definition *> comdatDefs(586 coffObj->getNumberOfSections() + 1);587 COFFLinkerContext &ctx = symtab.ctx;588 589 for (uint32_t i = 0; i < numSymbols; ++i) {590 COFFSymbolRef coffSym = check(coffObj->getSymbol(i));591 bool prevailingComdat;592 if (coffSym.isUndefined()) {593 symbols[i] = createUndefined(coffSym, false);594 } else if (coffSym.isWeakExternal()) {595 auto aux = coffSym.getAux<coff_aux_weak_external>();596 bool overrideLazy = true;597 598 // On ARM64EC, external function calls emit a pair of weak-dependency599 // aliases: func to #func and #func to the func guess exit thunk600 // (instead of a single undefined func symbol, which would be emitted on601 // other targets). Allow such aliases to be overridden by lazy archive602 // symbols, just as we would for undefined symbols.603 if (isArm64EC(getMachineType()) &&604 aux->Characteristics == IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY) {605 COFFSymbolRef targetSym = check(coffObj->getSymbol(aux->TagIndex));606 if (!targetSym.isAnyUndefined()) {607 // If the target is defined, it may be either a guess exit thunk or608 // the actual implementation. If it's the latter, consider the alias609 // to be part of the implementation and override potential lazy610 // archive symbols.611 StringRef targetName = check(coffObj->getSymbolName(targetSym));612 StringRef name = check(coffObj->getSymbolName(coffSym));613 std::optional<std::string> mangledName =614 getArm64ECMangledFunctionName(name);615 overrideLazy = mangledName == targetName;616 } else {617 overrideLazy = false;618 }619 }620 symbols[i] = createUndefined(coffSym, overrideLazy);621 weakAliases.emplace_back(symbols[i], aux);622 } else if (std::optional<Symbol *> optSym =623 createDefined(coffSym, comdatDefs, prevailingComdat)) {624 symbols[i] = *optSym;625 if (ctx.config.mingw && prevailingComdat)626 recordPrevailingSymbolForMingw(coffSym, prevailingSectionMap);627 } else {628 // createDefined() returns std::nullopt if a symbol belongs to a section629 // that was pending at the point when the symbol was read. This can happen630 // in two cases:631 // 1) section definition symbol for a comdat leader;632 // 2) symbol belongs to a comdat section associated with another section.633 // In both of these cases, we can expect the section to be resolved by634 // the time we finish visiting the remaining symbols in the symbol635 // table. So we postpone the handling of this symbol until that time.636 pendingIndexes.push_back(i);637 }638 i += coffSym.getNumberOfAuxSymbols();639 }640 641 for (uint32_t i : pendingIndexes) {642 COFFSymbolRef sym = check(coffObj->getSymbol(i));643 if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {644 if (def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)645 readAssociativeDefinition(sym, def);646 else if (ctx.config.mingw)647 maybeAssociateSEHForMingw(sym, def, prevailingSectionMap);648 }649 if (sparseChunks[sym.getSectionNumber()] == pendingComdat) {650 StringRef name = check(coffObj->getSymbolName(sym));651 Log(ctx) << "comdat section " << name652 << " without leader and unassociated, discarding";653 continue;654 }655 symbols[i] = createRegular(sym);656 }657 658 for (auto &kv : weakAliases) {659 Symbol *sym = kv.first;660 const coff_aux_weak_external *aux = kv.second;661 checkAndSetWeakAlias(symtab, this, sym, symbols[aux->TagIndex],662 aux->Characteristics ==663 IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY);664 }665 666 // Free the memory used by sparseChunks now that symbol loading is finished.667 decltype(sparseChunks)().swap(sparseChunks);668}669 670Symbol *ObjFile::createUndefined(COFFSymbolRef sym, bool overrideLazy) {671 StringRef name = check(coffObj->getSymbolName(sym));672 Symbol *s = symtab.addUndefined(name, this, overrideLazy);673 674 // Add an anti-dependency alias for undefined AMD64 symbols on the ARM64EC675 // target.676 if (symtab.isEC() && getMachineType() == AMD64) {677 auto u = dyn_cast<Undefined>(s);678 if (u && !u->weakAlias) {679 if (std::optional<std::string> mangledName =680 getArm64ECMangledFunctionName(name)) {681 Symbol *m = symtab.addUndefined(saver().save(*mangledName), this,682 /*overrideLazy=*/false);683 u->setWeakAlias(m, /*antiDep=*/true);684 }685 }686 }687 return s;688}689 690static const coff_aux_section_definition *findSectionDef(COFFObjectFile *obj,691 int32_t section) {692 uint32_t numSymbols = obj->getNumberOfSymbols();693 for (uint32_t i = 0; i < numSymbols; ++i) {694 COFFSymbolRef sym = check(obj->getSymbol(i));695 if (sym.getSectionNumber() != section)696 continue;697 if (const coff_aux_section_definition *def = sym.getSectionDefinition())698 return def;699 }700 return nullptr;701}702 703void ObjFile::handleComdatSelection(704 COFFSymbolRef sym, COMDATType &selection, bool &prevailing,705 DefinedRegular *leader,706 const llvm::object::coff_aux_section_definition *def) {707 if (prevailing)708 return;709 // There's already an existing comdat for this symbol: `Leader`.710 // Use the comdats's selection field to determine if the new711 // symbol in `Sym` should be discarded, produce a duplicate symbol712 // error, etc.713 714 SectionChunk *leaderChunk = leader->getChunk();715 COMDATType leaderSelection = leaderChunk->selection;716 COFFLinkerContext &ctx = symtab.ctx;717 718 assert(leader->data && "Comdat leader without SectionChunk?");719 if (isa<BitcodeFile>(leader->file)) {720 // If the leader is only a LTO symbol, we don't know e.g. its final size721 // yet, so we can't do the full strict comdat selection checking yet.722 selection = leaderSelection = IMAGE_COMDAT_SELECT_ANY;723 }724 725 if ((selection == IMAGE_COMDAT_SELECT_ANY &&726 leaderSelection == IMAGE_COMDAT_SELECT_LARGEST) ||727 (selection == IMAGE_COMDAT_SELECT_LARGEST &&728 leaderSelection == IMAGE_COMDAT_SELECT_ANY)) {729 // cl.exe picks "any" for vftables when building with /GR- and730 // "largest" when building with /GR. To be able to link object files731 // compiled with each flag, "any" and "largest" are merged as "largest".732 leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST;733 }734 735 // GCCs __declspec(selectany) doesn't actually pick "any" but "same size as".736 // Clang on the other hand picks "any". To be able to link two object files737 // with a __declspec(selectany) declaration, one compiled with gcc and the738 // other with clang, we merge them as proper "same size as"739 if (ctx.config.mingw && ((selection == IMAGE_COMDAT_SELECT_ANY &&740 leaderSelection == IMAGE_COMDAT_SELECT_SAME_SIZE) ||741 (selection == IMAGE_COMDAT_SELECT_SAME_SIZE &&742 leaderSelection == IMAGE_COMDAT_SELECT_ANY))) {743 leaderSelection = selection = IMAGE_COMDAT_SELECT_SAME_SIZE;744 }745 746 // Other than that, comdat selections must match. This is a bit more747 // strict than link.exe which allows merging "any" and "largest" if "any"748 // is the first symbol the linker sees, and it allows merging "largest"749 // with everything (!) if "largest" is the first symbol the linker sees.750 // Making this symmetric independent of which selection is seen first751 // seems better though.752 // (This behavior matches ModuleLinker::getComdatResult().)753 if (selection != leaderSelection) {754 Log(ctx) << "conflicting comdat type for " << symtab.printSymbol(leader)755 << ": " << (int)leaderSelection << " in " << leader->getFile()756 << " and " << (int)selection << " in " << this;757 symtab.reportDuplicate(leader, this);758 return;759 }760 761 switch (selection) {762 case IMAGE_COMDAT_SELECT_NODUPLICATES:763 symtab.reportDuplicate(leader, this);764 break;765 766 case IMAGE_COMDAT_SELECT_ANY:767 // Nothing to do.768 break;769 770 case IMAGE_COMDAT_SELECT_SAME_SIZE:771 if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) {772 if (!ctx.config.mingw) {773 symtab.reportDuplicate(leader, this);774 } else {775 const coff_aux_section_definition *leaderDef = nullptr;776 if (leaderChunk->file)777 leaderDef = findSectionDef(leaderChunk->file->getCOFFObj(),778 leaderChunk->getSectionNumber());779 if (!leaderDef || leaderDef->Length != def->Length)780 symtab.reportDuplicate(leader, this);781 }782 }783 break;784 785 case IMAGE_COMDAT_SELECT_EXACT_MATCH: {786 SectionChunk newChunk(this, getSection(sym));787 // link.exe only compares section contents here and doesn't complain788 // if the two comdat sections have e.g. different alignment.789 // Match that.790 if (leaderChunk->getContents() != newChunk.getContents())791 symtab.reportDuplicate(leader, this, &newChunk, sym.getValue());792 break;793 }794 795 case IMAGE_COMDAT_SELECT_ASSOCIATIVE:796 // createDefined() is never called for IMAGE_COMDAT_SELECT_ASSOCIATIVE.797 // (This means lld-link doesn't produce duplicate symbol errors for798 // associative comdats while link.exe does, but associate comdats799 // are never extern in practice.)800 llvm_unreachable("createDefined not called for associative comdats");801 802 case IMAGE_COMDAT_SELECT_LARGEST:803 if (leaderChunk->getSize() < getSection(sym)->SizeOfRawData) {804 // Replace the existing comdat symbol with the new one.805 StringRef name = check(coffObj->getSymbolName(sym));806 // FIXME: This is incorrect: With /opt:noref, the previous sections807 // make it into the final executable as well. Correct handling would808 // be to undo reading of the whole old section that's being replaced,809 // or doing one pass that determines what the final largest comdat810 // is for all IMAGE_COMDAT_SELECT_LARGEST comdats and then reading811 // only the largest one.812 replaceSymbol<DefinedRegular>(leader, this, name, /*IsCOMDAT*/ true,813 /*IsExternal*/ true, sym.getGeneric(),814 nullptr);815 prevailing = true;816 }817 break;818 819 case IMAGE_COMDAT_SELECT_NEWEST:820 llvm_unreachable("should have been rejected earlier");821 }822}823 824std::optional<Symbol *> ObjFile::createDefined(825 COFFSymbolRef sym,826 std::vector<const coff_aux_section_definition *> &comdatDefs,827 bool &prevailing) {828 prevailing = false;829 auto getName = [&]() { return check(coffObj->getSymbolName(sym)); };830 831 if (sym.isCommon()) {832 auto *c = make<CommonChunk>(sym);833 chunks.push_back(c);834 return symtab.addCommon(this, getName(), sym.getValue(), sym.getGeneric(),835 c);836 }837 838 COFFLinkerContext &ctx = symtab.ctx;839 if (sym.isAbsolute()) {840 StringRef name = getName();841 842 if (name == "@feat.00")843 feat00Flags = sym.getValue();844 // Skip special symbols.845 if (ignoredSymbolName(name))846 return nullptr;847 848 if (sym.isExternal())849 return symtab.addAbsolute(name, sym);850 return make<DefinedAbsolute>(ctx, name, sym);851 }852 853 int32_t sectionNumber = sym.getSectionNumber();854 if (sectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)855 return nullptr;856 857 if (sym.isEmptySectionDeclaration()) {858 // As there is no coff_section in the object file for these, make a859 // new virtual one, with everything zeroed out (i.e. an empty section),860 // with only the name and characteristics set.861 StringRef name = getName();862 auto *hdr = make<coff_section>();863 memset(hdr, 0, sizeof(*hdr));864 strncpy(hdr->Name, name.data(),865 std::min(name.size(), (size_t)COFF::NameSize));866 // The Value field in a section symbol may contain the characteristics,867 // or it may be zero, where we make something up (that matches what is868 // used in .idata sections in the regular object files in import libraries).869 if (sym.getValue())870 hdr->Characteristics = sym.getValue() | IMAGE_SCN_ALIGN_4BYTES;871 else872 hdr->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |873 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |874 IMAGE_SCN_ALIGN_4BYTES;875 auto *sc = make<SectionChunk>(this, hdr);876 chunks.push_back(sc);877 878 auto *symGen = cloneSymbol(sym);879 // Ignore the Value offset of these symbols, as it may be a bitmask.880 symGen->Value = 0;881 return make<DefinedRegular>(this, /*name=*/"", /*isCOMDAT=*/false,882 /*isExternal=*/false, symGen, sc);883 }884 885 if (llvm::COFF::isReservedSectionNumber(sectionNumber))886 Fatal(ctx) << toString(this) << ": " << getName()887 << " should not refer to special section "888 << Twine(sectionNumber);889 890 if ((uint32_t)sectionNumber >= sparseChunks.size())891 Fatal(ctx) << toString(this) << ": " << getName()892 << " should not refer to non-existent section "893 << Twine(sectionNumber);894 895 // Comdat handling.896 // A comdat symbol consists of two symbol table entries.897 // The first symbol entry has the name of the section (e.g. .text), fixed898 // values for the other fields, and one auxiliary record.899 // The second symbol entry has the name of the comdat symbol, called the900 // "comdat leader".901 // When this function is called for the first symbol entry of a comdat,902 // it sets comdatDefs and returns std::nullopt, and when it's called for the903 // second symbol entry it reads comdatDefs and then sets it back to nullptr.904 905 // Handle comdat leader.906 if (const coff_aux_section_definition *def = comdatDefs[sectionNumber]) {907 comdatDefs[sectionNumber] = nullptr;908 DefinedRegular *leader;909 910 if (sym.isExternal()) {911 std::tie(leader, prevailing) =912 symtab.addComdat(this, getName(), sym.getGeneric());913 } else {914 leader = make<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,915 /*IsExternal*/ false, sym.getGeneric());916 prevailing = true;917 }918 919 if (def->Selection < (int)IMAGE_COMDAT_SELECT_NODUPLICATES ||920 // Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe921 // doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.922 def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {923 Fatal(ctx) << "unknown comdat type "924 << std::to_string((int)def->Selection) << " for " << getName()925 << " in " << toString(this);926 }927 COMDATType selection = (COMDATType)def->Selection;928 929 if (leader->isCOMDAT)930 handleComdatSelection(sym, selection, prevailing, leader, def);931 932 if (prevailing) {933 SectionChunk *c = readSection(sectionNumber, def, getName());934 sparseChunks[sectionNumber] = c;935 if (!c)936 return nullptr;937 c->sym = cast<DefinedRegular>(leader);938 c->selection = selection;939 cast<DefinedRegular>(leader)->data = &c->repl;940 } else {941 sparseChunks[sectionNumber] = nullptr;942 }943 return leader;944 }945 946 // Prepare to handle the comdat leader symbol by setting the section's947 // ComdatDefs pointer if we encounter a non-associative comdat.948 if (sparseChunks[sectionNumber] == pendingComdat) {949 if (const coff_aux_section_definition *def = sym.getSectionDefinition()) {950 if (def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)951 comdatDefs[sectionNumber] = def;952 }953 return std::nullopt;954 }955 956 return createRegular(sym);957}958 959MachineTypes ObjFile::getMachineType() const {960 return static_cast<MachineTypes>(coffObj->getMachine());961}962 963ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {964 if (SectionChunk *sec = SectionChunk::findByName(debugChunks, secName))965 return sec->consumeDebugMagic();966 return {};967}968 969// OBJ files systematically store critical information in a .debug$S stream,970// even if the TU was compiled with no debug info. At least two records are971// always there. S_OBJNAME stores a 32-bit signature, which is loaded into the972// PCHSignature member. S_COMPILE3 stores compile-time cmd-line flags. This is973// currently used to initialize the hotPatchable member.974void ObjFile::initializeFlags() {975 ArrayRef<uint8_t> data = getDebugSection(".debug$S");976 if (data.empty())977 return;978 979 DebugSubsectionArray subsections;980 981 BinaryStreamReader reader(data, llvm::endianness::little);982 ExitOnError exitOnErr;983 exitOnErr(reader.readArray(subsections, data.size()));984 985 for (const DebugSubsectionRecord &ss : subsections) {986 if (ss.kind() != DebugSubsectionKind::Symbols)987 continue;988 989 unsigned offset = 0;990 991 // Only parse the first two records. We are only looking for S_OBJNAME992 // and S_COMPILE3, and they usually appear at the beginning of the993 // stream.994 for (unsigned i = 0; i < 2; ++i) {995 Expected<CVSymbol> sym = readSymbolFromStream(ss.getRecordData(), offset);996 if (!sym) {997 consumeError(sym.takeError());998 return;999 }1000 if (sym->kind() == SymbolKind::S_COMPILE3) {1001 auto cs =1002 cantFail(SymbolDeserializer::deserializeAs<Compile3Sym>(sym.get()));1003 hotPatchable =1004 (cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;1005 }1006 if (sym->kind() == SymbolKind::S_OBJNAME) {1007 auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(1008 sym.get()));1009 if (objName.Signature)1010 pchSignature = objName.Signature;1011 }1012 offset += sym->length();1013 }1014 }1015}1016 1017// Depending on the compilation flags, OBJs can refer to external files,1018// necessary to merge this OBJ into the final PDB. We currently support two1019// types of external files: Precomp/PCH OBJs, when compiling with /Yc and /Yu.1020// And PDB type servers, when compiling with /Zi. This function extracts these1021// dependencies and makes them available as a TpiSource interface (see1022// DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular1023// output even with /Yc and /Yu and with /Zi.1024void ObjFile::initializeDependencies() {1025 COFFLinkerContext &ctx = symtab.ctx;1026 if (!ctx.config.debug)1027 return;1028 1029 bool isPCH = false;1030 1031 ArrayRef<uint8_t> data = getDebugSection(".debug$P");1032 if (!data.empty())1033 isPCH = true;1034 else1035 data = getDebugSection(".debug$T");1036 1037 // symbols but no types, make a plain, empty TpiSource anyway, because it1038 // simplifies adding the symbols later.1039 if (data.empty()) {1040 if (!debugChunks.empty())1041 debugTypesObj = makeTpiSource(ctx, this);1042 return;1043 }1044 1045 // Get the first type record. It will indicate if this object uses a type1046 // server (/Zi) or a PCH file (/Yu).1047 CVTypeArray types;1048 BinaryStreamReader reader(data, llvm::endianness::little);1049 cantFail(reader.readArray(types, reader.getLength()));1050 CVTypeArray::Iterator firstType = types.begin();1051 if (firstType == types.end())1052 return;1053 1054 // Remember the .debug$T or .debug$P section.1055 debugTypes = data;1056 1057 // This object file is a PCH file that others will depend on.1058 if (isPCH) {1059 debugTypesObj = makePrecompSource(ctx, this);1060 return;1061 }1062 1063 // This object file was compiled with /Zi. Enqueue the PDB dependency.1064 if (firstType->kind() == LF_TYPESERVER2) {1065 TypeServer2Record ts = cantFail(1066 TypeDeserializer::deserializeAs<TypeServer2Record>(firstType->data()));1067 debugTypesObj = makeUseTypeServerSource(ctx, this, ts);1068 enqueuePdbFile(ts.getName(), this);1069 return;1070 }1071 1072 // This object was compiled with /Yu. It uses types from another object file1073 // with a matching signature.1074 if (firstType->kind() == LF_PRECOMP) {1075 PrecompRecord precomp = cantFail(1076 TypeDeserializer::deserializeAs<PrecompRecord>(firstType->data()));1077 // We're better off trusting the LF_PRECOMP signature. In some cases the1078 // S_OBJNAME record doesn't contain a valid PCH signature.1079 if (precomp.Signature)1080 pchSignature = precomp.Signature;1081 debugTypesObj = makeUsePrecompSource(ctx, this, precomp);1082 // Drop the LF_PRECOMP record from the input stream.1083 debugTypes = debugTypes.drop_front(firstType->RecordData.size());1084 return;1085 }1086 1087 // This is a plain old object file.1088 debugTypesObj = makeTpiSource(ctx, this);1089}1090 1091// The casing of the PDB path stamped in the OBJ can differ from the actual path1092// on disk. With this, we ensure to always use lowercase as a key for the1093// pdbInputFileInstances map, at least on Windows.1094static std::string normalizePdbPath(StringRef path) {1095#if defined(_WIN32)1096 return path.lower();1097#else // LINUX1098 return std::string(path);1099#endif1100}1101 1102// If existing, return the actual PDB path on disk.1103static std::optional<std::string>1104findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) {1105 // Ensure the file exists before anything else. In some cases, if the path1106 // points to a removable device, Driver::enqueuePath() would fail with an1107 // error (EAGAIN, "resource unavailable try again") which we want to skip1108 // silently.1109 if (llvm::sys::fs::exists(pdbPath))1110 return normalizePdbPath(pdbPath);1111 1112 StringRef objPath = !dependentFile->parentName.empty()1113 ? dependentFile->parentName1114 : dependentFile->getName();1115 1116 // Currently, type server PDBs are only created by MSVC cl, which only runs1117 // on Windows, so we can assume type server paths are Windows style.1118 StringRef pdbName = sys::path::filename(pdbPath, sys::path::Style::windows);1119 1120 // Check if the PDB is in the same folder as the OBJ.1121 SmallString<128> path;1122 sys::path::append(path, sys::path::parent_path(objPath), pdbName);1123 if (llvm::sys::fs::exists(path))1124 return normalizePdbPath(path);1125 1126 // Check if the PDB is in the output folder.1127 path.clear();1128 sys::path::append(path, sys::path::parent_path(outputPath), pdbName);1129 if (llvm::sys::fs::exists(path))1130 return normalizePdbPath(path);1131 1132 return std::nullopt;1133}1134 1135PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m)1136 : InputFile(ctx.symtab, PDBKind, m) {}1137 1138PDBInputFile::~PDBInputFile() = default;1139 1140PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,1141 StringRef path,1142 ObjFile *fromFile) {1143 auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);1144 if (!p)1145 return nullptr;1146 auto it = ctx.pdbInputFileInstances.find(*p);1147 if (it != ctx.pdbInputFileInstances.end())1148 return it->second;1149 return nullptr;1150}1151 1152void PDBInputFile::parse() {1153 symtab.ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this;1154 1155 std::unique_ptr<pdb::IPDBSession> thisSession;1156 Error E = pdb::NativeSession::createFromPdb(1157 MemoryBuffer::getMemBuffer(mb, false), thisSession);1158 if (E) {1159 loadErrorStr.emplace(toString(std::move(E)));1160 return; // fail silently at this point - the error will be handled later,1161 // when merging the debug type stream1162 }1163 1164 session.reset(static_cast<pdb::NativeSession *>(thisSession.release()));1165 1166 pdb::PDBFile &pdbFile = session->getPDBFile();1167 auto expectedInfo = pdbFile.getPDBInfoStream();1168 // All PDB Files should have an Info stream.1169 if (!expectedInfo) {1170 loadErrorStr.emplace(toString(expectedInfo.takeError()));1171 return;1172 }1173 debugTypesObj = makeTypeServerSource(symtab.ctx, this);1174}1175 1176// Used only for DWARF debug info, which is not common (except in MinGW1177// environments). This returns an optional pair of file name and line1178// number for where the variable was defined.1179std::optional<std::pair<StringRef, uint32_t>>1180ObjFile::getVariableLocation(StringRef var) {1181 if (!dwarf) {1182 dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));1183 if (!dwarf)1184 return std::nullopt;1185 }1186 if (symtab.machine == I386)1187 var.consume_front("_");1188 std::optional<std::pair<std::string, unsigned>> ret =1189 dwarf->getVariableLoc(var);1190 if (!ret)1191 return std::nullopt;1192 return std::make_pair(saver().save(ret->first), ret->second);1193}1194 1195// Used only for DWARF debug info, which is not common (except in MinGW1196// environments).1197std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,1198 uint32_t sectionIndex) {1199 if (!dwarf) {1200 dwarf = make<DWARFCache>(DWARFContext::create(*getCOFFObj()));1201 if (!dwarf)1202 return std::nullopt;1203 }1204 1205 return dwarf->getDILineInfo(offset, sectionIndex);1206}1207 1208void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {1209 auto p = findPdbPath(path.str(), fromFile, symtab.ctx.config.outputFile);1210 if (!p)1211 return;1212 auto it = symtab.ctx.pdbInputFileInstances.emplace(*p, nullptr);1213 if (!it.second)1214 return; // already scheduled for load1215 symtab.ctx.driver.enqueuePDB(*p);1216}1217 1218ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)1219 : InputFile(ctx.getSymtab(getMachineType(m)), ImportKind, m),1220 live(!ctx.config.doGC) {}1221 1222MachineTypes ImportFile::getMachineType(MemoryBufferRef m) {1223 uint16_t machine =1224 reinterpret_cast<const coff_import_header *>(m.getBufferStart())->Machine;1225 return MachineTypes(machine);1226}1227 1228bool ImportFile::isSameImport(const ImportFile *other) const {1229 if (!externalName.empty())1230 return other->externalName == externalName;1231 return hdr->OrdinalHint == other->hdr->OrdinalHint;1232}1233 1234ImportThunkChunk *ImportFile::makeImportThunk() {1235 switch (hdr->Machine) {1236 case AMD64:1237 return make<ImportThunkChunkX64>(symtab.ctx, impSym);1238 case I386:1239 return make<ImportThunkChunkX86>(symtab.ctx, impSym);1240 case ARM64:1241 return make<ImportThunkChunkARM64>(symtab.ctx, impSym, ARM64);1242 case ARMNT:1243 return make<ImportThunkChunkARM>(symtab.ctx, impSym);1244 }1245 llvm_unreachable("unknown machine type");1246}1247 1248void ImportFile::parse() {1249 const auto *hdr =1250 reinterpret_cast<const coff_import_header *>(mb.getBufferStart());1251 1252 // Check if the total size is valid.1253 if (mb.getBufferSize() < sizeof(*hdr) ||1254 mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)1255 Fatal(symtab.ctx) << "broken import library";1256 1257 // Read names and create an __imp_ symbol.1258 StringRef buf = mb.getBuffer().substr(sizeof(*hdr));1259 auto split = buf.split('\0');1260 buf = split.second;1261 StringRef name;1262 if (isArm64EC(hdr->Machine)) {1263 if (std::optional<std::string> demangledName =1264 getArm64ECDemangledFunctionName(split.first))1265 name = saver().save(*demangledName);1266 }1267 if (name.empty())1268 name = saver().save(split.first);1269 StringRef impName = saver().save("__imp_" + name);1270 dllName = buf.split('\0').first;1271 StringRef extName;1272 switch (hdr->getNameType()) {1273 case IMPORT_ORDINAL:1274 extName = "";1275 break;1276 case IMPORT_NAME:1277 extName = name;1278 break;1279 case IMPORT_NAME_NOPREFIX:1280 extName = ltrim1(name, "?@_");1281 break;1282 case IMPORT_NAME_UNDECORATE:1283 extName = ltrim1(name, "?@_");1284 extName = extName.substr(0, extName.find('@'));1285 break;1286 case IMPORT_NAME_EXPORTAS:1287 extName = buf.substr(dllName.size() + 1).split('\0').first;1288 break;1289 }1290 1291 this->hdr = hdr;1292 externalName = extName;1293 1294 bool isCode = hdr->getType() == llvm::COFF::IMPORT_CODE;1295 1296 if (!symtab.isEC()) {1297 impSym = symtab.addImportData(impName, this, location);1298 } else {1299 // In addition to the regular IAT, ARM64EC also contains an auxiliary IAT,1300 // which holds addresses that are guaranteed to be callable directly from1301 // ARM64 code. Function symbol naming is swapped: __imp_ symbols refer to1302 // the auxiliary IAT, while __imp_aux_ symbols refer to the regular IAT. For1303 // data imports, the naming is reversed.1304 StringRef auxImpName = saver().save("__imp_aux_" + name);1305 if (isCode) {1306 impSym = symtab.addImportData(auxImpName, this, location);1307 impECSym = symtab.addImportData(impName, this, auxLocation);1308 } else {1309 impSym = symtab.addImportData(impName, this, location);1310 impECSym = symtab.addImportData(auxImpName, this, auxLocation);1311 }1312 if (!impECSym)1313 return;1314 1315 StringRef auxImpCopyName = saver().save("__auximpcopy_" + name);1316 auxImpCopySym = symtab.addImportData(auxImpCopyName, this, auxCopyLocation);1317 if (!auxImpCopySym)1318 return;1319 }1320 // If this was a duplicate, we logged an error but may continue;1321 // in this case, impSym is nullptr.1322 if (!impSym)1323 return;1324 1325 if (hdr->getType() == llvm::COFF::IMPORT_CONST)1326 static_cast<void>(symtab.addImportData(name, this, location));1327 1328 // If type is function, we need to create a thunk which jump to an1329 // address pointed by the __imp_ symbol. (This allows you to call1330 // DLL functions just like regular non-DLL functions.)1331 if (isCode) {1332 if (!symtab.isEC()) {1333 thunkSym = symtab.addImportThunk(name, impSym, makeImportThunk());1334 } else {1335 thunkSym = symtab.addImportThunk(1336 name, impSym, make<ImportThunkChunkX64>(symtab.ctx, impSym));1337 1338 if (std::optional<std::string> mangledName =1339 getArm64ECMangledFunctionName(name)) {1340 StringRef auxThunkName = saver().save(*mangledName);1341 auxThunkSym = symtab.addImportThunk(1342 auxThunkName, impECSym,1343 make<ImportThunkChunkARM64>(symtab.ctx, impECSym, ARM64EC));1344 }1345 1346 StringRef impChkName = saver().save("__impchk_" + name);1347 impchkThunk = make<ImportThunkChunkARM64EC>(this);1348 impchkThunk->sym = symtab.addImportThunk(impChkName, impSym, impchkThunk);1349 symtab.ctx.driver.pullArm64ECIcallHelper();1350 }1351 }1352}1353 1354BitcodeFile::BitcodeFile(SymbolTable &symtab, MemoryBufferRef mb,1355 std::unique_ptr<lto::InputFile> &o, bool lazy)1356 : InputFile(symtab, BitcodeKind, mb, lazy) {1357 obj.swap(o);1358}1359 1360BitcodeFile *BitcodeFile::create(COFFLinkerContext &ctx, MemoryBufferRef mb,1361 StringRef archiveName,1362 uint64_t offsetInArchive, bool lazy) {1363 std::string path = mb.getBufferIdentifier().str();1364 if (ctx.config.thinLTOIndexOnly)1365 path = replaceThinLTOSuffix(mb.getBufferIdentifier(),1366 ctx.config.thinLTOObjectSuffixReplace.first,1367 ctx.config.thinLTOObjectSuffixReplace.second);1368 1369 // ThinLTO assumes that all MemoryBufferRefs given to it have a unique1370 // name. If two archives define two members with the same name, this1371 // causes a collision which result in only one of the objects being taken1372 // into consideration at LTO time (which very likely causes undefined1373 // symbols later in the link stage). So we append file offset to make1374 // filename unique.1375 MemoryBufferRef mbref(mb.getBuffer(),1376 saver().save(archiveName.empty()1377 ? path1378 : archiveName +1379 sys::path::filename(path) +1380 utostr(offsetInArchive)));1381 1382 std::unique_ptr<lto::InputFile> obj = check(lto::InputFile::create(mbref));1383 return make<BitcodeFile>(ctx.getSymtab(getMachineType(obj.get())), mb, obj,1384 lazy);1385}1386 1387BitcodeFile::~BitcodeFile() = default;1388 1389void BitcodeFile::parse() {1390 llvm::StringSaver &saver = lld::saver();1391 1392 std::vector<std::pair<Symbol *, bool>> comdat(obj->getComdatTable().size());1393 for (size_t i = 0; i != obj->getComdatTable().size(); ++i)1394 // FIXME: Check nodeduplicate1395 comdat[i] =1396 symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));1397 for (const lto::InputFile::Symbol &objSym : obj->symbols()) {1398 StringRef symName = saver.save(objSym.getName());1399 int comdatIndex = objSym.getComdatIndex();1400 Symbol *sym;1401 SectionChunk *fakeSC = nullptr;1402 if (objSym.isExecutable())1403 fakeSC = &symtab.ctx.ltoTextSectionChunk.chunk;1404 else1405 fakeSC = &symtab.ctx.ltoDataSectionChunk.chunk;1406 if (objSym.isUndefined()) {1407 sym = symtab.addUndefined(symName, this, false);1408 if (objSym.isWeak())1409 sym->deferUndefined = true;1410 // If one LTO object file references (i.e. has an undefined reference to)1411 // a symbol with an __imp_ prefix, the LTO compilation itself sees it1412 // as unprefixed but with a dllimport attribute instead, and doesn't1413 // understand the relation to a concrete IR symbol with the __imp_ prefix.1414 //1415 // For such cases, mark the symbol as used in a regular object (i.e. the1416 // symbol must be retained) so that the linker can associate the1417 // references in the end. If the symbol is defined in an import library1418 // or in a regular object file, this has no effect, but if it is defined1419 // in another LTO object file, this makes sure it is kept, to fulfill1420 // the reference when linking the output of the LTO compilation.1421 if (symName.starts_with("__imp_"))1422 sym->isUsedInRegularObj = true;1423 } else if (objSym.isCommon()) {1424 sym = symtab.addCommon(this, symName, objSym.getCommonSize());1425 } else if (objSym.isWeak() && objSym.isIndirect()) {1426 // Weak external.1427 sym = symtab.addUndefined(symName, this, true);1428 std::string fallback = std::string(objSym.getCOFFWeakExternalFallback());1429 Symbol *alias = symtab.addUndefined(saver.save(fallback));1430 checkAndSetWeakAlias(symtab, this, sym, alias, false);1431 } else if (comdatIndex != -1) {1432 if (symName == obj->getComdatTable()[comdatIndex].first) {1433 sym = comdat[comdatIndex].first;1434 if (cast<DefinedRegular>(sym)->data == nullptr)1435 cast<DefinedRegular>(sym)->data = &fakeSC->repl;1436 } else if (comdat[comdatIndex].second) {1437 sym = symtab.addRegular(this, symName, nullptr, fakeSC);1438 } else {1439 sym = symtab.addUndefined(symName, this, false);1440 }1441 } else {1442 sym =1443 symtab.addRegular(this, symName, nullptr, fakeSC, 0, objSym.isWeak());1444 }1445 symbols.push_back(sym);1446 if (objSym.isUsed())1447 symtab.ctx.config.gcroot.push_back(sym);1448 }1449 directives = saver.save(obj->getCOFFLinkerOpts());1450}1451 1452void BitcodeFile::parseLazy() {1453 for (const lto::InputFile::Symbol &sym : obj->symbols())1454 if (!sym.isUndefined()) {1455 symtab.addLazyObject(this, sym.getName());1456 if (!lazy)1457 return;1458 }1459}1460 1461MachineTypes BitcodeFile::getMachineType(const llvm::lto::InputFile *obj) {1462 Triple t(obj->getTargetTriple());1463 switch (t.getArch()) {1464 case Triple::x86_64:1465 return AMD64;1466 case Triple::x86:1467 return I386;1468 case Triple::arm:1469 case Triple::thumb:1470 return ARMNT;1471 case Triple::aarch64:1472 return t.isWindowsArm64EC() ? ARM64EC : ARM64;1473 default:1474 return IMAGE_FILE_MACHINE_UNKNOWN;1475 }1476}1477 1478std::string lld::coff::replaceThinLTOSuffix(StringRef path, StringRef suffix,1479 StringRef repl) {1480 if (path.consume_back(suffix))1481 return (path + repl).str();1482 return std::string(path);1483}1484 1485static bool isRVACode(COFFObjectFile *coffObj, uint64_t rva, InputFile *file) {1486 for (size_t i = 1, e = coffObj->getNumberOfSections(); i <= e; i++) {1487 const coff_section *sec = CHECK(coffObj->getSection(i), file);1488 if (rva >= sec->VirtualAddress &&1489 rva <= sec->VirtualAddress + sec->VirtualSize) {1490 return (sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE) != 0;1491 }1492 }1493 return false;1494}1495 1496void DLLFile::parse() {1497 // Parse a memory buffer as a PE-COFF executable.1498 std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);1499 1500 if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {1501 bin.release();1502 coffObj.reset(obj);1503 } else {1504 Err(symtab.ctx) << toString(this) << " is not a COFF file";1505 return;1506 }1507 1508 if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) {1509 Err(symtab.ctx) << toString(this) << " is not a PE-COFF executable";1510 return;1511 }1512 1513 for (const auto &exp : coffObj->export_directories()) {1514 StringRef dllName, symbolName;1515 uint32_t exportRVA;1516 checkError(exp.getDllName(dllName));1517 checkError(exp.getSymbolName(symbolName));1518 checkError(exp.getExportRVA(exportRVA));1519 1520 if (symbolName.empty())1521 continue;1522 1523 bool code = isRVACode(coffObj.get(), exportRVA, this);1524 1525 Symbol *s = make<Symbol>();1526 s->dllName = dllName;1527 s->symbolName = symbolName;1528 s->importType = code ? ImportType::IMPORT_CODE : ImportType::IMPORT_DATA;1529 s->nameType = ImportNameType::IMPORT_NAME;1530 1531 if (coffObj->getMachine() == I386) {1532 s->symbolName = symbolName = saver().save("_" + symbolName);1533 s->nameType = ImportNameType::IMPORT_NAME_NOPREFIX;1534 }1535 1536 StringRef impName = saver().save("__imp_" + symbolName);1537 symtab.addLazyDLLSymbol(this, s, impName);1538 if (code)1539 symtab.addLazyDLLSymbol(this, s, symbolName);1540 if (symtab.isEC()) {1541 StringRef impAuxName = saver().save("__imp_aux_" + symbolName);1542 symtab.addLazyDLLSymbol(this, s, impAuxName);1543 1544 if (code) {1545 std::optional<std::string> mangledName =1546 getArm64ECMangledFunctionName(symbolName);1547 if (mangledName)1548 symtab.addLazyDLLSymbol(this, s, *mangledName);1549 }1550 }1551 }1552}1553 1554MachineTypes DLLFile::getMachineType() const {1555 if (coffObj)1556 return static_cast<MachineTypes>(coffObj->getMachine());1557 return IMAGE_FILE_MACHINE_UNKNOWN;1558}1559 1560void DLLFile::makeImport(DLLFile::Symbol *s) {1561 if (!seen.insert(s->symbolName).second)1562 return;1563 1564 size_t impSize = s->dllName.size() + s->symbolName.size() + 2; // +2 for NULs1565 size_t size = sizeof(coff_import_header) + impSize;1566 char *buf = bAlloc().Allocate<char>(size);1567 memset(buf, 0, size);1568 char *p = buf;1569 auto *imp = reinterpret_cast<coff_import_header *>(p);1570 p += sizeof(*imp);1571 imp->Sig2 = 0xFFFF;1572 imp->Machine = coffObj->getMachine();1573 imp->SizeOfData = impSize;1574 imp->OrdinalHint = 0; // Only linking by name1575 imp->TypeInfo = (s->nameType << 2) | s->importType;1576 1577 // Write symbol name and DLL name.1578 memcpy(p, s->symbolName.data(), s->symbolName.size());1579 p += s->symbolName.size() + 1;1580 memcpy(p, s->dllName.data(), s->dllName.size());1581 MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName);1582 ImportFile *impFile = make<ImportFile>(symtab.ctx, mbref);1583 symtab.ctx.driver.addFile(impFile);1584}1585