Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenframebased-gcchack.c
Go to the documentation of this file.
00001 /* 00002 Copyright (c) 2008 KJK::Hyperion 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a 00005 copy of this software and associated documentation files (the "Software"), 00006 to deal in the Software without restriction, including without limitation 00007 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 and/or sell copies of the Software, and to permit persons to whom the 00009 Software is furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00019 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00020 DEALINGS IN THE SOFTWARE. 00021 */ 00022 00023 #define _NTSYSTEM_ /* removes dllimport attribute from RtlUnwind */ 00024 00025 #define STRICT 00026 #define WIN32_LEAN_AND_MEAN 00027 #include <windows.h> 00028 00029 #include <pseh/pseh2.h> 00030 #include <excpt.h> 00031 #include <intrin.h> 00032 00033 #ifndef EXCEPTION_EXIT_UNWIND 00034 #define EXCEPTION_EXIT_UNWIND 4 00035 #endif 00036 00037 #ifndef EXCEPTION_UNWINDING 00038 #define EXCEPTION_UNWINDING 2 00039 #endif 00040 00041 extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *, void *, void *, void *); 00042 extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); 00043 extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); 00044 00045 typedef struct __SEHTrampoline 00046 { 00047 unsigned char STR_MovEcx; 00048 unsigned char * STR_Closure; 00049 unsigned char STR_Jmp; 00050 unsigned char * STR_Function; 00051 } 00052 __attribute__((packed)) 00053 _SEHTrampoline_t; 00054 00055 FORCEINLINE 00056 int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_) 00057 { 00058 return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9; 00059 } 00060 00061 FORCEINLINE 00062 void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_) 00063 { 00064 return (int)(trampoline_ + 1) + trampoline_->STR_Function; 00065 } 00066 00067 FORCEINLINE 00068 void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) 00069 { 00070 return trampoline_->STR_Closure; 00071 } 00072 00073 FORCEINLINE 00074 _SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void) 00075 { 00076 return (_SEH2Registration_t *)__readfsdword(0); 00077 } 00078 00079 FORCEINLINE 00080 void __cdecl __SEH2EnterFrame(_SEH2Registration_t * frame) 00081 { 00082 frame->SER_Prev = _SEH2CurrentRegistration(); 00083 __writefsdword(0, (unsigned long)frame); 00084 } 00085 00086 FORCEINLINE 00087 void __cdecl __SEH2LeaveFrame(void) 00088 { 00089 __writefsdword(0, (unsigned long)_SEH2CurrentRegistration()->SER_Prev); 00090 } 00091 00092 FORCEINLINE 00093 void _SEH2GlobalUnwind(void * target) 00094 { 00095 __asm__ __volatile__ 00096 ( 00097 "push %%ebp\n\t" 00098 "push $0\n\t" 00099 "push $0\n\t" 00100 "push $Return%=\n\t" 00101 "push %[target]\n\t" 00102 "call %c[RtlUnwind]\n" 00103 "Return%=:\n\t" 00104 "pop %%ebp" : 00105 : 00106 [target] "g" (target), [RtlUnwind] "g" (&RtlUnwind) : 00107 "eax", "ebx", "ecx", "edx", "esi", "edi", "flags", "memory" 00108 ); 00109 } 00110 00111 static 00112 __SEH_EXCEPT_RET _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, struct _EXCEPTION_POINTERS * ep) 00113 { 00114 void * filter = trylevel->ST_Filter; 00115 void * context = NULL; 00116 __SEH_EXCEPT_RET ret; 00117 00118 if(filter == (void *)0) 00119 return 0; 00120 00121 if(filter == (void *)1) 00122 return 1; 00123 00124 if(filter == (void *)-1) 00125 return -1; 00126 00127 if(_SEHIsTrampoline((_SEHTrampoline_t *)filter)) 00128 { 00129 context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)filter); 00130 filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter); 00131 } 00132 00133 __asm__ __volatile__ 00134 ( 00135 "push %[ep]\n\t" 00136 "push %[frame]\n\t" 00137 "call *%[filter]\n\t" 00138 "pop %%edx\n\t" 00139 "pop %%edx" : 00140 [ret] "=a" (ret) : 00141 "c" (context), [filter] "r" (filter), [frame] "r" (frame), [ep] "r" (ep) : 00142 "edx", "flags", "memory" 00143 ); 00144 00145 return ret; 00146 } 00147 00148 static 00149 void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) 00150 { 00151 if(trylevel->ST_Filter == NULL && trylevel->ST_Body != NULL) 00152 { 00153 void * body = trylevel->ST_Body; 00154 void * context = NULL; 00155 00156 if(_SEHIsTrampoline((_SEHTrampoline_t *)body)) 00157 { 00158 context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)body); 00159 body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body); 00160 } 00161 00162 __asm__ __volatile__("call *%1" : : "c" (context), "r" (body) : "eax", "edx", "flags", "memory"); 00163 } 00164 } 00165 00166 typedef struct __SEH2UnwindFrame 00167 { 00168 _SEH2Registration_t SUF_Registration; 00169 _SEH2Frame_t * SUF_Frame; 00170 volatile _SEH2TryLevel_t * SUF_TargetTryLevel; 00171 } 00172 _SEH2UnwindFrame_t; 00173 00174 static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *); 00175 00176 extern 00177 int __cdecl _SEH2UnwindHandler 00178 ( 00179 struct _EXCEPTION_RECORD * ExceptionRecord, 00180 void * EstablisherFrame, 00181 struct _CONTEXT * ContextRecord, 00182 void * DispatcherContext 00183 ) 00184 { 00185 if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) 00186 { 00187 _SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration); 00188 _SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel); 00189 *((void **)DispatcherContext) = EstablisherFrame; 00190 return ExceptionCollidedUnwind; 00191 } 00192 00193 return ExceptionContinueSearch; 00194 } 00195 00196 static 00197 void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel) 00198 { 00199 volatile _SEH2TryLevel_t * trylevel; 00200 _SEH2UnwindFrame_t unwindframe; 00201 00202 unwindframe.SUF_Frame = frame; 00203 unwindframe.SUF_TargetTryLevel = dsttrylevel; 00204 00205 unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler; 00206 __SEH2EnterFrame(&unwindframe.SUF_Registration); 00207 00208 for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next) 00209 { 00210 frame->SF_TopTryLevel = trylevel->ST_Next; 00211 _SEH2Finally(frame, trylevel); 00212 } 00213 00214 __SEH2LeaveFrame(); 00215 } 00216 00217 static DECLSPEC_NORETURN 00218 void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) 00219 { 00220 volatile _SEH2HandleTryLevel_t * fulltrylevel = CONTAINING_RECORD(trylevel, _SEH2HandleTryLevel_t, SHT_Common); 00221 00222 _SEH2GlobalUnwind(frame); 00223 _SEH2LocalUnwind(frame, &fulltrylevel->SHT_Common); 00224 frame->SF_TopTryLevel = fulltrylevel->SHT_Common.ST_Next; 00225 00226 __SEH2Handle 00227 ( 00228 fulltrylevel->SHT_Common.ST_Body, 00229 fulltrylevel->SHT_Esp, 00230 fulltrylevel->SHT_Ebp, 00231 fulltrylevel->SHT_Ebx, 00232 fulltrylevel->SHT_Esi, 00233 fulltrylevel->SHT_Edi 00234 ); 00235 } 00236 00237 extern 00238 int __cdecl _SEH2FrameHandler 00239 ( 00240 struct _EXCEPTION_RECORD * ExceptionRecord, 00241 void * EstablisherFrame, 00242 struct _CONTEXT * ContextRecord, 00243 void * DispatcherContext 00244 ) 00245 { 00246 _SEH2Frame_t * frame; 00247 00248 frame = EstablisherFrame; 00249 00250 /* Unwinding */ 00251 if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) 00252 { 00253 _SEH2LocalUnwind(frame, NULL); 00254 } 00255 /* Handling */ 00256 else 00257 { 00258 int ret = 0; 00259 volatile _SEH2TryLevel_t * trylevel; 00260 EXCEPTION_POINTERS ep; 00261 00262 ep.ExceptionRecord = ExceptionRecord; 00263 ep.ContextRecord = ContextRecord; 00264 00265 frame->SF_Code = ExceptionRecord->ExceptionCode; 00266 00267 for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel = trylevel->ST_Next) 00268 { 00269 ret = _SEH2Except(frame, trylevel, &ep); 00270 00271 if(ret < 0) 00272 return ExceptionContinueExecution; 00273 else if(ret > 0) 00274 _SEH2Handle(frame, trylevel); 00275 } 00276 } 00277 00278 return ExceptionContinueSearch; 00279 } 00280 00281 extern 00282 void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame) 00283 { 00284 frame->SF_Registration.SER_Handler = __SEH2FrameHandler; 00285 frame->SF_Code = 0; 00286 __SEH2EnterFrame(&frame->SF_Registration); 00287 } 00288 00289 extern 00290 int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) 00291 { 00292 frame->SF_TopTryLevel = trylevel; 00293 _SEH2EnterFrame(frame); 00294 return 0; 00295 } 00296 00297 extern 00298 void __cdecl _SEH2LeaveFrame(void) 00299 { 00300 __SEH2LeaveFrame(); 00301 } 00302 00303 extern 00304 void __cdecl _SEH2Return(void) 00305 { 00306 _SEH2LocalUnwind(CONTAINING_RECORD(_SEH2CurrentRegistration(), _SEH2Frame_t, SF_Registration), NULL); 00307 _SEH2LeaveFrame(); 00308 } 00309 00310 /* EOF */ Generated on Sat May 26 2012 04:35:16 for ReactOS by
1.7.6.1
|