Made the thread creation code in ROSRTL more portable

svn path=/trunk/; revision=5220
This commit is contained in:
KJK::Hyperion 2003-07-22 20:10:04 +00:00
parent c1efb7ad67
commit 67939b3b7b
10 changed files with 161 additions and 55 deletions

View file

@ -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 #ifdef __cplusplus
@ -6,7 +6,7 @@ extern "C"
{ {
#endif #endif
NTSTATUS STDCALL RtlRosCreateUserThreadEx NTSTATUS NTAPI RtlRosCreateUserThread
( (
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES ObjectAttributes,
@ -36,7 +36,7 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa
... ...
); );
NTSTATUS NTAPI RtlRosInitializeContextEx NTSTATUS NTAPI RtlRosInitializeContext
( (
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
OUT PCONTEXT Context, OUT PCONTEXT Context,
@ -61,6 +61,27 @@ NTSTATUS NTAPI RtlRosDeleteStack
IN PUSER_STACK UserStack 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -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 * FILE: lib/kernel32/thread/fiber.c
* *
@ -179,7 +179,7 @@ LPVOID WINAPI CreateFiberEx
if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber; if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber;
/* initialize the context for the fiber */ /* initialize the context for the fiber */
nErrCode = RtlRosInitializeContextEx nErrCode = RtlRosInitializeContext
( (
NtCurrentProcess(), NtCurrentProcess(),
&ctxFiberContext, &ctxFiberContext,

View file

@ -51,7 +51,7 @@ NTSTATUS STDCALL RtlCreateUserThread
SecurityDescriptor SecurityDescriptor
); );
return RtlRosCreateUserThreadEx return RtlRosCreateUserThread
( (
ProcessHandle, ProcessHandle,
&oaThreadAttribs, &oaThreadAttribs,
@ -76,7 +76,7 @@ NTSTATUS STDCALL RtlInitializeContext
PUSER_STACK UserStack PUSER_STACK UserStack
) )
{ {
return RtlRosInitializeContextEx return RtlRosInitializeContext
( (
ProcessHandle, ProcessHandle,
Context, Context,

View file

@ -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 = ../.. PATH_TO_TOP = ../..
@ -11,7 +11,6 @@ TARGET_LFLAGS = -nostartfiles -nostdlib
TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a
THREAD_OBJECTS = \ THREAD_OBJECTS = \
thread/context.o \
thread/create.o \ thread/create.o \
thread/stack.o thread/stack.o
@ -20,6 +19,16 @@ MISC_OBJECTS = \
misc/logfont.o \ misc/logfont.o \
misc/qsort.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) TARGET_OBJECTS = $(THREAD_OBJECTS) $(MISC_OBJECTS)
DEP_OBJECTS = $(TARGET_OBJECTS) DEP_OBJECTS = $(TARGET_OBJECTS)

View file

@ -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

View file

@ -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 #define NDEBUG
#include <ntdll/ntdll.h> #include <ntdll/ntdll.h>
NTSTATUS STDCALL RtlRosCreateUserThreadEx #include <rosrtl/thread.h>
NTSTATUS STDCALL RtlRosCreateUserThread
( (
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES ObjectAttributes,
@ -26,7 +28,6 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
) )
{ {
USER_STACK usUserStack; USER_STACK usUserStack;
OBJECT_ATTRIBUTES oaThreadAttribs;
CONTEXT ctxInitialContext; CONTEXT ctxInitialContext;
NTSTATUS nErrCode; NTSTATUS nErrCode;
HANDLE hThread; HANDLE hThread;
@ -49,7 +50,7 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
if(!NT_SUCCESS(nErrCode)) goto l_Fail; if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* initialize the registers and stack for the thread */ /* initialize the registers and stack for the thread */
nErrCode = RtlRosInitializeContextEx nErrCode = RtlRosInitializeContext
( (
ProcessHandle, ProcessHandle,
&ctxInitialContext, &ctxInitialContext,
@ -111,8 +112,16 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa
va_start(vaArgs, ParameterCount); 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, ProcessHandle,
ObjectAttributes, ObjectAttributes,

View file

@ -0,0 +1,2 @@
*.o
.*.d

View file

@ -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 <string.h>
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ntos.h> #include <ntos.h>
#if defined(_M_IX86)
#include <napi/i386/segment.h> #include <napi/i386/segment.h>
#include <napi/i386/floatsave.h> #include <napi/i386/floatsave.h>
#else
#error Unsupported architecture
#endif
NTSTATUS NTAPI RtlRosInitializeContextEx #include <rosrtl/thread.h>
NTSTATUS NTAPI RtlRosInitializeContext
( (
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
OUT PCONTEXT Context, OUT PCONTEXT Context,
@ -23,35 +23,27 @@ NTSTATUS NTAPI RtlRosInitializeContextEx
IN ULONG_PTR * Parameters IN ULONG_PTR * Parameters
) )
{ {
static PVOID s_pRetAddr = (PVOID)0xDEADBEEF;
ULONG nDummy; ULONG nDummy;
PCHAR pStackBase;
PCHAR pStackLimit;
ULONG_PTR nRetAddr = 0xDEADBEEF;
SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR); SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
NTSTATUS nErrCode; NTSTATUS nErrCode;
PVOID pStackBase;
PVOID pStackLimit;
/* fixed-size stack */ /* Intel x86: linear top-down stack, all parameters passed on the stack */
if(UserStack->FixedStackBase && UserStack->FixedStackLimit) /* get the stack base and limit */
{ nErrCode = RtlpRosGetStackLimits(UserStack, &pStackBase, &pStackLimit);
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;
/* stack base lower than the limit */ /* failure */
if(pStackBase <= pStackLimit) if(!NT_SUCCESS(nErrCode)) return nErrCode;
return STATUS_BAD_INITIAL_STACK;
/* 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 */ /* too many parameters */
if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit)) if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit))
return STATUS_STACK_OVERFLOW; return STATUS_STACK_OVERFLOW;
@ -92,14 +84,10 @@ NTSTATUS NTAPI RtlRosInitializeContextEx
( (
ProcessHandle, ProcessHandle,
((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)), ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
&nRetAddr, &s_pRetAddr,
sizeof(ULONG_PTR), sizeof(s_pRetAddr),
&nDummy &nDummy
); );
#else
#error Unsupported architecture
#endif
} }
/* EOF */ /* EOF */

View file

@ -0,0 +1,38 @@
/* $Id: linearstack.c,v 1.1 2003/07/22 20:10:04 hyperion Exp $
*/
/*
*/
#define NTOS_MODE_USER
#include <ntos.h>
#include <rosrtl/thread.h>
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 */

View file

@ -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 #define NDEBUG
#include <ntdll/ntdll.h> #include <ntdll/ntdll.h>
#include <rosrtl/thread.h>
NTSTATUS NTAPI RtlRosCreateStack NTSTATUS NTAPI RtlRosCreateStack
( (
IN HANDLE ProcessHandle, IN HANDLE ProcessHandle,
@ -22,15 +24,13 @@ NTSTATUS NTAPI RtlRosCreateStack
ULONG_PTR nStackReserve = 0x100000; ULONG_PTR nStackReserve = 0x100000;
/* FIXME: when we finally have exception handling, make this PAGE_SIZE */ /* FIXME: when we finally have exception handling, make this PAGE_SIZE */
ULONG_PTR nStackCommit = 0x100000; ULONG_PTR nStackCommit = 0x100000;
PVOID pStackLowest;
ULONG_PTR nSize = 0;
NTSTATUS nErrCode; NTSTATUS nErrCode;
if(StackReserve == NULL) StackReserve = &nStackReserve; if(StackReserve == NULL) StackReserve = &nStackReserve;
else ROUNDUP(*StackReserve, PAGE_SIZE); else *StackReserve = ROUNDUP(*StackReserve, PAGE_SIZE);
if(StackCommit == NULL) StackCommit = &nStackCommit; if(StackCommit == NULL) StackCommit = &nStackCommit;
else ROUNDUP(*StackCommit, PAGE_SIZE); else *StackCommit = ROUNDUP(*StackCommit, PAGE_SIZE);
#if 0 #if 0
/* the stack commit size must be equal to or less than the reserve size */ /* the stack commit size must be equal to or less than the reserve size */
@ -184,4 +184,35 @@ NTSTATUS NTAPI RtlRosDeleteStack
return STATUS_SUCCESS; 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 */ /* EOF */