[lld] [LLD][COFF] Add support for delay-load imports on ARM64X (PR #124600)
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 28 03:31:36 PST 2025
================
@@ -921,54 +921,89 @@ void DelayLoadContents::create() {
auto *dir = make<DelayDirectoryChunk>(dllNames.back());
size_t base = addresses.size();
- 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);
- addresses.push_back(a);
- thunks.push_back(t);
- StringRef extName = s->getExternalName();
- if (extName.empty()) {
- names.push_back(make<OrdinalOnlyChunk>(ctx, s->getOrdinal()));
- } else {
- auto *c = make<HintNameChunk>(extName, 0);
- names.push_back(make<LookupChunk>(ctx, c));
- hintNames.push_back(c);
- // Add a synthetic symbol for this load thunk, using the "__imp___load"
- // prefix, in case this thunk needs to be added to the list of valid
- // call targets for Control Flow Guard.
- StringRef symName = saver().save("__imp___load_" + extName);
- s->loadThunkSym =
- cast<DefinedSynthetic>(ctx.symtab.addSynthetic(symName, t));
+ ctx.forEachSymtab([&](SymbolTable &symtab) {
+ if (ctx.hybridSymtab && symtab.isEC()) {
+ // For hybrid images, emit null-terminated native import entries
+ // followed by null-terminated EC entries. If a view is missing imports
+ // for a given module, only terminators are emitted. Emit ARM64X
+ // relocations to skip native entries in the EC view.
+ ctx.dynamicRelocs->add(
+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0,
+ Arm64XRelocVal(dir, offsetof(delay_import_directory_table_entry,
+ DelayImportAddressTable)),
+ (addresses.size() - base) * sizeof(uint64_t));
+ ctx.dynamicRelocs->add(
+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0,
+ Arm64XRelocVal(dir, offsetof(delay_import_directory_table_entry,
+ DelayImportNameTable)),
+ (addresses.size() - base) * sizeof(uint64_t));
}
- if (s->file->impECSym) {
- auto chunk = make<AuxImportChunk>(s->file);
- auxIat.push_back(chunk);
- s->file->impECSym->setLocation(chunk);
+ Chunk *tm = nullptr;
- chunk = make<AuxImportChunk>(s->file);
- auxIatCopy.push_back(chunk);
- s->file->auxImpCopySym->setLocation(chunk);
+ for (DefinedImportData *s : syms) {
+ // Process only the symbols belonging to the current symtab.
+ if (symtab.isEC() != s->file->isEC())
+ continue;
+
+ if (!tm) {
+ tm = newTailMergeChunk(symtab, dir);
+ Chunk *pdataChunk = newTailMergePDataChunk(symtab, tm);
+ if (pdataChunk)
+ pdata.push_back(pdataChunk);
+ }
+
+ Chunk *t = newThunkChunk(s, tm);
+ auto *a = make<DelayAddressChunk>(ctx, t);
+ addresses.push_back(a);
+ s->setLocation(a);
----------------
mstorsjo wrote:
I guess the moving of where the tail merge chunk is created, and this call to `s->setLocation`, also could be considered pre-refactorings?
https://github.com/llvm/llvm-project/pull/124600
More information about the llvm-commits
mailing list