-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libunwind] Add initial ARM64EC support #138583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ARM64EC defines __x86_64__, which is sufficient to make most C/C++ code behave correctly. To preserve an external ABI compatible with x86_64, this patch uses the x86_64 context layout and implements unw_getcontext by storing the appropriate aarch64 registers according to the mapping defined by the ARM64EC ABI.
@llvm/pr-subscribers-libunwind Author: Jacek Caban (cjacek) ChangesARM64EC defines Full diff: https://github.com/llvm/llvm-project/pull/138583.diff 2 Files Affected:
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index 1702d016c368b..5e199188945df 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -66,7 +66,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
# skip fs
# skip gs
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) && !defined(__arm64ec__)
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)
#
diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index a489a8ba6df15..12fd81d49299b 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -65,6 +65,53 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
xorl %eax, %eax # return UNW_ESUCCESS
ret
+#elif defined(__arm64ec__)
+
+//
+// extern int __unw_getcontext(unw_context_t* thread_state)
+//
+// On entry:
+// thread_state pointer is in x0
+//
+ .section .text,"xr",discard,"#__unw_getcontext"
+ .p2align 2
+DEFINE_LIBUNWIND_FUNCTION("#__unw_getcontext")
+ stp x8, x27, [x0, #0x000] // rax, rbx
+ stp x0, x1, [x0, #0x010] // rcx, rdx
+ stp x26,x25, [x0, #0x020] // rdi, rsi
+ mov x1, sp
+ stp fp, x1, [x0, #0x030] // rbp, rsp
+ stp x2, x3, [x0, #0x040] // r8, r9
+ stp x4, x5, [x0, #0x050] // r10, r11
+ stp x19,x20, [x0, #0x060] // r12, r13
+ stp x21,x22, [x0, #0x070] // r14, r15
+ str x30, [x0, #0x080] // store return address as pc
+ stp q0, q1, [x0, #0x0b0] // xmm0, xmm1
+ stp q2, q3, [x0, #0x0d0] // xmm2, xmm3
+ stp q4, q5, [x0, #0x0f0] // xmm4, xmm5
+ stp q6, q7, [x0, #0x110] // xmm6, xmm7
+ stp q8, q9, [x0, #0x130] // xmm8, xmm9
+ stp q10,q11, [x0, #0x150] // xmm10,xmm11
+ stp q12,q13, [x0, #0x170] // xmm12,xmm13
+ stp q14,q15, [x0, #0x190] // xmm14,xmm15
+ mov x0, #0 // return UNW_ESUCCESS
+ ret
+
+ .globl "#unw_getcontext"
+ .set "#unw_getcontext", "#__unw_getcontext"
+ .weak_anti_dep __unw_getcontext
+ .set __unw_getcontext, "#__unw_getcontext"
+ .weak_anti_dep unw_getcontext
+ .set unw_getcontext, "#unw_getcontext"
+
+ .section .hybmp$x,"yi"
+ .symidx "#__unw_getcontext"
+ .symidx $ientry_thunk$cdecl$i8$i8
+ .word 1
+ .text
+
+ EXPORT_SYMBOL(unw_getcontext)
+
#elif defined(__x86_64__)
#
@@ -1181,7 +1228,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
#endif
+#ifndef __arm64ec__
WEAK_ALIAS(__unw_getcontext, unw_getcontext)
+#endif
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */
|
This is enough to pass most tests, except for forced unwind. I suspect that test requires a similar change to #137949. ARM64EC modules can contain SEH in both x86_64 format (for x86_64 code, accessible through PE headers, this should already work) and ARM format (for ARM64 code, accessible through CHPE metadata, which is not yet implemented). I haven’t looked into that part in detail yet.
Due to the additional requirements for symbol mangling and unmangled aliases on ARM64EC, the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Quite amazing if this is the only change needed, if the existing #ifdef __x86_64__
work as needed here (except for the force unwinding tests).
ARM64EC defines
__x86_64__
, which is sufficient to make most C/C++ code behave correctly. To preserve an external ABI compatible with x86_64, this patch uses the x86_64 context layout and implementsunw_getcontext
by storing the appropriate aarch64 registers according to the mapping defined by the ARM64EC ABI.