From 1874f0c72f33ce0d677a78e4e6cbaf5185a82ec3 Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Sat, 27 Apr 2024 17:15:53 -0700 Subject: [PATCH] [CPU] Add Windows ARM64 stack-walker --- src/xenia/cpu/stack_walker_win.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/xenia/cpu/stack_walker_win.cc b/src/xenia/cpu/stack_walker_win.cc index aaaab140a..2fe8470c4 100644 --- a/src/xenia/cpu/stack_walker_win.cc +++ b/src/xenia/cpu/stack_walker_win.cc @@ -173,32 +173,62 @@ class Win32StackWalker : public StackWalker { } else { // Copy thread context local. We will be modifying it during stack // walking, so we don't want to mess with the incoming copy. +#if XE_ARCH_AMD64 thread_context.Rip = in_host_context->rip; thread_context.EFlags = in_host_context->eflags; std::memcpy(&thread_context.Rax, in_host_context->int_registers, sizeof(in_host_context->int_registers)); std::memcpy(&thread_context.Xmm0, in_host_context->xmm_registers, sizeof(in_host_context->xmm_registers)); +#elif XE_ARCH_ARM64 + thread_context.Pc = in_host_context->pc; + thread_context.Cpsr = in_host_context->cpsr; + std::memcpy(thread_context.X, in_host_context->x, + sizeof(in_host_context->x)); + std::memcpy(&thread_context.V, in_host_context->v, + sizeof(in_host_context->v)); +#endif } if (out_host_context) { // Write out the captured thread context if the caller asked for it. +#if XE_ARCH_AMD64 out_host_context->rip = thread_context.Rip; out_host_context->eflags = thread_context.EFlags; std::memcpy(out_host_context->int_registers, &thread_context.Rax, sizeof(out_host_context->int_registers)); std::memcpy(out_host_context->xmm_registers, &thread_context.Xmm0, sizeof(out_host_context->xmm_registers)); +#elif XE_ARCH_ARM64 + out_host_context->pc = thread_context.Pc; + out_host_context->cpsr = thread_context.Cpsr; + std::memcpy(out_host_context->x, &thread_context.X, + sizeof(out_host_context->x)); + std::memcpy(out_host_context->v, &thread_context.V, + sizeof(out_host_context->v)); +#endif } // Setup the frame for walking. STACKFRAME64 stack_frame = {0}; stack_frame.AddrPC.Mode = AddrModeFlat; +#if XE_ARCH_AMD64 stack_frame.AddrPC.Offset = thread_context.Rip; +#elif XE_ARCH_ARM64 + stack_frame.AddrPC.Offset = thread_context.Pc; +#endif stack_frame.AddrFrame.Mode = AddrModeFlat; +#if XE_ARCH_AMD64 stack_frame.AddrFrame.Offset = thread_context.Rbp; +#elif XE_ARCH_ARM64 + stack_frame.AddrFrame.Offset = thread_context.Fp; +#endif stack_frame.AddrStack.Mode = AddrModeFlat; +#if XE_ARCH_AMD64 stack_frame.AddrStack.Offset = thread_context.Rsp; +#elif XE_ARCH_ARM64 + stack_frame.AddrStack.Offset = thread_context.Sp; +#endif // Walk the stack. // Note that StackWalk64 is thread safe, though other dbghelp functions are