ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

framebased-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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.