Module: wine
Branch: master
Commit: 1fb4ce83f409539da74d994f5a37ed839ef6e9c0
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1fb4ce83f409539da74d994f…
Author: Martin Storsjö <martin(a)martin.st>
Date: Mon Nov 15 16:02:09 2021 +0200
ntdll: Subtract an offset from pc if dispatch->ControlPcIsUnwound on arm.
This fixes unwinding from functions ending with a call to a function
that won't return. This matches what is done on the PE side in the
call to lookup_function_info.
Signed-off-by: Martin Storsjö <martin(a)martin.st>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/ntdll/unix/signal_arm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 2017cf150db..ebc08984adf 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -229,7 +229,7 @@ extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, void
NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, CONTEXT *context )
{
#ifdef HAVE_LIBUNWIND
- DWORD ip = context->Pc;
+ DWORD ip = context->Pc - (dispatch->ControlPcIsUnwound ? 2 : 0);
unw_context_t unw_context;
unw_cursor_t cursor;
unw_proc_info_t info;
Module: wine
Branch: master
Commit: d00c897749a06a5fe24e8e6d09acb5dc735469bf
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d00c897749a06a5fe24e8e6d…
Author: Martin Storsjö <martin(a)martin.st>
Date: Mon Nov 15 16:02:08 2021 +0200
ntdll: Error out if unwinding isn't progressing on arm.
In PE builds of wine, there's no unwind info (as LLVM hasn't
implemented generating SEH unwind info for ARM yet).
On startup of wine, an exception of the type RPC_S_SERVER_UNAVAILABLE
is raised. In a PE build of Wine, the unwind would get stuck in
an infinite loop.
This still loops for a short while; after returning the error
STATUS_INVALID_DISPOSITION, KiUserExceptionDispatcher ends up
calling RtlRaiseStatus with this status, which then tries to
unwind again, getting stuck similarly. However by recursively
trying to unwind multiple times, the process crashes fairly soon
after running out of stack.
Signed-off-by: Martin Storsjö <martin(a)martin.st>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/ntdll/unix/signal_arm.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index fc37f917219..2017cf150db 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -255,13 +255,16 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispa
}
if (rc == -UNW_ENOINFO || ip < info.start_ip || ip > info.end_ip)
{
- TRACE( "no info found for %x ip %x-%x, assuming leaf function\n",
- ip, info.start_ip, info.end_ip );
+ NTSTATUS status = context->Pc != context->Lr ?
+ STATUS_SUCCESS : STATUS_INVALID_DISPOSITION;
+ TRACE( "no info found for %x ip %x-%x, %s\n",
+ ip, info.start_ip, info.end_ip, status == STATUS_SUCCESS ?
+ "assuming leaf function" : "error, stuck" );
dispatch->LanguageHandler = NULL;
dispatch->EstablisherFrame = context->Sp;
context->Pc = context->Lr;
context->ContextFlags |= CONTEXT_UNWOUND_TO_CALL;
- return STATUS_SUCCESS;
+ return status;
}
TRACE( "ip %#x function %#lx-%#lx personality %#lx lsda %#lx fde %#lx\n",