1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 // Provenance of this code unclear. From crosswin32-dtrans-mingw.diff,
4 // but from where it got there, I don't know.
11 #error This file should be included only in a MinGW compilation
18 // See _EH_UNWINDING in MSVS9/VC/crt/src/except.inc
19 #define EH_UNWINDING 2
28 typedef int (*PF
)(void *, LPEXCEPTION_POINTERS
);
29 typedef void (*PH
)(void *, LPEXCEPTION_POINTERS
);
30 typedef void (*PN
)(void *);
31 void Set(jmp_buf jb
, void *pdata
=NULL
, PF pfilter
=NULL
, PH phandlerbody
=NULL
, PN pfinal
=NULL
)
33 __builtin_memcpy(m_jmpbuf
, jb
, sizeof(jmp_buf));
35 switch (reinterpret_cast<int>(pfilter
))
40 case EXCEPTION_CONTINUE_EXECUTION
:
41 m_filter
=DefaultFilterContinueExecution
;
43 case EXCEPTION_EXECUTE_HANDLER
:
44 m_filter
=DefaultFilterExecuteHandler
;
46 case EXCEPTION_CONTINUE_SEARCH
:
47 m_filter
=DefaultFilterContinueSearch
;
51 m_handlerbody
=phandlerbody
;
53 m_handlerbody
=DefaultHandler
;
58 m_ER
.pHandlerClass
= this;
60 asm("movl %%fs:0, %%eax\n\t"
61 "movl %%eax, %0": : "m" (m_ER
.prev
): "%eax" );
62 asm("movl %0, %%eax\n\t"
63 "movl %%eax, %%fs:0": : "r" (&m_ER
): "%eax" );
68 asm("movl %0, %%eax \n\t"
70 : : "m" (m_ER
.prev
): "%eax");
73 __SEHandler(const __SEHandler
&);
74 __SEHandler
& operator=(const __SEHandler
&);
77 PEXCEPTION_HANDLER hp
;
78 __SEHandler
*pHandlerClass
;
80 static EXCEPTION_DISPOSITION
handler(struct _EXCEPTION_RECORD
*pExceptionRecord
,
81 void * EstablisherFrame
,
82 struct _CONTEXT
*ContextRecord
,
83 void * /*DispatcherContext*/)
85 __SEHandler
* pThis
= reinterpret_cast< _ER
* >(EstablisherFrame
)->pHandlerClass
;
86 if (pExceptionRecord
->ExceptionFlags
& EH_UNWINDING
)
88 pThis
->m_final(pThis
->m_pData
);
89 return ExceptionContinueSearch
;
91 EXCEPTION_POINTERS ep
={pExceptionRecord
, ContextRecord
};
92 switch (pThis
->m_filter(pThis
->m_pData
, &ep
))
94 case EXCEPTION_EXECUTE_HANDLER
:
95 RtlUnwind(EstablisherFrame
, &&__set_label
, pExceptionRecord
, 0);
97 pThis
->m_handlerbody(pThis
->m_pData
, &ep
);
98 ContextRecord
->Ebp
= pThis
->m_jmpbuf
[0];
99 ContextRecord
->Eip
= pThis
->m_jmpbuf
[1];
100 ContextRecord
->Esp
= pThis
->m_jmpbuf
[2];
101 return ExceptionContinueExecution
;
102 case EXCEPTION_CONTINUE_SEARCH
:
103 return ExceptionContinueSearch
;
104 case EXCEPTION_CONTINUE_EXECUTION
:
105 return ExceptionContinueExecution
;
107 return ExceptionContinueExecution
;
109 static int DefaultFilterContinueSearch(void *, LPEXCEPTION_POINTERS
) { return EXCEPTION_CONTINUE_SEARCH
; }
110 static int DefaultFilterContinueExecution(void *, LPEXCEPTION_POINTERS
) { return EXCEPTION_CONTINUE_EXECUTION
; }
111 static int DefaultFilterExecuteHandler(void *, LPEXCEPTION_POINTERS
) { return EXCEPTION_EXECUTE_HANDLER
; }
112 static void DefaultHandler(void *, LPEXCEPTION_POINTERS
) {}
113 static void DefaultFinal(void *) {}
114 typedef int (*handler_p
)(struct _EXCEPTION_RECORD
*ExceptionRecord
,
115 void * EstablisherFrame
,
116 struct _CONTEXT
*ContextRecord
,
117 void * DispatcherContext
);
128 #endif // _SEHANDLER_HXX