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

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

View file

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

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 = ../..
@ -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)

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
#include <ntdll/ntdll.h>
NTSTATUS STDCALL RtlRosCreateUserThreadEx
#include <rosrtl/thread.h>
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,

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
#include <ntos.h>
#if defined(_M_IX86)
#include <napi/i386/segment.h>
#include <napi/i386/floatsave.h>
#else
#error Unsupported architecture
#endif
NTSTATUS NTAPI RtlRosInitializeContextEx
#include <rosrtl/thread.h>
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 */

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
#include <ntdll/ntdll.h>
#include <rosrtl/thread.h>
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 */