diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index c3a8b2f91999b..ec0fdf0b67b38 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -56,7 +56,7 @@ SectionChunk::SectionChunk(ObjFile *f, const coff_section *h, Kind k) // files will be built with -ffunction-sections or /Gy, so most things worth // stripping will be in a comdat. if (file) - live = !file->ctx.config.doGC || !isCOMDAT(); + live = !file->symtab.ctx.config.doGC || !isCOMDAT(); else live = true; } @@ -129,7 +129,7 @@ void SectionChunk::applyRelX64(uint8_t *off, uint16_t type, OutputSection *os, case IMAGE_REL_AMD64_REL32_4: add32(off, s - p - 8); break; case IMAGE_REL_AMD64_REL32_5: add32(off, s - p - 9); break; case IMAGE_REL_AMD64_SECTION: - applySecIdx(off, os, file->ctx.outputSections.size()); + applySecIdx(off, os, file->symtab.ctx.outputSections.size()); break; case IMAGE_REL_AMD64_SECREL: applySecRel(this, off, os, s); break; default: @@ -149,7 +149,7 @@ void SectionChunk::applyRelX86(uint8_t *off, uint16_t type, OutputSection *os, case IMAGE_REL_I386_DIR32NB: add32(off, s); break; case IMAGE_REL_I386_REL32: add32(off, s - p - 4); break; case IMAGE_REL_I386_SECTION: - applySecIdx(off, os, file->ctx.outputSections.size()); + applySecIdx(off, os, file->symtab.ctx.outputSections.size()); break; case IMAGE_REL_I386_SECREL: applySecRel(this, off, os, s); break; default: @@ -225,7 +225,7 @@ void SectionChunk::applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(off, sx - p - 4); break; case IMAGE_REL_ARM_BLX23T: applyBranch24T(off, sx - p - 4); break; case IMAGE_REL_ARM_SECTION: - applySecIdx(off, os, file->ctx.outputSections.size()); + applySecIdx(off, os, file->symtab.ctx.outputSections.size()); break; case IMAGE_REL_ARM_SECREL: applySecRel(this, off, os, s); break; case IMAGE_REL_ARM_REL32: add32(off, sx - p - 4); break; @@ -346,7 +346,7 @@ void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os, case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, off, os, s); break; case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, off, os, s); break; case IMAGE_REL_ARM64_SECTION: - applySecIdx(off, os, file->ctx.outputSections.size()); + applySecIdx(off, os, file->symtab.ctx.outputSections.size()); break; case IMAGE_REL_ARM64_REL32: add32(off, s - p - 4); break; default: @@ -371,12 +371,12 @@ static void maybeReportRelocationToDiscarded(const SectionChunk *fromChunk, ObjFile *file = fromChunk->file; std::string name; if (sym) { - name = toString(file->ctx, *sym); + name = toString(file->symtab.ctx, *sym); } else { COFFSymbolRef coffSym = check(file->getCOFFObj()->getSymbol(rel.SymbolTableIndex)); name = maybeDemangleSymbol( - file->ctx, check(file->getCOFFObj()->getSymbolName(coffSym))); + file->symtab.ctx, check(file->getCOFFObj()->getSymbolName(coffSym))); } std::vector symbolLocations = @@ -428,7 +428,8 @@ void SectionChunk::applyRelocation(uint8_t *off, // section is needed to compute SECREL and SECTION relocations used in debug // info. Chunk *c = sym ? sym->getChunk() : nullptr; - OutputSection *os = c ? file->ctx.getOutputSection(c) : nullptr; + COFFLinkerContext &ctx = file->symtab.ctx; + OutputSection *os = c ? ctx.getOutputSection(c) : nullptr; // Skip the relocation if it refers to a discarded section, and diagnose it // as an error if appropriate. If a symbol was discarded early, it may be @@ -436,7 +437,7 @@ void SectionChunk::applyRelocation(uint8_t *off, // it was an absolute or synthetic symbol. if (!sym || (!os && !isa(sym) && !isa(sym))) { - maybeReportRelocationToDiscarded(this, sym, rel, file->ctx.config.mingw); + maybeReportRelocationToDiscarded(this, sym, rel, ctx.config.mingw); return; } @@ -444,7 +445,7 @@ void SectionChunk::applyRelocation(uint8_t *off, // Compute the RVA of the relocation for relative relocations. uint64_t p = rva + rel.VirtualAddress; - uint64_t imageBase = file->ctx.config.imageBase; + uint64_t imageBase = ctx.config.imageBase; switch (getArch()) { case Triple::x86_64: applyRelX64(off, rel.Type, os, s, p, imageBase); @@ -670,7 +671,7 @@ void SectionChunk::getRuntimePseudoRelocs( toString(file)); continue; } - int addressSizeInBits = file->ctx.config.is64() ? 64 : 32; + int addressSizeInBits = file->symtab.ctx.config.is64() ? 64 : 32; if (sizeInBits < addressSizeInBits) { warn("runtime pseudo relocation in " + toString(file) + " against " + "symbol " + target->getName() + " is too narrow (only " + @@ -1099,7 +1100,7 @@ void CHPERedirectionChunk::writeTo(uint8_t *buf) const { } ImportThunkChunkARM64EC::ImportThunkChunkARM64EC(ImportFile *file) - : ImportThunkChunk(file->ctx, file->impSym), file(file) {} + : ImportThunkChunk(file->symtab.ctx, file->impSym), file(file) {} size_t ImportThunkChunkARM64EC::getSize() const { if (!extended) @@ -1123,7 +1124,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const { applyArm64Addr(buf + 8, exitThunkRVA, rva + 8, 12); applyArm64Imm(buf + 12, exitThunkRVA & 0xfff, 0); - Defined *helper = cast(file->ctx.config.arm64ECIcallHelper); + Defined *helper = cast(file->symtab.ctx.config.arm64ECIcallHelper); if (extended) { // Replace last instruction with an inline range extension thunk. memcpy(buf + 16, arm64Thunk, sizeof(arm64Thunk)); @@ -1137,7 +1138,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const { bool ImportThunkChunkARM64EC::verifyRanges() { if (extended) return true; - auto helper = cast(file->ctx.config.arm64ECIcallHelper); + auto helper = cast(file->symtab.ctx.config.arm64ECIcallHelper); return isInt<28>(helper->getRVA() - rva - 16); } diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp index 0f6a40a41ca00..3d6ed5a9ddeae 100644 --- a/lld/COFF/DLL.cpp +++ b/lld/COFF/DLL.cpp @@ -160,13 +160,14 @@ class AuxImportChunk : public NonSectionChunk { void writeTo(uint8_t *buf) const override { uint64_t impchkVA = 0; if (file->impchkThunk) - impchkVA = file->impchkThunk->getRVA() + file->ctx.config.imageBase; + impchkVA = + file->impchkThunk->getRVA() + file->symtab.ctx.config.imageBase; write64le(buf, impchkVA); } void getBaserels(std::vector *res) override { if (file->impchkThunk) - res->emplace_back(rva, file->ctx.config.machine); + res->emplace_back(rva, file->symtab.ctx.config.machine); } private: diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 714de67e88b06..b47b3ffec0a90 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -241,7 +241,7 @@ void LinkerDriver::addBuffer(std::unique_ptr mb, break; case file_magic::pecoff_executable: if (ctx.config.mingw) { - ctx.symtab.addFile(make(ctx, mbref)); + ctx.symtab.addFile(make(ctx.symtab, mbref)); break; } if (filename.ends_with_insensitive(".dll")) { diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index f32bc5bbbc35f..42c1a9aa90a0f 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -78,7 +78,7 @@ const COFFSyncStream &coff::operator<<(const COFFSyncStream &s, /// Checks that Source is compatible with being a weak alias to Target. /// If Source is Undefined and has no weak alias set, makes it a weak /// alias to Target. -static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f, +static void checkAndSetWeakAlias(SymbolTable &symtab, InputFile *f, Symbol *source, Symbol *target, bool isAntiDep) { if (auto *u = dyn_cast(source)) { @@ -92,9 +92,9 @@ static void checkAndSetWeakAlias(COFFLinkerContext &ctx, InputFile *f, // of another symbol emitted near the weak symbol. // Just use the definition from the first object file that defined // this weak symbol. - if (ctx.config.allowDuplicateWeak) + if (symtab.ctx.config.allowDuplicateWeak) return; - ctx.symtab.reportDuplicate(source, f); + symtab.reportDuplicate(source, f); } } u->setWeakAlias(target, isAntiDep); @@ -106,9 +106,10 @@ static bool ignoredSymbolName(StringRef name) { } ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m) - : InputFile(ctx, ArchiveKind, m) {} + : InputFile(ctx.symtab, ArchiveKind, m) {} void ArchiveFile::parse() { + COFFLinkerContext &ctx = symtab.ctx; // Parse a MemoryBufferRef as an archive file. file = CHECK(Archive::create(mb), this); @@ -134,14 +135,14 @@ void ArchiveFile::parse() { // Returns a buffer pointing to a member file containing a given symbol. void ArchiveFile::addMember(const Archive::Symbol &sym) { const Archive::Child &c = - CHECK(sym.getMember(), - "could not get the member for symbol " + toCOFFString(ctx, sym)); + CHECK(sym.getMember(), "could not get the member for symbol " + + toCOFFString(symtab.ctx, sym)); // Return an empty buffer if we have already returned the same buffer. if (!seen.insert(c.getChildOffset()).second) return; - ctx.driver.enqueueArchiveMember(c, sym, getName()); + symtab.ctx.driver.enqueueArchiveMember(c, sym, getName()); } std::vector @@ -161,6 +162,9 @@ lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) { return v; } +ObjFile::ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy) + : InputFile(ctx.symtab, ObjectKind, m, lazy) {} + void ObjFile::parseLazy() { // Native object file. std::unique_ptr coffObjPtr = CHECK(createBinary(mb), this); @@ -174,7 +178,7 @@ void ObjFile::parseLazy() { StringRef name = check(coffObj->getSymbolName(coffSym)); if (coffSym.isAbsolute() && ignoredSymbolName(name)) continue; - ctx.symtab.addLazyObject(this, name); + symtab.addLazyObject(this, name); i += coffSym.getNumberOfAuxSymbols(); } } @@ -188,7 +192,8 @@ struct ECMapEntry { void ObjFile::initializeECThunks() { for (SectionChunk *chunk : hybmpChunks) { if (chunk->getContents().size() % sizeof(ECMapEntry)) { - Err(ctx) << "Invalid .hybmp chunk size " << chunk->getContents().size(); + Err(symtab.ctx) << "Invalid .hybmp chunk size " + << chunk->getContents().size(); continue; } @@ -199,15 +204,15 @@ void ObjFile::initializeECThunks() { auto entry = reinterpret_cast(iter); switch (entry->type) { case Arm64ECThunkType::Entry: - ctx.symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst)); + symtab.addEntryThunk(getSymbol(entry->src), getSymbol(entry->dst)); break; case Arm64ECThunkType::Exit: - ctx.symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst)); + symtab.addExitThunk(getSymbol(entry->src), getSymbol(entry->dst)); break; case Arm64ECThunkType::GuestExit: break; default: - Warn(ctx) << "Ignoring unknown EC thunk type " << entry->type; + Warn(symtab.ctx) << "Ignoring unknown EC thunk type " << entry->type; } } } @@ -221,7 +226,7 @@ void ObjFile::parse() { bin.release(); coffObj.reset(obj); } else { - Fatal(ctx) << toString(this) << " is not a COFF file"; + Fatal(symtab.ctx) << toString(this) << " is not a COFF file"; } // Read section and symbol tables. @@ -235,7 +240,7 @@ void ObjFile::parse() { const coff_section *ObjFile::getSection(uint32_t i) { auto sec = coffObj->getSection(i); if (!sec) - Fatal(ctx) << "getSection failed: #" << i << ": " << sec.takeError(); + Fatal(symtab.ctx) << "getSection failed: #" << i << ": " << sec.takeError(); return *sec; } @@ -268,8 +273,8 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber, if (Expected e = coffObj->getSectionName(sec)) name = *e; else - Fatal(ctx) << "getSectionName failed: #" << sectionNumber << ": " - << e.takeError(); + Fatal(symtab.ctx) << "getSectionName failed: #" << sectionNumber << ": " + << e.takeError(); if (name == ".drectve") { ArrayRef data; @@ -299,7 +304,7 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber, // and then write it to a separate .pdb file. // Ignore DWARF debug info unless requested to be included. - if (!ctx.config.includeDwarfChunks && name.starts_with(".debug_")) + if (!symtab.ctx.config.includeDwarfChunks && name.starts_with(".debug_")) return nullptr; if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE) @@ -328,12 +333,12 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber, sxDataChunks.push_back(c); else if (isArm64EC(getMachineType()) && name == ".hybmp$x") hybmpChunks.push_back(c); - else if (ctx.config.tailMerge && sec->NumberOfRelocations == 0 && + else if (symtab.ctx.config.tailMerge && sec->NumberOfRelocations == 0 && name == ".rdata" && leaderName.starts_with("??_C@")) // COFF sections that look like string literal sections (i.e. no // relocations, in .rdata, leader symbol name matches the MSVC name mangling // for string literals) are subject to string tail merging. - MergeChunk::addSection(ctx, c); + MergeChunk::addSection(symtab.ctx, c); else if (name == ".rsrc" || name.starts_with(".rsrc$")) resourceChunks.push_back(c); else @@ -364,9 +369,10 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef sym, const coff_section *parentSec = getSection(parentIndex); if (Expected e = coffObj->getSectionName(parentSec)) parentName = *e; - Err(ctx) << toString(this) << ": associative comdat " << name << " (sec " - << sectionNumber << ") has invalid reference to section " - << parentName << " (sec " << parentIndex << ")"; + Err(symtab.ctx) << toString(this) << ": associative comdat " << name + << " (sec " << sectionNumber + << ") has invalid reference to section " << parentName + << " (sec " << parentIndex << ")"; }; if (parent == pendingComdat) { @@ -427,16 +433,16 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) { if (sym.isExternal()) { StringRef name = check(coffObj->getSymbolName(sym)); if (sc) - return ctx.symtab.addRegular(this, name, sym.getGeneric(), sc, - sym.getValue()); + return symtab.addRegular(this, name, sym.getGeneric(), sc, + sym.getValue()); // For MinGW symbols named .weak.* that point to a discarded section, // don't create an Undefined symbol. If nothing ever refers to the symbol, // everything should be fine. If something actually refers to the symbol // (e.g. the undefined weak alias), linking will fail due to undefined // references at the end. - if (ctx.config.mingw && name.starts_with(".weak.")) + if (symtab.ctx.config.mingw && name.starts_with(".weak.")) return nullptr; - return ctx.symtab.addUndefined(name, this, false); + return symtab.addUndefined(name, this, false); } if (sc) return make(this, /*Name*/ "", /*IsCOMDAT*/ false, @@ -456,6 +462,7 @@ void ObjFile::initializeSymbols() { DenseMap prevailingSectionMap; std::vector comdatDefs( coffObj->getNumberOfSections() + 1); + COFFLinkerContext &ctx = symtab.ctx; for (uint32_t i = 0; i < numSymbols; ++i) { COFFSymbolRef coffSym = check(coffObj->getSymbol(i)); @@ -529,7 +536,7 @@ void ObjFile::initializeSymbols() { for (auto &kv : weakAliases) { Symbol *sym = kv.first; const coff_aux_weak_external *aux = kv.second; - checkAndSetWeakAlias(ctx, this, sym, symbols[aux->TagIndex], + checkAndSetWeakAlias(symtab, this, sym, symbols[aux->TagIndex], aux->Characteristics == IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY); } @@ -540,17 +547,17 @@ void ObjFile::initializeSymbols() { Symbol *ObjFile::createUndefined(COFFSymbolRef sym, bool overrideLazy) { StringRef name = check(coffObj->getSymbolName(sym)); - Symbol *s = ctx.symtab.addUndefined(name, this, overrideLazy); + Symbol *s = symtab.addUndefined(name, this, overrideLazy); // Add an anti-dependency alias for undefined AMD64 symbols on the ARM64EC // target. - if (isArm64EC(ctx.config.machine) && getMachineType() == AMD64) { + if (isArm64EC(symtab.ctx.config.machine) && getMachineType() == AMD64) { auto u = dyn_cast(s); if (u && !u->weakAlias) { if (std::optional mangledName = getArm64ECMangledFunctionName(name)) { - Symbol *m = ctx.symtab.addUndefined(saver().save(*mangledName), this, - /*overrideLazy=*/false); + Symbol *m = symtab.addUndefined(saver().save(*mangledName), this, + /*overrideLazy=*/false); u->setWeakAlias(m, /*antiDep=*/true); } } @@ -584,6 +591,7 @@ void ObjFile::handleComdatSelection( SectionChunk *leaderChunk = leader->getChunk(); COMDATType leaderSelection = leaderChunk->selection; + COFFLinkerContext &ctx = symtab.ctx; assert(leader->data && "Comdat leader without SectionChunk?"); if (isa(leader->file)) { @@ -624,13 +632,13 @@ void ObjFile::handleComdatSelection( Log(ctx) << "conflicting comdat type for " << leader << ": " << (int)leaderSelection << " in " << leader->getFile() << " and " << (int)selection << " in " << this; - ctx.symtab.reportDuplicate(leader, this); + symtab.reportDuplicate(leader, this); return; } switch (selection) { case IMAGE_COMDAT_SELECT_NODUPLICATES: - ctx.symtab.reportDuplicate(leader, this); + symtab.reportDuplicate(leader, this); break; case IMAGE_COMDAT_SELECT_ANY: @@ -640,14 +648,14 @@ void ObjFile::handleComdatSelection( case IMAGE_COMDAT_SELECT_SAME_SIZE: if (leaderChunk->getSize() != getSection(sym)->SizeOfRawData) { if (!ctx.config.mingw) { - ctx.symtab.reportDuplicate(leader, this); + symtab.reportDuplicate(leader, this); } else { const coff_aux_section_definition *leaderDef = nullptr; if (leaderChunk->file) leaderDef = findSectionDef(leaderChunk->file->getCOFFObj(), leaderChunk->getSectionNumber()); if (!leaderDef || leaderDef->Length != def->Length) - ctx.symtab.reportDuplicate(leader, this); + symtab.reportDuplicate(leader, this); } } break; @@ -658,7 +666,7 @@ void ObjFile::handleComdatSelection( // if the two comdat sections have e.g. different alignment. // Match that. if (leaderChunk->getContents() != newChunk.getContents()) - ctx.symtab.reportDuplicate(leader, this, &newChunk, sym.getValue()); + symtab.reportDuplicate(leader, this, &newChunk, sym.getValue()); break; } @@ -701,10 +709,11 @@ std::optional ObjFile::createDefined( if (sym.isCommon()) { auto *c = make(sym); chunks.push_back(c); - return ctx.symtab.addCommon(this, getName(), sym.getValue(), - sym.getGeneric(), c); + return symtab.addCommon(this, getName(), sym.getValue(), sym.getGeneric(), + c); } + COFFLinkerContext &ctx = symtab.ctx; if (sym.isAbsolute()) { StringRef name = getName(); @@ -715,7 +724,7 @@ std::optional ObjFile::createDefined( return nullptr; if (sym.isExternal()) - return ctx.symtab.addAbsolute(name, sym); + return symtab.addAbsolute(name, sym); return make(ctx, name, sym); } @@ -750,7 +759,7 @@ std::optional ObjFile::createDefined( if (sym.isExternal()) { std::tie(leader, prevailing) = - ctx.symtab.addComdat(this, getName(), sym.getGeneric()); + symtab.addComdat(this, getName(), sym.getGeneric()); } else { leader = make(this, /*Name*/ "", /*IsCOMDAT*/ false, /*IsExternal*/ false, sym.getGeneric()); @@ -865,6 +874,7 @@ void ObjFile::initializeFlags() { // DebugTypes.h). Both cases only happen with cl.exe: clang-cl produces regular // output even with /Yc and /Yu and with /Zi. void ObjFile::initializeDependencies() { + COFFLinkerContext &ctx = symtab.ctx; if (!ctx.config.debug) return; @@ -975,7 +985,7 @@ findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputPath) { } PDBInputFile::PDBInputFile(COFFLinkerContext &ctx, MemoryBufferRef m) - : InputFile(ctx, PDBKind, m) {} + : InputFile(ctx.symtab, PDBKind, m) {} PDBInputFile::~PDBInputFile() = default; @@ -992,7 +1002,7 @@ PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx, } void PDBInputFile::parse() { - ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this; + symtab.ctx.pdbInputFileInstances[mb.getBufferIdentifier().str()] = this; std::unique_ptr thisSession; Error E = pdb::NativeSession::createFromPdb( @@ -1012,7 +1022,7 @@ void PDBInputFile::parse() { loadErrorStr.emplace(toString(expectedInfo.takeError())); return; } - debugTypesObj = makeTypeServerSource(ctx, this); + debugTypesObj = makeTypeServerSource(symtab.ctx, this); } // Used only for DWARF debug info, which is not common (except in MinGW @@ -1025,7 +1035,7 @@ ObjFile::getVariableLocation(StringRef var) { if (!dwarf) return std::nullopt; } - if (ctx.config.machine == I386) + if (symtab.ctx.config.machine == I386) var.consume_front("_"); std::optional> ret = dwarf->getVariableLoc(var); @@ -1048,17 +1058,17 @@ std::optional ObjFile::getDILineInfo(uint32_t offset, } void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) { - auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile); + auto p = findPdbPath(path.str(), fromFile, symtab.ctx.config.outputFile); if (!p) return; - auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr); + auto it = symtab.ctx.pdbInputFileInstances.emplace(*p, nullptr); if (!it.second) return; // already scheduled for load - ctx.driver.enqueuePDB(*p); + symtab.ctx.driver.enqueuePDB(*p); } ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m) - : InputFile(ctx, ImportKind, m), live(!ctx.config.doGC) {} + : InputFile(ctx.symtab, ImportKind, m), live(!ctx.config.doGC) {} MachineTypes ImportFile::getMachineType() const { uint16_t machine = @@ -1070,13 +1080,13 @@ MachineTypes ImportFile::getMachineType() const { ImportThunkChunk *ImportFile::makeImportThunk() { switch (hdr->Machine) { case AMD64: - return make(ctx, impSym); + return make(symtab.ctx, impSym); case I386: - return make(ctx, impSym); + return make(symtab.ctx, impSym); case ARM64: - return make(ctx, impSym, ARM64); + return make(symtab.ctx, impSym, ARM64); case ARMNT: - return make(ctx, impSym); + return make(symtab.ctx, impSym); } llvm_unreachable("unknown machine type"); } @@ -1088,7 +1098,7 @@ void ImportFile::parse() { // Check if the total size is valid. if (mb.getBufferSize() < sizeof(*hdr) || mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData) - Fatal(ctx) << "broken import library"; + Fatal(symtab.ctx) << "broken import library"; // Read names and create an __imp_ symbol. StringRef buf = mb.getBuffer().substr(sizeof(*hdr)); @@ -1129,8 +1139,8 @@ void ImportFile::parse() { bool isCode = hdr->getType() == llvm::COFF::IMPORT_CODE; - if (ctx.config.machine != ARM64EC) { - impSym = ctx.symtab.addImportData(impName, this, location); + if (symtab.ctx.config.machine != ARM64EC) { + impSym = symtab.addImportData(impName, this, location); } else { // In addition to the regular IAT, ARM64EC also contains an auxiliary IAT, // which holds addresses that are guaranteed to be callable directly from @@ -1139,18 +1149,17 @@ void ImportFile::parse() { // data imports, the naming is reversed. StringRef auxImpName = saver().save("__imp_aux_" + name); if (isCode) { - impSym = ctx.symtab.addImportData(auxImpName, this, location); - impECSym = ctx.symtab.addImportData(impName, this, auxLocation); + impSym = symtab.addImportData(auxImpName, this, location); + impECSym = symtab.addImportData(impName, this, auxLocation); } else { - impSym = ctx.symtab.addImportData(impName, this, location); - impECSym = ctx.symtab.addImportData(auxImpName, this, auxLocation); + impSym = symtab.addImportData(impName, this, location); + impECSym = symtab.addImportData(auxImpName, this, auxLocation); } if (!impECSym) return; StringRef auxImpCopyName = saver().save("__auximpcopy_" + name); - auxImpCopySym = - ctx.symtab.addImportData(auxImpCopyName, this, auxCopyLocation); + auxImpCopySym = symtab.addImportData(auxImpCopyName, this, auxCopyLocation); if (!auxImpCopySym) return; } @@ -1160,31 +1169,30 @@ void ImportFile::parse() { return; if (hdr->getType() == llvm::COFF::IMPORT_CONST) - static_cast(ctx.symtab.addImportData(name, this, location)); + static_cast(symtab.addImportData(name, this, location)); // If type is function, we need to create a thunk which jump to an // address pointed by the __imp_ symbol. (This allows you to call // DLL functions just like regular non-DLL functions.) if (isCode) { - if (ctx.config.machine != ARM64EC) { - thunkSym = ctx.symtab.addImportThunk(name, impSym, makeImportThunk()); + if (symtab.ctx.config.machine != ARM64EC) { + thunkSym = symtab.addImportThunk(name, impSym, makeImportThunk()); } else { - thunkSym = ctx.symtab.addImportThunk( - name, impSym, make(ctx, impSym)); + thunkSym = symtab.addImportThunk( + name, impSym, make(symtab.ctx, impSym)); if (std::optional mangledName = getArm64ECMangledFunctionName(name)) { StringRef auxThunkName = saver().save(*mangledName); - auxThunkSym = ctx.symtab.addImportThunk( + auxThunkSym = symtab.addImportThunk( auxThunkName, impECSym, - make(ctx, impECSym, ARM64EC)); + make(symtab.ctx, impECSym, ARM64EC)); } StringRef impChkName = saver().save("__impchk_" + name); impchkThunk = make(this); - impchkThunk->sym = - ctx.symtab.addImportThunk(impChkName, impSym, impchkThunk); - ctx.driver.pullArm64ECIcallHelper(); + impchkThunk->sym = symtab.addImportThunk(impChkName, impSym, impchkThunk); + symtab.ctx.driver.pullArm64ECIcallHelper(); } } } @@ -1192,7 +1200,7 @@ void ImportFile::parse() { BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb, StringRef archiveName, uint64_t offsetInArchive, bool lazy) - : InputFile(ctx, BitcodeKind, mb, lazy) { + : InputFile(ctx.symtab, BitcodeKind, mb, lazy) { std::string path = mb.getBufferIdentifier().str(); if (ctx.config.thinLTOIndexOnly) path = replaceThinLTOSuffix(mb.getBufferIdentifier(), @@ -1224,18 +1232,18 @@ void BitcodeFile::parse() { for (size_t i = 0; i != obj->getComdatTable().size(); ++i) // FIXME: Check nodeduplicate comdat[i] = - ctx.symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first)); + symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first)); for (const lto::InputFile::Symbol &objSym : obj->symbols()) { StringRef symName = saver.save(objSym.getName()); int comdatIndex = objSym.getComdatIndex(); Symbol *sym; SectionChunk *fakeSC = nullptr; if (objSym.isExecutable()) - fakeSC = &ctx.ltoTextSectionChunk.chunk; + fakeSC = &symtab.ctx.ltoTextSectionChunk.chunk; else - fakeSC = &ctx.ltoDataSectionChunk.chunk; + fakeSC = &symtab.ctx.ltoDataSectionChunk.chunk; if (objSym.isUndefined()) { - sym = ctx.symtab.addUndefined(symName, this, false); + sym = symtab.addUndefined(symName, this, false); if (objSym.isWeak()) sym->deferUndefined = true; // If one LTO object file references (i.e. has an undefined reference to) @@ -1252,30 +1260,30 @@ void BitcodeFile::parse() { if (symName.starts_with("__imp_")) sym->isUsedInRegularObj = true; } else if (objSym.isCommon()) { - sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize()); + sym = symtab.addCommon(this, symName, objSym.getCommonSize()); } else if (objSym.isWeak() && objSym.isIndirect()) { // Weak external. - sym = ctx.symtab.addUndefined(symName, this, true); + sym = symtab.addUndefined(symName, this, true); std::string fallback = std::string(objSym.getCOFFWeakExternalFallback()); - Symbol *alias = ctx.symtab.addUndefined(saver.save(fallback)); - checkAndSetWeakAlias(ctx, this, sym, alias, false); + Symbol *alias = symtab.addUndefined(saver.save(fallback)); + checkAndSetWeakAlias(symtab, this, sym, alias, false); } else if (comdatIndex != -1) { if (symName == obj->getComdatTable()[comdatIndex].first) { sym = comdat[comdatIndex].first; if (cast(sym)->data == nullptr) cast(sym)->data = &fakeSC->repl; } else if (comdat[comdatIndex].second) { - sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC); + sym = symtab.addRegular(this, symName, nullptr, fakeSC); } else { - sym = ctx.symtab.addUndefined(symName, this, false); + sym = symtab.addUndefined(symName, this, false); } } else { - sym = ctx.symtab.addRegular(this, symName, nullptr, fakeSC, 0, - objSym.isWeak()); + sym = + symtab.addRegular(this, symName, nullptr, fakeSC, 0, objSym.isWeak()); } symbols.push_back(sym); if (objSym.isUsed()) - ctx.config.gcroot.push_back(sym); + symtab.ctx.config.gcroot.push_back(sym); } directives = saver.save(obj->getCOFFLinkerOpts()); } @@ -1283,7 +1291,7 @@ void BitcodeFile::parse() { void BitcodeFile::parseLazy() { for (const lto::InputFile::Symbol &sym : obj->symbols()) if (!sym.isUndefined()) - ctx.symtab.addLazyObject(this, sym.getName()); + symtab.addLazyObject(this, sym.getName()); } MachineTypes BitcodeFile::getMachineType() const { @@ -1329,12 +1337,12 @@ void DLLFile::parse() { bin.release(); coffObj.reset(obj); } else { - Err(ctx) << toString(this) << " is not a COFF file"; + Err(symtab.ctx) << toString(this) << " is not a COFF file"; return; } if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) { - Err(ctx) << toString(this) << " is not a PE-COFF executable"; + Err(symtab.ctx) << toString(this) << " is not a PE-COFF executable"; return; } @@ -1362,9 +1370,9 @@ void DLLFile::parse() { } StringRef impName = saver().save("__imp_" + symbolName); - ctx.symtab.addLazyDLLSymbol(this, s, impName); + symtab.addLazyDLLSymbol(this, s, impName); if (code) - ctx.symtab.addLazyDLLSymbol(this, s, symbolName); + symtab.addLazyDLLSymbol(this, s, symbolName); } } @@ -1396,6 +1404,6 @@ void DLLFile::makeImport(DLLFile::Symbol *s) { p += s->symbolName.size() + 1; memcpy(p, s->dllName.data(), s->dllName.size()); MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName); - ImportFile *impFile = make(ctx, mbref); - ctx.symtab.addFile(impFile); + ImportFile *impFile = make(symtab.ctx, mbref); + symtab.addFile(impFile); } diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 3c48e778ac5b5..fd2e409ada30f 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -62,6 +62,7 @@ class ImportThunkChunk; class ImportThunkChunkARM64EC; class SectionChunk; class Symbol; +class SymbolTable; class Undefined; class TpiSource; @@ -99,11 +100,11 @@ class InputFile { // Returns .drectve section contents if exist. StringRef getDirectives() { return directives; } - COFFLinkerContext &ctx; + SymbolTable &symtab; protected: - InputFile(COFFLinkerContext &c, Kind k, MemoryBufferRef m, bool lazy = false) - : mb(m), ctx(c), fileKind(k), lazy(lazy) {} + InputFile(SymbolTable &s, Kind k, MemoryBufferRef m, bool lazy = false) + : mb(m), symtab(s), fileKind(k), lazy(lazy) {} StringRef directives; @@ -135,8 +136,8 @@ class ArchiveFile : public InputFile { // .obj or .o file. This may be a member of an archive file. class ObjFile : public InputFile { public: - explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy = false) - : InputFile(ctx, ObjectKind, m, lazy) {} + explicit ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, + bool lazy = false); static bool classof(const InputFile *f) { return f->kind() == ObjectKind; } void parse() override; void parseLazy(); @@ -403,8 +404,8 @@ class BitcodeFile : public InputFile { // .dll file. MinGW only. class DLLFile : public InputFile { public: - explicit DLLFile(COFFLinkerContext &ctx, MemoryBufferRef m) - : InputFile(ctx, DLLKind, m) {} + explicit DLLFile(SymbolTable &symtab, MemoryBufferRef m) + : InputFile(symtab, DLLKind, m) {} static bool classof(const InputFile *f) { return f->kind() == DLLKind; } void parse() override; MachineTypes getMachineType() const override; diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 6dcab906b35bf..21475033b0ae8 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -1012,7 +1012,7 @@ static void warnUnusable(InputFile *f, Error e, bool shouldWarn) { consumeError(std::move(e)); return; } - auto diag = Warn(f->ctx); + auto diag = Warn(f->symtab.ctx); diag << "Cannot use debug info for '" << f << "' [LNK4099]"; if (e) diag << "\n>>> failed to load reference " << std::move(e); diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 26ace0e75c493..942e7ceda1ebe 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -117,7 +117,7 @@ static void forceLazy(Symbol *s) { } case Symbol::Kind::LazyObjectKind: { InputFile *file = cast(s)->file; - file->ctx.symtab.addFile(file); + file->symtab.ctx.symtab.addFile(file); break; } case Symbol::Kind::LazyDLLSymbolKind: { @@ -177,7 +177,7 @@ getFileLine(const SectionChunk *c, uint32_t addr) { std::optional> fileLine = getFileLineCodeView(c, addr); // If codeview didn't yield any result, check dwarf in MinGW mode. - if (!fileLine && c->file->ctx.config.mingw) + if (!fileLine && c->file->symtab.ctx.config.mingw) fileLine = getFileLineDwarf(c, addr); return fileLine; } @@ -235,7 +235,7 @@ getSymbolLocations(ObjFile *file, uint32_t symIndex, size_t maxStrings) { << "\n>>> "; os << toString(file); if (loc.sym) - os << ":(" << toString(file->ctx, *loc.sym) << ')'; + os << ":(" << toString(file->symtab.ctx, *loc.sym) << ')'; } return std::make_pair(symbolLocations, numLocations); } diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 1d9e908b8b991..92e94671ce813 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -119,6 +119,8 @@ class SymbolTable { SectionChunk *newSc = nullptr, uint32_t newSectionOffset = 0); + COFFLinkerContext &ctx; + // A list of chunks which to be added to .rdata. std::vector localImportChunks; @@ -147,8 +149,6 @@ class SymbolTable { bool ltoCompilationDone = false; std::vector> entryThunks; llvm::DenseMap exitThunks; - - COFFLinkerContext &ctx; }; std::vector getSymbolLocations(ObjFile *file, uint32_t symIndex); diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 35c421d599ff5..148822fdb68ff 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -166,10 +166,10 @@ bool Undefined::resolveWeakAlias() { MemoryBufferRef LazyArchive::getMemberBuffer() { Archive::Child c = CHECK(sym.getMember(), "could not get the member for symbol " + - toCOFFString(file->ctx, sym)); + toCOFFString(file->symtab.ctx, sym)); return CHECK(c.getMemoryBufferRef(), "could not get the buffer for the member defining symbol " + - toCOFFString(file->ctx, sym)); + toCOFFString(file->symtab.ctx, sym)); } } // namespace coff } // namespace lld