[llvm] [CodeGen][ARM64EC] Define hybrid_patchable EXP thunk symbol as a function. (PR #102898)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 12 06:19:15 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Jacek Caban (cjacek)
<details>
<summary>Changes</summary>
This is needed for MSVC link.exe to generate redirection metadata for hybrid patchable thunks.
I noticed this while working on LLD support for this. Redirection metadata is a part of CHPE metadata generated by the linker. It's undocumented, but I briefly documented my findings [here](https://wiki.winehq.org/ARM64ECToolchain#x86_64_thunks). Its logic seems to be separate from generating thunks themselves in the linker. While for export thunks any unresolved `EXP+...` symbol is sufficient, redirection metadata logic is more strict and, according to my experiments, function symbol type is important and enough to make it work.
There is a different logic for exported symbols, those already work fine with hybrid patchable functions, but for a different reason. I think that in practice that metadata is not actually needed for functions that are not exported. Call checkers don't need it, it's probably mostly used for auxiliary IAT handling. If that's right, then this fix won't change much in practice. But since it's undocumented, I can't be sure so I think it's better to just get it right and make sure that generated metadata matches what would be seen with MSVC.
---
Full diff: https://github.com/llvm/llvm-project/pull/102898.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+7)
- (modified) llvm/test/CodeGen/AArch64/arm64ec-hybrid-patchable.ll (+20-4)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 0391d518324315..b8f9b58a216446 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -1310,6 +1310,13 @@ void AArch64AsmPrinter::emitGlobalAlias(const Module &M,
StringRef ExpStr = cast<MDString>(Node->getOperand(0))->getString();
MCSymbol *ExpSym = MMI->getContext().getOrCreateSymbol(ExpStr);
MCSymbol *Sym = MMI->getContext().getOrCreateSymbol(GA.getName());
+
+ OutStreamer->beginCOFFSymbolDef(ExpSym);
+ OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);
+ OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+ << COFF::SCT_COMPLEX_TYPE_SHIFT);
+ OutStreamer->endCOFFSymbolDef();
+
OutStreamer->beginCOFFSymbolDef(Sym);
OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);
OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-hybrid-patchable.ll b/llvm/test/CodeGen/AArch64/arm64ec-hybrid-patchable.ll
index 64fb5b36b2c623..1ed6a273338abb 100644
--- a/llvm/test/CodeGen/AArch64/arm64ec-hybrid-patchable.ll
+++ b/llvm/test/CodeGen/AArch64/arm64ec-hybrid-patchable.ll
@@ -240,6 +240,10 @@ define dso_local void @caller() nounwind {
; CHECK-NEXT: .section .drectve,"yni"
; CHECK-NEXT: .ascii " /EXPORT:exp"
+; CHECK-NEXT: .def "EXP+#func";
+; CHECK-NEXT: .scl 2;
+; CHECK-NEXT: .type 32;
+; CHECK-NEXT: .endef
; CHECK-NEXT: .def func;
; CHECK-NEXT: .scl 2;
; CHECK-NEXT: .type 32;
@@ -252,6 +256,10 @@ define dso_local void @caller() nounwind {
; CHECK-NEXT: .type 32;
; CHECK-NEXT: .endef
; CHECK-NEXT: .set "#func", "#func$hybpatch_thunk"{{$}}
+; CHECK-NEXT: .def "EXP+#has_varargs";
+; CHECK-NEXT: .scl 2;
+; CHECK-NEXT: .type 32;
+; CHECK-NEXT: .endef
; CHECK-NEXT: .def has_varargs;
; CHECK-NEXT: .scl 2;
; CHECK-NEXT: .type 32;
@@ -264,6 +272,10 @@ define dso_local void @caller() nounwind {
; CHECK-NEXT: .type 32;
; CHECK-NEXT: .endef
; CHECK-NEXT: .set "#has_varargs", "#has_varargs$hybpatch_thunk"
+; CHECK-NEXT: .def "EXP+#has_sret";
+; CHECK-NEXT: .scl 2;
+; CHECK-NEXT: .type 32;
+; CHECK-NEXT: .endef
; CHECK-NEXT: .def has_sret;
; CHECK-NEXT: .scl 2;
; CHECK-NEXT: .type 32;
@@ -276,6 +288,10 @@ define dso_local void @caller() nounwind {
; CHECK-NEXT: .type 32;
; CHECK-NEXT: .endef
; CHECK-NEXT: .set "#has_sret", "#has_sret$hybpatch_thunk"
+; CHECK-NEXT: .def "EXP+#exp";
+; CHECK-NEXT: .scl 2;
+; CHECK-NEXT: .type 32;
+; CHECK-NEXT: .endef
; CHECK-NEXT: .def exp;
; CHECK-NEXT: .scl 2;
; CHECK-NEXT: .type 32;
@@ -295,18 +311,18 @@ define dso_local void @caller() nounwind {
; SYM: [78](sec 20)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 #exp$hybpatch_thunk
; SYM: [110](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 func
; SYM-NEXT: AUX indx 112 srch 3
-; SYM-NEXT: [112](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 EXP+#func
+; SYM-NEXT: [112](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 EXP+#func
; SYM: [116](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 #func
; SYM-NEXT: AUX indx 53 srch 3
; SYM: [122](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 has_varargs
; SYM-NEXT: AUX indx 124 srch 3
-; SYM-NEXT: [124](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 EXP+#has_varargs
+; SYM-NEXT: [124](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 EXP+#has_varargs
; SYM-NEXT: [125](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 has_sret
; SYM-NEXT: AUX indx 127 srch 3
-; SYM-NEXT: [127](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 EXP+#has_sret
+; SYM-NEXT: [127](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 EXP+#has_sret
; SYM-NEXT: [128](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 exp
; SYM-NEXT: AUX indx 130 srch 3
-; SYM-NEXT: [130](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 EXP+#exp
+; SYM-NEXT: [130](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 EXP+#exp
; SYM-NEXT: [131](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 #has_varargs
; SYM-NEXT: AUX indx 58 srch 3
; SYM-NEXT: [133](sec 0)(fl 0x00)(ty 0)(scl 69) (nx 1) 0x00000000 #has_sret
``````````
</details>
https://github.com/llvm/llvm-project/pull/102898
More information about the llvm-commits
mailing list