mirror of
https://github.com/intel/llvm.git
synced 2026-01-25 19:44:38 +08:00
[LLD][COFF] Store reference to SymbolTable instead of COFFLinkerContext in InputFile (NFC) (#119296)
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.
This commit is contained in:
@@ -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<std::string> 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<DefinedAbsolute>(sym) && !isa<DefinedSynthetic>(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<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));
|
||||
@@ -1137,7 +1138,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,13 +160,14 @@ public:
|
||||
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:
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ class ImportThunkChunk;
|
||||
class ImportThunkChunkARM64EC;
|
||||
class SectionChunk;
|
||||
class Symbol;
|
||||
class SymbolTable;
|
||||
class Undefined;
|
||||
class TpiSource;
|
||||
|
||||
@@ -99,11 +100,11 @@ public:
|
||||
// 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 @@ private:
|
||||
// .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 @@ private:
|
||||
// .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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -119,6 +119,8 @@ public:
|
||||
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 @@ private:
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user