[CPU] Add Windows ARM64 stack-walker

This commit is contained in:
Wunkolo 2024-04-27 17:15:53 -07:00
parent a6d9113b21
commit 1874f0c72f

View file

@ -173,32 +173,62 @@ class Win32StackWalker : public StackWalker {
} else { } else {
// Copy thread context local. We will be modifying it during stack // Copy thread context local. We will be modifying it during stack
// walking, so we don't want to mess with the incoming copy. // 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.Rip = in_host_context->rip;
thread_context.EFlags = in_host_context->eflags; thread_context.EFlags = in_host_context->eflags;
std::memcpy(&thread_context.Rax, in_host_context->int_registers, std::memcpy(&thread_context.Rax, in_host_context->int_registers,
sizeof(in_host_context->int_registers)); sizeof(in_host_context->int_registers));
std::memcpy(&thread_context.Xmm0, in_host_context->xmm_registers, std::memcpy(&thread_context.Xmm0, in_host_context->xmm_registers,
sizeof(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) { if (out_host_context) {
// Write out the captured thread context if the caller asked for it. // 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->rip = thread_context.Rip;
out_host_context->eflags = thread_context.EFlags; out_host_context->eflags = thread_context.EFlags;
std::memcpy(out_host_context->int_registers, &thread_context.Rax, std::memcpy(out_host_context->int_registers, &thread_context.Rax,
sizeof(out_host_context->int_registers)); sizeof(out_host_context->int_registers));
std::memcpy(out_host_context->xmm_registers, &thread_context.Xmm0, std::memcpy(out_host_context->xmm_registers, &thread_context.Xmm0,
sizeof(out_host_context->xmm_registers)); 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. // Setup the frame for walking.
STACKFRAME64 stack_frame = {0}; STACKFRAME64 stack_frame = {0};
stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrPC.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrPC.Offset = thread_context.Rip; stack_frame.AddrPC.Offset = thread_context.Rip;
#elif XE_ARCH_ARM64
stack_frame.AddrPC.Offset = thread_context.Pc;
#endif
stack_frame.AddrFrame.Mode = AddrModeFlat; stack_frame.AddrFrame.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrFrame.Offset = thread_context.Rbp; stack_frame.AddrFrame.Offset = thread_context.Rbp;
#elif XE_ARCH_ARM64
stack_frame.AddrFrame.Offset = thread_context.Fp;
#endif
stack_frame.AddrStack.Mode = AddrModeFlat; stack_frame.AddrStack.Mode = AddrModeFlat;
#if XE_ARCH_AMD64
stack_frame.AddrStack.Offset = thread_context.Rsp; stack_frame.AddrStack.Offset = thread_context.Rsp;
#elif XE_ARCH_ARM64
stack_frame.AddrStack.Offset = thread_context.Sp;
#endif
// Walk the stack. // Walk the stack.
// Note that StackWalk64 is thread safe, though other dbghelp functions are // Note that StackWalk64 is thread safe, though other dbghelp functions are