ntdll: Move private data to make room in the TEB for the activation context data.
This commit is contained in:
parent
303b357ce1
commit
44c9758d05
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue