André Hentschel : ntdll: Implement call_stack_handlers on ARM.
Alexandre Julliard
julliard at winehq.org
Mon Apr 18 11:10:57 CDT 2011
Module: wine
Branch: master
Commit: 372a32b53ecae0f1e9d0843f3b33bc7201f7154f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=372a32b53ecae0f1e9d0843f3b33bc7201f7154f
Author: André Hentschel <nerv at dawncrow.de>
Date: Fri Apr 15 19:37:58 2011 +0200
ntdll: Implement call_stack_handlers on ARM.
---
dlls/ntdll/signal_arm.c | 59 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index eb2a1b1..c87bb1c 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -93,6 +93,16 @@ static inline int dispatch_signal(unsigned int sig)
return handlers[sig](sig);
}
+/*******************************************************************
+ * is_valid_frame
+ */
+static inline BOOL is_valid_frame( void *frame )
+{
+ if ((ULONG_PTR)frame & 3) return FALSE;
+ return (frame >= NtCurrentTeb()->Tib.StackLimit &&
+ (void **)frame < (void **)NtCurrentTeb()->Tib.StackBase - 1);
+}
+
/***********************************************************************
* save_context
*
@@ -305,14 +315,49 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
*/
static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
{
- EXCEPTION_POINTERS ptrs;
+ EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame;
+ DWORD res;
- FIXME( "not implemented on ARM, exceptioncode: %x\n", rec->ExceptionCode );
+ frame = NtCurrentTeb()->Tib.ExceptionList;
+ nested_frame = NULL;
+ while (frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL)
+ {
+ /* Check frame address */
+ if (!is_valid_frame( frame ))
+ {
+ rec->ExceptionFlags |= EH_STACK_INVALID;
+ break;
+ }
- /* hack: call unhandled exception filter directly */
- ptrs.ExceptionRecord = rec;
- ptrs.ContextRecord = context;
- unhandled_exception_filter( &ptrs );
+ /* 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 );
+
+ if (frame == nested_frame)
+ {
+ /* no longer nested */
+ nested_frame = NULL;
+ rec->ExceptionFlags &= ~EH_NESTED_CALL;
+ }
+
+ switch(res)
+ {
+ case ExceptionContinueExecution:
+ if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS;
+ return STATUS_NONCONTINUABLE_EXCEPTION;
+ case ExceptionContinueSearch:
+ break;
+ case ExceptionNestedException:
+ if (nested_frame < dispatch) nested_frame = dispatch;
+ rec->ExceptionFlags |= EH_NESTED_CALL;
+ break;
+ default:
+ return STATUS_INVALID_DISPOSITION;
+ }
+ frame = frame->Prev;
+ }
return STATUS_UNHANDLED_EXCEPTION;
}
More information about the wine-cvs
mailing list