[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