[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