diff --git a/reactos/include/rosrtl/thread.h b/reactos/include/rosrtl/thread.h index 023b54d0a4e..8801e17c4e3 100644 --- a/reactos/include/rosrtl/thread.h +++ b/reactos/include/rosrtl/thread.h @@ -1,4 +1,4 @@ -/* $Id: thread.h,v 1.2 2003/05/29 00:36:41 hyperion Exp $ +/* $Id: thread.h,v 1.3 2003/07/22 20:10:04 hyperion Exp $ */ #ifdef __cplusplus @@ -6,7 +6,7 @@ extern "C" { #endif -NTSTATUS STDCALL RtlRosCreateUserThreadEx +NTSTATUS NTAPI RtlRosCreateUserThread ( IN HANDLE ProcessHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, @@ -36,7 +36,7 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa ... ); -NTSTATUS NTAPI RtlRosInitializeContextEx +NTSTATUS NTAPI RtlRosInitializeContext ( IN HANDLE ProcessHandle, OUT PCONTEXT Context, @@ -61,6 +61,27 @@ NTSTATUS NTAPI RtlRosDeleteStack IN PUSER_STACK UserStack ); +/* Private functions - for ROSRTL internal use only */ +NTSTATUS NTAPI RtlpRosGetStackLimits +( + IN PUSER_STACK UserStack, + OUT PVOID * StackBase, + OUT PVOID * StackLimit +); + +NTSTATUS NTAPI RtlpRosValidateLinearUserStack +( + IN PVOID StackBase, + IN PVOID StackLimit, + IN BOOLEAN Direction +); + +#define RtlpRosValidateTopDownUserStack(__B__, __L__) \ + (RtlpRosValidateLinearUserStack((__B__), (__L__), FALSE)) + +#define RtlpRosValidateDownTopUserStack(__B__, __L__) \ + (RtlpRosValidateLinearUserStack((__B__), (__L__), TRUE)) + #ifdef __cplusplus } #endif diff --git a/reactos/lib/kernel32/thread/fiber.c b/reactos/lib/kernel32/thread/fiber.c index efd569721e8..07d65b35a12 100644 --- a/reactos/lib/kernel32/thread/fiber.c +++ b/reactos/lib/kernel32/thread/fiber.c @@ -1,4 +1,4 @@ -/* $Id: fiber.c,v 1.6 2003/07/10 18:50:51 chorns Exp $ +/* $Id: fiber.c,v 1.7 2003/07/22 20:10:04 hyperion Exp $ * * FILE: lib/kernel32/thread/fiber.c * @@ -179,7 +179,7 @@ LPVOID WINAPI CreateFiberEx if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber; /* initialize the context for the fiber */ - nErrCode = RtlRosInitializeContextEx + nErrCode = RtlRosInitializeContext ( NtCurrentProcess(), &ctxFiberContext, diff --git a/reactos/lib/ntdll/rtl/thread.c b/reactos/lib/ntdll/rtl/thread.c index fbb665607df..086e02455e8 100644 --- a/reactos/lib/ntdll/rtl/thread.c +++ b/reactos/lib/ntdll/rtl/thread.c @@ -51,7 +51,7 @@ NTSTATUS STDCALL RtlCreateUserThread SecurityDescriptor ); - return RtlRosCreateUserThreadEx + return RtlRosCreateUserThread ( ProcessHandle, &oaThreadAttribs, @@ -76,7 +76,7 @@ NTSTATUS STDCALL RtlInitializeContext PUSER_STACK UserStack ) { - return RtlRosInitializeContextEx + return RtlRosInitializeContext ( ProcessHandle, Context, diff --git a/reactos/lib/rosrtl/makefile b/reactos/lib/rosrtl/makefile index 54f9e97d36c..1b303a32778 100644 --- a/reactos/lib/rosrtl/makefile +++ b/reactos/lib/rosrtl/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.7 2003/07/21 04:56:32 royce Exp $ +# $Id: makefile,v 1.8 2003/07/22 20:10:04 hyperion Exp $ PATH_TO_TOP = ../.. @@ -11,7 +11,6 @@ TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a THREAD_OBJECTS = \ - thread/context.o \ thread/create.o \ thread/stack.o @@ -20,6 +19,16 @@ MISC_OBJECTS = \ misc/logfont.o \ misc/qsort.o +include $(PATH_TO_TOP)/config + +include makefile.$(ARCH) + +TARGET_TYPE = library + +TARGET_NAME = rosrtl + +TARGET_CFLAGS = -Wall -Werror + TARGET_OBJECTS = $(THREAD_OBJECTS) $(MISC_OBJECTS) DEP_OBJECTS = $(TARGET_OBJECTS) diff --git a/reactos/lib/rosrtl/makefile.i386 b/reactos/lib/rosrtl/makefile.i386 new file mode 100644 index 00000000000..9252556a062 --- /dev/null +++ b/reactos/lib/rosrtl/makefile.i386 @@ -0,0 +1,8 @@ +# $Id: makefile.i386,v 1.1 2003/07/22 20:10:04 hyperion Exp $ + +THREAD_OBJECTS := \ + $(THREAD_OBJECTS) \ + thread/linearstack.o \ + thread/$(ARCH)/context.o + +# EOF diff --git a/reactos/lib/rosrtl/thread/create.c b/reactos/lib/rosrtl/thread/create.c index fce8696ff90..8181bf67828 100644 --- a/reactos/lib/rosrtl/thread/create.c +++ b/reactos/lib/rosrtl/thread/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.3 2003/06/01 14:59:02 chorns Exp $ +/* $Id: create.c,v 1.4 2003/07/22 20:10:04 hyperion Exp $ */ /* */ @@ -10,7 +10,9 @@ #define NDEBUG #include -NTSTATUS STDCALL RtlRosCreateUserThreadEx +#include + +NTSTATUS STDCALL RtlRosCreateUserThread ( IN HANDLE ProcessHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, @@ -26,7 +28,6 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx ) { USER_STACK usUserStack; - OBJECT_ATTRIBUTES oaThreadAttribs; CONTEXT ctxInitialContext; NTSTATUS nErrCode; HANDLE hThread; @@ -49,7 +50,7 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx if(!NT_SUCCESS(nErrCode)) goto l_Fail; /* initialize the registers and stack for the thread */ - nErrCode = RtlRosInitializeContextEx + nErrCode = RtlRosInitializeContext ( ProcessHandle, &ctxInitialContext, @@ -111,8 +112,16 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa va_start(vaArgs, ParameterCount); - /* FIXME: this code assumes a stack growing downwards */ - nErrCode = RtlRosCreateUserThreadEx + /* + FIXME: this code makes several non-portable assumptions: + - all parameters are passed on the stack + - the stack is a contiguous array of cells as large as an ULONG_PTR + - the stack grows downwards + + This happens to work on the Intel x86, but is likely to bomb horribly on most + other platforms + */ + nErrCode = RtlRosCreateUserThread ( ProcessHandle, ObjectAttributes, diff --git a/reactos/lib/rosrtl/thread/i386/.cvsignore b/reactos/lib/rosrtl/thread/i386/.cvsignore new file mode 100644 index 00000000000..b2bf6455490 --- /dev/null +++ b/reactos/lib/rosrtl/thread/i386/.cvsignore @@ -0,0 +1,2 @@ +*.o +.*.d \ No newline at end of file diff --git a/reactos/lib/rosrtl/thread/context.c b/reactos/lib/rosrtl/thread/i386/context.c similarity index 62% rename from reactos/lib/rosrtl/thread/context.c rename to reactos/lib/rosrtl/thread/i386/context.c index f2eb6d7ad8c..9569b41a41f 100644 --- a/reactos/lib/rosrtl/thread/context.c +++ b/reactos/lib/rosrtl/thread/i386/context.c @@ -1,19 +1,19 @@ -/* $Id: context.c,v 1.3 2003/06/01 14:59:02 chorns Exp $ +/* $Id: context.c,v 1.1 2003/07/22 20:10:04 hyperion Exp $ */ /* */ +#include + #define NTOS_MODE_USER #include -#if defined(_M_IX86) #include #include -#else -#error Unsupported architecture -#endif -NTSTATUS NTAPI RtlRosInitializeContextEx +#include + +NTSTATUS NTAPI RtlRosInitializeContext ( IN HANDLE ProcessHandle, OUT PCONTEXT Context, @@ -23,35 +23,27 @@ NTSTATUS NTAPI RtlRosInitializeContextEx IN ULONG_PTR * Parameters ) { + static PVOID s_pRetAddr = (PVOID)0xDEADBEEF; + ULONG nDummy; - PCHAR pStackBase; - PCHAR pStackLimit; - ULONG_PTR nRetAddr = 0xDEADBEEF; SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR); NTSTATUS nErrCode; + PVOID pStackBase; + PVOID pStackLimit; - /* fixed-size stack */ - if(UserStack->FixedStackBase && UserStack->FixedStackLimit) - { - pStackBase = UserStack->FixedStackBase; - pStackLimit = UserStack->FixedStackLimit; - } - /* expandable stack */ - else if(UserStack->ExpandableStackBase && UserStack->ExpandableStackLimit) - { - pStackBase = UserStack->ExpandableStackBase; - pStackLimit = UserStack->ExpandableStackLimit; - } - /* bad initial stack */ - else - return STATUS_BAD_INITIAL_STACK; + /* Intel x86: linear top-down stack, all parameters passed on the stack */ + /* get the stack base and limit */ + nErrCode = RtlpRosGetStackLimits(UserStack, &pStackBase, &pStackLimit); - /* stack base lower than the limit */ - if(pStackBase <= pStackLimit) - return STATUS_BAD_INITIAL_STACK; + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + /* validate the stack */ + nErrCode = RtlpRosValidateTopDownUserStack(pStackBase, pStackLimit); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; -#if defined(_M_IX86) - /* Intel x86: all parameters passed on the stack */ /* too many parameters */ if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit)) return STATUS_STACK_OVERFLOW; @@ -92,14 +84,10 @@ NTSTATUS NTAPI RtlRosInitializeContextEx ( ProcessHandle, ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)), - &nRetAddr, - sizeof(ULONG_PTR), + &s_pRetAddr, + sizeof(s_pRetAddr), &nDummy ); - -#else -#error Unsupported architecture -#endif } /* EOF */ diff --git a/reactos/lib/rosrtl/thread/linearstack.c b/reactos/lib/rosrtl/thread/linearstack.c new file mode 100644 index 00000000000..2c4c9f79fe6 --- /dev/null +++ b/reactos/lib/rosrtl/thread/linearstack.c @@ -0,0 +1,38 @@ +/* $Id: linearstack.c,v 1.1 2003/07/22 20:10:04 hyperion Exp $ +*/ +/* +*/ + +#define NTOS_MODE_USER +#include + +#include + +NTSTATUS NTAPI RtlpRosValidateLinearUserStack +( + IN PVOID StackBase, + IN PVOID StackLimit, + IN BOOLEAN Direction +) +{ + /* the stack has a null or negative (relatively to its direction) length */ + /* + Direction: TRUE for down-top, FALSE for top-down + + Direction == TRUE and positive stack size: OK + Direction == TRUE and negative stack size: error + Direction == FALSE and positive stack size: error + Direction == FALSE and negative stack size: OK + */ + if + ( + StackBase == StackLimit || + (Direction ^ ((PCHAR)StackBase < (PCHAR)StackLimit)) + ) + return STATUS_BAD_INITIAL_STACK; + + /* valid stack */ + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/reactos/lib/rosrtl/thread/stack.c b/reactos/lib/rosrtl/thread/stack.c index f1e1de648ad..0cb49ce7a79 100644 --- a/reactos/lib/rosrtl/thread/stack.c +++ b/reactos/lib/rosrtl/thread/stack.c @@ -1,4 +1,4 @@ -/* $Id: stack.c,v 1.2 2003/06/01 14:59:02 chorns Exp $ +/* $Id: stack.c,v 1.3 2003/07/22 20:10:04 hyperion Exp $ */ /* */ @@ -9,6 +9,8 @@ #define NDEBUG #include +#include + NTSTATUS NTAPI RtlRosCreateStack ( IN HANDLE ProcessHandle, @@ -22,15 +24,13 @@ NTSTATUS NTAPI RtlRosCreateStack ULONG_PTR nStackReserve = 0x100000; /* FIXME: when we finally have exception handling, make this PAGE_SIZE */ ULONG_PTR nStackCommit = 0x100000; - PVOID pStackLowest; - ULONG_PTR nSize = 0; NTSTATUS nErrCode; if(StackReserve == NULL) StackReserve = &nStackReserve; - else ROUNDUP(*StackReserve, PAGE_SIZE); + else *StackReserve = ROUNDUP(*StackReserve, PAGE_SIZE); if(StackCommit == NULL) StackCommit = &nStackCommit; - else ROUNDUP(*StackCommit, PAGE_SIZE); + else *StackCommit = ROUNDUP(*StackCommit, PAGE_SIZE); #if 0 /* the stack commit size must be equal to or less than the reserve size */ @@ -184,4 +184,35 @@ NTSTATUS NTAPI RtlRosDeleteStack return STATUS_SUCCESS; } + +NTSTATUS NTAPI RtlpRosGetStackLimits +( + IN PUSER_STACK UserStack, + OUT PVOID * StackBase, + OUT PVOID * StackLimit +) +{ + /* fixed-size stack */ + if(UserStack->FixedStackBase && UserStack->FixedStackLimit) + { + *StackBase = UserStack->FixedStackBase; + *StackLimit = UserStack->FixedStackLimit; + } + /* expandable stack */ + else if(UserStack->ExpandableStackBase && UserStack->ExpandableStackLimit) + { + *StackBase = UserStack->ExpandableStackBase; + *StackLimit = UserStack->ExpandableStackLimit; + } + /* can't determine the type of stack: failure */ + else + { + DPRINT("Invalid user-mode stack\n"); + return STATUS_BAD_INITIAL_STACK; + } + + /* valid stack */ + return STATUS_SUCCESS; +} + /* EOF */