Alexandre Julliard : ntdll: Implement __C_specific_handler for x86_64.

Alexandre Julliard julliard at winehq.org
Fri May 22 08:25:34 CDT 2009


Module: wine
Branch: master
Commit: 2c63d1d7dddfd1126e0650bc3257acb646bec57f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2c63d1d7dddfd1126e0650bc3257acb646bec57f

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri May 22 12:00:43 2009 +0200

ntdll: Implement __C_specific_handler for x86_64.

---

 dlls/ntdll/ntdll.spec      |    1 +
 dlls/ntdll/signal_x86_64.c |   78 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 4b5dfec..484ae8e 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1231,6 +1231,7 @@
 @ cdecl -private _CIpow() NTDLL__CIpow
 # @ stub _CIsin
 # @ stub _CIsqrt
+@ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr)
 # @ stub __isascii
 # @ stub __iscsym
 # @ stub __iscsymf
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index c9db2fe..673c2ec 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -54,6 +54,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh);
 
 struct _DISPATCHER_CONTEXT;
 
+typedef LONG (WINAPI *PC_LANGUAGE_EXCEPTION_HANDLER)( EXCEPTION_POINTERS *ptrs, ULONG64 frame );
 typedef EXCEPTION_DISPOSITION (WINAPI *PEXCEPTION_ROUTINE)( EXCEPTION_RECORD *rec,
                                                             ULONG64 frame,
                                                             CONTEXT *context,
@@ -73,6 +74,18 @@ typedef struct _DISPATCHER_CONTEXT
     ULONG                 ScopeIndex;
 } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
 
+typedef struct _SCOPE_TABLE
+{
+    ULONG Count;
+    struct
+    {
+        ULONG BeginAddress;
+        ULONG EndAddress;
+        ULONG HandlerAddress;
+        ULONG JumpTarget;
+    } ScopeRecord[1];
+} SCOPE_TABLE, *PSCOPE_TABLE;
+
 
 /***********************************************************************
  * signal context platform-specific definitions
@@ -322,6 +335,19 @@ static void dump_unwind_info( ULONG64 base, RUNTIME_FUNCTION *function )
     }
 }
 
+static void dump_scope_table( ULONG64 base, const SCOPE_TABLE *table )
+{
+    unsigned int i;
+
+    TRACE( "scope table at %p\n", table );
+    for (i = 0; i < table->Count; i++)
+        TRACE( "  %u: %lx-%lx handler %lx target %lx\n", i,
+               base + table->ScopeRecord[i].BeginAddress,
+               base + table->ScopeRecord[i].EndAddress,
+               base + table->ScopeRecord[i].HandlerAddress,
+               base + table->ScopeRecord[i].JumpTarget );
+}
+
 /***********************************************************************
  *           dispatch_signal
  */
@@ -1455,7 +1481,6 @@ void WINAPI RtlUnwindEx( ULONG64 frame, ULONG64 target_ip, EXCEPTION_RECORD *rec
     rec->ExceptionFlags |= EH_UNWINDING | (frame ? 0 : EH_EXIT_UNWIND);
 
     FIXME( "code=%x flags=%x not implemented on x86_64\n", rec->ExceptionCode, rec->ExceptionFlags );
-    NtTerminateProcess( GetCurrentProcess(), 1 );
 }
 
 
@@ -1471,6 +1496,57 @@ DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 )
 
 
 /*******************************************************************
+ *		__C_specific_handler (NTDLL.@)
+ */
+EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec,
+                                                   ULONG64 frame,
+                                                   CONTEXT *context,
+                                                   struct _DISPATCHER_CONTEXT *dispatch )
+{
+    SCOPE_TABLE *table = dispatch->HandlerData;
+    ULONG i;
+
+    TRACE( "%p %lx %p %p\n", rec, frame, context, dispatch );
+    if (TRACE_ON(seh)) dump_scope_table( dispatch->ImageBase, table );
+
+    if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))  /* FIXME */
+        return ExceptionContinueSearch;
+
+    for (i = 0; i < table->Count; i++)
+    {
+        if (context->Rip >= dispatch->ImageBase + table->ScopeRecord[i].BeginAddress &&
+            context->Rip < dispatch->ImageBase + table->ScopeRecord[i].EndAddress)
+        {
+            if (!table->ScopeRecord[i].JumpTarget) continue;
+            if (table->ScopeRecord[i].HandlerAddress != EXCEPTION_EXECUTE_HANDLER)
+            {
+                EXCEPTION_POINTERS ptrs;
+                PC_LANGUAGE_EXCEPTION_HANDLER filter;
+
+                filter = (PC_LANGUAGE_EXCEPTION_HANDLER)(dispatch->ImageBase + table->ScopeRecord[i].HandlerAddress);
+                ptrs.ExceptionRecord = rec;
+                ptrs.ContextRecord = context;
+                TRACE( "calling filter %p ptrs %p frame %lx\n", filter, &ptrs, frame );
+                switch (filter( &ptrs, frame ))
+                {
+                case EXCEPTION_EXECUTE_HANDLER:
+                    break;
+                case EXCEPTION_CONTINUE_SEARCH:
+                    continue;
+                case EXCEPTION_CONTINUE_EXECUTION:
+                    return ExceptionContinueExecution;
+                }
+            }
+            TRACE( "unwinding to target %lx\n", dispatch->ImageBase + table->ScopeRecord[i].JumpTarget );
+            RtlUnwindEx( frame, dispatch->ImageBase + table->ScopeRecord[i].JumpTarget,
+                         rec, 0, context, dispatch->HistoryTable );
+        }
+    }
+    return ExceptionContinueSearch;
+}
+
+
+/*******************************************************************
  *		NtRaiseException (NTDLL.@)
  */
 NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )




More information about the wine-cvs mailing list