diff --git a/reactos/lib/kernel32/thread/fiber.c b/reactos/lib/kernel32/thread/fiber.c index 2ecf0d9b2be..aefd2d41542 100644 --- a/reactos/lib/kernel32/thread/fiber.c +++ b/reactos/lib/kernel32/thread/fiber.c @@ -1,297 +1,251 @@ -/* $Id$ - * - * FILE: lib/kernel32/thread/fiber.c - * - * ReactOS Kernel32.dll - * +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: lib/kernel32/thread/fiber.c + * PURPOSE: Fiber Implementation + * PROGRAMMERS: + * Alex Ionescu (alex@relsoft.net) + * KJK::Hyperion */ #include -/* FIXME */ -#include - #define NDEBUG #include "../include/debug.h" -struct _FIBER /* Field offsets: */ -{ /* 32 bit 64 bit */ - /* this must be the first field */ - LPVOID Parameter; /* 0x00 0x00 */ - - struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList; /* 0x04 0x08 */ - LPVOID StackBase; /* 0x08 0x10 */ - LPVOID StackLimit; /* 0x0C 0x18 */ - LPVOID DeallocationStack; /* 0x10 0x20 */ - ULONG_PTR Flags; /* 0x14 0x28 */ -#if defined(_M_IX86) - /* control flow registers */ - DWORD Eip; /* 0x18 ---- */ - DWORD Esp; /* 0x1C ---- */ - DWORD Ebp; /* 0x20 ---- */ - - /* general-purpose registers that must be preserved across calls */ - DWORD Ebx; /* 0x24 ---- */ - DWORD Esi; /* 0x28 ---- */ - DWORD Edi; /* 0x2C ---- */ - - /* floating point save area (optional) */ - FLOATING_SAVE_AREA FloatSave; /* 0x30 ---- */ -#else -#error Unspecified or unsupported architecture. -#endif -}; - -typedef struct _FIBER FIBER, * PFIBER; - -__declspec(noreturn) void WINAPI FiberStartup(PVOID lpStartAddress); +typedef struct _FIBER /* Field offsets: */ +{ /* 32 bit 64 bit */ + /* this must be the first field */ + LPVOID Parameter; /* 0x00 0x00 */ + struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList; /* 0x04 0x08 */ + LPVOID StackBase; /* 0x08 0x10 */ + LPVOID StackLimit; /* 0x0C 0x18 */ + LPVOID DeallocationStack; /* 0x10 0x20 */ + CONTEXT Context; /* 0x14 0x28 */ + ULONG GuaranteedStackBytes; /* 0x2E0 */ + PVOID FlsData; /* 0x2E4 */ + PVOID ActivationContextStack; /* 0x2E8 */ +} FIBER, *PFIBER; /* * @implemented */ -BOOL WINAPI ConvertFiberToThread(void) +BOOL +WINAPI +ConvertFiberToThread(VOID) { - PTEB pTeb = NtCurrentTeb(); + PTEB pTeb = NtCurrentTeb(); + DPRINT1("Converting Fiber to Thread\n"); - /* the current thread isn't running a fiber: failure */ - if(!pTeb->HasFiberData) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + /* the current thread isn't running a fiber: failure */ + if(!pTeb->HasFiberData) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - /* this thread won't run a fiber anymore */ - pTeb->HasFiberData = FALSE; + /* this thread won't run a fiber anymore */ + pTeb->HasFiberData = FALSE; - /* free the fiber */ - if(pTeb->Tib.FiberData != NULL) - RtlFreeHeap(pTeb->ProcessEnvironmentBlock->ProcessHeap, 0, pTeb->Tib.FiberData); + /* free the fiber */ + if(pTeb->Tib.FiberData != NULL) + { + RtlFreeHeap(GetProcessHeap(), 0, pTeb->Tib.FiberData); + } - /* success */ - return TRUE; + /* success */ + return TRUE; } - /* * @implemented */ -LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter, DWORD dwFlags) +LPVOID +WINAPI +ConvertThreadToFiberEx(LPVOID lpParameter, + DWORD dwFlags) { - PTEB pTeb = NtCurrentTeb(); - PFIBER pfCurFiber; + PTEB pTeb = NtCurrentTeb(); + PFIBER pfCurFiber; + DPRINT1("Converting Thread to Fiber\n"); - /* the current thread is already a fiber */ - if(pTeb->HasFiberData && pTeb->Tib.FiberData) return pTeb->Tib.FiberData; + /* the current thread is already a fiber */ + if(pTeb->HasFiberData && pTeb->Tib.FiberData) return pTeb->Tib.FiberData; - /* allocate the fiber */ - pfCurFiber = (PFIBER)RtlAllocateHeap(pTeb->ProcessEnvironmentBlock->ProcessHeap, 0, sizeof(FIBER)); + /* allocate the fiber */ + pfCurFiber = (PFIBER)RtlAllocateHeap(GetProcessHeap(), + 0, + sizeof(FIBER)); - /* failure */ - if(pfCurFiber == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } + /* failure */ + if(pfCurFiber == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } - pfCurFiber->Parameter = lpParameter; - pfCurFiber->Flags = dwFlags; + /* copy some contextual data from the thread to the fiber */ + pfCurFiber->ExceptionList = pTeb->Tib.ExceptionList; + pfCurFiber->StackBase = pTeb->Tib.StackBase; + pfCurFiber->StackLimit = pTeb->Tib.StackLimit; + pfCurFiber->DeallocationStack = pTeb->DeallocationStack; + pfCurFiber->FlsData = pTeb->FlsData; + pfCurFiber->GuaranteedStackBytes = pTeb->GuaranteedStackBytes; + pfCurFiber->ActivationContextStack = pTeb->ActivationContextStackPointer; + pfCurFiber->Context.ContextFlags = CONTEXT_FULL; + + /* Save FPU State if requsted */ + if (dwFlags & FIBER_FLAG_FLOAT_SWITCH) + { + pfCurFiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT; + } - /* copy some contextual data from the thread to the fiber */ - pfCurFiber->ExceptionList = pTeb->Tib.ExceptionList; - pfCurFiber->StackBase = pTeb->Tib.StackBase; - pfCurFiber->StackLimit = pTeb->Tib.StackLimit; - pfCurFiber->DeallocationStack = pTeb->DeallocationStack; + /* associate the fiber to the current thread */ + pTeb->Tib.FiberData = pfCurFiber; + pTeb->HasFiberData = TRUE; - /* associate the fiber to the current thread */ - pTeb->Tib.FiberData = pfCurFiber; - pTeb->HasFiberData = TRUE; - - /* success */ - return (LPVOID)pfCurFiber; + /* success */ + return (LPVOID)pfCurFiber; } - /* * @implemented */ -LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter) +LPVOID +WINAPI +ConvertThreadToFiber(LPVOID lpParameter) { - return ConvertThreadToFiberEx(lpParameter, 0); + /* Call the newer function */ + return ConvertThreadToFiberEx(lpParameter, 0); } - /* * @implemented */ -LPVOID WINAPI CreateFiber -( - SIZE_T dwStackSize, - LPFIBER_START_ROUTINE lpStartAddress, - LPVOID lpParameter -) +LPVOID +WINAPI +CreateFiber(SIZE_T dwStackSize, + LPFIBER_START_ROUTINE lpStartAddress, + LPVOID lpParameter) { - return CreateFiberEx(dwStackSize, 0, 0, lpStartAddress, lpParameter); + /* Call the Newer Function */ + return CreateFiberEx(dwStackSize, 0, 0, lpStartAddress, lpParameter); } - /* * @implemented */ -LPVOID WINAPI CreateFiberEx -( - SIZE_T dwStackCommitSize, - SIZE_T dwStackReserveSize, - DWORD dwFlags, - LPFIBER_START_ROUTINE lpStartAddress, - LPVOID lpParameter -) +LPVOID +WINAPI +CreateFiberEx(SIZE_T dwStackCommitSize, + SIZE_T dwStackReserveSize, + DWORD dwFlags, + LPFIBER_START_ROUTINE lpStartAddress, + LPVOID lpParameter) { - PFIBER pfCurFiber; - NTSTATUS nErrCode; - PSIZE_T pnStackReserve = NULL; - PSIZE_T pnStackCommit = NULL; - INITIAL_TEB usFiberInitialTeb; - CONTEXT ctxFiberContext; - PTEB pTeb = NtCurrentTeb(); + PFIBER pfCurFiber; + NTSTATUS nErrCode; + INITIAL_TEB usFiberInitialTeb; + CONTEXT ctxFiberContext; + PVOID ActivationContextStack = NULL; + DPRINT1("Creating Fiber\n"); - /* allocate the fiber */ - pfCurFiber = (PFIBER)RtlAllocateHeap(pTeb->ProcessEnvironmentBlock->ProcessHeap, 0, sizeof(FIBER)); + #ifdef SXS_SUPPORT_ENABLED + /* Allocate the Activation Context Stack */ + nErrCode = RtlAllocateActivationContextStack(&ActivationContextStack); + #endif + + /* Allocate the fiber */ + pfCurFiber = (PFIBER)RtlAllocateHeap(GetProcessHeap(), + 0, + sizeof(FIBER)); + /* Failure */ + if(pfCurFiber == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } - /* failure */ - if(pfCurFiber == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } + /* Create the stack for the fiber */ + nErrCode = BasepCreateStack(NtCurrentProcess(), + dwStackCommitSize, + dwStackReserveSize, + &usFiberInitialTeb); + /* Failure */ + if(!NT_SUCCESS(nErrCode)) + { + /* Free the fiber */ + RtlFreeHeap(GetProcessHeap(), 0, pfCurFiber); - /* if the stack reserve or commit size weren't specified, use defaults */ - if(dwStackReserveSize > 0) pnStackReserve = &dwStackReserveSize; - if(dwStackCommitSize > 0) pnStackCommit = &dwStackCommitSize; - - /* create the stack for the fiber */ - nErrCode = RtlRosCreateStack - ( - NtCurrentProcess(), - &usFiberInitialTeb, - 0, - pnStackReserve, - pnStackCommit - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber; - - /* initialize the context for the fiber */ - nErrCode = RtlRosInitializeContext - ( - NtCurrentProcess(), - &ctxFiberContext, - FiberStartup, - &usFiberInitialTeb, - 1, - (ULONG_PTR *)&lpStartAddress - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_CleanupStack; - - /* copy the data into the fiber */ - - /* fixed-size stack */ - if(usFiberInitialTeb.PreviousStackBase && usFiberInitialTeb.PreviousStackLimit) - { - pfCurFiber->StackBase = usFiberInitialTeb.PreviousStackBase; - pfCurFiber->StackLimit = usFiberInitialTeb.PreviousStackLimit; - pfCurFiber->DeallocationStack = usFiberInitialTeb.PreviousStackLimit; - } - /* expandable stack */ - else if - ( - usFiberInitialTeb.StackBase && - usFiberInitialTeb.StackLimit && - usFiberInitialTeb.AllocatedStackBase - ) - { - pfCurFiber->StackBase = usFiberInitialTeb.StackBase; - pfCurFiber->StackLimit = usFiberInitialTeb.StackLimit; - pfCurFiber->DeallocationStack = usFiberInitialTeb.AllocatedStackBase; - } - /* bad initial stack */ - else goto l_CleanupStack; - - pfCurFiber->Parameter = lpParameter; - pfCurFiber->Flags = dwFlags; - pfCurFiber->ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)-1; - -#if defined(_M_IX86) - - pfCurFiber->Eip = ctxFiberContext.Eip; - pfCurFiber->Esp = ctxFiberContext.Esp; - pfCurFiber->Ebp = ctxFiberContext.Ebp; - pfCurFiber->Ebx = ctxFiberContext.Ebx; - pfCurFiber->Esi = ctxFiberContext.Esi; - pfCurFiber->Edi = ctxFiberContext.Edi; - - if(dwFlags & FIBER_FLAG_FLOAT_SWITCH) - pfCurFiber->FloatSave = ctxFiberContext.FloatSave; - -#else -#error Unspecified or unsupported architecture. -#endif - - return pfCurFiber; - -l_CleanupStack: - /* free the stack */ - RtlRosDeleteStack(NtCurrentProcess(), &usFiberInitialTeb); - -l_CleanupFiber: - /* free the fiber */ - RtlFreeHeap(pTeb->ProcessEnvironmentBlock->ProcessHeap, 0, pfCurFiber); - - /* failure */ - ASSERT(!NT_SUCCESS(nErrCode)); - SetLastErrorByStatus(nErrCode); - return NULL; + /* Failure */ + SetLastErrorByStatus(nErrCode); + return NULL; + } + + /* Clear the context */ + RtlZeroMemory(&pfCurFiber->Context, sizeof(CONTEXT)); + + /* copy the data into the fiber */ + pfCurFiber->StackBase = usFiberInitialTeb.StackBase; + pfCurFiber->StackLimit = usFiberInitialTeb.StackLimit; + pfCurFiber->DeallocationStack = usFiberInitialTeb.AllocatedStackBase; + pfCurFiber->Parameter = lpParameter; + pfCurFiber->ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)-1; + pfCurFiber->GuaranteedStackBytes = 0; + pfCurFiber->FlsData = NULL; + pfCurFiber->ActivationContextStack = ActivationContextStack; + pfCurFiber->Context.ContextFlags = CONTEXT_FULL; + + /* Save FPU State if requsted */ + if (dwFlags & FIBER_FLAG_FLOAT_SWITCH) + { + pfCurFiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT; + } + + /* initialize the context for the fiber */ + BasepInitializeContext(&ctxFiberContext, + lpParameter, + lpStartAddress, + usFiberInitialTeb.StackBase, + 2); + + /* Return the Fiber */ + return pfCurFiber; } - /* * @implemented */ -void WINAPI DeleteFiber(LPVOID lpFiber) +VOID +WINAPI +DeleteFiber(LPVOID lpFiber) { - SIZE_T nSize = 0; - PVOID pStackAllocBase = ((PFIBER)lpFiber)->DeallocationStack; - PTEB pTeb = NtCurrentTeb(); + SIZE_T nSize = 0; + PVOID pStackAllocBase = ((PFIBER)lpFiber)->DeallocationStack; - /* free the fiber */ - RtlFreeHeap(pTeb->ProcessEnvironmentBlock->ProcessHeap, 0, lpFiber); + /* free the fiber */ + RtlFreeHeap(GetProcessHeap(), 0, lpFiber); - /* the fiber is deleting itself: let the system deallocate the stack */ - if(pTeb->Tib.FiberData == lpFiber) ExitThread(1); + /* the fiber is deleting itself: let the system deallocate the stack */ + if(NtCurrentTeb()->Tib.FiberData == lpFiber) ExitThread(1); - /* deallocate the stack */ - NtFreeVirtualMemory - ( - NtCurrentProcess(), - &pStackAllocBase, - &nSize, - MEM_RELEASE - ); + /* deallocate the stack */ + NtFreeVirtualMemory(NtCurrentProcess(), + &pStackAllocBase, + &nSize, + MEM_RELEASE); } - -__declspec(noreturn) extern void WINAPI ThreadStartup -( - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter -); - - -__declspec(noreturn) void WINAPI FiberStartup(PVOID lpStartAddress) +__declspec(noreturn) +VOID +WINAPI +BaseFiberStartup(VOID) { - /* FIXME? this should be pretty accurate */ - ThreadStartup(lpStartAddress, GetFiberData()); + PFIBER Fiber = GetFiberData(); + + /* Call the Thread Startup Routine */ + DPRINT1("Starting Fiber\n"); + BaseThreadStartup((LPTHREAD_START_ROUTINE)Fiber->Context.Eax, + (LPVOID)Fiber->Context.Ebx); } /* EOF */ diff --git a/reactos/lib/kernel32/thread/i386/fiber.S b/reactos/lib/kernel32/thread/i386/fiber.S index 0c498022e02..5787fec6296 100644 --- a/reactos/lib/kernel32/thread/i386/fiber.S +++ b/reactos/lib/kernel32/thread/i386/fiber.S @@ -1,94 +1,128 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/kernel32/thread/i386/fiber.S - * PURPOSE: Fiber context switch code for the x86 architecture - * PROGRAMMER: KJK::Hyperion - * - * UPDATE HISTORY: - * 28/05/2003 - created - * +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/thread/i386/fiber.S + * PURPOSE: Fiber context switch code for the x86 architecture + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * KJK::Hyperion */ -.extern _DbgPrint +#include + +/* + * FIXME: When ntoskrnl header changes are complete, move asm.h out of ntoskrnl + * so that we can use it here as well + */ +//#include +#include <../ntoskrnl/include/internal/asm.h> .globl _SwitchToFiber@4 - -ErrStr: - .ascii \ -"(KERNEL32:" __FILE__ ") Saving and restoring the floating point context \ -currently unimplemented\n\0" +.intel_syntax noprefix _SwitchToFiber@4: + /* Get the TEB */ + mov edx, fs:[TEB_SELECTOR] + + /* Get the Fiber */ + mov eax, [edx+TEB_FIBER_DATA] + + /* Save the non-volatile registers */ + mov [eax+FIBER_CONTEXT_EBX], ebx + mov [eax+FIBER_CONTEXT_ESI], esi + mov [eax+FIBER_CONTEXT_EDI], edi + mov [eax+FIBER_CONTEXT_EBP], ebp + + /* Check if we're to save FPU State */ + cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL + CONTEXT_FLOATING_POINT + jnz NoFpuStateSave + + /* Save the FPU State (Status and Control)*/ + fstsw [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] + fstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] + + /* Check if the CPU supports SIMD MXCSR State Save */ + cmp byte ptr [PROCESSOR_FEATURE_FXSR], 0 + jnz NoFpuStateSave + stmxcsr [eax+FIBER_CONTEXT_DR6] + +NoFpuStateSave: - movl %fs:0x18, %ecx /* Teb = NtCurrentTeb() */ + /* Save stack since we're not touching it anymore */ + mov [eax+FIBER_CONTEXT_ESP], esp + + /* Transfer some data from the TEB */ + mov ecx, [edx+TEB_FLS_DATA] + mov [eax+FIBER_FLS_DATA], ecx + mov ecx, [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER] + mov [eax+FIBER_ACTIVATION_CONTEXT_STACK], ecx + + /* Transfer some data related to the Stack */ + mov ecx, [edx+TEB_EXCEPTION_LIST] + mov [eax+FIBER_EXCEPTION_LIST], ecx + mov ecx, [edx+TEB_STACK_LIMIT] + mov [eax+FIBER_STACK_LIMIT], ecx + mov ecx, [edx+TEB_GUARANTEED_STACK_BYTES] + mov [eax+FIBER_GUARANTEED_STACK_BYTES], ecx + + /* Switch to the new fiber */ + mov ecx, [esp+4] + mov [edx+TEB_FIBER_DATA], ecx + + /* Switch Fiber Data */ + mov esi, [ecx+FIBER_EXCEPTION_LIST] + mov [edx+TEB_EXCEPTION_LIST], esi + mov esi, [ecx+FIBER_STACK_BASE] + mov [edx+TEB_STACK_BASE], esi + mov esi, [ecx+FIBER_STACK_LIMIT] + mov [edx+TEB_STACK_LIMIT], esi + mov esi, [ecx+FIBER_DEALLOCATION_STACK] + mov [edx+TEB_DEALLOCATION_STACK], esi + mov esi, [ecx+FIBER_GUARANTEED_STACK_BYTES] + mov [edx+TEB_GUARANTEED_STACK_BYTES], esi + mov esi, [ecx+FIBER_ACTIVATION_CONTEXT_STACK] + mov [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER], esi + + /* Restore FPU State */ + cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL + CONTEXT_FLOATING_POINT + jnz NoFpuStateRestore + + /* Check if the Status Word Changed */ + mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] + cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD] + jnz StatusWordChanged + + /* Check if the Control Word Changed */ + mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] + cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] + jz ControlWordEqual + +StatusWordChanged: - /* get the current fiber */ - movl 0x10(%ecx), %eax /* Fiber = Teb->Tib.FiberData */ + /* Load the new one */ + mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], 0xFFFF + fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD] + +ControlWordEqual: - /* store the volatile context of the current fiber */ - movl 0x0(%ecx), %edx - movl %edx, 0x4(%eax) /* Fiber->ExceptionList = Teb->ExceptionList */ - movl 0x4(%ecx), %edx - movl %edx, 0x8(%eax) /* Fiber->StackBase = Teb->StackBase */ - movl 0x8(%ecx), %edx - movl %edx, 0xC(%eax) /* Fiber->StackLimit = Teb->StackLimit */ - movl 0xE0C(%ecx), %edx - movl %edx, 0x10(%eax) /* Fiber->StackBottom = Teb->DeallocationStack */ - movl 0x0(%esp), %edx - movl %edx, 0x18(%eax) /* Fiber->Eip = [esp + 0] */ - movl %esp, %edx - addl $0x8, %edx - movl %edx, 0x1C(%eax) /* Fiber->Esp = esp + 8 */ - movl %ebp, 0x20(%eax) /* Fiber->Ebp = ebp */ - movl %ebx, 0x24(%eax) /* Fiber->Ebx = ebx */ - movl %esi, 0x28(%eax) /* Fiber->Esi = edi */ - movl %edi, 0x2C(%eax) /* Fiber->Edi = esi */ + /* Load the new one */ + cmp byte ptr [PROCESSOR_FEATURE_FXSR], 0 + jnz NoFpuStateRestore + ldmxcsr [ecx+FIBER_CONTEXT_DR6] + +NoFpuStateRestore: - testl $1, 0x14(%eax) - jz l_NoFloatSave - - /* save the floating point context */ - /* TODO */ - pushl ErrStr - call _DbgPrint - popl %ecx - -l_NoFloatSave: - - /* switch to the specified fiber */ - movl 0x4(%esp), %eax /* Fiber = lpFiber */ - movl %eax, 0x10(%ecx) /* Teb->Tib.FiberData = Fiber */ - - /* restore the volatile context of the specified fiber */ - movl 0x4(%eax), %edx - movl %edx, 0x0(%ecx) /* Teb->ExceptionList = Fiber->ExceptionList */ - movl 0x8(%eax), %edx - movl %edx, 0x4(%ecx) /* Teb->StackBase = Fiber->StackBase */ - movl 0xC(%eax), %edx - movl %edx, 0x8(%ecx) /* Teb->StackLimit = Fiber->StackLimit */ - movl 0x10(%eax), %edx - movl %edx, 0xE0C(%ecx) /* Teb->StackBottom = Fiber->DeallocationStack */ - movl 0x18(%eax), %edx /* edx = Fiber->Eip */ - movl 0x1C(%eax), %esp /* esp = Fiber->Esp */ - movl 0x20(%eax), %ebp /* ebp = Fiber->Ebp */ - movl 0x24(%eax), %ebx /* ebx = Fiber->Ebx */ - movl 0x28(%eax), %esi /* esi = Fiber->Esi */ - movl 0x2C(%eax), %edi /* edi = Fiber->Edi */ - - testb $1, 0x14(%eax) - jz l_NoFloatRestore - - /* restore the floating point context */ - /* TODO */ - pushl ErrStr - call _DbgPrint - popl %ecx - -l_NoFloatRestore: - - /* jump to the saved program counter */ - jmp *%edx + /* Restore non-volatile registers */ + mov esi, [ecx+FIBER_CONTEXT_ESI] + mov edi, [ecx+FIBER_CONTEXT_EDI] + mov ebx, [ecx+FIBER_CONTEXT_EBX] + mov ebp, [ecx+FIBER_CONTEXT_EBP] + mov esp, [ecx+FIBER_CONTEXT_ESP] + + /* Restore FLS Data */ + mov eax, [ecx+FIBER_FLS_DATA] + mov [edx+TEB_FLS_DATA], eax + /* Return */ + ret 4 + /* EOF */ diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 8a8d3ec0936..cf61e62f8b5 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -44,26 +44,28 @@ _SEH_FILTER(BaseThreadExceptionFilter) return ExceptionDisposition; } -__declspec(noreturn) void STDCALL -ThreadStartup -( - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter -) +__declspec(noreturn) +VOID +STDCALL +BaseThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter) { - volatile UINT uExitCode = 0; + volatile UINT uExitCode = 0; - _SEH_TRY - { - uExitCode = (lpStartAddress)((PVOID)lpParameter); - } - _SEH_EXCEPT(BaseThreadExceptionFilter) - { - uExitCode = _SEH_GetExceptionCode(); - } - _SEH_END; + /* Attempt to call the Thread Start Address */ + _SEH_TRY + { + /* Get the exit code from the Thread Start */ + uExitCode = (lpStartAddress)((PVOID)lpParameter); + } + _SEH_EXCEPT(BaseThreadExceptionFilter) + { + /* Get the Exit code from the SEH Handler */ + uExitCode = _SEH_GetExceptionCode(); + } _SEH_END; - ExitThread(uExitCode); + /* Exit the Thread */ + ExitThread(uExitCode); } @@ -209,7 +211,7 @@ CreateRemoteThread 0, nStackReserve, nStackCommit, - ThreadStartup, + BaseThreadStartup, &hThread, &cidClientId, 2, @@ -226,7 +228,7 @@ CreateRemoteThread 0, &nStackReserve, &nStackCommit, - (PTHREAD_START_ROUTINE)ThreadStartup, + (PTHREAD_START_ROUTINE)BaseThreadStartup, &hThread, &cidClientId, 2,