[lld] [llvm] [LLD][COFF] Allow overriding EC alias symbols with alternate names (PR #113456)

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 24 02:05:53 PDT 2024


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

>From a063406afe04e43b9c7957b8e712dfd298dbaa14 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 18 Sep 2023 19:21:21 +0200
Subject: [PATCH] [LLD][COFF] Allow overriding EC alias symbols with alternate
 names

---
 lld/COFF/Driver.cpp              |  16 ++++-
 lld/test/COFF/arm64ec-altnames.s | 109 +++++++++++++++++++++++++++++++
 llvm/include/llvm/IR/Mangler.h   |   6 ++
 3 files changed, 128 insertions(+), 3 deletions(-)
 create mode 100644 lld/test/COFF/arm64ec-altnames.s

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e7f768789271fa..08c1476a595f64 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2518,9 +2518,19 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
         Symbol *sym = ctx.symtab.find(from);
         if (!sym)
           continue;
-        if (auto *u = dyn_cast<Undefined>(sym))
-          if (!u->weakAlias)
-            u->setWeakAlias(ctx.symtab.addUndefined(to));
+        if (auto *u = dyn_cast<Undefined>(sym)) {
+          if (u->weakAlias) {
+            // On ARM64EC, anti-dependency aliases are treated as undefined
+            // symbols unless a demangled symbol aliases a defined one, which is
+            // part of the implementation.
+            if (!isArm64EC(ctx.config.machine) || !u->isAntiDep)
+              continue;
+            if (!isa<Undefined>(u->weakAlias) &&
+                !isArm64ECMangledFunctionName(u->getName()))
+              continue;
+          }
+          u->setWeakAlias(ctx.symtab.addUndefined(to));
+        }
       }
 
       // If any inputs are bitcode files, the LTO code generator may create
diff --git a/lld/test/COFF/arm64ec-altnames.s b/lld/test/COFF/arm64ec-altnames.s
new file mode 100644
index 00000000000000..fb28ae15895f98
--- /dev/null
+++ b/lld/test/COFF/arm64ec-altnames.s
@@ -0,0 +1,109 @@
+REQUIRES: aarch64
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext.s -o ext.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl.s -o impl.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl-cpp.s -o impl-cpp.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig.obj
+
+# Ensure -alternatename can change a mangled function symbol aliasing a defined symbol (typically a guest exit thunk).
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out1.dll ext.obj loadconfig.obj "-alternatename:#func=altsym"
+
+RUN: llvm-objdump -d out1.dll | FileCheck --check-prefix=DISASM %s
+DISASM:      0000000180001000 <.text>:
+DISASM-NEXT: 180001000: 52800020     mov     w0, #0x1                // =1
+DISASM-NEXT: 180001004: d65f03c0     ret
+DISASM-NOT: .thnk
+
+RUN: llvm-readobj --hex-dump=.test out1.dll | FileCheck --check-prefix=TESTSEC %s
+TESTSEC: 0x180004000 00100000 00100000
+
+# Ensure -alternatename can change a demangled function symbol aliasing an anti-dependency symbol.
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out2.dll ext.obj loadconfig.obj -alternatename:func=altsym
+
+RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM2 %s
+DISASM2:      Disassembly of section .text:
+DISASM2-EMPTY:
+DISASM2-NEXT: 0000000180001000 <.text>:
+DISASM2-NEXT: 180001000: 52800020     mov     w0, #0x1                // =1
+DISASM2-NEXT: 180001004: d65f03c0     ret
+DISASM2-EMPTY:
+DISASM2-NEXT: Disassembly of section .thnk:
+DISASM2-EMPTY:
+DISASM2-NEXT: 0000000180005000 <.thnk>:
+DISASM2-NEXT: 180005000: 52800040     mov     w0, #0x2                // =2
+DISASM2-NEXT: 180005004: d65f03c0     ret
+
+RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC2 %s
+TESTSEC2: 0x180004000 00100000 00500000
+
+# Ensure -alternatename cannot modify a demangled function symbol aliasing a defined symbol.
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out3.dll impl.obj loadconfig.obj -alternatename:func=altsym
+RUN: llvm-objdump -d out3.dll | FileCheck --check-prefix=DISASM %s
+RUN: llvm-readobj --hex-dump=.test out3.dll | FileCheck --check-prefix=TESTSEC %s
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out4.dll impl-cpp.obj loadconfig.obj -alternatename:func=altsym
+RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s
+RUN: llvm-readobj --hex-dump=.test out4.dll | FileCheck --check-prefix=TESTSEC %s
+
+#--- ext.s
+        .weak_anti_dep func
+.set func, "#func"
+        .weak_anti_dep "#func"
+.set "#func", thunksym
+
+        .section .test, "r"
+        .rva func
+        .rva "#func"
+
+        .section .thnk,"xr",discard,thunksym
+thunksym:
+        mov w0, #2
+        ret
+
+        .section .text,"xr",discard,altsym
+        .globl altsym
+altsym:
+        mov w0, #1
+        ret
+
+#--- impl.s
+        .weak_anti_dep func
+.set func, "#func"
+
+        .section .test, "r"
+        .rva func
+        .rva "#func"
+
+        .section .text,"xr",discard,"#func"
+"#func":
+        mov w0, #1
+        ret
+
+        .section .text,"xr",discard,altsym
+        .globl altsym
+altsym:
+        mov w0, #2
+        ret
+
+#--- impl-cpp.s
+        .weak_anti_dep func
+.set func, "?func@@$$hYAXXZ"
+
+        .section .test, "r"
+        .rva func
+        .rva "?func@@$$hYAXXZ"
+
+        .section .text,"xr",discard,"?func@@$$hYAXXZ"
+"?func@@$$hYAXXZ":
+        mov w0, #1
+        ret
+
+        .section .text,"xr",discard,altsym
+        .globl altsym
+altsym:
+        mov w0, #2
+        ret
diff --git a/llvm/include/llvm/IR/Mangler.h b/llvm/include/llvm/IR/Mangler.h
index 349f9e6e752339..3c3f0c6dce80fa 100644
--- a/llvm/include/llvm/IR/Mangler.h
+++ b/llvm/include/llvm/IR/Mangler.h
@@ -61,6 +61,12 @@ std::optional<std::string> getArm64ECMangledFunctionName(StringRef Name);
 /// mangled.
 std::optional<std::string> getArm64ECDemangledFunctionName(StringRef Name);
 
+/// Check if an ARM64EC function name is mangled.
+bool inline isArm64ECMangledFunctionName(StringRef Name) {
+  return Name[0] == '#' ||
+         (Name[0] == '?' && Name.find("$$h") != StringRef::npos);
+}
+
 } // End llvm namespace
 
 #endif



More information about the llvm-commits mailing list