ReactOS 0.4.16-dev-106-g10b08aa
framebased-gcchack.c
Go to the documentation of this file.
1/*
2 Copyright (c) 2008 KJK::Hyperion
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21*/
22
23#define _NTSYSTEM_ /* removes dllimport attribute from RtlUnwind */
24
25#define STRICT
26#include <windef.h>
27#include <stdarg.h>
28
29#include <pseh/pseh2.h>
30#include <excpt.h>
31#include <intrin.h>
32
33#ifndef EXCEPTION_EXIT_UNWIND
34#define EXCEPTION_EXIT_UNWIND 4
35#endif
36
37#ifndef EXCEPTION_UNWINDING
38#define EXCEPTION_UNWINDING 2
39#endif
40
41extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *, void *, void *, void *);
42extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
43extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
44
45typedef struct __SEHTrampoline
46{
47 unsigned char STR_MovEcx;
48 unsigned char * STR_Closure;
49 unsigned char STR_Jmp;
50 unsigned char * STR_Function;
51}
53_SEHTrampoline_t;
56int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_)
57{
58 return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9;
59}
60
62void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_)
63{
64 return (int)(trampoline_ + 1) + trampoline_->STR_Function;
65}
66
68void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
69{
70 return trampoline_->STR_Closure;
71}
72
74_SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void)
75{
76 return (_SEH2Registration_t *)__readfsdword(0);
77}
78
80void __cdecl __SEH2EnterFrame(_SEH2Registration_t * frame)
81{
82 frame->SER_Prev = _SEH2CurrentRegistration();
83 __writefsdword(0, (unsigned long)frame);
84}
85
88{
89 __writefsdword(0, (unsigned long)_SEH2CurrentRegistration()->SER_Prev);
90}
91
94{
95 __asm__ __volatile__
96 (
97 "push %%ebp\n\t"
98 "push $0\n\t"
99 "push $0\n\t"
100 "push $Return%=\n\t"
101 "push %[target]\n\t"
102 "call %c[RtlUnwind]\n"
103 "Return%=:\n\t"
104 "pop %%ebp" :
105 :
106 [target] "g" (target), [RtlUnwind] "g" (&RtlUnwind) :
107 "eax", "ebx", "ecx", "edx", "esi", "edi", "flags", "memory"
108 );
109}
110
111static
112__SEH_EXCEPT_RET _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, struct _EXCEPTION_POINTERS * ep)
113{
114 void * filter = trylevel->ST_Filter;
115 void * context = NULL;
116 __SEH_EXCEPT_RET ret;
117
118 if(filter == (void *)0)
119 return 0;
120
121 if(filter == (void *)1)
122 return 1;
123
124 if(filter == (void *)-1)
125 return -1;
126
127 if(_SEHIsTrampoline((_SEHTrampoline_t *)filter))
128 {
129 context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)filter);
130 filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter);
131 }
132
133 __asm__ __volatile__
134 (
135 "push %[ep]\n\t"
136 "push %[frame]\n\t"
137 "call *%[filter]\n\t"
138 "pop %%edx\n\t"
139 "pop %%edx" :
140 [ret] "=a" (ret) :
141 "c" (context), [filter] "r" (filter), [frame] "r" (frame), [ep] "r" (ep) :
142 "edx", "flags", "memory"
143 );
144
145 return ret;
146}
147
148static
149void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
150{
151 if(trylevel->ST_Filter == NULL && trylevel->ST_Body != NULL)
152 {
153 void * body = trylevel->ST_Body;
154 void * context = NULL;
155
156 if(_SEHIsTrampoline((_SEHTrampoline_t *)body))
157 {
158 context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)body);
159 body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body);
160 }
161
162 __asm__ __volatile__("call *%1" : : "c" (context), "r" (body) : "eax", "edx", "flags", "memory");
163 }
164}
165
166typedef struct __SEH2UnwindFrame
167{
168 _SEH2Registration_t SUF_Registration;
169 _SEH2Frame_t * SUF_Frame;
170 volatile _SEH2TryLevel_t * SUF_TargetTryLevel;
171}
173
174static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
175
176extern
178(
179 struct _EXCEPTION_RECORD * ExceptionRecord,
180 void * EstablisherFrame,
181 struct _CONTEXT * ContextRecord,
182 void * DispatcherContext
183)
184{
186 {
188 _SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel);
191 }
192
194}
195
196static
197void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel)
198{
199 volatile _SEH2TryLevel_t * trylevel;
200 _SEH2UnwindFrame_t unwindframe;
201
202 unwindframe.SUF_Frame = frame;
203 unwindframe.SUF_TargetTryLevel = dsttrylevel;
204
205 unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler;
207
208 for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next)
209 {
210 frame->SF_TopTryLevel = trylevel->ST_Next;
211 _SEH2Finally(frame, trylevel);
212 }
213
215}
216
218void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
219{
220 volatile _SEH2HandleTryLevel_t * fulltrylevel = CONTAINING_RECORD(trylevel, _SEH2HandleTryLevel_t, SHT_Common);
221
222 _SEH2GlobalUnwind(frame);
223 _SEH2LocalUnwind(frame, &fulltrylevel->SHT_Common);
224 frame->SF_TopTryLevel = fulltrylevel->SHT_Common.ST_Next;
225
227 (
228 fulltrylevel->SHT_Common.ST_Body,
229 fulltrylevel->SHT_Esp,
230 fulltrylevel->SHT_Ebp,
231 fulltrylevel->SHT_Ebx,
232 fulltrylevel->SHT_Esi,
233 fulltrylevel->SHT_Edi
234 );
235}
236
237extern
239(
240 struct _EXCEPTION_RECORD * ExceptionRecord,
241 void * EstablisherFrame,
242 struct _CONTEXT * ContextRecord,
243 void * DispatcherContext
244)
245{
246 _SEH2Frame_t * frame;
247
248 frame = EstablisherFrame;
249
250 /* Unwinding */
252 {
253 _SEH2LocalUnwind(frame, NULL);
254 }
255 /* Handling */
256 else
257 {
258 int ret = 0;
259 volatile _SEH2TryLevel_t * trylevel;
261
262 ep.ExceptionRecord = ExceptionRecord;
264
265 frame->SF_Code = ExceptionRecord->ExceptionCode;
266
267 for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel = trylevel->ST_Next)
268 {
269 ret = _SEH2Except(frame, trylevel, &ep);
270
271 if(ret < 0)
273 else if(ret > 0)
274 _SEH2Handle(frame, trylevel);
275 }
276 }
277
279}
280
281extern
282void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame)
283{
284 frame->SF_Registration.SER_Handler = __SEH2FrameHandler;
285 frame->SF_Code = 0;
286 __SEH2EnterFrame(&frame->SF_Registration);
287}
288
289extern
290int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
291{
292 frame->SF_TopTryLevel = trylevel;
293 _SEH2EnterFrame(frame);
294 return 0;
295}
296
297extern
299{
301}
302
303extern
305{
306 _SEH2LocalUnwind(CONTAINING_RECORD(_SEH2CurrentRegistration(), _SEH2Frame_t, SF_Registration), NULL);
308}
309
310/* EOF */
#define __cdecl
Definition: accygwin.h:79
#define NULL
Definition: types.h:112
#define __attribute__(x)
Definition: wpp_private.h:207
@ ExceptionContinueSearch
Definition: compat.h:91
@ ExceptionCollidedUnwind
Definition: compat.h:93
@ ExceptionContinueExecution
Definition: compat.h:90
FORCEINLINE _SEH2Registration_t *__cdecl _SEH2CurrentRegistration(void)
#define EXCEPTION_EXIT_UNWIND
static __SEH_EXCEPT_RET _SEH2Except(_SEH2Frame_t *frame, volatile _SEH2TryLevel_t *trylevel, struct _EXCEPTION_POINTERS *ep)
FORCEINLINE void __cdecl __SEH2LeaveFrame(void)
static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *)
int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *)
struct __SEH2UnwindFrame _SEH2UnwindFrame_t
int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *frame, volatile _SEH2TryLevel_t *trylevel)
static DECLSPEC_NORETURN void _SEH2Handle(_SEH2Frame_t *frame, volatile _SEH2TryLevel_t *trylevel)
FORCEINLINE void * _SEHFunctionFromTrampoline(_SEHTrampoline_t *trampoline_)
int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *)
void __cdecl _SEH2EnterFrame(_SEH2Frame_t *frame)
void __cdecl _SEH2Return(void)
FORCEINLINE void * _SEHClosureFromTrampoline(_SEHTrampoline_t *trampoline_)
int __cdecl _SEH2UnwindHandler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, void *DispatcherContext)
static void _SEH2Finally(_SEH2Frame_t *frame, volatile _SEH2TryLevel_t *trylevel)
#define EXCEPTION_UNWINDING
DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *, void *, void *, void *)
void __cdecl _SEH2LeaveFrame(void)
int __cdecl _SEH2FrameHandler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, void *DispatcherContext)
FORCEINLINE void __cdecl __SEH2EnterFrame(_SEH2Registration_t *frame)
FORCEINLINE void _SEH2GlobalUnwind(void *target)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
GLenum target
Definition: glext.h:7315
PPC_QUAL void __writefsdword(const unsigned long Offset, const unsigned long Data)
Definition: intrin_ppc.h:354
PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
Definition: intrin_ppc.h:382
NTSYSAPI VOID NTAPI RtlUnwind(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue)
Definition: unwind.c:918
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:653
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:654
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT _In_ PVOID DispatcherContext
Definition: ntbasedef.h:655
__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")
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
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
volatile _SEH2TryLevel_t * SUF_TargetTryLevel
_SEH2Frame_t * SUF_Frame
_SEH2Registration_t SUF_Registration
unsigned char * STR_Closure
unsigned char STR_MovEcx
unsigned char * STR_Function
unsigned char STR_Jmp
Definition: http.c:7252
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
int ret
#define FORCEINLINE
Definition: wdftypes.h:67