[llvm] [llvm-dlltool] Add ARM64EC target support. (PR #81624)

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 14 04:04:41 PST 2024


https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/81624

>From 2697c69bff7457a100194133c8cb0cc5239472e0 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 17 Oct 2023 13:48:26 +0200
Subject: [PATCH] [llvm-dlltool] Add ARM64EC target support.

Adds new target and a new -n option allowing to specify native module
definition file, similar to how -defArm64Native works in llvm-lib.
This also changes archive format to use K_COFF like non-mingw targets.
It's required on ARM64EC, but it should be fine for other targets too.
---
 llvm/lib/Object/COFFImportFile.cpp            |  2 +-
 .../llvm-dlltool/DlltoolDriver.cpp            | 22 +++++++--
 llvm/lib/ToolDrivers/llvm-dlltool/Options.td  |  3 ++
 llvm/test/tools/llvm-dlltool/arm64ec.test     | 46 +++++++++++++++++++
 4 files changed, 68 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/tools/llvm-dlltool/arm64ec.test

diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index f6f6cf2a1602cf..376dd126baf61a 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -712,7 +712,7 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
     return e;
 
   return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,
-                      MinGW ? object::Archive::K_GNU : object::Archive::K_COFF,
+                      object::Archive::K_COFF,
                       /*Deterministic*/ true, /*Thin*/ false,
                       /*OldArchiveBuf*/ nullptr, isArm64EC(Machine));
 }
diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
index 98795c51ce1336..fa716a281a69fc 100644
--- a/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
@@ -75,6 +75,7 @@ MachineTypes getEmulation(StringRef S) {
       .Case("i386:x86-64", IMAGE_FILE_MACHINE_AMD64)
       .Case("arm", IMAGE_FILE_MACHINE_ARMNT)
       .Case("arm64", IMAGE_FILE_MACHINE_ARM64)
+      .Case("arm64ec", IMAGE_FILE_MACHINE_ARM64EC)
       .Default(IMAGE_FILE_MACHINE_UNKNOWN);
 }
 
@@ -87,7 +88,8 @@ MachineTypes getMachine(Triple T) {
   case Triple::arm:
     return COFF::IMAGE_FILE_MACHINE_ARMNT;
   case Triple::aarch64:
-    return COFF::IMAGE_FILE_MACHINE_ARM64;
+    return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC
+                                : COFF::IMAGE_FILE_MACHINE_ARM64;
   default:
     return COFF::IMAGE_FILE_MACHINE_UNKNOWN;
   }
@@ -168,7 +170,7 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
       (!Args.hasArgNoClaim(OPT_d) && !Args.hasArgNoClaim(OPT_l))) {
     Table.printHelp(outs(), "llvm-dlltool [options] file...", "llvm-dlltool",
                     false);
-    llvm::outs() << "\nTARGETS: i386, i386:x86-64, arm, arm64\n";
+    llvm::outs() << "\nTARGETS: i386, i386:x86-64, arm, arm64, arm64ec\n";
     return 1;
   }
 
@@ -201,7 +203,19 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
   if (auto *Arg = Args.getLastArg(OPT_D))
     OutputFile = Arg->getValue();
 
-  std::vector<COFFShortExport> Exports;
+  std::vector<COFFShortExport> Exports, NativeExports;
+
+  if (Args.hasArg(OPT_n)) {
+    if (!isArm64EC(Machine)) {
+      llvm::errs() << "native .def file is supported only on arm64ec target\n";
+      return 1;
+    }
+    if (!parseModuleDefinition(Args.getLastArg(OPT_n)->getValue(),
+                               IMAGE_FILE_MACHINE_ARM64, AddUnderscores,
+                               NativeExports, OutputFile))
+      return 1;
+  }
+
   if (!parseModuleDefinition(Args.getLastArg(OPT_d)->getValue(), Machine,
                              AddUnderscores, Exports, OutputFile))
     return 1;
@@ -230,7 +244,7 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
 
   std::string Path = std::string(Args.getLastArgValue(OPT_l));
   if (!Path.empty() && writeImportLibrary(OutputFile, Path, Exports, Machine,
-                                          /*MinGW=*/true))
+                                          /*MinGW=*/true, NativeExports))
     return 1;
   return 0;
 }
diff --git a/llvm/lib/ToolDrivers/llvm-dlltool/Options.td b/llvm/lib/ToolDrivers/llvm-dlltool/Options.td
index fee408fd0e9a80..ba94aed067e6ad 100644
--- a/llvm/lib/ToolDrivers/llvm-dlltool/Options.td
+++ b/llvm/lib/ToolDrivers/llvm-dlltool/Options.td
@@ -12,6 +12,9 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias<D>;
 def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">;
 def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
 
+def n: JoinedOrSeparate<["-"], "n">, HelpText<"Input native .def File on ARM64EC">;
+def n_long : JoinedOrSeparate<["--"], "input-native-def">, Alias<d>;
+
 def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
 def k_alias: Flag<["--"], "kill-at">, Alias<k>;
 
diff --git a/llvm/test/tools/llvm-dlltool/arm64ec.test b/llvm/test/tools/llvm-dlltool/arm64ec.test
new file mode 100644
index 00000000000000..77cef16a5fb193
--- /dev/null
+++ b/llvm/test/tools/llvm-dlltool/arm64ec.test
@@ -0,0 +1,46 @@
+Test creating ARM64EC importlib.
+
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-dlltool -m arm64ec -d test.def -l test.lib
+RUN: llvm-nm --print-armap test.lib | FileCheck --check-prefix=ARMAP %s
+
+ARMAP:      Archive map
+ARMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
+ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
+ARMAP-EMPTY:
+ARMAP-NEXT: Archive EC map
+ARMAP-NEXT: #func in test.dll
+ARMAP-NEXT: __imp_aux_func in test.dll
+ARMAP-NEXT: __imp_func in test.dll
+ARMAP-NEXT: func in test.dll
+
+RUN: llvm-dlltool -m arm64ec -d test.def -n test2.def -l test2.lib
+RUN: llvm-nm --print-armap test2.lib | FileCheck --check-prefix=ARMAP2 %s
+
+ARMAP2:      Archive map
+ARMAP2-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAP2-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
+ARMAP2-NEXT: __imp_otherfunc in test.dll
+ARMAP2-NEXT: otherfunc in test.dll
+ARMAP2-NEXT: test_NULL_THUNK_DATA in test.dll
+ARMAP2-EMPTY:
+ARMAP2-NEXT: Archive EC map
+ARMAP2-NEXT: #func in test.dll
+ARMAP2-NEXT: __imp_aux_func in test.dll
+ARMAP2-NEXT: __imp_func in test.dll
+ARMAP2-NEXT: func in test.dll
+
+RUN: not llvm-dlltool -m arm64 -d test.def -n test2.def -l test2.lib 2>&1 | FileCheck --check-prefix=ERR %s
+ERR: native .def file is supported only on arm64ec target
+
+#--- test.def
+LIBRARY test.dll
+EXPORTS
+    func
+
+#--- test2.def
+LIBRARY test.dll
+EXPORTS
+    otherfunc



More information about the llvm-commits mailing list