[PSEH]
[reactos.git] / reactos / lib / pseh / i386 / pseh3.c
index 7e7d438..96760ea 100644 (file)
@@ -64,7 +64,7 @@ _SEH3$_Unregister(
 static inline
 LONG
 _SEH3$_InvokeNestedFunctionFilter(
-    PSEH3$_REGISTRATION_FRAME RegistrationFrame,
+    volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame,
     PVOID Filter)
 {
     LONG FilterResult;
@@ -82,8 +82,8 @@ _SEH3$_InvokeNestedFunctionFilter(
 
         /* Second call to get the filter result */
         "mov $1, %%ecx\n\t"
-        "call *%[Filter]\n\t"
-        : "=a"(FilterResult)
+        "call *%[Filter]"
+        : "=a" (FilterResult)
         : [RegistrationFrame] "m" (RegistrationFrame), [Filter] "m" (Filter)
         : "ecx", "edx");
 
@@ -93,17 +93,17 @@ _SEH3$_InvokeNestedFunctionFilter(
 long
 __attribute__((regparm(1)))
 _SEH3$_InvokeEmbeddedFilter(
-    PSEH3$_REGISTRATION_FRAME RegistrationFrame);
+    volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame);
 
 long
 __attribute__((regparm(1)))
 _SEH3$_InvokeEmbeddedFilterFromRegistration(
-    PSEH3$_REGISTRATION_FRAME RegistrationFrame);
+    volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame);
 
 static inline
 LONG
 _SEH3$_InvokeFilter(
-    PSEH3$_REGISTRATION_FRAME RegistrationFrame,
+    volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame,
     PVOID Filter)
 {
     LONG FilterResult;
@@ -130,6 +130,23 @@ _SEH3$_InvokeFilter(
     return FilterResult;
 }
 
+void
+__attribute__((regparm(1)))
+_SEH3$_AutoCleanup(
+    volatile SEH3$_REGISTRATION_FRAME *Frame)
+{
+    /* Check for __finally frames */
+    if (Frame->ScopeTable->Target == NULL)
+    {
+         _SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter);
+    }
+
+    if (Frame->Handler)
+        _SEH3$_UnregisterFrame(Frame);
+    else
+        _SEH3$_UnregisterTryLevel(Frame);
+}
+
 static inline
 LONG
 _SEH3$_GetFilterResult(
@@ -180,14 +197,14 @@ _SEH3$_JumpToTarget(
     {
         asm volatile (
             /* Load the registers */
-            "movl 20(%%ecx), %%esp\n"
-            "movl 24(%%ecx), %%ebp\n"
+            "movl 24(%%ecx), %%esp\n\t"
+            "movl 28(%%ecx), %%ebp\n\t"
 
             /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
-            "addl $4, %%esp\n"
+            "addl $4, %%esp\n\t"
 
             /* Jump into the exception handler */
-            "jmp *%[Target]\n"
+            "jmp *%[Target]"
             : :
             "c" (RegistrationFrame),
             "a" (RegistrationFrame->ScopeTable),
@@ -198,14 +215,14 @@ _SEH3$_JumpToTarget(
     {
         asm volatile (
             /* Load the registers */
-            "movl 20(%%ecx), %%esp\n"
-            "movl 24(%%ecx), %%ebp\n"
+            "movl 24(%%ecx), %%esp\n\t"
+            "movl 28(%%ecx), %%ebp\n\t"
 
             /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
-            "addl $4, %%esp\n"
+            "addl $4, %%esp\n\t"
 
             /* Jump into the exception handler */
-            "jmp *%[Target]\n"
+            "jmp *%[Target]"
             : :
             "c" (RegistrationFrame),
             "a" (RegistrationFrame->ScopeTable),
@@ -224,7 +241,9 @@ _SEH3$_CallRtlUnwind(
 
 EXCEPTION_DISPOSITION
 __cdecl
+#ifndef __clang__
 __attribute__ ((__target__ ("cld")))
+#endif
 _SEH3$_except_handler(
     struct _EXCEPTION_RECORD * ExceptionRecord,
     PSEH3$_REGISTRATION_FRAME EstablisherFrame,
@@ -236,7 +255,7 @@ _SEH3$_except_handler(
     LONG FilterResult;
 
     /* Clear the direction flag. */
-    asm volatile ("cld\n" : : : "memory");
+    asm volatile ("cld" : : : "memory");
 
     /* Save the exception pointers on the stack */
     ExceptionPointers.ExceptionRecord = ExceptionRecord;
@@ -257,8 +276,9 @@ _SEH3$_except_handler(
             /* Check if we have an exception handler */
             if (CurrentFrame->ScopeTable->Target != NULL)
             {
-                /* Set exception pointers for this frame */
+                /* Set exception pointers and code for this frame */
                 CurrentFrame->ExceptionPointers = &ExceptionPointers;
+                CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
 
                 /* Get the filter result */
                 FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
@@ -299,8 +319,9 @@ _SEH3$_except_handler(
         /* Check if this is an unwind frame */
         if (CurrentFrame->ScopeTable->Target == NULL)
         {
-            /* Set exception pointers for this frame */
+            /* Set exception pointers and code for this frame */
             CurrentFrame->ExceptionPointers = &ExceptionPointers;
+            CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
 
             /* Call the finally function */
             _SEH3$_CallFinally(CurrentFrame);