[lld] [LLD][COFF] Initial support for ARM64EC importlibs. (PR #107164)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 4 03:38:25 PDT 2024
https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/107164
>From 575cc03b0df8185d3cc09ed9faa43c557ebdce27 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Thu, 7 Sep 2023 00:51:40 +0200
Subject: [PATCH] [LLD][COFF] Initial support for ARM64EC importlibs.
Use demangled symbol name for __imp_ symbols and define demangled thunk
symbol as AMD64 thunk.
---
lld/COFF/InputFiles.cpp | 23 +++++++++--
lld/test/COFF/arm64ec-import.test | 68 +++++++++++++++++++++++++++++++
2 files changed, 87 insertions(+), 4 deletions(-)
create mode 100644 lld/test/COFF/arm64ec-import.test
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 50bc62312a6f87..fa2d230075d9d3 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -25,6 +25,7 @@
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
@@ -1019,9 +1020,17 @@ void ImportFile::parse() {
// Read names and create an __imp_ symbol.
StringRef buf = mb.getBuffer().substr(sizeof(*hdr));
- StringRef name = saver().save(buf.split('\0').first);
+ auto split = buf.split('\0');
+ buf = split.second;
+ StringRef name;
+ if (isArm64EC(hdr->Machine)) {
+ if (std::optional<std::string> demangledName =
+ getArm64ECDemangledFunctionName(split.first))
+ name = saver().save(*demangledName);
+ }
+ if (name.empty())
+ name = saver().save(split.first);
StringRef impName = saver().save("__imp_" + name);
- buf = buf.substr(name.size() + 1);
dllName = buf.split('\0').first;
StringRef extName;
switch (hdr->getNameType()) {
@@ -1058,8 +1067,14 @@ void ImportFile::parse() {
// 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 (hdr->getType() == llvm::COFF::IMPORT_CODE)
- thunkSym = ctx.symtab.addImportThunk(name, impSym, hdr->Machine);
+ if (hdr->getType() == llvm::COFF::IMPORT_CODE) {
+ if (ctx.config.machine != ARM64EC) {
+ thunkSym = ctx.symtab.addImportThunk(name, impSym, hdr->Machine);
+ } else {
+ thunkSym = ctx.symtab.addImportThunk(name, impSym, AMD64);
+ // FIXME: Add aux IAT symbols.
+ }
+ }
}
BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,
diff --git a/lld/test/COFF/arm64ec-import.test b/lld/test/COFF/arm64ec-import.test
new file mode 100644
index 00000000000000..2a80a30910b5c7
--- /dev/null
+++ b/lld/test/COFF/arm64ec-import.test
@@ -0,0 +1,68 @@
+REQUIRES: aarch64, x86
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
+RUN: llvm-lib -machine:arm64ec -def:test.def -out:test-arm64ec.lib
+RUN: llvm-lib -machine:arm64ec -def:test2.def -out:test2-arm64ec.lib
+RUN: llvm-lib -machine:x64 -def:test.def -out:test-x86_64.lib
+
+Link using ARM64EC import library:
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj \
+RUN: test.obj test-arm64ec.lib test2-arm64ec.lib
+
+Link using x86_64 import library:
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out2.dll loadconfig-arm64ec.obj \
+RUN: test.obj test-x86_64.lib test2-arm64ec.lib
+
+RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
+RUN: llvm-readobj --coff-imports out2.dll | FileCheck --check-prefix=IMPORTS %s
+IMPORTS: Import {
+IMPORTS-NEXT: Name: test.dll
+IMPORTS-NEXT: ImportLookupTableRVA:
+IMPORTS-NEXT: ImportAddressTableRVA: 0x2258
+IMPORTS-NEXT: Symbol: data (0)
+IMPORTS-NEXT: Symbol: func (0)
+IMPORTS-NEXT: Symbol: func2 (0)
+IMPORTS-NEXT: }
+IMPORTS-NEXT: Import {
+IMPORTS-NEXT: Name: test2.dll
+IMPORTS-NEXT: ImportLookupTableRVA:
+IMPORTS-NEXT: ImportAddressTableRVA: 0x2278
+IMPORTS-NEXT: Symbol: t2func (0)
+IMPORTS-NEXT: }
+
+RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
+RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM %s
+
+DISASM: 0000000180001000 <.text>:
+DISASM-NEXT: 180001000: ff 25 5a 12 00 00 jmpq *0x125a(%rip) # 0x180002260
+
+RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
+RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC %s
+TESTSEC: 0x180004000 60220000 58220000 68220000 78220000
+TESTSEC-NEXT: 0x180004010 00100000
+
+#--- test.s
+ .section .test, "r"
+ .globl arm64ec_data_sym
+ .p2align 2, 0x0
+arm64ec_data_sym:
+ .rva __imp_func
+ .rva __imp_data
+ .rva __imp_func2
+ .rva __imp_t2func
+ .rva func
+
+#--- test.def
+NAME test.dll
+EXPORTS
+ data DATA
+ func
+ func2
+ unused_func
+
+#--- test2.def
+NAME test2.dll
+EXPORTS
+ t2func
More information about the llvm-commits
mailing list