ntdll: Move private data to make room in the TEB for the activation context data.

This commit is contained in:
Alexandre Julliard 2007-07-19 16:56:10 +02:00
parent 303b357ce1
commit 44c9758d05
6 changed files with 47 additions and 35 deletions

View File

@ -146,15 +146,18 @@ struct debug_info
char output[1024]; /* current output line */ char output[1024]; /* current output line */
}; };
/* thread private data, stored in NtCurrentTeb()->SystemReserved2 */
struct ntdll_thread_data struct ntdll_thread_data
{ {
struct debug_info *debug_info; /* info for debugstr functions */ DWORD fs; /* 1d4 TEB selector */
int request_fd; /* fd for sending server requests */ DWORD gs; /* 1d8 libc selector; update winebuild if you move this! */
int reply_fd; /* fd for receiving server replies */ struct debug_info *debug_info; /* 1dc info for debugstr functions */
int wait_fd[2]; /* fd for sleeping server requests */ int request_fd; /* 1e0 fd for sending server requests */
void *vm86_ptr; /* data for vm86 mode */ int reply_fd; /* 1e4 fd for receiving server replies */
int wait_fd[2]; /* 1e8 fd for sleeping server requests */
void *vm86_ptr; /* 1f0 data for vm86 mode */
void *pad[4]; /* change this if you add fields! */ void *pad[2]; /* 1f4 change this if you add fields! */
}; };
static inline struct ntdll_thread_data *ntdll_get_thread_data(void) static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
@ -162,18 +165,15 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
return (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2; return (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2;
} }
/* thread registers, stored in NtCurrentTeb()->SpareBytes1 */ /* thread debug_registers, stored in NtCurrentTeb()->SpareBytes1 */
struct ntdll_thread_regs struct ntdll_thread_regs
{ {
DWORD fs; /* 00 TEB selector */ DWORD dr0;
DWORD gs; /* 04 libc selector; update winebuild if you move this! */ DWORD dr1;
DWORD dr0; /* 08 debug registers */ DWORD dr2;
DWORD dr1; /* 0c */ DWORD dr3;
DWORD dr2; /* 10 */ DWORD dr6;
DWORD dr3; /* 14 */ DWORD dr7;
DWORD dr6; /* 18 */
DWORD dr7; /* 1c */
DWORD spare[2]; /* 20 change this if you add fields! */
}; };
static inline struct ntdll_thread_regs *ntdll_get_thread_regs(void) static inline struct ntdll_thread_regs *ntdll_get_thread_regs(void)

View File

@ -543,7 +543,7 @@ static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD *
{ {
void *stack = (void *)(ESP_sig(sigcontext) & ~3); void *stack = (void *)(ESP_sig(sigcontext) & ~3);
TEB *teb = get_current_teb(); TEB *teb = get_current_teb();
struct ntdll_thread_regs *thread_regs = (struct ntdll_thread_regs *)teb->SpareBytes1; struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
/* get %fs and %gs at time of the fault */ /* get %fs and %gs at time of the fault */
#ifdef FS_sig #ifdef FS_sig
@ -557,7 +557,7 @@ static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD *
*gs = wine_get_gs(); *gs = wine_get_gs();
#endif #endif
wine_set_fs( thread_regs->fs ); wine_set_fs( thread_data->fs );
/* now restore a proper %gs for the fault handler */ /* now restore a proper %gs for the fault handler */
if (!wine_ldt_is_system(CS_sig(sigcontext)) || if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
@ -570,7 +570,7 @@ static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD *
* SS is still non-system segment. This is why both CS and SS * SS is still non-system segment. This is why both CS and SS
* are checked. * are checked.
*/ */
wine_set_gs( thread_regs->gs ); wine_set_gs( thread_data->gs );
stack = teb->WOW32Reserved; stack = teb->WOW32Reserved;
} }
#ifdef __HAVE_VM86 #ifdef __HAVE_VM86

View File

@ -108,7 +108,6 @@ static void ldt_unlock(void)
static inline NTSTATUS init_teb( TEB *teb ) static inline NTSTATUS init_teb( TEB *teb )
{ {
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
struct ntdll_thread_regs *thread_regs = (struct ntdll_thread_regs *)teb->SpareBytes1;
teb->Tib.ExceptionList = (void *)~0UL; teb->Tib.ExceptionList = (void *)~0UL;
teb->Tib.StackBase = (void *)~0UL; teb->Tib.StackBase = (void *)~0UL;
@ -116,7 +115,7 @@ static inline NTSTATUS init_teb( TEB *teb )
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer; teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer); teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
if (!(thread_regs->fs = wine_ldt_alloc_fs())) return STATUS_TOO_MANY_THREADS; if (!(thread_data->fs = wine_ldt_alloc_fs())) return STATUS_TOO_MANY_THREADS;
thread_data->request_fd = -1; thread_data->request_fd = -1;
thread_data->reply_fd = -1; thread_data->reply_fd = -1;
thread_data->wait_fd[0] = -1; thread_data->wait_fd[0] = -1;
@ -230,7 +229,6 @@ HANDLE thread_init(void)
HANDLE exe_file = 0; HANDLE exe_file = 0;
LARGE_INTEGER now; LARGE_INTEGER now;
struct ntdll_thread_data *thread_data; struct ntdll_thread_data *thread_data;
struct ntdll_thread_regs *thread_regs;
struct wine_pthread_thread_info thread_info; struct wine_pthread_thread_info thread_info;
static struct debug_info debug_info; /* debug info for initial thread */ static struct debug_info debug_info; /* debug info for initial thread */
@ -284,14 +282,13 @@ HANDLE thread_init(void)
thread_info.teb_size = size; thread_info.teb_size = size;
init_teb( teb ); init_teb( teb );
thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; thread_data = (struct ntdll_thread_data *)teb->SystemReserved2;
thread_regs = (struct ntdll_thread_regs *)teb->SpareBytes1;
thread_data->debug_info = &debug_info; thread_data->debug_info = &debug_info;
InsertHeadList( &tls_links, &teb->TlsLinks ); InsertHeadList( &tls_links, &teb->TlsLinks );
thread_info.stack_base = NULL; thread_info.stack_base = NULL;
thread_info.stack_size = 0; thread_info.stack_size = 0;
thread_info.teb_base = teb; thread_info.teb_base = teb;
thread_info.teb_sel = thread_regs->fs; thread_info.teb_sel = thread_data->fs;
wine_pthread_get_functions( &pthread_functions, sizeof(pthread_functions) ); wine_pthread_get_functions( &pthread_functions, sizeof(pthread_functions) );
pthread_functions.init_current_teb( &thread_info ); pthread_functions.init_current_teb( &thread_info );
pthread_functions.init_thread( &thread_info ); pthread_functions.init_thread( &thread_info );
@ -495,8 +492,8 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
HANDLE *handle_ptr, CLIENT_ID *id ) HANDLE *handle_ptr, CLIENT_ID *id )
{ {
sigset_t sigset; sigset_t sigset;
struct ntdll_thread_data *thread_data; struct ntdll_thread_data *thread_data = NULL;
struct ntdll_thread_regs *thread_regs = NULL; struct ntdll_thread_regs *thread_regs;
struct startup_info *info = NULL; struct startup_info *info = NULL;
void *addr = NULL; void *addr = NULL;
HANDLE handle = 0; HANDLE handle = 0;
@ -575,7 +572,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
thread_data->request_fd = request_pipe[1]; thread_data->request_fd = request_pipe[1];
info->pthread_info.teb_base = teb; info->pthread_info.teb_base = teb;
info->pthread_info.teb_sel = thread_regs->fs; info->pthread_info.teb_sel = thread_data->fs;
/* inherit debug registers from parent thread */ /* inherit debug registers from parent thread */
thread_regs->dr0 = ntdll_get_thread_regs()->dr0; thread_regs->dr0 = ntdll_get_thread_regs()->dr0;
@ -616,7 +613,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
return STATUS_SUCCESS; return STATUS_SUCCESS;
error: error:
if (thread_regs) wine_ldt_free_fs( thread_regs->fs ); if (thread_data) wine_ldt_free_fs( thread_data->fs );
if (addr) if (addr)
{ {
SIZE_T size = 0; SIZE_T size = 0;

View File

@ -47,9 +47,9 @@ typedef struct _TEB
ULONG CurrentLocale; /* 0c4 */ ULONG CurrentLocale; /* 0c4 */
ULONG FpSoftwareStatusRegister; /* 0c8 */ ULONG FpSoftwareStatusRegister; /* 0c8 */
PVOID SystemReserved1[54]; /* 0cc */ PVOID SystemReserved1[54]; /* 0cc */
PVOID Spare1; /* 1a4 */ LONG ExceptionCode; /* 1a4 */
LONG ExceptionCode; /* 1a8 */ ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 1a8 */
BYTE SpareBytes1[40]; /* 1ac */ BYTE SpareBytes1[24]; /* 1bc */
PVOID SystemReserved2[10]; /* 1d4 */ PVOID SystemReserved2[10]; /* 1d4 */
/* The following are Wine-specific fields (NT: GdiTebBatch) */ /* The following are Wine-specific fields (NT: GdiTebBatch) */

View File

@ -200,6 +200,21 @@ typedef struct _GDI_TEB_BATCH
ULONG Buffer[0x136]; ULONG Buffer[0x136];
} GDI_TEB_BATCH; } GDI_TEB_BATCH;
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME
{
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME *Previous;
struct _ACTIVATION_CONTEXT *ActivationContext;
ULONG Flags;
} RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
typedef struct _ACTIVATION_CONTEXT_STACK
{
ULONG Flags;
ULONG NextCookieSequenceNumber;
RTL_ACTIVATION_CONTEXT_STACK_FRAME *ActiveFrame;
LIST_ENTRY FrameListCache;
} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK;
/*********************************************************************** /***********************************************************************
* PEB data structure * PEB data structure
*/ */
@ -286,9 +301,9 @@ typedef struct _TEB
ULONG CurrentLocale; /* 0c4 */ ULONG CurrentLocale; /* 0c4 */
ULONG FpSoftwareStatusRegister; /* 0c8 */ ULONG FpSoftwareStatusRegister; /* 0c8 */
PVOID SystemReserved1[54]; /* 0cc used for kernel32 private data in Wine */ PVOID SystemReserved1[54]; /* 0cc used for kernel32 private data in Wine */
PVOID Spare1; /* 1a4 */ LONG ExceptionCode; /* 1a4 */
LONG ExceptionCode; /* 1a8 */ ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 1a8 */
BYTE SpareBytes1[40]; /* 1ac used for ntdll private data in Wine */ BYTE SpareBytes1[24]; /* 1bc used for ntdll private data in Wine */
PVOID SystemReserved2[10]; /* 1d4 used for ntdll private data in Wine */ PVOID SystemReserved2[10]; /* 1d4 used for ntdll private data in Wine */
GDI_TEB_BATCH GdiTebBatch; /* 1fc */ GDI_TEB_BATCH GdiTebBatch; /* 1fc */
ULONG gdiRgn; /* 6dc */ ULONG gdiRgn; /* 6dc */

View File

@ -48,7 +48,7 @@
#define STACKOFFSET 0xc0 /* STRUCTOFFSET(TEB,WOW32Reserved) */ #define STACKOFFSET 0xc0 /* STRUCTOFFSET(TEB,WOW32Reserved) */
/* fix this if the ntdll_thread_regs structure is changed */ /* fix this if the ntdll_thread_regs structure is changed */
#define GS_OFFSET 0x1b0 /* STRUCTOFFSET(TEB,SpareBytes1) + STRUCTOFFSET(ntdll_thread_regs,gs) */ #define GS_OFFSET 0x1d8 /* STRUCTOFFSET(TEB,SystemReserved2) + STRUCTOFFSET(ntdll_thread_data,gs) */
static void function_header( const char *name ) static void function_header( const char *name )
{ {