From 2db7ea2321ea2d0d3cb98d83818d958b8e964097 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 11 Nov 2007 15:47:21 +0000 Subject: [PATCH] - After bugfixing, more complete except_nt exception handling implementation could be used, so get rid of the old one and thus code duplication. - Move cpp/cppexcept.c to /except directory, and add a specific note in README.WINE that those files are shared with Wine. - I moved PowerPC stubs too, but it will most probably break anyway, due to more missing stubs, my apologize. See issue #2371 for more details. svn path=/trunk/; revision=30359 --- reactos/lib/sdk/crt/crt.rbuild | 11 +- reactos/lib/sdk/crt/except/abnorter.c | 15 - reactos/lib/sdk/crt/{wine => except}/cpp.c | 0 .../lib/sdk/crt/{wine => except}/cppexcept.c | 0 reactos/lib/sdk/crt/except/exhand2.c | 33 - .../{except_nt => except}/i386/chkstk_asm.s | 0 reactos/lib/sdk/crt/except/i386/seh.s | 731 ++++++++++-------- reactos/lib/sdk/crt/except/i386/unwind.c | 16 - .../powerpc/chkstk_asm.s | 0 .../crt/{except_nt => except}/powerpc/seh.s | 0 reactos/lib/sdk/crt/except_nt/i386/seh.s | 468 ----------- reactos/lib/sdk/crt/libcntpr.rbuild | 2 +- reactos/media/doc/README.WINE | 2 + 13 files changed, 427 insertions(+), 851 deletions(-) rename reactos/lib/sdk/crt/{wine => except}/cpp.c (100%) rename reactos/lib/sdk/crt/{wine => except}/cppexcept.c (100%) delete mode 100644 reactos/lib/sdk/crt/except/exhand2.c rename reactos/lib/sdk/crt/{except_nt => except}/i386/chkstk_asm.s (100%) mode change 100755 => 100644 reactos/lib/sdk/crt/except/i386/seh.s rename reactos/lib/sdk/crt/{except_nt => except}/powerpc/chkstk_asm.s (100%) rename reactos/lib/sdk/crt/{except_nt => except}/powerpc/seh.s (100%) delete mode 100644 reactos/lib/sdk/crt/except_nt/i386/seh.s diff --git a/reactos/lib/sdk/crt/crt.rbuild b/reactos/lib/sdk/crt/crt.rbuild index e08dbce33b1..94c1714b98a 100644 --- a/reactos/lib/sdk/crt/crt.rbuild +++ b/reactos/lib/sdk/crt/crt.rbuild @@ -40,7 +40,8 @@ abnorter.c - exhand2.c + cpp.c + cppexcept.c matherr.c @@ -49,6 +50,12 @@ unwind.c + + + seh.s + chkstk_asm.s + + xcptfil.c @@ -475,8 +482,6 @@ wlasttok.c - cpp.c - cppexcept.c heap.c scanf.c thread.c diff --git a/reactos/lib/sdk/crt/except/abnorter.c b/reactos/lib/sdk/crt/except/abnorter.c index 8cdf74c6efc..05342c2d6c5 100644 --- a/reactos/lib/sdk/crt/except/abnorter.c +++ b/reactos/lib/sdk/crt/except/abnorter.c @@ -1,16 +1 @@ #include - -#ifdef __GNUC__ - -/* - * @unimplemented - */ -int _abnormal_termination(void) -{ - printf("Abnormal Termination\n"); -// return AbnormalTermination(); - return 0; -} - -#else -#endif diff --git a/reactos/lib/sdk/crt/wine/cpp.c b/reactos/lib/sdk/crt/except/cpp.c similarity index 100% rename from reactos/lib/sdk/crt/wine/cpp.c rename to reactos/lib/sdk/crt/except/cpp.c diff --git a/reactos/lib/sdk/crt/wine/cppexcept.c b/reactos/lib/sdk/crt/except/cppexcept.c similarity index 100% rename from reactos/lib/sdk/crt/wine/cppexcept.c rename to reactos/lib/sdk/crt/except/cppexcept.c diff --git a/reactos/lib/sdk/crt/except/exhand2.c b/reactos/lib/sdk/crt/except/exhand2.c deleted file mode 100644 index 963e9730248..00000000000 --- a/reactos/lib/sdk/crt/except/exhand2.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#ifdef __GNUC__ -#else -ULONG DbgPrint(PCH Format,...) -{ - return 0; -} -#endif - -VOID STDCALL -MsvcrtDebug(ULONG Value) -{ - //DbgPrint("MsvcrtDebug 0x%.08x\n", Value); -} - -struct _EXCEPTION_RECORD; -struct _CONTEXT; - -/* - * @implemented - */ -EXCEPTION_DISPOSITION -_except_handler2( -struct _EXCEPTION_RECORD *ExceptionRecord, -void *Frame, -struct _CONTEXT *ContextRecord, -void *DispatcherContext) -{ - //printf("_except_handler2()\n"); - return 0; -} diff --git a/reactos/lib/sdk/crt/except_nt/i386/chkstk_asm.s b/reactos/lib/sdk/crt/except/i386/chkstk_asm.s similarity index 100% rename from reactos/lib/sdk/crt/except_nt/i386/chkstk_asm.s rename to reactos/lib/sdk/crt/except/i386/chkstk_asm.s diff --git a/reactos/lib/sdk/crt/except/i386/seh.s b/reactos/lib/sdk/crt/except/i386/seh.s old mode 100755 new mode 100644 index 351a7dff7e9..96ec9951e9b --- a/reactos/lib/sdk/crt/except/i386/seh.s +++ b/reactos/lib/sdk/crt/except/i386/seh.s @@ -1,367 +1,468 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS MSVCRT Runtime Library - * PURPOSE: Runtime library exception support for IA-32 - * FILE: lib/msvcrt/except/seh.s - * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * NOTES: This file is shared with ntoskrnl/rtl/i386/seh.s. - * Please keep them in sync. +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS CRT + * FILE: lib/crt/misc/i386/seh.S + * PURPOSE: SEH Support for the CRT + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -#define ExceptionContinueExecution 0 -#define ExceptionContinueSearch 1 -#define ExceptionNestedException 2 -#define ExceptionCollidedUnwind 3 +/* INCLUDES ******************************************************************/ -#define EXCEPTION_NONCONTINUABLE 0x01 -#define EXCEPTION_UNWINDING 0x02 -#define EXCEPTION_EXIT_UNWIND 0x04 -#define EXCEPTION_STACK_INVALID 0x08 -#define EXCEPTION_NESTED_CALL 0x10 -#define EXCEPTION_TARGET_UNWIND 0x20 -#define EXCEPTION_COLLIDED_UNWIND 0x40 +#include +.intel_syntax noprefix -#define EXCEPTION_UNWIND_MODE \ -( EXCEPTION_UNWINDING \ - | EXCEPTION_EXIT_UNWIND \ - | EXCEPTION_TARGET_UNWIND \ - | EXCEPTION_COLLIDED_UNWIND) +#define DISPOSITION_DISMISS 0 +#define DISPOSITION_CONTINUE_SEARCH 1 +#define DISPOSITION_COLLIDED_UNWIND 3 -#define EREC_CODE 0x00 -#define EREC_FLAGS 0x04 -#define EREC_RECORD 0x08 -#define EREC_ADDRESS 0x0C -#define EREC_NUMPARAMS 0x10 -#define EREC_INFO 0x14 - -#define TRYLEVEL_NONE -1 -#define TRYLEVEL_INVALID -2 - -#define ER_STANDARDESP -0x08 -#define ER_EPOINTERS -0x04 -#define ER_PREVFRAME 0x00 -#define ER_HANDLER 0x04 -#define ER_SCOPETABLE 0x08 -#define ER_TRYLEVEL 0x0C -#define ER_EBP 0x10 - -#define ST_TRYLEVEL 0x00 -#define ST_FILTER 0x04 -#define ST_HANDLER 0x08 - -#define CONTEXT_EDI 0x9C -#define CONTEXT_EBX 0xA4 -#define CONTEXT_EIP 0xB8 +/* GLOBALS *******************************************************************/ +.globl __global_unwind2 .globl __local_unwind2 +.globl __abnormal_termination +.globl __except_handler2 .globl __except_handler3 -// EAX = value to print -_do_debug: - pushal - pushl %eax - call _MsvcrtDebug@4 - popal - ret +/* FUNCTIONS *****************************************************************/ -#define LU2_TRYLEVEL 0x08 -#define LU2_REGFRAME 0x04 +.func unwind_handler +_unwind_handler: -// -// void -// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame, -// LONG TryLevel) -// -// Parameters: -// [EDX+08h] - PEXCEPTION_REGISTRATION RegistrationFrame -// [EDX+04h] - LONG TryLevel -// Registers: -// EBP - EBP of call frame we are unwinding -// Returns: -// Nothing -// Notes: -// Run all termination handlers for a call frame from the current -// try-level up to (but not including) the given stop try-level. -__local_unwind2: - // Setup our call frame so we can access parameters using EDX - //pushl %ebp - movl %esp, %edx + /* Check if we were unwinding and continue search if not */ + mov ecx, [esp+4] + test dword ptr [ecx+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING + mov eax, DISPOSITION_CONTINUE_SEARCH + jz unwind_handler_return - // FIXME: Setup an EXCEPTION_REGISTRATION entry to protect the - // unwinding in case something goes wrong + /* We have a collision, do a local unwind */ + mov eax, [esp+20] + push ebp + mov ebp, [eax+16] + mov edx, [eax+40] + push edx + mov edx, [eax+36] + push edx + call __local_unwind2 + add esp, 8 + pop ebp -.lu2_next_scope: + /* Set new try level */ + mov eax, [esp+8] + mov edx, [esp+16] + mov [edx], eax - // Keep a pointer to the exception registration in EBX - movl LU2_REGFRAME(%edx), %ebx + /* Return collided unwind */ + mov eax, DISPOSITION_COLLIDED_UNWIND - // If we have reached the end of the chain or we're asked to stop here - // by the caller then exit - test %ebx, %ebx - je .lu2_done - - movl ER_TRYLEVEL(%ebx), %eax - cmpl $-1, %eax - je .lu2_done - - cmpl LU2_TRYLEVEL(%edx), %eax - je .lu2_done - - // Keep a pointer to the scopetable in ESI - movl ER_SCOPETABLE(%ebx), %esi - - // Compute the offset of the entry in the scopetable that describes - // the scope that is to be unwound. Put the offset in EDI. - movl ST_TRYLEVEL(%esi), %edi - lea (%edi, %edi, 2), %edi - shll $2, %edi - addl %esi, %edi - - // If this is not a termination handler then skip it - cmpl $0, ST_FILTER(%edi) - jne .lu2_next_scope - - // Save the previous try-level in the exception registration structure - movl ST_TRYLEVEL(%edi), %eax - movl %eax, ER_TRYLEVEL(%ebx) - - // Fetch the address of the termination handler - movl ST_HANDLER(%edi), %eax - - // Termination handlers may trash all registers so save the - // important ones and then call the handler - pushl %edx - call *%eax - - // Get our base pointer back - popl %edx - - jmp .lu2_next_scope - -.lu2_done: - - // FIXME: Tear down the EXCEPTION_REGISTRATION entry setup to protect - // the unwinding - - //movl %esi, %esp - //popl %ebp +unwind_handler_return: ret +.endfunc -#define EH3_DISPCONTEXT 0x14 -#define EH3_CONTEXT 0x10 -#define EH3_REGFRAME 0x0C -#define EH3_ERECORD 0x08 +.func _global_unwind2 +__global_unwind2: -// Parameters: -// [ESP+14h] - PVOID DispatcherContext -// [ESP+10h] - PCONTEXT Context -// [ESP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame -// [ESP+08h] - PEXCEPTION_RECORD ExceptionRecord -// Registers: -// Unknown -// Returns: -// EXCEPTION_DISPOSITION - How this handler handled the exception -// Notes: -// Try to find an exception handler that will handle the exception. -// Traverse the entries in the scopetable that is associated with the -// exception registration passed as a parameter to this function. -// If an exception handler that will handle the exception is found, it -// is called and this function never returns -__except_handler3: - // Setup our call frame so we can access parameters using EBP - pushl %ebp // Standard ESP in frame (considered part of EXCEPTION_REGISTRATION) - movl %esp, %ebp + /* Create stack and save all registers */ + push ebp + mov ebp, esp + push ebx + push esi + push edi + push ebp - // Don't trust the direction flag to be cleared + /* Call unwind */ + push 0 + push 0 + push glu_return + push [ebp+8] + call _RtlUnwind@16 + +glu_return: + /* Restore registers and return */ + pop ebp + pop edi + pop esi + pop ebx + mov esp, ebp + pop ebp + ret +.endfunc + +.func _abnormal_termination +__abnormal_termination: + + /* Assume false */ + xor eax, eax + + /* Check if the handler is the unwind handler */ + mov ecx, fs:0 + cmp dword ptr [ecx+4], offset _unwind_handler + jne short ab_return + + /* Get the try level */ + mov edx, [ecx+12] + mov edx, [edx+12] + + /* Compare it */ + cmp [ecx+8], edx + jne ab_return + + /* Return true */ + mov eax, 1 + + /* Return */ +ab_return: + ret +.endfunc + +.func _local_unwind2 +__local_unwind2: + + /* Save volatiles */ + push ebx + push esi + push edi + + /* Get the exception registration */ + mov eax, [esp+16] + + /* Setup SEH to protect the unwind */ + push ebp + push eax + push -2 + push offset _unwind_handler + push fs:0 + mov fs:0, esp + +unwind_loop: + /* Get the exception registration and try level */ + mov eax, [esp+36] + mov ebx, [eax+8] + mov esi, [eax+12] + + /* Validate the unwind */ + cmp esi, -1 + je unwind_return + cmp dword ptr [esp+40], -1 + je unwind_ok + cmp esi, [esp+40] + jbe unwind_return + +unwind_ok: + /* Get the new enclosing level and save it */ + lea esi, [esi+esi*2] + mov ecx, [ebx+esi*4] + mov [esp+8], ecx + mov [eax+12], ecx + + /* Check the filter type */ + cmp dword ptr [ebx+esi*4+4], 0 + jnz __NLG_Return2 + + /* FIXME: NLG Notification */ + + /* Call the handler */ + call dword ptr [ebx+esi*4+8] + +__NLG_Return2: + /* Unwind again */ + jmp unwind_loop + +unwind_return: + /* Cleanup SEH */ + pop fs:0 + add esp, 16 + pop edi + pop esi + pop ebx + ret +.endfunc + +.func _except_handler2 +__except_handler2: + + /* Setup stack and save volatiles */ + push ebp + mov ebp, esp + sub esp, 8 + push ebx + push esi + push edi + push ebp + + /* Clear direction flag */ cld - // Either we're called to handle an exception or we're called to unwind - movl EH3_ERECORD(%ebp), %eax - testl $EXCEPTION_UNWIND_MODE, EREC_FLAGS(%eax) - jnz .eh3_unwind + /* Get exception registration and record */ + mov ebx, [ebp+12] + mov eax, [ebp+8] - // Keep a pointer to the exception registration in EBX - movl EH3_REGFRAME(%ebp), %ebx + /* Check if this is an unwind */ + test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING + jnz except_unwind2 - // Build an EXCEPTION_POINTERS structure on the stack and store it's - // address in the EXCEPTION_REGISTRATION structure - movl EH3_CONTEXT(%esp), %eax - pushl %ebx // Registration frame - pushl %eax // Context - movl %esp, ER_EPOINTERS(%ebx) // Pointer to EXCEPTION_REGISTRATION on the stack + /* Save exception pointers structure */ + mov [ebp-8], eax + mov eax, [ebp+16] + mov [ebp-4], eax + lea eax, [ebp-8] + mov [ebx+20], eax - // Keep current try-level in EDI - movl ER_TRYLEVEL(%ebx), %edi + /* Get the try level and scope table */ + mov esi, [ebx+12] + mov edi, [ebx+8] - // Keep a pointer to the scopetable in ESI - movl ER_SCOPETABLE(%ebx), %esi +except_loop2: + /* Validate try level */ + cmp esi, -1 + je except_search2 -.eh3_next_scope: + /* Check if this is the termination handler */ + lea ecx, [esi+esi*2] + cmp dword ptr [edi+ecx*4+4], 0 + jz except_continue2 - // If we have reached the end of the chain then exit - cmpl $-1, %edi - je .eh3_search + /* Save registers and call filter, then restore them */ + push esi + push ebp + mov ebp, [ebx+16] + call dword ptr [edi+ecx*4+4] + pop ebp + pop esi - // Compute the offset of the entry in the scopetable and store - // the absolute address in EAX - lea (%edi, %edi, 2), %eax - shll $2, %eax - addl %esi, %eax + /* Restore ebx and check the result */ + mov ebx, [ebp+12] + or eax, eax + jz except_continue2 + js except_dismiss2 - // Fetch the address of the filter routine - movl ST_FILTER(%eax), %eax + /* So this is an accept, call the termination handlers */ + mov edi, [ebx+8] + push ebx + call __global_unwind2 + add esp, 4 - // If this is a termination handler then skip it - cmpl $0, %eax - je .eh3_continue + /* Restore ebp */ + mov ebp, [ebx+16] - // Filter routines may trash all registers so save the important - // ones before restoring the call frame ebp and calling the handler - pushl %ebp - pushl %edi // Stop try-level - lea ER_EBP(%ebx), %ebp - call *%eax - popl %edi // Stop try-level - popl %ebp + /* Do local unwind */ + push esi + push ebx + call __local_unwind2 + add esp, 8 - // Reload EBX with registration frame address - movl EH3_REGFRAME(%ebp), %ebx + /* Set new try level */ + lea ecx, [esi+esi*2] + mov eax, [edi+ecx*4] + mov [ebx+12], eax - // Be more flexible here by checking if the return value is less than - // zero, equal to zero, or larger than zero instead of the defined - // values: - // -1 (EXCEPTION_CONTINUE_EXECUTION) - // 0 (EXCEPTION_CONTINUE_SEARCH) - // +1 (EXCEPTION_EXECUTE_HANDLER) - orl %eax, %eax - jz .eh3_continue - js .eh3_dismiss + /* Call except handler */ + call [edi+ecx*4+8] - // Filter returned: EXCEPTION_EXECUTE_HANDLER +except_continue2: + /* Reload try level and except again */ + mov edi, [ebx+8] + lea ecx, [esi+esi*2] + mov esi, [edi+ecx*4] + jmp except_loop2 - // Ask the OS to perform global unwinding. - pushl %edi // Save stop try-level - pushl %ebx // Save registration frame address - pushl %ebx // Registration frame address - call __global_unwind2 - popl %eax // Remove parameter to __global_unwind2 - popl %ebx // Restore registration frame address - popl %edi // Restore stop try-level +except_dismiss2: + /* Dismiss it */ + mov eax, DISPOSITION_DISMISS + jmp except_return2 - // Change the context structure so _except_finish is called in the - // correct context since we return ExceptionContinueExecution. - movl EH3_CONTEXT(%ebp), %eax - - movl %edi, CONTEXT_EDI(%eax) // Stop try-level - movl %ebx, CONTEXT_EBX(%eax) // Registration frame address - movl $_except_finish, CONTEXT_EIP(%eax) +except_search2: + /* Continue searching */ + mov eax, DISPOSITION_CONTINUE_SEARCH + jmp except_return2 - movl $ExceptionContinueExecution, %eax - jmp .eh3_return + /* Do local unwind */ +except_unwind2: + push ebp + mov ebp, [ebx+16] + push -1 + push ebx + call __local_unwind2 + add esp, 8 - // Filter returned: EXCEPTION_CONTINUE_SEARCH -.eh3_continue: + /* Retore EBP and set return disposition */ + pop ebp + mov eax, DISPOSITION_CONTINUE_SEARCH - // Reload ESI because the filter routine may have trashed it - movl ER_SCOPETABLE(%ebx), %esi - - // Go one try-level closer to the top - lea (%edi, %edi, 2), %edi - shll $2, %edi - addl %esi, %edi - movl ST_TRYLEVEL(%edi), %edi - - jmp .eh3_next_scope - - // Filter returned: EXCEPTION_CONTINUE_EXECUTION - // Continue execution like nothing happened -.eh3_dismiss: - movl $ExceptionContinueExecution, %eax - jmp .eh3_return - - // Tell the OS to search for another handler that will handle the exception -.eh3_search: - - movl $ExceptionContinueSearch, %eax - jmp .eh3_return - - // Perform local unwinding -.eh3_unwind: - - testl $EXCEPTION_TARGET_UNWIND, EREC_FLAGS(%eax) - jnz .eh3_return - - // Save some important registers - pushl %ebp - - lea ER_EBP(%ebx), %ebp - pushl $-1 - pushl %ebx - call __local_unwind2 - addl $8, %esp - - // Restore some important registers - popl %ebp - - movl $ExceptionContinueSearch, %eax - - // Get me out of here -.eh3_return: - - movl %ebp, %esp - popl %ebp +except_return2: + /* Restore registers and stack */ + pop ebp + pop edi + pop esi + pop ebx + mov esp, ebp + pop ebp ret +.endfunc -// Parameters: -// None -// Registers: -// EBX - Pointer to exception registration structure -// EDI - Stop try-level -// Returns: -// - -// Notes: -// - -_except_finish: +.func _except_handler3 +__except_handler3: - // Setup EBP for the exception handler. By doing this the exception - // handler can access local variables as normal - lea ER_EBP(%ebx), %ebp + /* Setup stack and save volatiles */ + push ebp + mov ebp, esp + sub esp, 8 + push ebx + push esi + push edi + push ebp - // Save some important registers - pushl %ebp - pushl %ebx - pushl %edi + /* Clear direction flag */ + cld - // Stop try-level - pushl %edi + /* Get exception registration and record */ + mov ebx, [ebp+12] + mov eax, [ebp+8] - // Pointer to exception registration structure - pushl %ebx - call __local_unwind2 - addl $8, %esp + /* Check if this is an unwind */ + test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING + jnz except_unwind3 - // Restore some important registers - popl %edi - popl %ebx - popl %ebp + /* Save exception pointers structure */ + mov [ebp-8], eax + mov eax, [ebp+16] + mov [ebp-4], eax + lea eax, [ebp-8] + mov [ebx-4], eax - // Keep a pointer to the scopetable in ESI - movl ER_SCOPETABLE(%ebx), %esi + /* Get the try level and scope table */ + mov esi, [ebx+12] + mov edi, [ebx+8] - // Compute the offset of the entry in the scopetable and store - // the absolute address in EDI - lea (%edi, %edi, 2), %edi - shll $2, %edi - addl %esi, %edi + /* FIXME: Validate the SEH exception */ - // Set the current try-level to the previous try-level and call - // the exception handler - movl ST_TRYLEVEL(%edi), %eax - movl %eax, ER_TRYLEVEL(%ebx) - movl ST_HANDLER(%edi), %eax +except_loop3: + /* Validate try level */ + cmp esi, -1 + je except_search3 - call *%eax + /* Check if this is the termination handler */ + lea ecx, [esi+esi*2] + mov eax, [edi+ecx*4+4] + or eax, eax + jz except_continue3 - // We should never get here + /* Save registers clear them all */ + push esi + push ebp + lea ebp, [ebx+16] + xor ebx, ebx + xor ecx, ecx + xor edx, edx + xor esi, esi + xor edi, edi + + /* Call the filter and restore our registers */ + call eax + pop ebp + pop esi + + /* Restore ebx and check the result */ + mov ebx, [ebp+12] + or eax, eax + jz except_continue3 + js except_dismiss3 + + /* So this is an accept, call the termination handlers */ + mov edi, [ebx+8] + push ebx + call __global_unwind2 + add esp, 4 + + /* Restore ebp */ + lea ebp, [ebx+16] + + /* Do local unwind */ + push esi + push ebx + call __local_unwind2 + add esp, 8 + + /* FIXME: Do NLG Notification */ + + /* Set new try level */ + lea ecx, [esi+esi*2] + mov eax, [edi+ecx*4] + mov [ebx+12], eax + + /* Clear registers and call except handler */ + mov eax, [edi+ecx*4+8] + xor ebx, ebx + xor ecx, ecx + xor edx, edx + xor esi, esi + xor edi, edi + call eax + +except_continue3: + /* Reload try level and except again */ + mov edi, [ebx+8] + lea ecx, [esi+esi*2] + mov esi, [edi+ecx*4] + jmp except_loop3 + +except_dismiss3: + /* Dismiss it */ + mov eax, DISPOSITION_DISMISS + jmp except_return3 + +except_search3: + /* Continue searching */ + mov eax, DISPOSITION_CONTINUE_SEARCH + jmp except_return3 + + /* Do local unwind */ +except_unwind3: + push ebp + mov ebp, [ebx+16] + push -1 + push ebx + call __local_unwind2 + add esp, 8 + + /* Retore EBP and set return disposition */ + pop ebp + mov eax, DISPOSITION_CONTINUE_SEARCH + +except_return3: + /* Restore registers and stack */ + pop ebp + pop edi + pop esi + pop ebx + mov esp, ebp + pop ebp ret +.endfunc + +// +// +// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME +// +// +.func RtlpGetStackLimits@8 +.globl _RtlpGetStackLimits@8 +_RtlpGetStackLimits@8: + + /* Get the current thread */ + mov eax, [fs:KPCR_CURRENT_THREAD] + + /* Get the stack limits */ + mov ecx, [eax+KTHREAD_STACK_LIMIT] + mov edx, [eax+KTHREAD_INITIAL_STACK] + sub edx, SIZEOF_FX_SAVE_AREA + + /* Return them */ + mov eax, [esp+4] + mov [eax], ecx + + mov eax, [esp+8] + mov [eax], edx + + /* return */ + ret 8 +.endfunc diff --git a/reactos/lib/sdk/crt/except/i386/unwind.c b/reactos/lib/sdk/crt/except/i386/unwind.c index 7ac0aaf14a0..bb2c302a3b6 100644 --- a/reactos/lib/sdk/crt/except/i386/unwind.c +++ b/reactos/lib/sdk/crt/except/i386/unwind.c @@ -6,22 +6,6 @@ #include #include -/* - * @implemented - */ -void __cdecl -_global_unwind2(PEXCEPTION_REGISTRATION_RECORD RegistrationFrame) -{ -#ifdef __GNUC__ - RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0); -__ret_label: - // return is important - return; -#else -#endif -} - - /* VC++ extensions to Win32 SEH */ typedef struct _SCOPETABLE { diff --git a/reactos/lib/sdk/crt/except_nt/powerpc/chkstk_asm.s b/reactos/lib/sdk/crt/except/powerpc/chkstk_asm.s similarity index 100% rename from reactos/lib/sdk/crt/except_nt/powerpc/chkstk_asm.s rename to reactos/lib/sdk/crt/except/powerpc/chkstk_asm.s diff --git a/reactos/lib/sdk/crt/except_nt/powerpc/seh.s b/reactos/lib/sdk/crt/except/powerpc/seh.s similarity index 100% rename from reactos/lib/sdk/crt/except_nt/powerpc/seh.s rename to reactos/lib/sdk/crt/except/powerpc/seh.s diff --git a/reactos/lib/sdk/crt/except_nt/i386/seh.s b/reactos/lib/sdk/crt/except_nt/i386/seh.s deleted file mode 100644 index 57cdab5ce2e..00000000000 --- a/reactos/lib/sdk/crt/except_nt/i386/seh.s +++ /dev/null @@ -1,468 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS CRT - * FILE: lib/crt/misc/i386/seh.S - * PURPOSE: SEH Support for the CRT - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include -.intel_syntax noprefix - -#define DISPOSITION_DISMISS 0 -#define DISPOSITION_CONTINUE_SEARCH 1 -#define DISPOSITION_COLLIDED_UNWIND 3 - -/* GLOBALS *******************************************************************/ - -.globl __global_unwind2 -.globl __local_unwind2 -.globl __abnormal_termination -.globl __except_handler2 -.globl __except_handler3 - -/* FUNCTIONS *****************************************************************/ - -.func unwind_handler -_unwind_handler: - - /* Check if we were unwinding and continue search if not */ - mov ecx, [esp+4] - test dword ptr [ecx+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING - mov eax, DISPOSITION_CONTINUE_SEARCH - jz unwind_handler_return - - /* We have a collision, do a local unwind */ - mov eax, [esp+20] - push ebp - mov ebp, [eax+16] - mov edx, [eax+40] - push edx - mov edx, [eax+36] - push edx - call __local_unwind2 - add esp, 8 - pop ebp - - /* Set new try level */ - mov eax, [esp+8] - mov edx, [esp+16] - mov [edx], eax - - /* Return collided unwind */ - mov eax, DISPOSITION_COLLIDED_UNWIND - -unwind_handler_return: - ret -.endfunc - -.func _global_unwind2 -__global_unwind2: - - /* Create stack and save all registers */ - push ebp - mov ebp, esp - push ebx - push esi - push edi - push ebp - - /* Call unwind */ - push 0 - push 0 - push glu_return - push [ebp+8] - call _RtlUnwind@16 - -glu_return: - /* Restore registers and return */ - pop ebp - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - ret -.endfunc - -.func _abnormal_termination -__abnormal_termination: - - /* Assume false */ - xor eax, eax - - /* Check if the handler is the unwind handler */ - mov ecx, fs:0 - cmp dword ptr [ecx+4], offset _unwind_handler - jne short ab_return - - /* Get the try level */ - mov edx, [ecx+12] - mov edx, [edx+12] - - /* Compare it */ - cmp [ecx+8], edx - jne ab_return - - /* Return true */ - mov eax, 1 - - /* Return */ -ab_return: - ret -.endfunc - -.func _local_unwind2 -__local_unwind2: - - /* Save volatiles */ - push ebx - push esi - push edi - - /* Get the exception registration */ - mov eax, [esp+16] - - /* Setup SEH to protect the unwind */ - push ebp - push eax - push -2 - push offset _unwind_handler - push fs:0 - mov fs:0, esp - -unwind_loop: - /* Get the exception registration and try level */ - mov eax, [esp+36] - mov ebx, [eax+8] - mov esi, [eax+12] - - /* Validate the unwind */ - cmp esi, -1 - je unwind_return - cmp dword ptr [esp+40], -1 - je unwind_ok - cmp esi, [esp+40] - jbe unwind_return - -unwind_ok: - /* Get the new enclosing level and save it */ - lea esi, [esi+esi*2] - mov ecx, [ebx+esi*4] - mov [esp+8], ecx - mov [eax+12], ecx - - /* Check the filter type */ - cmp dword ptr [ebx+esi*4+4], 0 - jnz __NLG_Return2 - - /* FIXME: NLG Notification */ - - /* Call the handler */ - call dword ptr [ebx+esi*4+8] - -__NLG_Return2: - /* Unwind again */ - jmp unwind_loop - -unwind_return: - /* Cleanup SEH */ - pop fs:0 - add esp, 16 - pop edi - pop esi - pop ebx - ret -.endfunc - -.func _except_handler2 -__except_handler2: - - /* Setup stack and save volatiles */ - push ebp - mov ebp, esp - sub esp, 8 - push ebx - push esi - push edi - push ebp - - /* Clear direction flag */ - cld - - /* Get exception registration and record */ - mov ebx, [ebp+12] - mov eax, [ebp+8] - - /* Check if this is an unwind */ - test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING - jnz except_unwind2 - - /* Save exception pointers structure */ - mov [ebp-8], eax - mov eax, [ebp+16] - mov [ebp-4], eax - lea eax, [ebp-8] - mov [ebx+20], eax - - /* Get the try level and scope table */ - mov esi, [ebx+12] - mov edi, [ebx+8] - -except_loop2: - /* Validate try level */ - cmp esi, -1 - je except_search2 - - /* Check if this is the termination handler */ - lea ecx, [esi+esi*2] - cmp dword ptr [edi+ecx*4+4], 0 - jz except_continue2 - - /* Save registers and call filter, then restore them */ - push esi - push ebp - mov ebp, [ebx+16] - call dword ptr [edi+ecx*4+4] - pop ebp - pop esi - - /* Restore ebx and check the result */ - mov ebx, [ebp+12] - or eax, eax - jz except_continue2 - js except_dismiss2 - - /* So this is an accept, call the termination handlers */ - mov edi, [ebx+8] - push ebx - call __global_unwind2 - add esp, 4 - - /* Restore ebp */ - mov ebp, [ebx+16] - - /* Do local unwind */ - push esi - push ebx - call __local_unwind2 - add esp, 8 - - /* Set new try level */ - lea ecx, [esi+esi*2] - mov eax, [edi+ecx*4] - mov [ebx+12], eax - - /* Call except handler */ - call [edi+ecx*4+8] - -except_continue2: - /* Reload try level and except again */ - mov edi, [ebx+8] - lea ecx, [esi+esi*2] - mov esi, [edi+ecx*4] - jmp except_loop2 - -except_dismiss2: - /* Dismiss it */ - mov eax, DISPOSITION_DISMISS - jmp except_return2 - -except_search2: - /* Continue searching */ - mov eax, DISPOSITION_CONTINUE_SEARCH - jmp except_return2 - - /* Do local unwind */ -except_unwind2: - push ebp - mov ebp, [ebx+16] - push -1 - push ebx - call __local_unwind2 - add esp, 8 - - /* Retore EBP and set return disposition */ - pop ebp - mov eax, DISPOSITION_CONTINUE_SEARCH - -except_return2: - /* Restore registers and stack */ - pop ebp - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - ret -.endfunc - -.func _except_handler3 -__except_handler3: - - /* Setup stack and save volatiles */ - push ebp - mov ebp, esp - sub esp, 8 - push ebx - push esi - push edi - push ebp - - /* Clear direction flag */ - cld - - /* Get exception registration and record */ - mov ebx, [ebp+12] - mov eax, [ebp+8] - - /* Check if this is an unwind */ - test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING - jnz except_unwind3 - - /* Save exception pointers structure */ - mov [ebp-8], eax - mov eax, [ebp+16] - mov [ebp-4], eax - lea eax, [ebp-8] - mov [ebx-4], eax - - /* Get the try level and scope table */ - mov esi, [ebx+12] - mov edi, [ebx+8] - - /* FIXME: Validate the SEH exception */ - -except_loop3: - /* Validate try level */ - cmp esi, -1 - je except_search3 - - /* Check if this is the termination handler */ - lea ecx, [esi+esi*2] - mov eax, [edi+ecx*4+4] - or eax, eax - jz except_continue3 - - /* Save registers clear them all */ - push esi - push ebp - lea ebp, [ebx+16] - xor ebx, ebx - xor ecx, ecx - xor edx, edx - xor esi, esi - xor edi, edi - - /* Call the filter and restore our registers */ - call eax - pop ebp - pop esi - - /* Restore ebx and check the result */ - mov ebx, [ebp+12] - or eax, eax - jz except_continue3 - js except_dismiss3 - - /* So this is an accept, call the termination handlers */ - mov edi, [ebx+8] - push ebx - call __global_unwind2 - add esp, 4 - - /* Restore ebp */ - lea ebp, [ebx+16] - - /* Do local unwind */ - push esi - push ebx - call __local_unwind2 - add esp, 8 - - /* FIXME: Do NLG Notification */ - - /* Set new try level */ - lea ecx, [esi+esi*2] - mov eax, [edi+ecx*4] - mov [ebx+12], eax - - /* Clear registers and call except handler */ - mov eax, [edi+ecx*4+8] - xor ebx, ebx - xor ecx, ecx - xor edx, edx - xor esi, esi - xor edi, edi - call eax - -except_continue3: - /* Reload try level and except again */ - mov edi, [ebx+8] - lea ecx, [esi+esi*2] - mov esi, [edi+ecx*4] - jmp except_loop3 - -except_dismiss3: - /* Dismiss it */ - mov eax, DISPOSITION_DISMISS - jmp except_return3 - -except_search3: - /* Continue searching */ - mov eax, DISPOSITION_CONTINUE_SEARCH - jmp except_return3 - - /* Do local unwind */ -except_unwind3: - push ebp - mov ebp, [ebx+16] - push -1 - push ebx - call __local_unwind2 - add esp, 8 - - /* Retore EBP and set return disposition */ - pop ebp - mov eax, DISPOSITION_CONTINUE_SEARCH - -except_return3: - /* Restore registers and stack */ - pop ebp - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - ret -.endfunc - -// -// -// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME -// -// -.func RtlpGetStackLimits@8 -.globl _RtlpGetStackLimits@8 -_RtlpGetStackLimits@8: - - /* Get the current thread */ - mov eax, [fs:KPCR_CURRENT_THREAD] - - /* Get the stack limits */ - mov ecx, [eax+KTHREAD_STACK_LIMIT] - mov edx, [eax+KTHREAD_INITIAL_STACK] - sub edx, SIZEOF_FX_SAVE_AREA - - /* Return them */ - mov eax, [esp+4] - mov [eax], ecx - - mov eax, [esp+8] - mov [eax], edx - - /* return */ - ret 8 -.endfunc diff --git a/reactos/lib/sdk/crt/libcntpr.rbuild b/reactos/lib/sdk/crt/libcntpr.rbuild index fdb4abb09b8..9781eb8f29b 100644 --- a/reactos/lib/sdk/crt/libcntpr.rbuild +++ b/reactos/lib/sdk/crt/libcntpr.rbuild @@ -13,7 +13,7 @@ "extern __attribute__ ((dllexport))" - + chkstk_asm.s diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index b433312e438..9a8e27347b4 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -119,6 +119,8 @@ kernel32 - msvcrt - reactos/dll/win32/msvcrt/wine/*.c # Out of sync + reactos/lib/sdk/crt/except # Synced at XXXXXXXX + reactos/lib/sdk/crt/wine # Synced at XXXXXXXX User32 - reactos/dll/win32/user32/controls/button.c # Synced at 20071022