[lld] [LLD][COFF] Factor out LinkerDriver::setMachine (NFC) (PR #119297)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 9 16:13:30 PST 2024
https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/119297
None
>From 845a44344ef5cb8ba284c0aab5642a4e1b7efa2e Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 3 Dec 2024 23:30:29 +0100
Subject: [PATCH 1/2] [LLD][COFF] Store reference to SymbolTable instead of
COFFLinkerContext in InputFile (NFC)
This change prepares for the introduction of separate hybrid namespaces. Hybrid images will
require two SymbolTable instances, making it necessary to associate InputFile objects with
the relevant one.
---
lld/COFF/Chunks.cpp | 25 ++---
lld/COFF/DLL.cpp | 5 +-
lld/COFF/Driver.cpp | 2 +-
lld/COFF/InputFiles.cpp | 192 ++++++++++++++++++++-------------------
lld/COFF/InputFiles.h | 15 +--
lld/COFF/PDB.cpp | 2 +-
lld/COFF/SymbolTable.cpp | 6 +-
lld/COFF/SymbolTable.h | 4 +-
lld/COFF/Symbols.cpp | 4 +-
9 files changed, 133 insertions(+), 122 deletions(-)
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 23fab0e66bb67f..6490adcc81d66e 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:
@@ -427,7 +427,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
@@ -435,7 +436,7 @@ void SectionChunk::applyRelocation(uint8_t *off,
// it was an absolute or synthetic symbol.
if (!sym ||
(!os && !isa<DefinedAbsolute>(sym) && !isa<DefinedSynthetic>(sym))) {
- maybeReportRelocationToDiscarded(this, sym, rel, file->ctx.config.mingw);
+ maybeReportRelocationToDiscarded(this, sym, rel, ctx.config.mingw);
return;
}
@@ -443,7 +444,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);
@@ -669,7 +670,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 " +
@@ -1098,7 +1099,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)
@@ -1122,7 +1123,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const {
applyArm64Addr(buf + 8, exitThunkRVA, rva + 8, 12);
applyArm64Imm(buf + 12, exitThunkRVA & 0xfff, 0);
- Defined *helper = cast<Defined>(file->ctx.config.arm64ECIcallHelper);
+ Defined *helper = cast<Defined>(file->symtab.ctx.config.arm64ECIcallHelper);
if (extended) {
// Replace last instruction with an inline range extension thunk.
memcpy(buf + 16, arm64Thunk, sizeof(arm64Thunk));
@@ -1136,7 +1137,7 @@ void ImportThunkChunkARM64EC::writeTo(uint8_t *buf) const {
bool ImportThunkChunkARM64EC::verifyRanges() {
if (extended)
return true;
- auto helper = cast<Defined>(file->ctx.config.arm64ECIcallHelper);
+ auto helper = cast<Defined>(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 0f6a40a41ca00f..3d6ed5a9ddeae9 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<Baserel> *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 714de67e88b065..b47b3ffec0a908 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -241,7 +241,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
break;
case file_magic::pecoff_executable:
if (ctx.config.mingw) {
- ctx.symtab.addFile(make<DLLFile>(ctx, mbref));
+ ctx.symtab.addFile(make<DLLFile>(ctx.symtab, mbref));
break;
}
if (filename.ends_with_insensitive(".dll")) {
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index f32bc5bbbc35f1..42c1a9aa90a0f8 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<Undefined>(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<MemoryBufferRef>
@@ -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<Binary> 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<const ECMapEntry *>(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<StringRef> 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<uint8_t> 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<StringRef> 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<DefinedRegular>(this, /*Name*/ "", /*IsCOMDAT*/ false,
@@ -456,6 +462,7 @@ void ObjFile::initializeSymbols() {
DenseMap<StringRef, uint32_t> prevailingSectionMap;
std::vector<const coff_aux_section_definition *> 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<Undefined>(s);
if (u && !u->weakAlias) {
if (std::optional<std::string> 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<BitcodeFile>(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<Symbol *> ObjFile::createDefined(
if (sym.isCommon()) {
auto *c = make<CommonChunk>(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<Symbol *> ObjFile::createDefined(
return nullptr;
if (sym.isExternal())
- return ctx.symtab.addAbsolute(name, sym);
+ return symtab.addAbsolute(name, sym);
return make<DefinedAbsolute>(ctx, name, sym);
}
@@ -750,7 +759,7 @@ std::optional<Symbol *> 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<DefinedRegular>(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<pdb::IPDBSession> 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<std::pair<std::string, unsigned>> ret =
dwarf->getVariableLoc(var);
@@ -1048,17 +1058,17 @@ std::optional<DILineInfo> 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<ImportThunkChunkX64>(ctx, impSym);
+ return make<ImportThunkChunkX64>(symtab.ctx, impSym);
case I386:
- return make<ImportThunkChunkX86>(ctx, impSym);
+ return make<ImportThunkChunkX86>(symtab.ctx, impSym);
case ARM64:
- return make<ImportThunkChunkARM64>(ctx, impSym, ARM64);
+ return make<ImportThunkChunkARM64>(symtab.ctx, impSym, ARM64);
case ARMNT:
- return make<ImportThunkChunkARM>(ctx, impSym);
+ return make<ImportThunkChunkARM>(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<void>(ctx.symtab.addImportData(name, this, location));
+ static_cast<void>(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<ImportThunkChunkX64>(ctx, impSym));
+ thunkSym = symtab.addImportThunk(
+ name, impSym, make<ImportThunkChunkX64>(symtab.ctx, impSym));
if (std::optional<std::string> mangledName =
getArm64ECMangledFunctionName(name)) {
StringRef auxThunkName = saver().save(*mangledName);
- auxThunkSym = ctx.symtab.addImportThunk(
+ auxThunkSym = symtab.addImportThunk(
auxThunkName, impECSym,
- make<ImportThunkChunkARM64>(ctx, impECSym, ARM64EC));
+ make<ImportThunkChunkARM64>(symtab.ctx, impECSym, ARM64EC));
}
StringRef impChkName = saver().save("__impchk_" + name);
impchkThunk = make<ImportThunkChunkARM64EC>(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<DefinedRegular>(sym)->data == nullptr)
cast<DefinedRegular>(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<ImportFile>(ctx, mbref);
- ctx.symtab.addFile(impFile);
+ ImportFile *impFile = make<ImportFile>(symtab.ctx, mbref);
+ symtab.addFile(impFile);
}
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index 3c48e778ac5b5d..fd2e409ada30f4 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 4382dd677ff59a..41f86749a392fc 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1007,7 +1007,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 26ace0e75c4931..942e7ceda1ebe3 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<LazyObject>(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<std::pair<StringRef, uint32_t>> 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 1d9e908b8b9918..92e94671ce8130 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<Chunk *> localImportChunks;
@@ -147,8 +149,6 @@ class SymbolTable {
bool ltoCompilationDone = false;
std::vector<std::pair<Symbol *, Symbol *>> entryThunks;
llvm::DenseMap<Symbol *, Symbol *> exitThunks;
-
- COFFLinkerContext &ctx;
};
std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex);
diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp
index 7de2c3829d1b0d..405fdbfa4a10a6 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
>From 7a11be2fd41e49c74f98a38b2469bbbdc8b3ee9b Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Wed, 4 Dec 2024 16:41:08 +0100
Subject: [PATCH 2/2] [LLD][COFF] Factor out LinkerDriver::setMachine (NFC)
---
lld/COFF/Driver.cpp | 17 ++++++++++++-----
lld/COFF/Driver.h | 8 +++++---
lld/COFF/SymbolTable.cpp | 3 +--
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index b47b3ffec0a908..5a3db548463181 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -591,6 +591,14 @@ std::optional<StringRef> LinkerDriver::findLibIfNew(StringRef filename) {
return path;
}
+void LinkerDriver::setMachine(MachineTypes machine) {
+ assert(ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN);
+ assert(machine != IMAGE_FILE_MACHINE_UNKNOWN);
+
+ ctx.config.machine = machine;
+ addWinSysRootLibSearchPaths();
+}
+
void LinkerDriver::detectWinSysRoot(const opt::InputArgList &Args) {
IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();
@@ -1887,10 +1895,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
{
llvm::TimeTraceScope timeScope2("Machine arg");
if (auto *arg = args.getLastArg(OPT_machine)) {
- config->machine = getMachineType(arg->getValue());
- if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN)
+ MachineTypes machine = getMachineType(arg->getValue());
+ if (machine == IMAGE_FILE_MACHINE_UNKNOWN)
Fatal(ctx) << "unknown /machine argument: " << arg->getValue();
- addWinSysRootLibSearchPaths();
+ setMachine(machine);
}
}
@@ -2298,8 +2306,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// not we assume x64.
if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) {
Warn(ctx) << "/machine is not specified. x64 is assumed";
- config->machine = AMD64;
- addWinSysRootLibSearchPaths();
+ setMachine(AMD64);
}
config->wordsize = config->is64() ? 8 : 4;
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 3889feb7511c0a..e94a961953581f 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -80,9 +80,7 @@ class LinkerDriver {
void linkerMain(llvm::ArrayRef<const char *> args);
- // Adds various search paths based on the sysroot. Must only be called once
- // config->machine has been set.
- void addWinSysRootLibSearchPaths();
+ void setMachine(llvm::COFF::MachineTypes machine);
void addClangLibSearchPaths(const std::string &argv0);
@@ -116,6 +114,10 @@ class LinkerDriver {
// Determines the location of the sysroot based on `args`, environment, etc.
void detectWinSysRoot(const llvm::opt::InputArgList &args);
+ // Adds various search paths based on the sysroot. Must only be called once
+ // config->machine has been set.
+ void addWinSysRootLibSearchPaths();
+
// Symbol names are mangled by prepending "_" on x86.
StringRef mangle(StringRef sym);
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 942e7ceda1ebe3..d6cf10756e2963 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -95,8 +95,7 @@ void SymbolTable::addFile(InputFile *file) {
if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN &&
mt != IMAGE_FILE_MACHINE_UNKNOWN) {
ctx.config.machineInferred = true;
- ctx.config.machine = mt;
- ctx.driver.addWinSysRootLibSearchPaths();
+ ctx.driver.setMachine(mt);
}
ctx.driver.parseDirectives(file);
More information about the llvm-commits
mailing list