diff --git a/reactos/lib/sdk/crt/except_nt/i386/chkstk_asm.s b/reactos/lib/sdk/crt/except_nt/i386/chkstk_asm.s new file mode 100644 index 00000000000..5104a35b1c4 --- /dev/null +++ b/reactos/lib/sdk/crt/except_nt/i386/chkstk_asm.s @@ -0,0 +1,66 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Stack checker + * FILE: lib/ntdll/rtl/i386/chkstk.s + * PROGRAMER: KJK::Hyperion + */ + +.globl __chkstk +.globl __alloca_probe + +/* + _chkstk() is called by all stack allocations of more than 4 KB. It grows the + stack in areas of 4 KB each, trying to access each area. This ensures that the + guard page for the stack is hit, and the stack growing triggered + */ +__chkstk: +__alloca_probe: + +/* EAX = size to be allocated */ +/* save the ECX register */ + pushl %ecx + +/* ECX = top of the previous stack frame */ + leal 8(%esp), %ecx + +/* probe the desired memory, page by page */ + cmpl $0x1000, %eax + jge .l_MoreThanAPage + jmp .l_LessThanAPage + +.l_MoreThanAPage: + +/* raise the top of the stack by a page and probe */ + subl $0x1000, %ecx + testl %eax, 0(%ecx) + +/* loop if still more than a page must be probed */ + subl $0x1000, %eax + cmpl $0x1000, %eax + jge .l_MoreThanAPage + +.l_LessThanAPage: + +/* raise the top of the stack by EAX bytes (size % 4096) and probe */ + subl %eax, %ecx + testl %eax, 0(%ecx) + +/* EAX = top of the stack */ + movl %esp, %eax + +/* allocate the memory */ + movl %ecx, %esp + +/* restore ECX */ + movl 0(%eax), %ecx + +/* restore the return address */ + movl 4(%eax), %eax + pushl %eax + +/* return */ + ret + +/* EOF */ diff --git a/reactos/lib/sdk/crt/except_nt/i386/seh.s b/reactos/lib/sdk/crt/except_nt/i386/seh.s new file mode 100644 index 00000000000..5b2bc36a9b8 --- /dev/null +++ b/reactos/lib/sdk/crt/except_nt/i386/seh.s @@ -0,0 +1,468 @@ +/* + * 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 esi + pop edi + 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 esi, [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 + jz 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 esi, [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 + jz 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_nt/powerpc/chkstk_asm.s b/reactos/lib/sdk/crt/except_nt/powerpc/chkstk_asm.s new file mode 100644 index 00000000000..653fec4dd07 --- /dev/null +++ b/reactos/lib/sdk/crt/except_nt/powerpc/chkstk_asm.s @@ -0,0 +1,23 @@ +/* $Id: chkstk_asm.s 26099 2007-03-14 20:30:32Z ion $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Stack checker + * FILE: lib/ntdll/rtl/i386/chkstk.s + * PROGRAMER: arty + */ + +.globl _chkstk +.globl _alloca_probe + +/* + _chkstk() is called by all stack allocations of more than 4 KB. It grows the + stack in areas of 4 KB each, trying to access each area. This ensures that the + guard page for the stack is hit, and the stack growing triggered + */ +_chkstk: +_alloca_probe: + /* return */ + blr + +/* EOF */ diff --git a/reactos/lib/sdk/crt/except_nt/powerpc/seh.s b/reactos/lib/sdk/crt/except_nt/powerpc/seh.s new file mode 100644 index 00000000000..4965d634b9b --- /dev/null +++ b/reactos/lib/sdk/crt/except_nt/powerpc/seh.s @@ -0,0 +1,75 @@ +/* + * 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: arty + */ + +/* INCLUDES ******************************************************************/ + +#include + +#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 *****************************************************************/ + +unwind_handler: + blr + +_global_unwind2: + blr + +_local_unwind2: + blr + +_except_handler2: + blr + +_except_handler3: + blr + +// +// +// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME +// sorry +// +// +.globl RtlpGetStackLimits +RtlpGetStackLimits: + stwu 1,16(1) + mflr 0 + + stw 0,4(1) + stw 3,8(1) + stw 4,12(1) + + /* Get the current thread */ + lwz 3,KPCR_CURRENT_THREAD(13) + + /* Get the stack limits */ + lwz 4,KTHREAD_STACK_LIMIT(3) + lwz 5,KTHREAD_INITIAL_STACK(3) + subi 5,5,SIZEOF_FX_SAVE_AREA + + /* Return them */ + lwz 3,8(1) + stw 4,0(3) + + lwz 3,12(1) + stw 5,0(3) + + addi 1,1,16 + + /* return */ + blr diff --git a/reactos/lib/sdk/crt/mem/memccpy.c b/reactos/lib/sdk/crt/mem/memccpy.c new file mode 100644 index 00000000000..c760b85021e --- /dev/null +++ b/reactos/lib/sdk/crt/mem/memccpy.c @@ -0,0 +1,25 @@ +/* + * $Id$ + */ + +#include + + +void * +_memccpy (void *to, const void *from,int c,size_t count) +{ + char t; + size_t i; + char *dst=(char*)to; + const char *src=(const char*)from; + + for ( i = 0; i < count; i++ ) + { + dst[i] = t = src[i]; + if ( t == '\0' ) + break; + if ( t == c ) + return &dst[i+1]; + } + return NULL; /* didn't copy c */ +}