[lld] [LLD][COFF] Add support for importing ARM64X images (PR #210080)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 08:18:20 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-lld-coff
Author: Jacek Caban (cjacek)
<details>
<summary>Changes</summary>
When importing ARM64X image, add both native and EC views to the symbol table on EC targets. Also getMachine() on such images returns ARM64X, treat it as ARM64 instead.
---
Full diff: https://github.com/llvm/llvm-project/pull/210080.diff
4 Files Affected:
- (modified) lld/COFF/Driver.cpp (+16-1)
- (modified) lld/COFF/InputFiles.cpp (+5-3)
- (modified) lld/COFF/InputFiles.h (+2-2)
- (added) lld/test/COFF/link-dll-arm64x.s (+81)
``````````diff
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index dc4903a5fe126..10ceabce603a8 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -356,7 +356,22 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
break;
case file_magic::pecoff_executable:
if (ctx.config.mingw) {
- addFile(make<DLLFile>(ctx.symtab, mbref));
+ std::unique_ptr<COFFObjectFile> obj =
+ ObjFile::createCOFFObject(ctx, mbref);
+ if (ctx.symtab.isEC()) {
+ // When importing an ARM64X image, add both the native and EC views.
+ if (std::unique_ptr<MemoryBuffer> hybridView =
+ obj->getHybridObjectView()) {
+ std::unique_ptr<COFFObjectFile> hybridObj = ObjFile::createCOFFObject(
+ ctx, hybridView.release()->getMemBufferRef());
+ addFile(make<DLLFile>(ctx.symtab, hybridObj.release()));
+ addFile(make<DLLFile>(*ctx.hybridSymtab, obj.release()));
+ break;
+ }
+ }
+ addFile(make<DLLFile>(
+ ctx.getSymtab(static_cast<MachineTypes>(obj->getMachine())),
+ obj.release()));
break;
}
if (filename.ends_with_insensitive(".dll")) {
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 757a0f7be9b36..6db9da2f5fab5 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -1564,8 +1564,10 @@ void DLLFile::parse() {
}
MachineTypes DLLFile::getMachineType() const {
- if (coffObj)
- return static_cast<MachineTypes>(coffObj->getMachine());
+ if (coffObj) {
+ auto machine = static_cast<MachineTypes>(coffObj->getMachine());
+ return machine == ARM64X ? ARM64 : machine;
+ }
return IMAGE_FILE_MACHINE_UNKNOWN;
}
@@ -1581,7 +1583,7 @@ void DLLFile::makeImport(DLLFile::Symbol *s) {
auto *imp = reinterpret_cast<coff_import_header *>(p);
p += sizeof(*imp);
imp->Sig2 = 0xFFFF;
- imp->Machine = coffObj->getMachine();
+ imp->Machine = static_cast<uint16_t>(getMachineType());
imp->SizeOfData = impSize;
imp->OrdinalHint = 0; // Only linking by name
imp->TypeInfo = (s->nameType << 2) | s->importType;
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index b8a2acf6e1b41..7c88b7cec3bd8 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -424,8 +424,8 @@ class BitcodeFile : public InputFile {
// .dll file. MinGW only.
class DLLFile : public InputFile {
public:
- explicit DLLFile(SymbolTable &symtab, MemoryBufferRef m)
- : InputFile(symtab, DLLKind, m) {}
+ explicit DLLFile(SymbolTable &symtab, COFFObjectFile *coffObj)
+ : InputFile(symtab, DLLKind, coffObj->getMemoryBufferRef()) {}
static bool classof(const InputFile *f) { return f->kind() == DLLKind; }
void parse() override;
MachineTypes getMachineType() const override;
diff --git a/lld/test/COFF/link-dll-arm64x.s b/lld/test/COFF/link-dll-arm64x.s
new file mode 100644
index 0000000000000..b97a61aa3f5be
--- /dev/null
+++ b/lld/test/COFF/link-dll-arm64x.s
@@ -0,0 +1,81 @@
+REQUIRES: aarch64, x86
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows sym-ec.s -o sym-ec.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ref-ec.s -o ref-ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows sym-native.s -o sym-native.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows ref-native.s -o ref-native.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
+RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:import.dll sym-ec.obj sym-native.obj loadconfig-arm64ec.obj loadconfig-arm64.obj
+
+RUN: lld-link -machine:arm64 -dll -noentry -out:out-arm64.dll ref-native.obj import.dll \
+RUN: -lldmingw -exclude-all-symbols -auto-import:no
+
+RUN: llvm-readobj --coff-imports out-arm64.dll | FileCheck --check-prefix=NATIVE %s
+NATIVE: Import {
+NATIVE-NEXT: Name: import.dll
+NATIVE-NEXT: ImportLookupTableRVA:
+NATIVE-NEXT: ImportAddressTableRVA:
+NATIVE-NEXT: Symbol: native_data (0)
+NATIVE-NEXT: }
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out-arm64ec.dll ref-ec.obj import.dll \
+RUN: loadconfig-arm64ec.obj -lldmingw -exclude-all-symbols -auto-import:no
+
+RUN: llvm-readobj --coff-imports out-arm64ec.dll | FileCheck --check-prefix=EC %s
+EC: Import {
+EC-NEXT: Name: import.dll
+EC-NEXT: ImportLookupTableRVA:
+EC-NEXT: ImportAddressTableRVA:
+EC-NEXT: Symbol: ec_data (0)
+EC-NEXT: }
+
+RUN: lld-link -machine:arm64x -dll -noentry -out:out-arm64x.dll ref-ec.obj ref-native.obj import.dll \
+RUN: loadconfig-arm64ec.obj loadconfig-arm64.obj -lldmingw -exclude-all-symbols -auto-import:no
+
+RUN: llvm-readobj --coff-imports out-arm64x.dll | FileCheck --check-prefix=ARM64X %s
+ARM64X: Import {
+ARM64X-NEXT: Name: import.dll
+ARM64X-NEXT: ImportLookupTableRVA:
+ARM64X-NEXT: ImportAddressTableRVA:
+ARM64X-NEXT: Symbol: native_data (0)
+ARM64X-NEXT: }
+ARM64X-NEXT: HybridObject {
+ARM64X-NEXT: Format: COFF-ARM64EC
+ARM64X-NEXT: Arch: aarch64
+ARM64X-NEXT: AddressSize: 64bit
+ARM64X-NEXT: Import {
+ARM64X-NEXT: Name: import.dll
+ARM64X-NEXT: ImportLookupTableRVA:
+ARM64X-NEXT: ImportAddressTableRVA:
+ARM64X-NEXT: Symbol: ec_data (0)
+ARM64X-NEXT: }
+ARM64X-NEXT: }
+
+#--- sym-ec.s
+ .data
+ .globl ec_data
+ec_data:
+ .word 0
+
+ .section .drectve, "yn"
+ .ascii " -export:ec_data"
+
+#--- sym-native.s
+ .data
+ .globl native_data
+native_data:
+ .word 0
+
+ .section .drectve, "yn"
+ .ascii " -export:native_data"
+
+#--- ref-ec.s
+ .data
+ .rva __imp_ec_data
+
+#--- ref-native.s
+ .data
+ .rva __imp_native_data
``````````
</details>
https://github.com/llvm/llvm-project/pull/210080
More information about the llvm-commits
mailing list