Module: wine Branch: master Commit: 2c63d1d7dddfd1126e0650bc3257acb646bec57f URL: http://source.winehq.org/git/wine.git/?a=commit;h=2c63d1d7dddfd1126e0650bc32...
Author: Alexandre Julliard julliard@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 )