- new statically linked library ROSRTL, for code to be shared among system DLLs

- user-mode thread creation code moved to ROSRTL
 - user-mode thread context initialization code fixed
 - LdrInitializeThunk() breakin stub fixed

svn path=/trunk/; revision=4615
This commit is contained in:
KJK::Hyperion 2003-04-29 02:17:01 +00:00
parent 6247d82cc7
commit 38a1364aae
15 changed files with 584 additions and 412 deletions

View file

@ -33,7 +33,7 @@ LIB_FSLIB = vfatlib
# User mode libraries
# advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32
# oleaut32 epsapi psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda
DLLS = advapi32 crtdll fmifs freetype gdi32 kernel32 packet msafd msvcrt ntdll \
DLLS = rosrtl advapi32 crtdll fmifs freetype gdi32 kernel32 packet msafd msvcrt ntdll \
epsapi psapi secur32 user32 version winedbgc ws2help ws2_32 wsock32 wshirda zlib #winmm
SUBSYS = smss win32k csrss ntvdm

View file

@ -0,0 +1,11 @@
#ifndef __NAPI_I386_FLOATSAVE_H__
#define __NAPI_I386_FLOATSAVE_H__
#define FLOAT_SAVE_CONTROL (0xFFFF037F)
#define FLOAT_SAVE_STATUS (0xFFFF0000)
#define FLOAT_SAVE_TAG (0xFFFFFFFF)
#define FLOAT_SAVE_DATA (0xFFFF0000)
#endif /* __NAPI_I386_FLOATSAVE_H__ */
/* EOF */

View file

@ -0,0 +1,53 @@
/* $Id: thread.h,v 1.1 2003/04/29 02:17:00 hyperion Exp $
*/
#ifdef __cplusplus
extern "C"
{
#endif
NTSTATUS STDCALL RtlRosCreateUserThreadEx
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN CreateSuspended,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
IN PTHREAD_START_ROUTINE StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
IN ULONG_PTR * Parameters
);
NTSTATUS CDECL RtlRosCreateUserThreadVa
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN CreateSuspended,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
IN PTHREAD_START_ROUTINE StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
...
);
NTSTATUS NTAPI RtlRosInitializeContextEx
(
IN HANDLE ProcessHandle,
IN PCONTEXT Context,
IN PTHREAD_START_ROUTINE StartAddress,
IN PUSER_STACK UserStack,
IN ULONG ParameterCount,
IN ULONG_PTR * Parameters
);
#ifdef __cplusplus
}
#endif
/* EOF */

View file

@ -24,3 +24,4 @@
#include <ntos/minmax.h>
#include <csrss/csrss.h>
#include <reactos/buildno.h>
#include <rosrtl/thread.h>

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.63 2003/04/14 01:19:06 hyperion Exp $
# $Id: makefile,v 1.64 2003/04/29 02:16:59 hyperion Exp $
PATH_TO_TOP = ../..
@ -10,7 +10,7 @@ TARGET_BASE = 0x77f00000
TARGET_LFLAGS = -nostartfiles -nostdlib
TARGET_SDKLIBS = ntdll.a
TARGET_SDKLIBS = rosrtl.a ntdll.a
TARGET_GCCLIBS = gcc

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.66 2003/04/26 23:13:28 hyperion Exp $
/* $Id: create.c,v 1.67 2003/04/29 02:16:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -93,21 +93,6 @@ VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed
}
}
NTSTATUS CDECL RtlCreateUserThreadVa
(
HANDLE ProcessHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN CreateSuspended,
LONG StackZeroBits,
PULONG StackReserve,
PULONG StackCommit,
PTHREAD_START_ROUTINE StartAddress,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId,
ULONG ParameterCount,
...
);
BOOL STDCALL CreateProcessA
(
LPCSTR lpApplicationName,
@ -408,8 +393,39 @@ HANDLE STDCALL KlCreateFirstThread
else
pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine;
DPRINT
(
"RtlRosCreateUserThreadVa\n"
"(\n"
" ProcessHandle %p,\n"
" ObjectAttributes %p,\n"
" CreateSuspended %d,\n"
" StackZeroBits %d,\n"
" StackReserve %lu,\n"
" StackCommit %lu,\n"
" StartAddress %p,\n"
" ThreadHandle %p,\n"
" ClientId %p,\n"
" ParameterCount %u,\n"
" Parameters[0] %p,\n"
" Parameters[1] %p\n"
")\n",
ProcessHandle,
&oaThreadAttribs,
dwCreationFlags & CREATE_SUSPENDED,
0,
Sii->StackReserve,
Sii->StackCommit,
pTrueStartAddress,
&hThread,
&cidClientId,
2,
lpStartAddress,
PEB_BASE
);
/* create the first thread */
nErrCode = RtlCreateUserThreadVa
nErrCode = RtlRosCreateUserThreadVa
(
ProcessHandle,
&oaThreadAttribs,
@ -431,8 +447,21 @@ HANDLE STDCALL KlCreateFirstThread
SetLastErrorByStatus(nErrCode);
return NULL;
}
DPRINT
(
"StackReserve %p\n"
"StackCommit %p\n"
"ThreadHandle %p\n"
"ClientId.UniqueThread %p\n",
Sii->StackReserve,
Sii->StackCommit,
hThread,
cidClientId.UniqueThread
);
/* success */
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
return hThread;
}

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.37 2003/04/26 23:13:28 hyperion Exp $
/* $Id: thread.c,v 1.38 2003/04/29 02:16:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -22,21 +22,6 @@
/* FUNCTIONS *****************************************************************/
/* FIXME: please put this in some header */
extern NTSTATUS CDECL RtlCreateUserThreadVa
(
HANDLE ProcessHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN CreateSuspended,
LONG StackZeroBits,
PULONG StackReserve,
PULONG StackCommit,
PTHREAD_START_ROUTINE StartAddress,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId,
ULONG ParameterCount,
...
);
static EXCEPTION_DISPOSITION __cdecl
_except_handler(EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
@ -113,6 +98,24 @@ HANDLE STDCALL CreateRemoteThread
PIMAGE_NT_HEADERS pinhHeader =
RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
DPRINT
(
"hProcess %08X\n"
"lpThreadAttributes %08X\n"
"dwStackSize %08X\n"
"lpStartAddress %08X\n"
"lpParameter %08X\n"
"dwCreationFlags %08X\n"
"lpThreadId %08X\n",
hProcess,
lpThreadAttributes,
dwStackSize,
lpStartAddress,
lpParameter,
dwCreationFlags,
lpThreadId
);
/* FIXME: do more checks - e.g. the image may not have an optional header */
if(pinhHeader == NULL)
{
@ -163,8 +166,39 @@ HANDLE STDCALL CreateRemoteThread
oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
}
DPRINT
(
"RtlRosCreateUserThreadVa\n"
"(\n"
" ProcessHandle %p,\n"
" ObjectAttributes %p,\n"
" CreateSuspended %d,\n"
" StackZeroBits %d,\n"
" StackReserve %lu,\n"
" StackCommit %lu,\n"
" StartAddress %p,\n"
" ThreadHandle %p,\n"
" ClientId %p,\n"
" ParameterCount %u,\n"
" Parameters[0] %p,\n"
" Parameters[1] %p\n"
")\n",
hProcess,
&oaThreadAttribs,
dwCreationFlags & CREATE_SUSPENDED,
0,
nStackReserve,
nStackCommit,
ThreadStartup,
&hThread,
&cidClientId,
2,
lpStartAddress,
lpParameter
);
/* create the thread */
nErrCode = RtlCreateUserThreadVa
nErrCode = RtlRosCreateUserThreadVa
(
hProcess,
&oaThreadAttribs,
@ -186,6 +220,18 @@ HANDLE STDCALL CreateRemoteThread
SetLastErrorByStatus(nErrCode);
return NULL;
}
DPRINT
(
"StackReserve %p\n"
"StackCommit %p\n"
"ThreadHandle %p\n"
"ClientId.UniqueThread %p\n",
nStackReserve,
nStackCommit,
hThread,
cidClientId.UniqueThread
);
/* success */
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;

View file

@ -1,4 +1,4 @@
; $Id: ntdll.def,v 1.97 2003/04/26 23:13:29 hyperion Exp $
; $Id: ntdll.def,v 1.98 2003/04/29 02:16:59 hyperion Exp $
;
; ReactOS Operating System
;
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz@8
RtlCreateUserProcess@40
;RtlCreateUserSecurityObject
RtlCreateUserThread@40
RtlCreateUserThread@44
RtlCreateUserThreadVa
RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams@4
@ -450,7 +448,6 @@ RtlInitUnicodeString@8
;RtlInitializeAtomPackage
RtlInitializeBitMap@12
RtlInitializeContext@20
RtlInitializeContextEx@24
RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
RtlInitializeHandleTable@12

View file

@ -1,4 +1,4 @@
; $Id: ntdll.edf,v 1.86 2003/04/26 23:13:29 hyperion Exp $
; $Id: ntdll.edf,v 1.87 2003/04/29 02:16:59 hyperion Exp $
;
; ReactOS Operating System
;
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8
RtlCreateUserProcess=RtlCreateUserProcess@40
;RtlCreateUserSecurityObject
RtlCreateUserThread=RtlCreateUserThread@40
RtlCreateUserThreadEx=RtlCreateUserThreadEx@44
RtlCreateUserThreadVa=RtlCreateUserThreadVa
RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4
@ -449,7 +447,6 @@ RtlInitUnicodeString=RtlInitUnicodeString@8
;RtlInitializeAtomPackage
RtlInitializeBitMap=RtlInitializeBitMap@12
RtlInitializeContext=RtlInitializeContext@20
RtlInitializeContextEx=RtlInitializeContextEx@24
RtlInitializeCriticalSection=RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
RtlInitializeHandleTable=RtlInitializeHandleTable@12

View file

@ -5,14 +5,14 @@
.globl _LdrInitializeThunk@16
_LdrInitializeThunk@16:
#if defined(_M_IX86)
nop /* breakin overwrites this with "int 3" */
jmp ___true_LdrInitializeThunk@16
nop /* breakin overwrites this with "int 3" */
jmp ___true_LdrInitializeThunk@16
#elif defined(_M_ALPHA)
nop /* breakin overwrites this with "call_pal bpt" */
"br"
nop /* breakin overwrites this with "call_pal bpt" */
br ___true_LdrInitializeThunk@16
#elif defined(_M_MIPS)
nop /* breakin overwrites this with "break" */
j ___true_LdrInitializeThunk@16
nop /* breakin overwrites this with "break" */
j ___true_LdrInitializeThunk@16
#else
#error Unsupported architecture.
#endif

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.82 2003/04/27 14:45:52 chorns Exp $
# $Id: makefile,v 1.83 2003/04/29 02:17:00 hyperion Exp $
PATH_TO_TOP = ../..
@ -16,6 +16,8 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \
-Wl,--section-alignment,0x1000 \
-nostartfiles
TARGET_SDKLIBS = rosrtl.a
TARGET_GCCLIBS = gcc
TARGET_BASE = 0x77f60000

View file

@ -10,292 +10,24 @@
* 25/04/03: Near rewrite. Made code more readable, replaced
* INITIAL_TEB with USER_STACK, added support for
* fixed-size stacks
* 28/04/03: Moved all code to a new statically linked
* library (ROSRTL) so it can be shared with
* kernel32.dll without exporting non-standard
* functions from ntdll.dll
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <napi/i386/segment.h>
#include <napi/teb.h>
#include <ntdll/rtl.h>
#include <rosrtl/thread.h>
//#define NDEBUG
#define NDEBUG
#include <ntdll/ntdll.h>
/* FUNCTIONS ***************************************************************/
NTSTATUS STDCALL RtlInitializeContextEx
(
HANDLE ProcessHandle,
PCONTEXT Context,
PTHREAD_START_ROUTINE StartAddress,
PUSER_STACK UserStack,
ULONG ParameterCount,
ULONG_PTR * Parameters
);
NTSTATUS STDCALL RtlCreateUserThreadEx
(
HANDLE ProcessHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN CreateSuspended,
LONG StackZeroBits,
PULONG StackReserve,
PULONG StackCommit,
PTHREAD_START_ROUTINE StartAddress,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId,
ULONG ParameterCount,
ULONG_PTR * Parameters
)
{
USER_STACK usUserStack;
OBJECT_ATTRIBUTES oaThreadAttribs;
/* FIXME: read the defaults from the executable image */
ULONG_PTR nStackReserve = 0x100000;
/* FIXME: when we finally have exception handling, make this PAGE_SIZE */
ULONG_PTR nStackCommit = 0x100000;
ULONG_PTR nSize = 0;
PVOID pStackLowest = NULL;
ULONG nDummy;
CONTEXT ctxInitialContext;
NTSTATUS nErrCode;
HANDLE hThread;
CLIENT_ID cidClientId;
ULONG i;
DPRINT("blah\n");
for(i = 0; i < ParameterCount; ++ i)
DPRINT("parameter %lu = %p\n", i, Parameters[i]);
DPRINT("doh\n");
if(ThreadHandle == NULL) ThreadHandle = &hThread;
if(ClientId == NULL) ClientId = &cidClientId;
if(StackReserve == NULL) StackReserve = &nStackReserve;
else ROUNDUP(*StackReserve, PAGE_SIZE);
if(StackCommit == NULL) StackCommit = &nStackCommit;
else ROUNDUP(*StackCommit, PAGE_SIZE);
#if 0
/* the stack commit size must be equal to or less than the reserve size */
if(*StackCommit > *StackReserve) *StackCommit = *StackReserve;
#else
/* FIXME: no SEH, no guard pages */
*StackCommit = *StackReserve;
#endif
usUserStack.FixedStackBase = NULL;
usUserStack.FixedStackLimit = NULL;
usUserStack.ExpandableStackBase = NULL;
usUserStack.ExpandableStackLimit = NULL;
usUserStack.ExpandableStackBottom = NULL;
/* FIXME: this code assumes a stack growing downwards */
/* fixed stack */
if(*StackCommit == *StackReserve)
{
DPRINT("Fixed stack\n");
usUserStack.FixedStackLimit = NULL;
/* allocate the stack */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.FixedStackLimit),
StackZeroBits,
StackReserve,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* store the highest (first) address of the stack */
usUserStack.FixedStackBase =
(PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve;
*StackCommit = *StackReserve;
DPRINT("Stack base %p\n", usUserStack.FixedStackBase);
DPRINT("Stack limit %p\n", usUserStack.FixedStackLimit);
}
/* expandable stack */
else
{
ULONG_PTR nGuardSize = PAGE_SIZE;
PVOID pGuardBase;
DPRINT("Expandable stack\n");
usUserStack.FixedStackLimit = NULL;
usUserStack.FixedStackBase = NULL;
usUserStack.ExpandableStackBottom = NULL;
/* reserve the stack */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.ExpandableStackBottom),
StackZeroBits,
StackReserve,
MEM_RESERVE,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
DPRINT("Reserved %08X bytes\n", *StackReserve);
/* expandable stack base - the highest address of the stack */
usUserStack.ExpandableStackBase =
(PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve;
/* expandable stack limit - the lowest committed address of the stack */
usUserStack.ExpandableStackLimit =
(PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit;
DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase);
DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit);
DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom);
/* commit as much stack as requested */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.ExpandableStackLimit),
0,
StackCommit,
MEM_COMMIT,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
assert((*StackReserve - *StackCommit) >= PAGE_SIZE);
assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0);
pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE;
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
/* set up the guard page */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&pGuardBase,
0,
&nGuardSize,
MEM_COMMIT,
PAGE_READWRITE | PAGE_GUARD
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
}
/* initialize the registers and stack for the thread */
nErrCode = RtlInitializeContextEx
(
ProcessHandle,
&ctxInitialContext,
StartAddress,
&usUserStack,
ParameterCount,
Parameters
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
/* create the thread object */
nErrCode = NtCreateThread
(
ThreadHandle,
THREAD_ALL_ACCESS,
ObjectAttributes,
ProcessHandle,
ClientId,
&ctxInitialContext,
&usUserStack,
CreateSuspended
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
/* success */
return STATUS_SUCCESS;
/* deallocate the stack */
l_Cleanup:
if(usUserStack.FixedStackLimit)
pStackLowest = usUserStack.FixedStackLimit;
else if(usUserStack.ExpandableStackBottom)
pStackLowest = usUserStack.ExpandableStackBottom;
/* free the stack, if it was allocated */
if(pStackLowest != NULL)
NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
/* failure */
l_Fail:
assert(!NT_SUCCESS(nErrCode));
return nErrCode;
}
NTSTATUS CDECL RtlCreateUserThreadVa
(
HANDLE ProcessHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
BOOLEAN CreateSuspended,
LONG StackZeroBits,
PULONG StackReserve,
PULONG StackCommit,
PTHREAD_START_ROUTINE StartAddress,
PHANDLE ThreadHandle,
PCLIENT_ID ClientId,
ULONG ParameterCount,
...
)
{
va_list vaArgs;
NTSTATUS nErrCode;
va_start(vaArgs, ParameterCount);
/* FIXME: this code assumes a stack growing downwards */
nErrCode = RtlCreateUserThreadEx
(
ProcessHandle,
ObjectAttributes,
CreateSuspended,
StackZeroBits,
StackReserve,
StackCommit,
StartAddress,
ThreadHandle,
ClientId,
ParameterCount,
(ULONG_PTR *)vaArgs
);
va_end(vaArgs);
return nErrCode;
}
NTSTATUS STDCALL RtlCreateUserThread
(
HANDLE ProcessHandle,
@ -321,7 +53,7 @@ NTSTATUS STDCALL RtlCreateUserThread
SecurityDescriptor
);
return RtlCreateUserThreadEx
return RtlRosCreateUserThreadEx
(
ProcessHandle,
&oaThreadAttribs,
@ -337,90 +69,6 @@ NTSTATUS STDCALL RtlCreateUserThread
);
}
NTSTATUS STDCALL RtlInitializeContextEx
(
HANDLE ProcessHandle,
PCONTEXT Context,
PTHREAD_START_ROUTINE StartAddress,
PUSER_STACK UserStack,
ULONG ParameterCount,
ULONG_PTR * Parameters
)
{
ULONG nDummy;
PCHAR pStackBase;
PCHAR pStackLimit;
ULONG_PTR nRetAddr = 0xDEADBEEF;
SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
NTSTATUS nErrCode;
if(UserStack->FixedStackBase != NULL && UserStack->FixedStackLimit != NULL)
{
pStackBase = UserStack->FixedStackBase;
pStackLimit = UserStack->FixedStackLimit;
}
else if(UserStack->ExpandableStackBase != NULL)
{
pStackBase = UserStack->ExpandableStackBase;
pStackLimit = UserStack->ExpandableStackLimit;
}
else
return STATUS_BAD_INITIAL_STACK;
if(pStackBase <= pStackLimit)
return STATUS_BAD_INITIAL_STACK;
/* too many parameters */
if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit))
return STATUS_STACK_OVERFLOW;
#if defined(_M_IX86)
memset(Context, 0, sizeof(CONTEXT));
Context->ContextFlags = CONTEXT_FULL;
Context->FloatSave.ControlWord = 0xffff037f;
Context->FloatSave.StatusWord = 0xffff0000;
Context->FloatSave.TagWord = 0xffffffff;
Context->FloatSave.DataSelector = 0xffff0000;
Context->Eip = (ULONG_PTR)StartAddress;
Context->SegGs = USER_DS;
Context->SegFs = TEB_SELECTOR;
Context->SegEs = USER_DS;
Context->SegDs = USER_DS;
Context->SegCs = USER_CS;
Context->SegSs = USER_DS;
Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR));
Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
DPRINT("Effective stack base %p\n", Context->Esp);
#else
#error Unsupported architecture
#endif
/* write the parameters */
nErrCode = NtWriteVirtualMemory
(
ProcessHandle,
((PUCHAR)pStackBase) - nParamsSize,
Parameters,
nParamsSize,
&nDummy
);
/* failure */
if(!NT_SUCCESS(nErrCode)) return nErrCode;
/* write the return address */
return NtWriteVirtualMemory
(
ProcessHandle,
((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
&nRetAddr,
sizeof(ULONG_PTR),
&nDummy
);
}
NTSTATUS STDCALL RtlInitializeContext
(
HANDLE ProcessHandle,
@ -430,7 +78,7 @@ NTSTATUS STDCALL RtlInitializeContext
PUSER_STACK UserStack
)
{
return RtlInitializeContextEx
return RtlRosInitializeContextEx
(
ProcessHandle,
Context,

View file

@ -0,0 +1,23 @@
# $Id: makefile,v 1.1 2003/04/29 02:17:01 hyperion Exp $
PATH_TO_TOP = ../..
TARGET_TYPE = library
TARGET_NAME = rosrtl
THREAD_OBJECTS = \
thread/context.o \
thread/create.o
TARGET_OBJECTS = $(THREAD_OBJECTS)
DEP_OBJECTS = $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk
# EOF

View file

@ -0,0 +1,105 @@
/* $Id: context.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
*/
/*
*/
#include <ddk/ntddk.h>
#include <rosrtl/thread.h>
#if defined(_M_IX86)
#include <napi/i386/segment.h>
#include <napi/i386/floatsave.h>
#else
#error Unsupported architecture
#endif
NTSTATUS NTAPI RtlRosInitializeContextEx
(
IN HANDLE ProcessHandle,
IN PCONTEXT Context,
IN PTHREAD_START_ROUTINE StartAddress,
IN PUSER_STACK UserStack,
IN ULONG ParameterCount,
IN ULONG_PTR * Parameters
)
{
ULONG nDummy;
PCHAR pStackBase;
PCHAR pStackLimit;
ULONG_PTR nRetAddr = 0xDEADBEEF;
SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
NTSTATUS nErrCode;
/* 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;
/* stack base lower than the limit */
if(pStackBase <= pStackLimit)
return STATUS_BAD_INITIAL_STACK;
#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;
memset(Context, 0, sizeof(CONTEXT));
/* initialize the context */
Context->ContextFlags = CONTEXT_FULL;
Context->FloatSave.ControlWord = FLOAT_SAVE_CONTROL;
Context->FloatSave.StatusWord = FLOAT_SAVE_STATUS;
Context->FloatSave.TagWord = FLOAT_SAVE_TAG;
Context->FloatSave.DataSelector = FLOAT_SAVE_DATA;
Context->Eip = (ULONG_PTR)StartAddress;
Context->SegGs = USER_DS;
Context->SegFs = TEB_SELECTOR;
Context->SegEs = USER_DS;
Context->SegDs = USER_DS;
Context->SegCs = USER_CS;
Context->SegSs = USER_DS;
Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR));
Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
/* write the parameters */
nErrCode = NtWriteVirtualMemory
(
ProcessHandle,
((PUCHAR)pStackBase) - nParamsSize,
Parameters,
nParamsSize,
&nDummy
);
/* failure */
if(!NT_SUCCESS(nErrCode)) return nErrCode;
/* write the return address */
return NtWriteVirtualMemory
(
ProcessHandle,
((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
&nRetAddr,
sizeof(ULONG_PTR),
&nDummy
);
#else
#error Unsupported architecture
#endif
}
/* EOF */

View file

@ -0,0 +1,260 @@
/* $Id: create.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
*/
/*
*/
#include <stdarg.h>
#include <ddk/ntddk.h>
#include <rosrtl/thread.h>
#define NDEBUG
#include <ntdll/ntdll.h>
NTSTATUS STDCALL RtlRosCreateUserThreadEx
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN CreateSuspended,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
IN PTHREAD_START_ROUTINE StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
IN ULONG_PTR * Parameters
)
{
USER_STACK usUserStack;
OBJECT_ATTRIBUTES oaThreadAttribs;
/* FIXME: read the defaults from the executable image */
ULONG_PTR nStackReserve = 0x100000;
/* FIXME: when we finally have exception handling, make this PAGE_SIZE */
ULONG_PTR nStackCommit = 0x100000;
ULONG_PTR nSize = 0;
PVOID pStackLowest = NULL;
ULONG nDummy;
CONTEXT ctxInitialContext;
NTSTATUS nErrCode;
HANDLE hThread;
CLIENT_ID cidClientId;
if(ThreadHandle == NULL) ThreadHandle = &hThread;
if(ClientId == NULL) ClientId = &cidClientId;
if(StackReserve == NULL) StackReserve = &nStackReserve;
else ROUNDUP(*StackReserve, PAGE_SIZE);
if(StackCommit == NULL) StackCommit = &nStackCommit;
else ROUNDUP(*StackCommit, PAGE_SIZE);
#if 0
/* the stack commit size must be equal to or less than the reserve size */
if(*StackCommit > *StackReserve) *StackCommit = *StackReserve;
#else
/* FIXME: no SEH, no guard pages */
*StackCommit = *StackReserve;
#endif
usUserStack.FixedStackBase = NULL;
usUserStack.FixedStackLimit = NULL;
usUserStack.ExpandableStackBase = NULL;
usUserStack.ExpandableStackLimit = NULL;
usUserStack.ExpandableStackBottom = NULL;
/* FIXME: this code assumes a stack growing downwards */
/* fixed stack */
if(*StackCommit == *StackReserve)
{
usUserStack.FixedStackLimit = NULL;
/* allocate the stack */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.FixedStackLimit),
StackZeroBits,
StackReserve,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* store the highest (first) address of the stack */
usUserStack.FixedStackBase =
(PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve;
*StackCommit = *StackReserve;
}
/* expandable stack */
else
{
ULONG_PTR nGuardSize = PAGE_SIZE;
PVOID pGuardBase;
DPRINT("Expandable stack\n");
usUserStack.FixedStackLimit = NULL;
usUserStack.FixedStackBase = NULL;
usUserStack.ExpandableStackBottom = NULL;
/* reserve the stack */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.ExpandableStackBottom),
StackZeroBits,
StackReserve,
MEM_RESERVE,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
DPRINT("Reserved %08X bytes\n", *StackReserve);
/* expandable stack base - the highest address of the stack */
usUserStack.ExpandableStackBase =
(PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve;
/* expandable stack limit - the lowest committed address of the stack */
usUserStack.ExpandableStackLimit =
(PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit;
DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase);
DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit);
DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom);
/* commit as much stack as requested */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&(usUserStack.ExpandableStackLimit),
0,
StackCommit,
MEM_COMMIT,
PAGE_READWRITE
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
assert((*StackReserve - *StackCommit) >= PAGE_SIZE);
assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0);
pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE;
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
/* set up the guard page */
nErrCode = NtAllocateVirtualMemory
(
ProcessHandle,
&pGuardBase,
0,
&nGuardSize,
MEM_COMMIT,
PAGE_READWRITE | PAGE_GUARD
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
}
/* initialize the registers and stack for the thread */
nErrCode = RtlRosInitializeContextEx
(
ProcessHandle,
&ctxInitialContext,
StartAddress,
&usUserStack,
ParameterCount,
Parameters
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
/* create the thread object */
nErrCode = NtCreateThread
(
ThreadHandle,
THREAD_ALL_ACCESS,
ObjectAttributes,
ProcessHandle,
ClientId,
&ctxInitialContext,
&usUserStack,
CreateSuspended
);
/* failure */
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
/* success */
return STATUS_SUCCESS;
/* deallocate the stack */
l_Cleanup:
if(usUserStack.FixedStackLimit)
pStackLowest = usUserStack.FixedStackLimit;
else if(usUserStack.ExpandableStackBottom)
pStackLowest = usUserStack.ExpandableStackBottom;
/* free the stack, if it was allocated */
if(pStackLowest != NULL)
NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
/* failure */
l_Fail:
assert(!NT_SUCCESS(nErrCode));
return nErrCode;
}
NTSTATUS CDECL RtlRosCreateUserThreadVa
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN CreateSuspended,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
IN PTHREAD_START_ROUTINE StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
...
)
{
va_list vaArgs;
NTSTATUS nErrCode;
va_start(vaArgs, ParameterCount);
/* FIXME: this code assumes a stack growing downwards */
nErrCode = RtlRosCreateUserThreadEx
(
ProcessHandle,
ObjectAttributes,
CreateSuspended,
StackZeroBits,
StackReserve,
StackCommit,
StartAddress,
ThreadHandle,
ClientId,
ParameterCount,
(ULONG_PTR *)vaArgs
);
va_end(vaArgs);
return nErrCode;
}
/* EOF */