ReactOS 0.4.16-dev-2104-gb84fa49
except_i386.c
Go to the documentation of this file.
1/*
2 * msvcrt C++ exception handling
3 *
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2002 Alexandre Julliard
6 * Copyright 2005 Juan Lang
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * NOTES
23 * A good reference is the article "How a C++ compiler implements
24 * exception handling" by Vishal Kochhar, available on
25 * www.thecodeproject.com.
26 */
27
28#ifdef __i386__
29
30#include <stdarg.h>
31#include <fpieee.h>
32#define longjmp ms_longjmp /* avoid prototype mismatch */
33#include <setjmp.h>
34#undef longjmp
35
36#include "windef.h"
37#include "winbase.h"
38#include "winternl.h"
39#include "msvcrt.h"
40#include "wine/exception.h"
41#include "excpt.h"
42#include "wine/debug.h"
43
44#include "cppexcept.h"
45
47
48
49/* the exception frame used by CxxFrameHandler */
50typedef struct __cxx_exception_frame
51{
52 EXCEPTION_REGISTRATION_RECORD frame; /* the standard exception frame */
53 int trylevel;
54 DWORD ebp;
56
57/* exception frame for nested exceptions in catch block */
58typedef struct
59{
60 EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
61 cxx_exception_frame *cxx_frame; /* frame of parent exception */
62 const cxx_function_descr *descr; /* descriptor of parent exception */
63 int trylevel; /* current try level */
65} catch_func_nested_frame;
66
67typedef struct
68{
71 catch_func_nested_frame *nested_frame;
73
74typedef struct _SCOPETABLE
75{
76 int previousTryLevel;
77 int (*lpfnFilter)(PEXCEPTION_POINTERS);
78 void * (*lpfnHandler)(void);
79} SCOPETABLE, *PSCOPETABLE;
80
81typedef struct MSVCRT_EXCEPTION_FRAME
82{
86 PSCOPETABLE scopetable;
87 int trylevel;
88 int _ebp;
89 PEXCEPTION_POINTERS xpointers;
90} MSVCRT_EXCEPTION_FRAME;
91
92typedef struct
93{
94 int gs_cookie_offset;
95 ULONG gs_cookie_xor;
96 int eh_cookie_offset;
97 ULONG eh_cookie_xor;
98 SCOPETABLE entries[1];
99} SCOPETABLE_V4;
100
101#define TRYLEVEL_END (-1) /* End of trylevel list */
102
105 const cxx_function_descr*, int nested_trylevel,
107
111 catch_func_nested_frame* nested_frame );
112
113/* continue execution to the specified address after exception is caught */
114extern void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr );
115
116__ASM_GLOBAL_FUNC( continue_after_catch,
117 "movl 4(%esp), %edx\n\t"
118 "movl 8(%esp), %eax\n\t"
119 "movl -4(%edx), %esp\n\t"
120 "leal 12(%edx), %ebp\n\t"
121 "jmp *%eax" );
122
123extern void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr );
124
125__ASM_GLOBAL_FUNC( call_finally_block,
126 "movl 8(%esp), %ebp\n\t"
127 "jmp *4(%esp)" );
128
129extern int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp );
130
131__ASM_GLOBAL_FUNC( call_filter,
132 "pushl %ebp\n\t"
133 "pushl 12(%esp)\n\t"
134 "movl 20(%esp), %ebp\n\t"
135 "call *12(%esp)\n\t"
136 "popl %ebp\n\t"
137 "popl %ebp\n\t"
138 "ret" );
139
140extern void *call_handler( void * (*func)(void), void *ebp );
141
142__ASM_GLOBAL_FUNC( call_handler,
143 "pushl %ebp\n\t"
144 "pushl %ebx\n\t"
145 "pushl %esi\n\t"
146 "pushl %edi\n\t"
147 "movl 24(%esp), %ebp\n\t"
148 "call *20(%esp)\n\t"
149 "popl %edi\n\t"
150 "popl %esi\n\t"
151 "popl %ebx\n\t"
152 "popl %ebp\n\t"
153 "ret" );
154
155/* unwind the local function up to a given trylevel */
156static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
157{
158 void * (*handler)(void);
159 int trylevel = frame->trylevel;
160
161 while (trylevel != last_level)
162 {
163 if (trylevel < 0 || trylevel >= descr->unwind_count)
164 {
165 ERR( "invalid trylevel %d\n", trylevel );
166 terminate();
167 }
168 handler = descr->unwind_table[trylevel].handler;
169 if (handler)
170 {
171 TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
172 handler, trylevel, last_level, &frame->ebp );
173 call_handler( handler, &frame->ebp );
174 }
175 trylevel = descr->unwind_table[trylevel].prev;
176 }
177 frame->trylevel = last_level;
178}
179
180/* handler for exceptions happening while calling a catch function */
181static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
183{
184 catch_func_nested_frame *nested_frame = (catch_func_nested_frame *)frame;
185
187 {
188 __CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
190 }
191
192 TRACE( "got nested exception in catch function\n" );
193
194 if(rec->ExceptionCode == CXX_EXCEPTION)
195 {
196 PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
197
198 if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
199 (prev_rec->ExceptionCode == CXX_EXCEPTION &&
200 rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
201 rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]))
202 {
203 /* exception was rethrown */
204 *rec = *prev_rec;
205 rec->ExceptionFlags &= ~EXCEPTION_UNWINDING;
206 if(TRACE_ON(seh)) {
207 TRACE("detect rethrow: exception code: %lx\n", rec->ExceptionCode);
208 if(rec->ExceptionCode == CXX_EXCEPTION)
209 TRACE("re-propagate: obj: %Ix, type: %Ix\n",
211 }
212 }
213 else
214 {
215 TRACE("detect threw new exception in catch block\n");
216 }
217 }
218
219 return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
220 NULL, nested_frame->descr, nested_frame );
221}
222
223/* find and call the appropriate catch block for an exception */
224/* returns the address to continue execution to after the catch block was called */
225static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context,
226 cxx_exception_frame *frame,
228 catch_func_nested_frame *catch_frame,
230{
231 UINT i;
232 void *addr, *handler, *object = (void *)rec->ExceptionInformation[1];
233 catch_func_nested_frame nested_frame;
234 int trylevel = frame->trylevel;
235 DWORD save_esp = ((DWORD*)frame)[-1];
237
238 data->processing_throw++;
239 for (i = 0; i < descr->tryblock_count; i++)
240 {
241 const tryblock_info *tryblock = &descr->tryblock[i];
242
243 /* only handle try blocks inside current catch block */
244 if (catch_frame && catch_frame->trylevel > tryblock->start_level) continue;
245
246 if (trylevel < tryblock->start_level) continue;
247 if (trylevel > tryblock->end_level) continue;
248
249 handler = find_catch_handler( object, (uintptr_t)&frame->ebp, 0, tryblock, info, 0 );
250 if (!handler) continue;
251
252 /* Add frame info here so exception is not freed inside RtlUnwind call */
253 _CreateFrameInfo(&nested_frame.frame_info.frame_info, object);
254
255 /* unwind the stack */
256 RtlUnwind( catch_frame ? &catch_frame->frame : &frame->frame, 0, rec, 0 );
257 cxx_local_unwind( frame, descr, tryblock->start_level );
258 frame->trylevel = tryblock->end_level + 1;
259
260 nested_frame.frame_info.rec = data->exc_record;
261 nested_frame.frame_info.context = data->ctx_record;
262 data->exc_record = rec;
263 data->ctx_record = context;
264 data->processing_throw--;
265
266 /* call the catch block */
267 TRACE( "calling handler %p ebp %p\n", handler, &frame->ebp );
268
269 /* setup an exception block for nested exceptions */
270 nested_frame.frame.Handler = catch_function_nested_handler;
271 nested_frame.cxx_frame = frame;
272 nested_frame.descr = descr;
273 nested_frame.trylevel = tryblock->end_level + 1;
274
275 __wine_push_frame( &nested_frame.frame );
276 addr = call_handler( handler, &frame->ebp );
277 __wine_pop_frame( &nested_frame.frame );
278
279 ((DWORD*)frame)[-1] = save_esp;
280 __CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
281 TRACE( "done, continuing at %p\n", addr );
282
283 continue_after_catch( frame, addr );
284 }
285 data->processing_throw--;
286}
287
289{
292 cxx_exception_type *exc_type;
293
294 if (rec->ExceptionCode != CXX_EXCEPTION)
295 {
296 TRACE( "non-c++ exception thrown in SEH handler: %lx\n", rec->ExceptionCode );
297 terminate();
298 }
299
300 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
301 call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr,
302 ctx->nested_frame, exc_type );
303
306}
307
308static void check_noexcept( PEXCEPTION_RECORD rec,
310{
311 if (!nested && rec->ExceptionCode == CXX_EXCEPTION &&
312 descr->magic >= CXX_FRAME_MAGIC_VC8 &&
313 (descr->flags & FUNC_DESCR_NOEXCEPT))
314 {
315 ERR("noexcept function propagating exception\n");
316 terminate();
317 }
318}
319
320/*********************************************************************
321 * cxx_frame_handler
322 *
323 * Implementation of __CxxFrameHandler.
324 */
328 catch_func_nested_frame* nested_frame )
329{
330 cxx_exception_type *exc_type;
331
332 if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
333 {
334 ERR( "invalid frame magic %x\n", descr->magic );
336 }
337 if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
338 (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
340 return ExceptionContinueSearch; /* handle only c++ exceptions */
341
343 {
344 if (descr->unwind_count && !nested_frame) cxx_local_unwind( frame, descr, -1 );
346 }
347 if (!descr->tryblock_count)
348 {
349 check_noexcept(rec, descr, nested_frame != NULL);
351 }
352
353 if(rec->ExceptionCode == CXX_EXCEPTION &&
354 rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
355 {
356 *rec = *msvcrt_get_thread_data()->exc_record;
357 rec->ExceptionFlags &= ~EXCEPTION_UNWINDING;
358 if(TRACE_ON(seh)) {
359 TRACE("detect rethrow: exception code: %lx\n", rec->ExceptionCode);
360 if(rec->ExceptionCode == CXX_EXCEPTION)
361 TRACE("re-propagate: obj: %Ix, type: %Ix\n",
363 }
364 }
365
366 if(rec->ExceptionCode == CXX_EXCEPTION)
367 {
368 exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
369
371 exc_type->custom_handler)
372 {
374 return handler( rec, frame, context, dispatch, descr,
375 nested_frame ? nested_frame->trylevel : 0,
376 nested_frame ? &nested_frame->frame : NULL, 0 );
377 }
378
379 if (TRACE_ON(seh))
380 {
381 TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
382 rec, frame, frame->trylevel, descr, nested_frame );
383 TRACE_EXCEPTION_TYPE( exc_type, 0 );
385 }
386 }
387 else
388 {
390
391 exc_type = NULL;
392 TRACE("handling C exception code %lx rec %p frame %p trylevel %d descr %p nested_frame %p\n",
393 rec->ExceptionCode, rec, frame, frame->trylevel, descr, nested_frame );
394
395 if (data->se_translator) {
396 EXCEPTION_POINTERS except_ptrs;
398
399 ctx.frame = frame;
400 ctx.descr = descr;
401 ctx.nested_frame = nested_frame;
402 __TRY
403 {
404 except_ptrs.ExceptionRecord = rec;
405 except_ptrs.ContextRecord = context;
406 data->se_translator( rec->ExceptionCode, &except_ptrs );
407 }
409 {
410 }
412 }
413 }
414
415 call_catch_block( rec, context, frame, descr,
416 nested_frame, exc_type );
417 check_noexcept(rec, descr, nested_frame != NULL);
419}
420
421
422/*********************************************************************
423 * __CxxFrameHandler (MSVCRT.@)
424 */
428 "pushl $0\n\t" /* nested_frame */
429 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
430 "pushl %eax\n\t" /* descr */
431 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
432 "pushl 24(%esp)\n\t" /* dispatch */
433 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
434 "pushl 24(%esp)\n\t" /* context */
435 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
436 "pushl 24(%esp)\n\t" /* frame */
437 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
438 "pushl 24(%esp)\n\t" /* rec */
439 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
440 "call " __ASM_NAME("cxx_frame_handler") "\n\t"
441 "add $24,%esp\n\t"
442 __ASM_CFI(".cfi_adjust_cfa_offset -24\n\t")
443 "ret" )
444
445
446/*********************************************************************
447 * __CxxLongjmpUnwind (MSVCRT.@)
448 *
449 * Callback meant to be used as UnwindFunc for setjmp/longjmp.
450 */
451void __stdcall __CxxLongjmpUnwind( const _JUMP_BUFFER *buf )
452{
453 cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration;
454 const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0];
455
456 TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel );
457 cxx_local_unwind( frame, descr, buf->TryLevel );
458}
459
460/*********************************************************************
461 * _EH_prolog (MSVCRT.@)
462 */
463
464/* Provided for VC++ binary compatibility only */
465__ASM_GLOBAL_FUNC(_EH_prolog,
466 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") /* skip ret addr */
467 "pushl $-1\n\t"
468 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
469 "pushl %eax\n\t"
470 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
471 "pushl %fs:0\n\t"
472 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
473 "movl %esp, %fs:0\n\t"
474 "movl 12(%esp), %eax\n\t"
475 "movl %ebp, 12(%esp)\n\t"
476 "leal 12(%esp), %ebp\n\t"
477 "pushl %eax\n\t"
478 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
479 "ret")
480
481static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
482{
483 return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
484}
485
486static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
490{
493 *dispatch = frame;
495}
496
497static void msvcrt_local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp)
498{
500
501 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
502
503 /* Register a handler in case of a nested exception */
504 reg.Handler = MSVCRT_nested_handler;
505 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
507
508 while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel)
509 {
510 int level = frame->trylevel;
511 frame->trylevel = frame->scopetable[level].previousTryLevel;
512 if (!frame->scopetable[level].lpfnFilter)
513 {
514 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
515 level, frame->scopetable[level].lpfnHandler, ebp );
516 call_handler( frame->scopetable[level].lpfnHandler, ebp );
517 }
518 }
520 TRACE("unwound OK\n");
521}
522
523static void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
524{
526 const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
527
528 TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
529
530 /* Register a handler in case of a nested exception */
531 reg.Handler = MSVCRT_nested_handler;
532 reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
534
535 while (frame->trylevel != -2 && frame->trylevel != trylevel)
536 {
537 int level = frame->trylevel;
538 frame->trylevel = scopetable->entries[level].previousTryLevel;
539 if (!scopetable->entries[level].lpfnFilter)
540 {
541 TRACE( "__try block cleanup level %d handler %p ebp %p\n",
542 level, scopetable->entries[level].lpfnHandler, ebp );
543 call_handler( scopetable->entries[level].lpfnHandler, ebp );
544 }
545 }
547 TRACE("unwound OK\n");
548}
549
550#ifndef __REACTOS__
551/*******************************************************************
552 * _local_unwind2 (MSVCRT.@)
553 */
554void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel)
555{
556 msvcrt_local_unwind2( frame, trylevel, &frame->_ebp );
557}
558#endif
559
560/*******************************************************************
561 * _local_unwind4 (MSVCRT.@)
562 */
563void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel )
564{
565 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
566}
567
568#ifdef __REACTOS__
570#else
571/*******************************************************************
572 * _global_unwind2 (MSVCRT.@)
573 */
575{
576 TRACE("(%p)\n",frame);
577 RtlUnwind( frame, 0, 0, 0 );
578}
579
580/*********************************************************************
581 * _except_handler2 (MSVCRT.@)
582 */
583int CDECL _except_handler2(PEXCEPTION_RECORD rec,
587{
588 FIXME("exception %lx flags=%lx at %p handler=%p %p %p stub\n",
590 frame->Handler, context, dispatcher);
592}
593
594/*********************************************************************
595 * _except_handler3 (MSVCRT.@)
596 */
597int CDECL _except_handler3(PEXCEPTION_RECORD rec,
598 MSVCRT_EXCEPTION_FRAME* frame,
599 PCONTEXT context, void* dispatcher)
600{
601 int retval, trylevel;
602 EXCEPTION_POINTERS exceptPtrs;
603 PSCOPETABLE pScopeTable;
604
605 TRACE("exception %lx flags=%lx at %p handler=%p %p %p semi-stub\n",
607 frame->handler, context, dispatcher);
608
609#ifdef _MSC_VER
610 __asm{ cld }
611#else
612 __asm__ __volatile__ ("cld");
613#endif
615 {
616 /* Unwinding the current frame */
617 msvcrt_local_unwind2(frame, TRYLEVEL_END, &frame->_ebp);
618 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
620 }
621 else
622 {
623 /* Hunting for handler */
624 exceptPtrs.ExceptionRecord = rec;
625 exceptPtrs.ContextRecord = context;
626 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
627 trylevel = frame->trylevel;
628 pScopeTable = frame->scopetable;
629
630 while (trylevel != TRYLEVEL_END)
631 {
632 TRACE( "level %d prev %d filter %p\n", trylevel, pScopeTable[trylevel].previousTryLevel,
633 pScopeTable[trylevel].lpfnFilter );
634 if (pScopeTable[trylevel].lpfnFilter)
635 {
636 retval = call_filter( pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
637
638 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
639 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
640 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
641
644
646 {
647 /* Unwind all higher frames, this one will handle the exception */
649 msvcrt_local_unwind2(frame, trylevel, &frame->_ebp);
650
651 /* Set our trylevel to the enclosing block, and call the __finally
652 * code, which won't return
653 */
654 frame->trylevel = pScopeTable[trylevel].previousTryLevel;
655 TRACE("__finally block %p\n",pScopeTable[trylevel].lpfnHandler);
656 call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp);
657 }
658 }
659 trylevel = pScopeTable[trylevel].previousTryLevel;
660 }
661 }
662 TRACE("reached TRYLEVEL_END, returning ExceptionContinueSearch\n");
664}
665#endif
666
667/*********************************************************************
668 * _except_handler4_common (MSVCRT.@)
669 */
670int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
671 EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
673{
674 int retval, trylevel;
675 EXCEPTION_POINTERS exceptPtrs;
676 const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
677
678 TRACE( "exception %lx flags=%lx at %p handler=%p %p %p cookie=%lx scope table=%p cookies=%d/%lx,%d/%lx\n",
680 frame->handler, context, dispatcher, *cookie, scope_table,
681 scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
682 scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
683
684 /* FIXME: no cookie validation yet */
685
687 {
688 /* Unwinding the current frame */
689 msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
690 TRACE("unwound current frame, returning ExceptionContinueSearch\n");
692 }
693 else
694 {
695 /* Hunting for handler */
696 exceptPtrs.ExceptionRecord = rec;
697 exceptPtrs.ContextRecord = context;
698 *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
699 trylevel = frame->trylevel;
700
701 while (trylevel != -2)
702 {
703 TRACE( "level %d prev %d filter %p\n", trylevel,
704 scope_table->entries[trylevel].previousTryLevel,
705 scope_table->entries[trylevel].lpfnFilter );
706 if (scope_table->entries[trylevel].lpfnFilter)
707 {
708 retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
709
710 TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
711 "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
712 "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
713
716
718 {
720
721 /* Unwind all higher frames, this one will handle the exception */
723 msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
724
725 /* Set our trylevel to the enclosing block, and call the __finally
726 * code, which won't return
727 */
728 frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
729 TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
730 call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
731 }
732 }
733 trylevel = scope_table->entries[trylevel].previousTryLevel;
734 }
735 }
736 TRACE("reached -2, returning ExceptionContinueSearch\n");
738}
739
740
741#ifndef __REACTOS__
742/*
743 * setjmp/longjmp implementation
744 */
745
746#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
747typedef void (__stdcall *MSVCRT_unwind_function)(const _JUMP_BUFFER *);
748
749/* define an entrypoint for setjmp/setjmp3 that stores the registers in the jmp buf */
750/* and then jumps to the C backend function */
751#define DEFINE_SETJMP_ENTRYPOINT(name) \
752 __ASM_GLOBAL_FUNC( name, \
753 "movl 4(%esp),%ecx\n\t" /* jmp_buf */ \
754 "movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */ \
755 "movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */ \
756 "movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */ \
757 "movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */ \
758 "movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */ \
759 "movl 0(%esp),%eax\n\t" \
760 "movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */ \
761 "jmp " __ASM_NAME("__regs_") # name )
762
763/*******************************************************************
764 * _setjmp (MSVCRT.@)
765 */
766#undef _setjmp
767DEFINE_SETJMP_ENTRYPOINT( _setjmp )
768int CDECL __regs__setjmp(_JUMP_BUFFER *jmp)
769{
770 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
771 if (jmp->Registration == ~0UL)
772 jmp->TryLevel = TRYLEVEL_END;
773 else
774 jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
775
776 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
777 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
778 return 0;
779}
780
781/*******************************************************************
782 * _setjmp3 (MSVCRT.@)
783 */
784DEFINE_SETJMP_ENTRYPOINT( _setjmp3 )
785int WINAPIV __regs__setjmp3(_JUMP_BUFFER *jmp, int nb_args, ...)
786{
787 jmp->Cookie = MSVCRT_JMP_MAGIC;
788 jmp->UnwindFunc = 0;
789 jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
790 if (jmp->Registration == ~0UL)
791 {
792 jmp->TryLevel = TRYLEVEL_END;
793 }
794 else
795 {
796 int i;
798
799 va_start( args, nb_args );
800 if (nb_args > 0) jmp->UnwindFunc = va_arg( args, unsigned long );
801 if (nb_args > 1) jmp->TryLevel = va_arg( args, unsigned long );
802 else jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
803 for (i = 0; i < 6 && i < nb_args - 2; i++)
804 jmp->UnwindData[i] = va_arg( args, unsigned long );
805 va_end( args );
806 }
807
808 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
809 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
810 return 0;
811}
812
813/*********************************************************************
814 * longjmp (MSVCRT.@)
815 */
816void __cdecl longjmp(_JUMP_BUFFER *jmp, int retval)
817{
818 unsigned long cur_frame = 0;
819
820 TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx retval=%08x\n",
821 jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration, retval );
822
823 cur_frame=(unsigned long)NtCurrentTeb()->Tib.ExceptionList;
824 TRACE("cur_frame=%lx\n",cur_frame);
825
826 if (cur_frame != jmp->Registration)
828
829 if (jmp->Registration)
830 {
831 if (IsBadReadPtr(&jmp->Cookie, sizeof(long)) || jmp->Cookie != MSVCRT_JMP_MAGIC)
832 {
833 msvcrt_local_unwind2((MSVCRT_EXCEPTION_FRAME*)jmp->Registration,
834 jmp->TryLevel, (void *)jmp->Ebp);
835 }
836 else if(jmp->UnwindFunc)
837 {
838 MSVCRT_unwind_function unwind_func;
839
840 unwind_func=(MSVCRT_unwind_function)jmp->UnwindFunc;
841 unwind_func(jmp);
842 }
843 }
844
845 if (!retval)
846 retval = 1;
847
849}
850#endif // __REACTOS__
851
852/*********************************************************************
853 * _seh_longjmp_unwind (MSVCRT.@)
854 */
855void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp)
856{
857 msvcrt_local_unwind2( (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, jmp->TryLevel, (void *)jmp->Ebp );
858}
859
860/*********************************************************************
861 * _seh_longjmp_unwind4 (MSVCRT.@)
862 */
863void __stdcall _seh_longjmp_unwind4(_JUMP_BUFFER *jmp)
864{
865 msvcrt_local_unwind4( (ULONG *)&jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration,
866 jmp->TryLevel, (void *)jmp->Ebp );
867}
868
869/*********************************************************************
870 * handle_fpieee_flt
871 */
874{
876 _FPIEEE_RECORD rec;
877 int ret;
878
879 memset(&rec, 0, sizeof(rec));
880 rec.RoundingMode = ctx->ControlWord >> 10;
881 switch((ctx->ControlWord >> 8) & 0x3) {
882 case 0: rec.Precision = 2; break;
883 case 1: rec.Precision = 3; break;
884 case 2: rec.Precision = 1; break;
885 case 3: rec.Precision = 0; break;
886 }
887 rec.Status.InvalidOperation = ctx->StatusWord & 0x1;
888 rec.Status.ZeroDivide = ((ctx->StatusWord & 0x4) != 0);
889 rec.Status.Overflow = ((ctx->StatusWord & 0x8) != 0);
890 rec.Status.Underflow = ((ctx->StatusWord & 0x10) != 0);
891 rec.Status.Inexact = ((ctx->StatusWord & 0x20) != 0);
892 rec.Enable.InvalidOperation = ((ctx->ControlWord & 0x1) == 0);
893 rec.Enable.ZeroDivide = ((ctx->ControlWord & 0x4) == 0);
894 rec.Enable.Overflow = ((ctx->ControlWord & 0x8) == 0);
895 rec.Enable.Underflow = ((ctx->ControlWord & 0x10) == 0);
896 rec.Enable.Inexact = ((ctx->ControlWord & 0x20) == 0);
901 rec.Cause.Inexact = rec.Enable.Inexact & rec.Status.Inexact;
902
903 TRACE("code %lx handler %p opcode %lx\n", exception_code, handler,
905
906 if(*(WORD*)ctx->ErrorOffset == 0x35dc) { /* fdiv m64fp */
908 rec.Operand1.OperandValid = 1;
909 rec.Result.OperandValid = 0;
910 } else {
911 rec.Operand1.OperandValid = 0;
912 rec.Result.OperandValid = 1;
913 }
914 rec.Operand2.OperandValid = 1;
917 memcpy(&rec.Operand1.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
919 rec.Operand2.Value.Fp64Value = *(double*)ctx->DataOffset;
921 memcpy(&rec.Result.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
922
923 ret = handler(&rec);
924
926 memcpy(ctx->RegisterArea, &rec.Result.Value.Fp80Value, sizeof(rec.Operand1.Value.Fp80Value));
927 return ret;
928 }
929
930 FIXME("unsupported opcode: %lx\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
932}
933
934#endif /* __i386__ */
#define RtlUnwind
Definition: longjmp.c:9
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define CDECL
Definition: compat.h:29
@ ExceptionContinueSearch
Definition: compat.h:91
@ ExceptionCollidedUnwind
Definition: compat.h:93
@ ExceptionContinueExecution
Definition: compat.h:90
CONTEXT * PCONTEXT
Definition: compat.h:699
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#define __ENDTRY
Definition: compat.h:82
struct _EXCEPTION_RECORD * PEXCEPTION_RECORD
#define CALLBACK
Definition: compat.h:35
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
void CDECL terminate(void)
Definition: cpp.c:698
#define CXX_EXCEPTION
Definition: cppexcept.h:34
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:31
#define TRACE_EXCEPTION_TYPE(type, base)
Definition: cppexcept.h:265
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:33
#define FUNC_DESCR_SYNCHRONOUS
Definition: cppexcept.h:134
void dump_function_descr(const cxx_function_descr *descr, uintptr_t base)
Definition: except.c:50
int handle_fpieee_flt(__msvcrt_ulong exception_code, EXCEPTION_POINTERS *ep, int(__cdecl *handler)(_FPIEEE_RECORD *))
#define FUNC_DESCR_NOEXCEPT
Definition: cppexcept.h:135
void * find_catch_handler(void *object, uintptr_t frame, uintptr_t exc_base, const tryblock_info *tryblock, cxx_exception_type *exc_type, uintptr_t image_base)
Definition: except.c:96
static void check_noexcept(PEXCEPTION_RECORD rec, const cxx_function_descr *descr, BOOL nested)
Definition: except.c:359
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:950
static void *WINAPI call_catch_block(EXCEPTION_RECORD *rec)
Definition: except.c:210
static void cxx_local_unwind(ULONG_PTR frame, DISPATCHER_CONTEXT *dispatch, const cxx_function_descr *descr, int last_level)
Definition: except.c:163
EXCEPTION_DISPOSITION CDECL __CxxFrameHandler(EXCEPTION_RECORD *rec, ULONG_PTR frame, CONTEXT *context, DISPATCHER_CONTEXT *dispatch)
Definition: except.c:497
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:889
static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG_PTR frame, CONTEXT *context, DISPATCHER_CONTEXT *dispatch, const cxx_function_descr *descr)
Definition: except.c:371
static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
Definition: except.c:339
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:992
#define __cdecl
Definition: corecrt.h:121
unsigned int uintptr_t
Definition: corecrt.h:185
#define __stdcall
Definition: corecrt.h:120
#define DECLSPEC_NORETURN
Definition: corecrt.h:131
unsigned long __msvcrt_ulong
Definition: corecrt.h:168
@ _FpCodeDivide
Definition: fpieee.h:42
@ _FpFormatFp64
Definition: fpieee.h:23
@ _FpFormatFp80
Definition: fpieee.h:24
_ACRTIMP void __cdecl longjmp(jmp_buf, int)
#define va_end(v)
Definition: stdarg.h:28
#define va_arg(v, l)
Definition: stdarg.h:27
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: thread.c:45
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
#define ULONG_PTR
Definition: config.h:101
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint level
Definition: gl.h:1546
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int reg
Definition: i386-dis.c:1290
void __cdecl _global_unwind2(void *Registration)
void _stdcall _seh_longjmp_unwind(const _JUMP_BUFFER *_Buf)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define exception_code
Definition: excpt.h:84
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
#define NtCurrentTeb
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT WINAPI nested(MSIHANDLE hinst)
Definition: custom.c:565
#define __ASM_NAME(name)
Definition: config.h:934
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:472
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:474
long LONG
Definition: pedump.c:60
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
int _setjmp3(jmp_buf env, int count,...)
#define long
Definition: qsort.c:33
#define WINAPIV
Definition: sdbpapi.h:64
DWORD(* cxx_exc_custom_handler)(PEXCEPTION_RECORD, cxx_exception_frame *, PCONTEXT, EXCEPTION_REGISTRATION_RECORD **, const cxx_function_descr *, int nested_trylevel, EXCEPTION_REGISTRATION_RECORD *nested_frame, DWORD unknown3)
Definition: cppexcept.h:137
struct __cxx_exception_frame cxx_exception_frame
const char * descr
Definition: boot.c:45
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
FLOATING_SAVE_AREA FloatSave
Definition: nt_native.h:1449
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
PEXCEPTION_ROUTINE Handler
Definition: compat.h:727
unsigned int Overflow
Definition: fpieee.h:214
unsigned int Inexact
Definition: fpieee.h:212
unsigned int ZeroDivide
Definition: fpieee.h:215
unsigned int Underflow
Definition: fpieee.h:213
unsigned int InvalidOperation
Definition: fpieee.h:216
_FPIEEE_EXCEPTION_FLAGS Status
Definition: fpieee.h:225
_FPIEEE_VALUE Operand2
Definition: fpieee.h:227
unsigned int Operation
Definition: fpieee.h:222
_FPIEEE_EXCEPTION_FLAGS Cause
Definition: fpieee.h:223
unsigned int Precision
Definition: fpieee.h:221
unsigned int RoundingMode
Definition: fpieee.h:220
_FPIEEE_EXCEPTION_FLAGS Enable
Definition: fpieee.h:224
_FPIEEE_VALUE Result
Definition: fpieee.h:228
_FPIEEE_VALUE Operand1
Definition: fpieee.h:226
unsigned int Format
Definition: fpieee.h:208
_FP64 Fp64Value
Definition: fpieee.h:192
union _FPIEEE_VALUE::@577 Value
_FP80 Fp80Value
Definition: fpieee.h:193
unsigned int OperandValid
Definition: fpieee.h:207
EXCEPTION_REGISTRATION_RECORD frame
Definition: cppexcept.h:58
Definition: match.c:390
Definition: http.c:7252
Definition: cookie.c:34
unsigned int custom_handler
Definition: cxx.h:453
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw edi esi edx esi movl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm1 paddd mm5 psrad mm1 psrad mm5 packssdw mm1 packssdw mm5 psubd mm0 psubd mm4 psubsw mm0 psubsw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi subl esi addl edx edi decl ecx jnz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm1 psrad mm1 packssdw mm1 psubd mm0 psubsw mm0 movd eax movw edi emms popl ebx popl esi popl edi mov ebp
Definition: synth_sse3d.h:266
#define UL
Definition: tui.h:164
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
int retval
Definition: wcstombs.cpp:91
#define __ASM_CFI(str)
Definition: asm.h:39
static EXCEPTION_REGISTRATION_RECORD * __wine_push_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:111
#define __EXCEPT_CTX(func, ctx)
Definition: exception.h:63
DECLSPEC_NORETURN void __cdecl __wine_longjmp(__wine_jmp_buf *buf, int retval)
static EXCEPTION_REGISTRATION_RECORD * __wine_pop_frame(EXCEPTION_REGISTRATION_RECORD *frame)
Definition: exception.h:125
#define EXCEPTION_EXIT_UNWIND
Definition: rtltypes.h:156
struct _EXCEPTION_POINTERS * PEXCEPTION_POINTERS
#define EXCEPTION_UNWINDING
Definition: rtltypes.h:155
#define const
Definition: zconf.h:233