Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lld/COFF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ struct Configuration {
bool noimplib = false;
std::set<std::string> delayLoads;
std::map<std::string, int> dllOrder;
Symbol *delayLoadHelper = nullptr;
Symbol *arm64ECIcallHelper = nullptr;

llvm::DenseSet<llvm::StringRef> saveTempsArgs;
Expand Down
41 changes: 17 additions & 24 deletions lld/COFF/DLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -911,21 +911,18 @@ 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<std::vector<DefinedImportData *>> v = binImports(ctx, imports);

Chunk *unwind = newTailMergeUnwindInfoChunk();

// Create .didat contents for each DLL.
for (std::vector<DefinedImportData *> &syms : v) {
// Create the delay import table header.
dllNames.push_back(make<StringChunk>(syms[0]->getDLLName()));
auto *dir = make<DelayDirectoryChunk>(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<DelayAddressChunk>(ctx, t);
Expand Down Expand Up @@ -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<NullChunk>(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<Defined>(symtab.delayLoadHelper);
switch (symtab.machine) {
case AMD64:
case ARM64EC:
return make<TailMergeChunkX64>(dir, helper);
Expand All @@ -1005,21 +1005,14 @@ Chunk *DelayLoadContents::newTailMergeChunk(Chunk *dir) {
}
}

Chunk *DelayLoadContents::newTailMergeUnwindInfoChunk() {
switch (ctx.config.machine) {
case AMD64:
case ARM64EC:
return make<TailMergeUnwindInfoX64>();
// 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<TailMergePDataChunkX64>(tm, unwind);
if (!symtab.tailMergeUnwindInfoChunk)
symtab.tailMergeUnwindInfoChunk = make<TailMergeUnwindInfoX64>();
return make<TailMergePDataChunkX64>(tm, symtab.tailMergeUnwindInfoChunk);
// FIXME: Add support for other architectures.
default:
return nullptr; // Just don't generate unwind info.
Expand All @@ -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<ThunkChunkX64>(s, tailMerge);
Expand Down
8 changes: 3 additions & 5 deletions lld/COFF/DLL.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Chunk *> getChunks();
std::vector<Chunk *> getDataChunks();
ArrayRef<Chunk *> getCodeChunks() { return thunks; }
Expand All @@ -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<DefinedImportData *> imports;
std::vector<Chunk *> dirs;
std::vector<Chunk *> moduleHandles;
Expand Down
13 changes: 7 additions & 6 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2353,12 +2353,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> 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);
}
});
}
}

Expand Down
3 changes: 3 additions & 0 deletions lld/COFF/SymbolTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1307,8 +1307,7 @@ void Writer::appendImportThunks() {
}

if (!delayIdata.empty()) {
Defined *helper = cast<Defined>(ctx.config.delayLoadHelper);
delayIdata.create(helper);
delayIdata.create();
for (Chunk *c : delayIdata.getChunks())
didatSec->addChunk(c);
for (Chunk *c : delayIdata.getDataChunks())
Expand Down
Loading