branch update for HEAD-2003091401
[reactos.git] / lib / ntdll / rtl / i386 / except.s
index 41c12ac..49acc79 100755 (executable)
-/* $Id$\r
- *\r
- * COPYRIGHT:         See COPYING in the top level directory\r
- * PROJECT:           ReactOS kernel\r
- * PURPOSE:           User-mode exception support for IA-32\r
- * FILE:              lib/ntdll/rtl/i386/except.s\r
- * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)\r
- * NOTES:             This file is shared with ntoskrnl/rtl/i386/except.s.\r
- *                    Please keep them in sync.\r
- */\r
-\r
-#define EXCEPTION_UNWINDING            0x02\r
-\r
-#define EREC_FLAGS                             0x04\r
-\r
-#define ExceptionContinueExecution 0\r
-#define ExceptionContinueSearch    1\r
-#define ExceptionNestedException   2\r
-#define ExceptionCollidedUnwind    3\r
-\r
-.globl _RtlpExecuteHandlerForException\r
-.globl _RtlpExecuteHandlerForUnwind\r
-\r
-#define CONTEXT_FLAGS  0x00\r
-#define CONTEXT_SEGGS  0x8C\r
-#define CONTEXT_SEGFS  0x90\r
-#define CONTEXT_SEGES  0x94\r
-#define CONTEXT_SEGDS  0x98\r
-#define CONTEXT_EDI            0x9C\r
-#define CONTEXT_ESI            0xA0\r
-#define CONTEXT_EBX            0xA4\r
-#define CONTEXT_EDX            0xA8\r
-#define CONTEXT_ECX            0xAC\r
-#define CONTEXT_EAX            0xB0\r
-#define CONTEXT_EBP            0xB4\r
-#define CONTEXT_EIP            0xB8\r
-#define CONTEXT_SEGCS  0xBC\r
-#define CONTEXT_EFLAGS 0xC0\r
-#define CONTEXT_ESP            0xC4\r
-#define CONTEXT_SEGSS  0xC8\r
-\r
-\r
-#define RCC_CONTEXT            0x08\r
-\r
-// EAX = value to print\r
-_do_debug:\r
-       pushal\r
-       pushl   %eax\r
-       call    _AsmDebug@4\r
-       popal\r
-       ret\r
-\r
-#ifndef __NTOSKRNL__\r
-\r
-//\r
-// VOID\r
-// RtlpCaptureContext(PCONTEXT pContext);\r
-//\r
-// Parameters:\r
-//   [ESP+08h] - PCONTEXT_X86 pContext\r
-// Registers:\r
-//   None\r
-// Returns:\r
-//   Nothing\r
-// Notes:\r
-//   Grabs the current CPU context.\r
-.globl _RtlpCaptureContext\r
-_RtlpCaptureContext:\r
-       pushl   %ebp\r
-    movl       %esp, %ebp\r
-       movl    RCC_CONTEXT(%ebp), %edx         // EDX = Address of context structure\r
-\r
-       cld\r
-       pushf\r
-       pop             %eax\r
-       movl    %eax, CONTEXT_EFLAGS(%edx)\r
-       xorl    %eax, %eax\r
-       movl    %eax, CONTEXT_EAX(%edx)\r
-       movl    %eax, CONTEXT_EBX(%edx)\r
-       movl    %eax, CONTEXT_ECX(%edx)\r
-       movl    %eax, CONTEXT_EDX(%edx)\r
-       movl    %eax, CONTEXT_ESI(%edx)\r
-       movl    %eax, CONTEXT_EDI(%edx)\r
-       movl    %cs, %eax\r
-       movl    %eax, CONTEXT_SEGCS(%edx)\r
-       movl    %ds, %eax\r
-       movl    %eax, CONTEXT_SEGDS(%edx)\r
-       movl    %es, %eax\r
-       movl    %eax, CONTEXT_SEGES(%edx)\r
-       movl    %fs, %eax\r
-       movl    %eax, CONTEXT_SEGFS(%edx)\r
-       movl    %gs, %eax\r
-       movl    %eax, CONTEXT_SEGGS(%edx)\r
-       movl    %ss, %eax\r
-       movl    %eax, CONTEXT_SEGSS(%edx)\r
-\r
-       //\r
-       // STACK LAYOUT: - (ESP to put in context structure)\r
-       //               - RETURN ADDRESS OF CALLER OF CALLER\r
-       //               - EBP OF CALLER OF CALLER\r
-       //                 ...\r
-       //               - RETURN ADDRESS OF CALLER\r
-       //               - EBP OF CALLER\r
-       //                 ...\r
-       //\r
-\r
-       // Get return address of the caller of the caller of this function\r
-       movl    %ebp, %ebx\r
-       //movl  4(%ebx), %eax                   // EAX = return address of caller\r
-       movl    (%ebx), %ebx                    // EBX = EBP of caller\r
-\r
-       movl    4(%ebx), %eax                   // EAX = return address of caller of caller\r
-       movl    (%ebx), %ebx                    // EBX = EBP of caller of caller\r
-\r
-       movl    %eax, CONTEXT_EIP(%edx) // EIP = return address of caller of caller\r
-       movl    %ebx, CONTEXT_EBP(%edx) // EBP = EBP of caller of caller\r
-       addl    $8, %ebx\r
-       movl    %ebx, CONTEXT_ESP(%edx) // ESP = EBP of caller of caller + 8\r
-\r
-    movl       %ebp, %esp\r
-    popl       %ebp\r
-    ret\r
-\r
-#endif /* !__NTOSKRNL__ */\r
-\r
-#define REH_ERECORD            0x08\r
-#define REH_RFRAME             0x0C\r
-#define REH_CONTEXT            0x10\r
-#define REH_DCONTEXT   0x14\r
-#define REH_EROUTINE   0x18\r
-\r
-// Parameters:\r
-//   None\r
-// Registers:\r
-//   [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord\r
-//   [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame\r
-//   [EBP+10h] - PVOID Context\r
-//   [EBP+14h] - PVOID DispatcherContext\r
-//   [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine\r
-//   EDX       - Address of protecting exception handler\r
-// Returns:\r
-//   EXCEPTION_DISPOSITION\r
-// Notes:\r
-//   Setup the protecting exception handler and call the exception\r
-//   handler in the right context.\r
-_RtlpExecuteHandler:\r
-       pushl    %ebp\r
-    movl     %esp, %ebp\r
-    pushl    REH_RFRAME(%ebp)\r
-\r
-    pushl    %edx\r
-    pushl    %fs:0x0\r
-    movl     %esp, %fs:0x0\r
-\r
-    // Prepare to call the exception handler\r
-    pushl    REH_DCONTEXT(%ebp)\r
-    pushl    REH_CONTEXT(%ebp)\r
-    pushl    REH_RFRAME(%ebp)\r
-    pushl    REH_ERECORD(%ebp)\r
-\r
-    // Now call the exception handler\r
-    movl     REH_EROUTINE(%ebp), %eax\r
-    call    *%eax\r
-\r
-       cmpl    $-1, %fs:0x0\r
-       jne             .reh_stack_looks_ok\r
-\r
-       // This should not happen\r
-       pushl   0\r
-       pushl   0\r
-       pushl   0\r
-       pushl   0\r
-       call    _RtlAssert@16\r
-\r
-.reh_loop:\r
-       jmp     .reh_loop\r
-       \r
-.reh_stack_looks_ok:\r
-    movl     %fs:0x0, %esp\r
-\r
-    // Return to the 'front-end' for this function\r
-    popl     %fs:0x0\r
-    movl     %ebp, %esp\r
-    popl     %ebp\r
-    ret\r
-\r
-\r
-#define REP_ERECORD     0x04\r
-#define REP_RFRAME      0x08\r
-#define REP_CONTEXT     0x0C\r
-#define REP_DCONTEXT    0x10\r
-\r
-// Parameters:\r
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord\r
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame\r
-//   [ESP+0Ch] - PCONTEXT Context\r
-//   [ESP+10h] - PVOID DispatcherContext\r
-// Registers:\r
-//   None\r
-// Returns:\r
-//   EXCEPTION_DISPOSITION\r
-// Notes:\r
-//    This exception handler protects the exception handling\r
-//    mechanism by detecting nested exceptions.\r
-_RtlpExceptionProtector:\r
-    movl     $ExceptionContinueSearch, %eax\r
-    movl     REP_ERECORD(%esp), %ecx\r
-    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)\r
-    jnz      .rep_end\r
-\r
-    // Unwinding is not taking place, so return ExceptionNestedException\r
-\r
-    // Set DispatcherContext field to the exception registration for the\r
-    // exception handler that executed when a nested exception occurred\r
-    movl     REP_DCONTEXT(%esp), %ecx\r
-    movl     REP_RFRAME(%esp), %eax\r
-    movl     %eax, (%ecx)\r
-    movl     $ExceptionNestedException, %eax\r
-\r
-.rep_end:\r
-    ret\r
-\r
-\r
-// Parameters:\r
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord\r
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame\r
-//   [ESP+0Ch] - PCONTEXT Context\r
-//   [ESP+10h] - PVOID DispatcherContext\r
-//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler\r
-// Registers:\r
-//   None\r
-// Returns:\r
-//   EXCEPTION_DISPOSITION\r
-// Notes:\r
-//   Front-end\r
-_RtlpExecuteHandlerForException:\r
-    movl     $_RtlpExceptionProtector, %edx\r
-    jmp      _RtlpExecuteHandler\r
-\r
-\r
-#define RUP_ERECORD     0x04\r
-#define RUP_RFRAME      0x08\r
-#define RUP_CONTEXT     0x0C\r
-#define RUP_DCONTEXT    0x10\r
-\r
-// Parameters:\r
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord\r
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame\r
-//   [ESP+0Ch] - PCONTEXT Context\r
-//   [ESP+10h] - PVOID DispatcherContext\r
-// Registers:\r
-//   None\r
-// Returns:\r
-//   EXCEPTION_DISPOSITION\r
-// Notes:\r
-//    This exception handler protects the exception handling\r
-//    mechanism by detecting collided unwinds.\r
-_RtlpUnwindProtector:\r
-    movl     $ExceptionContinueSearch, %eax\r
-    movl     %ecx, RUP_ERECORD(%esp)\r
-    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)\r
-    jz       .rup_end\r
-\r
-    // Unwinding is taking place, so return ExceptionCollidedUnwind\r
-\r
-    movl     RUP_RFRAME(%esp), %ecx\r
-    movl     RUP_DCONTEXT(%esp), %edx\r
-\r
-    // Set DispatcherContext field to the exception registration for the\r
-    // exception handler that executed when a collision occurred\r
-    movl     RUP_RFRAME(%ecx), %eax\r
-    movl     %eax, (%edx)\r
-    movl     $ExceptionCollidedUnwind, %eax\r
-\r
-.rup_end:\r
-    ret\r
-\r
-\r
-// Parameters:\r
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord\r
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame\r
-//   [ESP+0Ch] - PCONTEXT Context\r
-//   [ESP+10h] - PVOID DispatcherContext\r
-//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler\r
-// Registers:\r
-//   None\r
-// Returns:\r
-//   EXCEPTION_DISPOSITION\r
-_RtlpExecuteHandlerForUnwind:\r
-    movl     $_RtlpUnwindProtector, %edx\r
-    jmp      _RtlpExecuteHandler\r
+/* $Id$
+ *
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS kernel
+ * PURPOSE:           User-mode exception support for IA-32
+ * FILE:              lib/ntdll/rtl/i386/except.s
+ * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:             This file is shared with ntoskrnl/rtl/i386/except.s.
+ *                    Please keep them in sync.
+ */
+
+#define EXCEPTION_UNWINDING            0x02
+
+#define EREC_FLAGS                             0x04
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch    1
+#define ExceptionNestedException   2
+#define ExceptionCollidedUnwind    3
+
+.globl _RtlpExecuteHandlerForException
+.globl _RtlpExecuteHandlerForUnwind
+
+#define CONTEXT_FLAGS  0x00
+#define CONTEXT_SEGGS  0x8C
+#define CONTEXT_SEGFS  0x90
+#define CONTEXT_SEGES  0x94
+#define CONTEXT_SEGDS  0x98
+#define CONTEXT_EDI            0x9C
+#define CONTEXT_ESI            0xA0
+#define CONTEXT_EBX            0xA4
+#define CONTEXT_EDX            0xA8
+#define CONTEXT_ECX            0xAC
+#define CONTEXT_EAX            0xB0
+#define CONTEXT_EBP            0xB4
+#define CONTEXT_EIP            0xB8
+#define CONTEXT_SEGCS  0xBC
+#define CONTEXT_EFLAGS 0xC0
+#define CONTEXT_ESP            0xC4
+#define CONTEXT_SEGSS  0xC8
+
+
+#define RCC_CONTEXT            0x08
+
+// EAX = value to print
+_do_debug:
+       pushal
+       pushl   %eax
+       call    _AsmDebug@4
+       popal
+       ret
+
+#ifndef __NTOSKRNL__
+
+//
+// VOID
+// RtlpCaptureContext(PCONTEXT pContext);
+//
+// Parameters:
+//   [ESP+08h] - PCONTEXT_X86 pContext
+// Registers:
+//   None
+// Returns:
+//   Nothing
+// Notes:
+//   Grabs the current CPU context.
+.globl _RtlpCaptureContext
+_RtlpCaptureContext:
+       pushl   %ebp
+    movl       %esp, %ebp
+       movl    RCC_CONTEXT(%ebp), %edx         // EDX = Address of context structure
+
+       cld
+       pushf
+       pop             %eax
+       movl    %eax, CONTEXT_EFLAGS(%edx)
+       xorl    %eax, %eax
+       movl    %eax, CONTEXT_EAX(%edx)
+       movl    %eax, CONTEXT_EBX(%edx)
+       movl    %eax, CONTEXT_ECX(%edx)
+       movl    %eax, CONTEXT_EDX(%edx)
+       movl    %eax, CONTEXT_ESI(%edx)
+       movl    %eax, CONTEXT_EDI(%edx)
+       movl    %cs, %eax
+       movl    %eax, CONTEXT_SEGCS(%edx)
+       movl    %ds, %eax
+       movl    %eax, CONTEXT_SEGDS(%edx)
+       movl    %es, %eax
+       movl    %eax, CONTEXT_SEGES(%edx)
+       movl    %fs, %eax
+       movl    %eax, CONTEXT_SEGFS(%edx)
+       movl    %gs, %eax
+       movl    %eax, CONTEXT_SEGGS(%edx)
+       movl    %ss, %eax
+       movl    %eax, CONTEXT_SEGSS(%edx)
+
+       //
+       // STACK LAYOUT: - (ESP to put in context structure)
+       //               - RETURN ADDRESS OF CALLER OF CALLER
+       //               - EBP OF CALLER OF CALLER
+       //                 ...
+       //               - RETURN ADDRESS OF CALLER
+       //               - EBP OF CALLER
+       //                 ...
+       //
+
+       // Get return address of the caller of the caller of this function
+       movl    %ebp, %ebx
+       //movl  4(%ebx), %eax                   // EAX = return address of caller
+       movl    (%ebx), %ebx                    // EBX = EBP of caller
+
+       movl    4(%ebx), %eax                   // EAX = return address of caller of caller
+       movl    (%ebx), %ebx                    // EBX = EBP of caller of caller
+
+       movl    %eax, CONTEXT_EIP(%edx) // EIP = return address of caller of caller
+       movl    %ebx, CONTEXT_EBP(%edx) // EBP = EBP of caller of caller
+       addl    $8, %ebx
+       movl    %ebx, CONTEXT_ESP(%edx) // ESP = EBP of caller of caller + 8
+
+    movl       %ebp, %esp
+    popl       %ebp
+    ret
+
+#endif /* !__NTOSKRNL__ */
+
+#define REH_ERECORD            0x08
+#define REH_RFRAME             0x0C
+#define REH_CONTEXT            0x10
+#define REH_DCONTEXT   0x14
+#define REH_EROUTINE   0x18
+
+// Parameters:
+//   None
+// Registers:
+//   [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
+//   [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [EBP+10h] - PVOID Context
+//   [EBP+14h] - PVOID DispatcherContext
+//   [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
+//   EDX       - Address of protecting exception handler
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Setup the protecting exception handler and call the exception
+//   handler in the right context.
+_RtlpExecuteHandler:
+       pushl    %ebp
+    movl     %esp, %ebp
+    pushl    REH_RFRAME(%ebp)
+
+    pushl    %edx
+    pushl    %fs:0x0
+    movl     %esp, %fs:0x0
+
+    // Prepare to call the exception handler
+    pushl    REH_DCONTEXT(%ebp)
+    pushl    REH_CONTEXT(%ebp)
+    pushl    REH_RFRAME(%ebp)
+    pushl    REH_ERECORD(%ebp)
+
+    // Now call the exception handler
+    movl     REH_EROUTINE(%ebp), %eax
+    call    *%eax
+
+       cmpl    $-1, %fs:0x0
+       jne             .reh_stack_looks_ok
+
+       // This should not happen
+       pushl   0
+       pushl   0
+       pushl   0
+       pushl   0
+       call    _RtlAssert@16
+
+.reh_loop:
+       jmp     .reh_loop
+
+.reh_stack_looks_ok:
+    movl     %fs:0x0, %esp
+
+    // Return to the 'front-end' for this function
+    popl     %fs:0x0
+    movl     %ebp, %esp
+    popl     %ebp
+    ret
+
+
+#define REP_ERECORD     0x04
+#define REP_RFRAME      0x08
+#define REP_CONTEXT     0x0C
+#define REP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting nested exceptions.
+_RtlpExceptionProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     REP_ERECORD(%esp), %ecx
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jnz      .rep_end
+
+    // Unwinding is not taking place, so return ExceptionNestedException
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a nested exception occurred
+    movl     REP_DCONTEXT(%esp), %ecx
+    movl     REP_RFRAME(%esp), %eax
+    movl     %eax, (%ecx)
+    movl     $ExceptionNestedException, %eax
+
+.rep_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Front-end
+_RtlpExecuteHandlerForException:
+    movl     $_RtlpExceptionProtector, %edx
+    jmp      _RtlpExecuteHandler
+
+
+#define RUP_ERECORD     0x04
+#define RUP_RFRAME      0x08
+#define RUP_CONTEXT     0x0C
+#define RUP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting collided unwinds.
+_RtlpUnwindProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     %ecx, RUP_ERECORD(%esp)
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jz       .rup_end
+
+    // Unwinding is taking place, so return ExceptionCollidedUnwind
+
+    movl     RUP_RFRAME(%esp), %ecx
+    movl     RUP_DCONTEXT(%esp), %edx
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a collision occurred
+    movl     RUP_RFRAME(%ecx), %eax
+    movl     %eax, (%edx)
+    movl     $ExceptionCollidedUnwind, %eax
+
+.rup_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+_RtlpExecuteHandlerForUnwind:
+    movl     $_RtlpUnwindProtector, %edx
+    jmp      _RtlpExecuteHandler