Module: wine Branch: master Commit: 356be34dcd2b1acfaa55c5d896b06a2628d41dfe URL: https://gitlab.winehq.org/wine/wine/-/commit/356be34dcd2b1acfaa55c5d896b06a2...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Jun 7 10:19:57 2024 +0200
msvcrt: Reimplement __crtCapturePreviousContext() based on RtlWalkFrameChain().
---
dlls/msvcrt/except_arm64ec.c | 20 +++++++++++++++++++- dlls/msvcrt/except_x86_64.c | 36 ++++++++++++++---------------------- 2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/dlls/msvcrt/except_arm64ec.c b/dlls/msvcrt/except_arm64ec.c index 12790cee7d8..b2e723f79b3 100644 --- a/dlls/msvcrt/except_arm64ec.c +++ b/dlls/msvcrt/except_arm64ec.c @@ -144,7 +144,25 @@ int handle_fpieee_flt( __msvcrt_ulong exception_code, EXCEPTION_POINTERS *ep, */ void __cdecl __crtCapturePreviousContext( CONTEXT *ctx ) { - FIXME("not implemented\n"); + UNWIND_HISTORY_TABLE table; + RUNTIME_FUNCTION *func; + PEXCEPTION_ROUTINE handler; + ULONG_PTR pc, frame, base; + void *data; + ULONG i; + + RtlCaptureContext( ctx ); + for (i = 0; i < 2; i++) + { + pc = ctx->Rip; + if ((ctx->ContextFlags & CONTEXT_UNWOUND_TO_CALL) && RtlIsEcCode( pc )) pc -= 4; + if (!(func = RtlLookupFunctionEntry( pc, &base, &table ))) break; + if (RtlVirtualUnwind2( UNW_FLAG_NHANDLER, base, pc, func, ctx, NULL, + &data, &frame, NULL, NULL, NULL, &handler, 0 )) + break; + if (!ctx->Rip) break; + if (!frame) break; + } } #endif
diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 1c3cc62bc7f..e0fda975be4 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -133,33 +133,25 @@ int handle_fpieee_flt( __msvcrt_ulong exception_code, EXCEPTION_POINTERS *ep, /********************************************************************* * __crtCapturePreviousContext (MSVCR110.@) */ -void __cdecl get_prev_context(CONTEXT *ctx, DWORD64 rip) +void __cdecl __crtCapturePreviousContext( CONTEXT *ctx ) { - ULONG64 frame, image_base; - RUNTIME_FUNCTION *rf; + UNWIND_HISTORY_TABLE table; + RUNTIME_FUNCTION *func; + PEXCEPTION_ROUTINE handler; + ULONG_PTR frame, base; void *data; + ULONG i;
- TRACE("(%p)\n", ctx); - - rf = RtlLookupFunctionEntry(ctx->Rip, &image_base, NULL); - if(!rf) { - FIXME("RtlLookupFunctionEntry failed\n"); - return; + RtlCaptureContext( ctx ); + for (i = 0; i < 2; i++) + { + if (!(func = RtlLookupFunctionEntry( ctx->Rip, &base, &table ))) break; + if (RtlVirtualUnwind2( UNW_FLAG_NHANDLER, base, ctx->Rip, func, ctx, NULL, + &data, &frame, NULL, NULL, NULL, &handler, 0 )) break; + if (!ctx->Rip) break; + if (!frame) break; } - - RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, ctx->Rip, - rf, ctx, &data, &frame, NULL); } - -__ASM_GLOBAL_FUNC( __crtCapturePreviousContext, - "movq %rcx,8(%rsp)\n\t" - "call " __ASM_NAME("RtlCaptureContext") "\n\t" - "movq 8(%rsp),%rcx\n\t" /* context */ - "leaq 8(%rsp),%rax\n\t" - "movq %rax,0x98(%rcx)\n\t" /* context->Rsp */ - "movq (%rsp),%rax\n\t" - "movq %rax,0xf8(%rcx)\n\t" /* context->Rip */ - "jmp " __ASM_NAME("get_prev_context") ) #endif
#endif /* __x86_64__ */