[2/2] ntdll: Implement RtlUnwind for ARM64
André Hentschel
nerv at dawncrow.de
Mon Sep 4 13:46:32 CDT 2017
Signed-off-by: André Hentschel <nerv at dawncrow.de>
---
dlls/ntdll/signal_arm64.c | 55 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 53 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 59d7b44..d506bc0 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -933,9 +933,60 @@ void __wine_enter_vm86( CONTEXT *context )
/***********************************************************************
* RtlUnwind (NTDLL.@)
*/
-void WINAPI RtlUnwind( PVOID pEndFrame, PVOID targetIp, PEXCEPTION_RECORD pRecord, PVOID retval )
+void WINAPI RtlUnwind( PVOID endframe, PVOID target_ip, PEXCEPTION_RECORD rec, PVOID retval )
{
- FIXME( "Not implemented on ARM64\n" );
+ CONTEXT context;
+ EXCEPTION_RECORD record;
+ EXCEPTION_REGISTRATION_RECORD *frame, *dispatch;
+ DWORD res;
+
+ RtlCaptureContext( &context );
+ context.X0 = (ULONGLONG)retval;
+
+ /* build an exception record, if we do not have one */
+ if (!rec)
+ {
+ record.ExceptionCode = STATUS_UNWIND;
+ record.ExceptionFlags = 0;
+ record.ExceptionRecord = NULL;
+ record.ExceptionAddress = (void *)context.Pc;
+ record.NumberParameters = 0;
+ rec = &record;
+ }
+
+ rec->ExceptionFlags |= EH_UNWINDING | (endframe ? 0 : EH_EXIT_UNWIND);
+
+ TRACE( "code=%x flags=%x\n", rec->ExceptionCode, rec->ExceptionFlags );
+
+ /* get chain of exception frames */
+ frame = NtCurrentTeb()->Tib.ExceptionList;
+ while ((frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) && (frame != endframe))
+ {
+ /* Check frame address */
+ if (endframe && ((void*)frame > endframe))
+ raise_status( STATUS_INVALID_UNWIND_TARGET, rec );
+
+ if (!is_valid_frame( frame )) raise_status( STATUS_BAD_STACK, rec );
+
+ /* Call handler */
+ TRACE( "calling handler at %p code=%x flags=%x\n",
+ frame->Handler, rec->ExceptionCode, rec->ExceptionFlags );
+ res = frame->Handler(rec, frame, &context, &dispatch);
+ TRACE( "handler at %p returned %x\n", frame->Handler, res );
+
+ switch(res)
+ {
+ case ExceptionContinueSearch:
+ break;
+ case ExceptionCollidedUnwind:
+ frame = dispatch;
+ break;
+ default:
+ raise_status( STATUS_INVALID_DISPOSITION, rec );
+ break;
+ }
+ frame = __wine_pop_frame( frame );
+ }
}
/*******************************************************************
--
2.7.4
More information about the wine-patches
mailing list