summaryrefslogtreecommitdiff
path: root/lld/COFF/InputFiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/InputFiles.cpp')
-rw-r--r--lld/COFF/InputFiles.cpp259
1 files changed, 139 insertions, 120 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index dd309f70fd13..e698f66b84f6 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,22 +106,23 @@ 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);
// Try to read symbols from ECSYMBOLS section on ARM64EC.
- if (isArm64EC(ctx.config.machine)) {
+ if (ctx.symtabEC) {
iterator_range<Archive::symbol_iterator> symbols =
CHECK(file->ec_symbols(), this);
if (!symbols.empty()) {
for (const Archive::Symbol &sym : symbols)
- ctx.symtab.addLazyArchive(this, sym);
+ ctx.symtabEC->addLazyArchive(this, sym);
// Read both EC and native symbols on ARM64X.
- if (ctx.config.machine != ARM64X)
+ if (!ctx.hybridSymtab)
return;
}
}
@@ -134,17 +135,18 @@ 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> lld::coff::getArchiveMembers(Archive *file) {
+std::vector<MemoryBufferRef>
+lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {
std::vector<MemoryBufferRef> v;
Error err = Error::success();
for (const Archive::Child &c : file->children(err)) {
@@ -155,15 +157,32 @@ std::vector<MemoryBufferRef> lld::coff::getArchiveMembers(Archive *file) {
v.push_back(mbref);
}
if (err)
- fatal(file->getFileName() +
- ": Archive::children failed: " + toString(std::move(err)));
+ Fatal(ctx) << file->getFileName()
+ << ": Archive::children failed: " << toString(std::move(err));
return v;
}
+ObjFile::ObjFile(SymbolTable &symtab, COFFObjectFile *coffObj, bool lazy)
+ : InputFile(symtab, ObjectKind, coffObj->getMemoryBufferRef(), lazy),
+ coffObj(coffObj) {}
+
+ObjFile *ObjFile::create(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy) {
+ // Parse a memory buffer as a COFF file.
+ Expected<std::unique_ptr<Binary>> bin = createBinary(m);
+ if (!bin)
+ Fatal(ctx) << "Could not parse " << m.getBufferIdentifier();
+
+ auto *obj = dyn_cast<COFFObjectFile>(bin->get());
+ if (!obj)
+ Fatal(ctx) << m.getBufferIdentifier() << " is not a COFF file";
+
+ bin->release();
+ return make<ObjFile>(ctx.getSymtab(MachineTypes(obj->getMachine())), obj,
+ lazy);
+}
+
void ObjFile::parseLazy() {
// Native object file.
- std::unique_ptr<Binary> coffObjPtr = CHECK(createBinary(mb), this);
- COFFObjectFile *coffObj = cast<COFFObjectFile>(coffObjPtr.get());
uint32_t numSymbols = coffObj->getNumberOfSymbols();
for (uint32_t i = 0; i < numSymbols; ++i) {
COFFSymbolRef coffSym = check(coffObj->getSymbol(i));
@@ -173,7 +192,9 @@ void ObjFile::parseLazy() {
StringRef name = check(coffObj->getSymbolName(coffSym));
if (coffSym.isAbsolute() && ignoredSymbolName(name))
continue;
- ctx.symtab.addLazyObject(this, name);
+ symtab.addLazyObject(this, name);
+ if (!lazy)
+ return;
i += coffSym.getNumberOfAuxSymbols();
}
}
@@ -187,7 +208,8 @@ struct ECMapEntry {
void ObjFile::initializeECThunks() {
for (SectionChunk *chunk : hybmpChunks) {
if (chunk->getContents().size() % sizeof(ECMapEntry)) {
- error("Invalid .hybmp chunk size " + Twine(chunk->getContents().size()));
+ Err(symtab.ctx) << "Invalid .hybmp chunk size "
+ << chunk->getContents().size();
continue;
}
@@ -198,31 +220,21 @@ 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;
}
}
}
}
void ObjFile::parse() {
- // Parse a memory buffer as a COFF file.
- std::unique_ptr<Binary> bin = CHECK(createBinary(mb), this);
-
- if (auto *obj = dyn_cast<COFFObjectFile>(bin.get())) {
- bin.release();
- coffObj.reset(obj);
- } else {
- fatal(toString(this) + " is not a COFF file");
- }
-
// Read section and symbol tables.
initializeChunks();
initializeSymbols();
@@ -234,7 +246,7 @@ void ObjFile::parse() {
const coff_section *ObjFile::getSection(uint32_t i) {
auto sec = coffObj->getSection(i);
if (!sec)
- fatal("getSection failed: #" + Twine(i) + ": " + toString(sec.takeError()));
+ Fatal(symtab.ctx) << "getSection failed: #" << i << ": " << sec.takeError();
return *sec;
}
@@ -267,8 +279,8 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
if (Expected<StringRef> e = coffObj->getSectionName(sec))
name = *e;
else
- fatal("getSectionName failed: #" + Twine(sectionNumber) + ": " +
- toString(e.takeError()));
+ Fatal(symtab.ctx) << "getSectionName failed: #" << sectionNumber << ": "
+ << e.takeError();
if (name == ".drectve") {
ArrayRef<uint8_t> data;
@@ -298,7 +310,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)
@@ -327,12 +339,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
@@ -363,9 +375,10 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef sym,
const coff_section *parentSec = getSection(parentIndex);
if (Expected<StringRef> e = coffObj->getSectionName(parentSec))
parentName = *e;
- error(toString(this) + ": associative comdat " + name + " (sec " +
- Twine(sectionNumber) + ") has invalid reference to section " +
- parentName + " (sec " + Twine(parentIndex) + ")");
+ Err(symtab.ctx) << toString(this) << ": associative comdat " << name
+ << " (sec " << sectionNumber
+ << ") has invalid reference to section " << parentName
+ << " (sec " << parentIndex << ")";
};
if (parent == pendingComdat) {
@@ -426,16 +439,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,
@@ -455,6 +468,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));
@@ -528,7 +542,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);
}
@@ -539,17 +553,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 (symtab.isEC() && 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);
}
}
@@ -583,6 +597,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)) {
@@ -620,16 +635,16 @@ void ObjFile::handleComdatSelection(
// seems better though.
// (This behavior matches ModuleLinker::getComdatResult().)
if (selection != leaderSelection) {
- Log(ctx) << "conflicting comdat type for " << toString(ctx, *leader) << ": "
+ 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:
@@ -639,14 +654,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;
@@ -657,7 +672,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;
}
@@ -700,10 +715,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();
@@ -714,7 +730,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);
}
@@ -723,12 +739,14 @@ std::optional<Symbol *> ObjFile::createDefined(
return nullptr;
if (llvm::COFF::isReservedSectionNumber(sectionNumber))
- fatal(toString(this) + ": " + getName() +
- " should not refer to special section " + Twine(sectionNumber));
+ Fatal(ctx) << toString(this) << ": " << getName()
+ << " should not refer to special section "
+ << Twine(sectionNumber);
if ((uint32_t)sectionNumber >= sparseChunks.size())
- fatal(toString(this) + ": " + getName() +
- " should not refer to non-existent section " + Twine(sectionNumber));
+ Fatal(ctx) << toString(this) << ": " << getName()
+ << " should not refer to non-existent section "
+ << Twine(sectionNumber);
// Comdat handling.
// A comdat symbol consists of two symbol table entries.
@@ -747,7 +765,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());
@@ -758,8 +776,9 @@ std::optional<Symbol *> ObjFile::createDefined(
// Intentionally ends at IMAGE_COMDAT_SELECT_LARGEST: link.exe
// doesn't understand IMAGE_COMDAT_SELECT_NEWEST either.
def->Selection > (int)IMAGE_COMDAT_SELECT_LARGEST) {
- fatal("unknown comdat type " + std::to_string((int)def->Selection) +
- " for " + getName() + " in " + toString(this));
+ Fatal(ctx) << "unknown comdat type "
+ << std::to_string((int)def->Selection) << " for " << getName()
+ << " in " << toString(this);
}
COMDATType selection = (COMDATType)def->Selection;
@@ -794,9 +813,7 @@ std::optional<Symbol *> ObjFile::createDefined(
}
MachineTypes ObjFile::getMachineType() const {
- if (coffObj)
- return static_cast<MachineTypes>(coffObj->getMachine());
- return IMAGE_FILE_MACHINE_UNKNOWN;
+ return static_cast<MachineTypes>(coffObj->getMachine());
}
ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {
@@ -861,6 +878,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;
@@ -971,7 +989,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;
@@ -988,7 +1006,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(
@@ -1008,7 +1026,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
@@ -1021,7 +1039,7 @@ ObjFile::getVariableLocation(StringRef var) {
if (!dwarf)
return std::nullopt;
}
- if (ctx.config.machine == I386)
+ if (symtab.machine == I386)
var.consume_front("_");
std::optional<std::pair<std::string, unsigned>> ret =
dwarf->getVariableLoc(var);
@@ -1044,17 +1062,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 =
@@ -1066,13 +1084,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");
}
@@ -1084,7 +1102,7 @@ void ImportFile::parse() {
// Check if the total size is valid.
if (mb.getBufferSize() < sizeof(*hdr) ||
mb.getBufferSize() != sizeof(*hdr) + hdr->SizeOfData)
- fatal("broken import library");
+ Fatal(symtab.ctx) << "broken import library";
// Read names and create an __imp_ symbol.
StringRef buf = mb.getBuffer().substr(sizeof(*hdr));
@@ -1125,8 +1143,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.isEC()) {
+ 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
@@ -1135,18 +1153,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;
}
@@ -1156,31 +1173,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.isEC()) {
+ 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();
}
}
}
@@ -1188,7 +1204,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(),
@@ -1220,18 +1236,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)
@@ -1248,38 +1264,41 @@ 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());
}
void BitcodeFile::parseLazy() {
for (const lto::InputFile::Symbol &sym : obj->symbols())
- if (!sym.isUndefined())
- ctx.symtab.addLazyObject(this, sym.getName());
+ if (!sym.isUndefined()) {
+ symtab.addLazyObject(this, sym.getName());
+ if (!lazy)
+ return;
+ }
}
MachineTypes BitcodeFile::getMachineType() const {
@@ -1325,12 +1344,12 @@ void DLLFile::parse() {
bin.release();
coffObj.reset(obj);
} else {
- error(toString(this) + " is not a COFF file");
+ Err(symtab.ctx) << toString(this) << " is not a COFF file";
return;
}
if (!coffObj->getPE32Header() && !coffObj->getPE32PlusHeader()) {
- error(toString(this) + " is not a PE-COFF executable");
+ Err(symtab.ctx) << toString(this) << " is not a PE-COFF executable";
return;
}
@@ -1358,9 +1377,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);
}
}
@@ -1392,6 +1411,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.ctx.driver.addFile(impFile);
}