diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index cd280aa09964d..0c7c4e91402f1 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -164,7 +164,6 @@ struct Configuration { bool noimplib = false; std::set delayLoads; std::map dllOrder; - Symbol *delayLoadHelper = nullptr; Symbol *arm64ECIcallHelper = nullptr; llvm::DenseSet saveTempsArgs; diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp index b6fbd5a484b5e..534cd47be1051 100644 --- a/lld/COFF/DLL.cpp +++ b/lld/COFF/DLL.cpp @@ -911,12 +911,9 @@ uint64_t DelayLoadContents::getDirSize() { return dirs.size() * sizeof(delay_import_directory_table_entry); } -void DelayLoadContents::create(Defined *h) { - helper = h; +void DelayLoadContents::create() { std::vector> v = binImports(ctx, imports); - Chunk *unwind = newTailMergeUnwindInfoChunk(); - // Create .didat contents for each DLL. for (std::vector &syms : v) { // Create the delay import table header. @@ -924,8 +921,8 @@ void DelayLoadContents::create(Defined *h) { auto *dir = make(dllNames.back()); size_t base = addresses.size(); - Chunk *tm = newTailMergeChunk(dir); - Chunk *pdataChunk = unwind ? newTailMergePDataChunk(tm, unwind) : nullptr; + Chunk *tm = newTailMergeChunk(ctx.symtab, dir); + Chunk *pdataChunk = newTailMergePDataChunk(ctx.symtab, tm); for (DefinedImportData *s : syms) { Chunk *t = newThunkChunk(s, tm); auto *a = make(ctx, t); @@ -982,15 +979,18 @@ void DelayLoadContents::create(Defined *h) { dirs.push_back(dir); } - if (unwind) - unwindinfo.push_back(unwind); + ctx.forEachSymtab([&](SymbolTable &symtab) { + if (symtab.tailMergeUnwindInfoChunk) + unwindinfo.push_back(symtab.tailMergeUnwindInfoChunk); + }); // Add null terminator. dirs.push_back( make(sizeof(delay_import_directory_table_entry), 4)); } -Chunk *DelayLoadContents::newTailMergeChunk(Chunk *dir) { - switch (ctx.config.machine) { +Chunk *DelayLoadContents::newTailMergeChunk(SymbolTable &symtab, Chunk *dir) { + auto helper = cast(symtab.delayLoadHelper); + switch (symtab.machine) { case AMD64: case ARM64EC: return make(dir, helper); @@ -1005,21 +1005,14 @@ Chunk *DelayLoadContents::newTailMergeChunk(Chunk *dir) { } } -Chunk *DelayLoadContents::newTailMergeUnwindInfoChunk() { - switch (ctx.config.machine) { - case AMD64: - case ARM64EC: - return make(); - // FIXME: Add support for other architectures. - default: - return nullptr; // Just don't generate unwind info. - } -} -Chunk *DelayLoadContents::newTailMergePDataChunk(Chunk *tm, Chunk *unwind) { - switch (ctx.config.machine) { +Chunk *DelayLoadContents::newTailMergePDataChunk(SymbolTable &symtab, + Chunk *tm) { + switch (symtab.machine) { case AMD64: case ARM64EC: - return make(tm, unwind); + if (!symtab.tailMergeUnwindInfoChunk) + symtab.tailMergeUnwindInfoChunk = make(); + return make(tm, symtab.tailMergeUnwindInfoChunk); // FIXME: Add support for other architectures. default: return nullptr; // Just don't generate unwind info. @@ -1028,7 +1021,7 @@ Chunk *DelayLoadContents::newTailMergePDataChunk(Chunk *tm, Chunk *unwind) { Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *s, Chunk *tailMerge) { - switch (ctx.config.machine) { + switch (s->file->getMachineType()) { case AMD64: case ARM64EC: return make(s, tailMerge); diff --git a/lld/COFF/DLL.h b/lld/COFF/DLL.h index 724a323d62d20..5105b79f15d31 100644 --- a/lld/COFF/DLL.h +++ b/lld/COFF/DLL.h @@ -42,7 +42,7 @@ class DelayLoadContents { DelayLoadContents(COFFLinkerContext &ctx) : ctx(ctx) {} void add(DefinedImportData *sym) { imports.push_back(sym); } bool empty() { return imports.empty(); } - void create(Defined *helper); + void create(); std::vector getChunks(); std::vector getDataChunks(); ArrayRef getCodeChunks() { return thunks; } @@ -56,11 +56,9 @@ class DelayLoadContents { private: Chunk *newThunkChunk(DefinedImportData *s, Chunk *tailMerge); - Chunk *newTailMergeChunk(Chunk *dir); - Chunk *newTailMergePDataChunk(Chunk *tm, Chunk *unwind); - Chunk *newTailMergeUnwindInfoChunk(); + Chunk *newTailMergeChunk(SymbolTable &symtab, Chunk *dir); + Chunk *newTailMergePDataChunk(SymbolTable &symtab, Chunk *tm); - Defined *helper; std::vector imports; std::vector dirs; std::vector moduleHandles; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 6eea11f5f451f..ac3ac57bd17f4 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2353,12 +2353,13 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { llvm::TimeTraceScope timeScope("Delay load"); for (auto *arg : args.filtered(OPT_delayload)) { config->delayLoads.insert(StringRef(arg->getValue()).lower()); - if (config->machine == I386) { - config->delayLoadHelper = ctx.symtab.addGCRoot("___delayLoadHelper2@8"); - } else { - config->delayLoadHelper = - ctx.symtab.addGCRoot("__delayLoadHelper2", true); - } + ctx.forEachSymtab([&](SymbolTable &symtab) { + if (symtab.machine == I386) { + symtab.delayLoadHelper = symtab.addGCRoot("___delayLoadHelper2@8"); + } else { + symtab.delayLoadHelper = symtab.addGCRoot("__delayLoadHelper2", true); + } + }); } } diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index c8d7251838842..ff6e8487f0734 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -158,6 +158,9 @@ class SymbolTable { Chunk *edataStart = nullptr; Chunk *edataEnd = nullptr; + Symbol *delayLoadHelper = nullptr; + Chunk *tailMergeUnwindInfoChunk = nullptr; + void fixupExports(); void assignExportOrdinals(); void parseModuleDefs(StringRef path); diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index bef2ced9f2957..2bdaeb58ab432 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1307,8 +1307,7 @@ void Writer::appendImportThunks() { } if (!delayIdata.empty()) { - Defined *helper = cast(ctx.config.delayLoadHelper); - delayIdata.create(helper); + delayIdata.create(); for (Chunk *c : delayIdata.getChunks()) didatSec->addChunk(c); for (Chunk *c : delayIdata.getDataChunks())