Module: wine Branch: master Commit: 33e783c5ba8c7b98fd3b078c3b0bf2bf57cbea18 URL: https://gitlab.winehq.org/wine/wine/-/commit/33e783c5ba8c7b98fd3b078c3b0bf2b...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jun 5 08:24:15 2024 +0200
msvcrt: Add platform-specific helpers to retrieve the exception PC.
---
dlls/msvcrt/cppexcept.h | 1 + dlls/msvcrt/except.c | 15 ++++----------- dlls/msvcrt/except_arm.c | 11 +++++++++++ dlls/msvcrt/except_arm64.c | 11 +++++++++++ dlls/msvcrt/except_arm64ec.c | 11 +++++++++++ dlls/msvcrt/except_x86_64.c | 9 +++++++++ 6 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index f6a02c44362..b6f962a62e0 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -284,6 +284,7 @@ extern int handle_fpieee_flt( __msvcrt_ulong exception_code, EXCEPTION_POINTERS #ifndef __i386__ extern void *call_catch_handler( EXCEPTION_RECORD *rec ); extern void *call_unwind_handler( void *func, uintptr_t frame, DISPATCHER_CONTEXT *dispatch ); +extern ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch ); #endif
#if _MSVCR_VER >= 80 diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index 77d10cc7176..374357ed096 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -165,16 +165,9 @@ static void cxx_local_unwind(ULONG_PTR frame, DISPATCHER_CONTEXT *dispatch, { const unwind_info *unwind_table = rtti_rva(descr->unwind_table, dispatch->ImageBase); int *unwind_help = (int *)(frame + descr->unwind_help); - int trylevel; + int trylevel = unwind_help[0];
- if (unwind_help[0] == -2) - { - trylevel = ip_to_state( descr, dispatch->ControlPc, dispatch->ImageBase ); - } - else - { - trylevel = unwind_help[0]; - } + if (trylevel == -2) trylevel = ip_to_state( descr, get_exception_pc(dispatch), dispatch->ImageBase );
TRACE("current level: %d, last level: %d\n", trylevel, last_level); while (trylevel > last_level) @@ -277,7 +270,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context, { ULONG_PTR exc_base = (rec->NumberParameters == 4 ? rec->ExceptionInformation[3] : 0); void *handler, *object = (void *)rec->ExceptionInformation[1]; - int trylevel = ip_to_state( descr, dispatch->ControlPc, dispatch->ImageBase ); + int trylevel = ip_to_state( descr, get_exception_pc(dispatch), dispatch->ImageBase ); thread_data_t *data = msvcrt_get_thread_data(); const tryblock_info *in_catch; EXCEPTION_RECORD catch_record; @@ -378,7 +371,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG_PTR frame, CONTEXT *context, DISPATCHER_CONTEXT *dispatch, const cxx_function_descr *descr) { - int trylevel = ip_to_state( descr, dispatch->ControlPc, dispatch->ImageBase ); + int trylevel = ip_to_state( descr, get_exception_pc(dispatch), dispatch->ImageBase ); cxx_exception_type *exc_type; ULONG_PTR orig_frame = frame; ULONG_PTR throw_base; diff --git a/dlls/msvcrt/except_arm.c b/dlls/msvcrt/except_arm.c index b25bbd32175..b2bf94d5338 100644 --- a/dlls/msvcrt/except_arm.c +++ b/dlls/msvcrt/except_arm.c @@ -73,6 +73,17 @@ void *call_unwind_handler( void *handler, ULONG_PTR frame, DISPATCHER_CONTEXT *d }
+/******************************************************************* + * get_exception_pc + */ +ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch ) +{ + ULONG_PTR pc = dispatch->ControlPc; + if (dispatch->ControlPcIsUnwound) pc -= 2; + return pc; +} + + /********************************************************************* * handle_fpieee_flt */ diff --git a/dlls/msvcrt/except_arm64.c b/dlls/msvcrt/except_arm64.c index d577211503b..6d515f8b150 100644 --- a/dlls/msvcrt/except_arm64.c +++ b/dlls/msvcrt/except_arm64.c @@ -98,6 +98,17 @@ void *call_unwind_handler( void *handler, ULONG_PTR frame, DISPATCHER_CONTEXT *d }
+/******************************************************************* + * get_exception_pc + */ +ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch ) +{ + ULONG_PTR pc = dispatch->ControlPc; + if (dispatch->ControlPcIsUnwound) pc -= 4; + return pc; +} + + /******************************************************************* * _setjmp (MSVCRT.@) */ diff --git a/dlls/msvcrt/except_arm64ec.c b/dlls/msvcrt/except_arm64ec.c index b3af0d7e419..12790cee7d8 100644 --- a/dlls/msvcrt/except_arm64ec.c +++ b/dlls/msvcrt/except_arm64ec.c @@ -117,6 +117,17 @@ void *call_unwind_handler( void *handler, ULONG_PTR frame, DISPATCHER_CONTEXT *d }
+/******************************************************************* + * get_exception_pc + */ +ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch ) +{ + ULONG_PTR pc = dispatch->ControlPc; + if (RtlIsEcCode( pc ) && ((DISPATCHER_CONTEXT_ARM64EC *)dispatch)->ControlPcIsUnwound) pc -= 4; + return pc; +} + + /********************************************************************* * handle_fpieee_flt */ diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 26eeb542f0f..1c3cc62bc7f 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -78,6 +78,15 @@ void *call_unwind_handler( void *handler, ULONG_PTR frame, DISPATCHER_CONTEXT *d }
+/******************************************************************* + * get_exception_pc + */ +ULONG_PTR get_exception_pc( DISPATCHER_CONTEXT *dispatch ) +{ + return dispatch->ControlPc; +} + + /******************************************************************* * longjmp (MSVCRT.@) */