wined3d: Use glFinish() for synchronisation when cleaning up a destroyed context...
[wine.git] / dlls / ntdll / signal_arm.c
blob512462b70664cee10af353abfac298d983d0c0d7
1 /*
2 * ARM signal handling routines
4 * Copyright 2002 Marcus Meissner, SuSE Linux AG
5 * Copyright 2010-2013, 2015 André Hentschel
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #ifdef __arm__
24 #include <stdlib.h>
25 #include <stdarg.h>
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
29 #include "ntstatus.h"
30 #define WIN32_NO_STATUS
31 #include "windef.h"
32 #include "winternl.h"
33 #include "wine/exception.h"
34 #include "ntdll_misc.h"
35 #include "wine/debug.h"
36 #include "winnt.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(seh);
41 /*******************************************************************
42 * is_valid_frame
44 static inline BOOL is_valid_frame( void *frame )
46 if ((ULONG_PTR)frame & 3) return FALSE;
47 return (frame >= NtCurrentTeb()->Tib.StackLimit &&
48 (void **)frame < (void **)NtCurrentTeb()->Tib.StackBase - 1);
52 /**************************************************************************
53 * __chkstk (NTDLL.@)
55 * Incoming r4 contains words to allocate, converting to bytes then return
57 __ASM_GLOBAL_FUNC( __chkstk, "lsl r4, r4, #2\n\t"
58 "bx lr" )
60 /***********************************************************************
61 * RtlCaptureContext (NTDLL.@)
63 __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
64 ".arm\n\t"
65 "stmib r0, {r0-r12}\n\t" /* context->R0..R12 */
66 "mov r1, #0x0200000\n\t" /* CONTEXT_ARM */
67 "add r1, r1, #0x3\n\t" /* CONTEXT_FULL */
68 "str r1, [r0]\n\t" /* context->ContextFlags */
69 "str SP, [r0, #0x38]\n\t" /* context->Sp */
70 "str LR, [r0, #0x3c]\n\t" /* context->Lr */
71 "str LR, [r0, #0x40]\n\t" /* context->Pc */
72 "mrs r1, CPSR\n\t"
73 "str r1, [r0, #0x44]\n\t" /* context->Cpsr */
74 "bx lr"
78 /**********************************************************************
79 * call_stack_handlers
81 * Call the stack handlers chain.
83 static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
85 EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame;
86 DWORD res;
88 frame = NtCurrentTeb()->Tib.ExceptionList;
89 nested_frame = NULL;
90 while (frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL)
92 /* Check frame address */
93 if (!is_valid_frame( frame ))
95 rec->ExceptionFlags |= EH_STACK_INVALID;
96 break;
99 /* Call handler */
100 TRACE( "calling handler at %p code=%x flags=%x\n",
101 frame->Handler, rec->ExceptionCode, rec->ExceptionFlags );
102 res = frame->Handler( rec, frame, context, &dispatch );
103 TRACE( "handler at %p returned %x\n", frame->Handler, res );
105 if (frame == nested_frame)
107 /* no longer nested */
108 nested_frame = NULL;
109 rec->ExceptionFlags &= ~EH_NESTED_CALL;
112 switch(res)
114 case ExceptionContinueExecution:
115 if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS;
116 return STATUS_NONCONTINUABLE_EXCEPTION;
117 case ExceptionContinueSearch:
118 break;
119 case ExceptionNestedException:
120 if (nested_frame < dispatch) nested_frame = dispatch;
121 rec->ExceptionFlags |= EH_NESTED_CALL;
122 break;
123 default:
124 return STATUS_INVALID_DISPOSITION;
126 frame = frame->Prev;
128 return STATUS_UNHANDLED_EXCEPTION;
132 /*******************************************************************
133 * KiUserExceptionDispatcher (NTDLL.@)
135 NTSTATUS WINAPI KiUserExceptionDispatcher( EXCEPTION_RECORD *rec, CONTEXT *context )
137 NTSTATUS status;
138 DWORD c;
140 TRACE( "code=%x flags=%x addr=%p pc=%08x tid=%04x\n",
141 rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
142 context->Pc, GetCurrentThreadId() );
143 for (c = 0; c < rec->NumberParameters; c++)
144 TRACE( " info[%d]=%08lx\n", c, rec->ExceptionInformation[c] );
146 if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
148 if (rec->ExceptionInformation[1] >> 16)
149 MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
150 rec->ExceptionAddress,
151 (char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
152 else
153 MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n",
154 rec->ExceptionAddress,
155 (char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
157 else
159 TRACE( " r0=%08x r1=%08x r2=%08x r3=%08x r4=%08x r5=%08x\n",
160 context->R0, context->R1, context->R2, context->R3, context->R4, context->R5 );
161 TRACE( " r6=%08x r7=%08x r8=%08x r9=%08x r10=%08x r11=%08x\n",
162 context->R6, context->R7, context->R8, context->R9, context->R10, context->R11 );
163 TRACE( " r12=%08x sp=%08x lr=%08x pc=%08x cpsr=%08x\n",
164 context->R12, context->Sp, context->Lr, context->Pc, context->Cpsr );
167 if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
168 NtContinue( context, FALSE );
170 if ((status = call_stack_handlers( rec, context )) == STATUS_SUCCESS)
171 NtContinue( context, FALSE );
173 if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
174 return NtRaiseException( rec, context, FALSE );
178 /*******************************************************************
179 * KiUserApcDispatcher (NTDLL.@)
181 void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
182 PNTAPCFUNC func )
184 func( ctx, arg1, arg2 );
185 NtContinue( context, TRUE );
189 /***********************************************************************
190 * RtlUnwind (NTDLL.@)
192 void WINAPI RtlUnwind( void *endframe, void *target_ip, EXCEPTION_RECORD *rec, void *retval )
194 CONTEXT context;
195 EXCEPTION_RECORD record;
196 EXCEPTION_REGISTRATION_RECORD *frame, *dispatch;
197 DWORD res;
199 RtlCaptureContext( &context );
200 context.R0 = (DWORD)retval;
202 /* build an exception record, if we do not have one */
203 if (!rec)
205 record.ExceptionCode = STATUS_UNWIND;
206 record.ExceptionFlags = 0;
207 record.ExceptionRecord = NULL;
208 record.ExceptionAddress = (void *)context.Pc;
209 record.NumberParameters = 0;
210 rec = &record;
213 rec->ExceptionFlags |= EH_UNWINDING | (endframe ? 0 : EH_EXIT_UNWIND);
215 TRACE( "code=%x flags=%x\n", rec->ExceptionCode, rec->ExceptionFlags );
217 /* get chain of exception frames */
218 frame = NtCurrentTeb()->Tib.ExceptionList;
219 while ((frame != (EXCEPTION_REGISTRATION_RECORD*)~0UL) && (frame != endframe))
221 /* Check frame address */
222 if (endframe && ((void*)frame > endframe))
223 raise_status( STATUS_INVALID_UNWIND_TARGET, rec );
225 if (!is_valid_frame( frame )) raise_status( STATUS_BAD_STACK, rec );
227 /* Call handler */
228 TRACE( "calling handler at %p code=%x flags=%x\n",
229 frame->Handler, rec->ExceptionCode, rec->ExceptionFlags );
230 res = frame->Handler(rec, frame, &context, &dispatch);
231 TRACE( "handler at %p returned %x\n", frame->Handler, res );
233 switch(res)
235 case ExceptionContinueSearch:
236 break;
237 case ExceptionCollidedUnwind:
238 frame = dispatch;
239 break;
240 default:
241 raise_status( STATUS_INVALID_DISPOSITION, rec );
242 break;
244 frame = __wine_pop_frame( frame );
249 /***********************************************************************
250 * RtlRaiseException (NTDLL.@)
252 __ASM_STDCALL_FUNC( RtlRaiseException, 4,
253 "push {r0, lr}\n\t"
254 "sub sp, sp, #0x1a0\n\t" /* sizeof(CONTEXT) */
255 "mov r0, sp\n\t" /* context */
256 "bl " __ASM_NAME("RtlCaptureContext") "\n\t"
257 "ldr r0, [sp, #0x1a0]\n\t" /* rec */
258 "ldr r1, [sp, #0x1a4]\n\t"
259 "str r1, [sp, #0x40]\n\t" /* context->Pc */
260 "str r1, [r0, #12]\n\t" /* rec->ExceptionAddress */
261 "add r1, sp, #0x1a8\n\t"
262 "str r1, [sp, #0x38]\n\t" /* context->Sp */
263 "mov r1, sp\n\t"
264 "mov r2, #1\n\t"
265 "bl " __ASM_NAME("NtRaiseException") "\n\t"
266 "bl " __ASM_NAME("RtlRaiseStatus") )
268 /*************************************************************************
269 * RtlCaptureStackBackTrace (NTDLL.@)
271 USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, ULONG *hash )
273 FIXME( "(%d, %d, %p, %p) stub!\n", skip, count, buffer, hash );
274 return 0;
277 /***********************************************************************
278 * signal_start_thread
280 __ASM_GLOBAL_FUNC( signal_start_thread,
281 "mov sp, r0\n\t" /* context */
282 "mov r1, #1\n\t"
283 "b " __ASM_NAME("NtContinue") )
285 /**********************************************************************
286 * DbgBreakPoint (NTDLL.@)
288 __ASM_STDCALL_FUNC( DbgBreakPoint, 0, "bkpt #0; bx lr; nop; nop; nop; nop" );
290 /**********************************************************************
291 * DbgUserBreakPoint (NTDLL.@)
293 __ASM_STDCALL_FUNC( DbgUserBreakPoint, 0, "bkpt #0; bx lr; nop; nop; nop; nop" );
295 /**********************************************************************
296 * NtCurrentTeb (NTDLL.@)
298 TEB * WINAPI NtCurrentTeb(void)
300 return unix_funcs->NtCurrentTeb();
303 #endif /* __arm__ */