From 16ddc624050a9780c16abb0421e093925bc351cf Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 19 Nov 2009 12:27:09 +0100 Subject: [PATCH] ntdll: Merge the thread data and thread regs structure, and make sure i386 regs are not available on other platforms. --- dlls/ntdll/ntdll_misc.h | 44 ++++++++++++++-------------------- dlls/ntdll/signal_i386.c | 51 ++++++++++++++++++---------------------- dlls/ntdll/thread.c | 31 ++++++++++++------------ 3 files changed, 56 insertions(+), 70 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index f74007b4db..1150f47d39 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -199,40 +199,30 @@ struct debug_info /* thread private data, stored in NtCurrentTeb()->SystemReserved2 */ struct ntdll_thread_data { - DWORD fs; /* 1d4/300 TEB selector */ - DWORD gs; /* 1d8/304 libc selector; update winebuild if you move this! */ - struct debug_info *debug_info; /* 1dc/308 info for debugstr functions */ - int request_fd; /* 1e0/310 fd for sending server requests */ - int reply_fd; /* 1e4/314 fd for receiving server replies */ - int wait_fd[2]; /* 1e8/318 fd for sleeping server requests */ - BOOL wow64_redir; /* 1f0/320 Wow64 filesystem redirection flag */ #ifdef __i386__ - void *vm86_ptr; /* 1f4/328 data for vm86 mode */ + DWORD dr0; /* 1bc Debug registers */ + DWORD dr1; /* 1c0 */ + DWORD dr2; /* 1c4 */ + DWORD dr3; /* 1c8 */ + DWORD dr6; /* 1cc */ + DWORD dr7; /* 1d0 */ + DWORD fs; /* 1d4 TEB selector */ + DWORD gs; /* 1d8 libc selector; update winebuild if you move this! */ + void *vm86_ptr; /* 1dc data for vm86 mode */ #else - void *exit_frame; /* 1f4/328 exit frame pointer */ + void *exit_frame; /* /2e8 exit frame pointer */ #endif - pthread_t pthread_id; /* 1f8/330 pthread thread id */ + struct debug_info *debug_info; /* 1e0/2f0 info for debugstr functions */ + int request_fd; /* 1e4/2f8 fd for sending server requests */ + int reply_fd; /* 1e8/2fc fd for receiving server replies */ + int wait_fd[2]; /* 1ec/300 fd for sleeping server requests */ + BOOL wow64_redir; /* 1f4/308 Wow64 filesystem redirection flag */ + pthread_t pthread_id; /* 1f8/310 pthread thread id */ }; static inline struct ntdll_thread_data *ntdll_get_thread_data(void) { - return (struct ntdll_thread_data *)NtCurrentTeb()->SystemReserved2; -} - -/* thread debug_registers, stored in NtCurrentTeb()->SpareBytes1 */ -struct ntdll_thread_regs -{ - DWORD dr0; - DWORD dr1; - DWORD dr2; - DWORD dr3; - DWORD dr6; - DWORD dr7; -}; - -static inline struct ntdll_thread_regs *ntdll_get_thread_regs(void) -{ - return (struct ntdll_thread_regs *)NtCurrentTeb()->SpareBytes1; + return (struct ntdll_thread_data *)NtCurrentTeb()->SpareBytes1; } /* Register functions */ diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 48e3ef1d7e..a4bb95d23a 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -847,7 +847,7 @@ static void wine_sigacthandler( int signal, siginfo_t *siginfo, void *sigcontext __asm__ __volatile__("mov %ss,%ax; mov %ax,%ds; mov %ax,%es"); - thread_data = (struct ntdll_thread_data *)get_current_teb()->SystemReserved2; + thread_data = (struct ntdll_thread_data *)get_current_teb()->SpareBytes1; wine_set_fs( thread_data->fs ); wine_set_gs( thread_data->gs ); @@ -898,7 +898,7 @@ static inline void *init_handler( const SIGCONTEXT *sigcontext, WORD *fs, WORD * #ifndef __sun /* see above for Solaris handling */ { - struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; wine_set_fs( thread_data->fs ); wine_set_gs( thread_data->gs ); } @@ -1042,7 +1042,7 @@ static void fpux_to_fpu( FLOATING_SAVE_AREA *fpu, const XMM_SAVE_AREA32 *fpux ) */ static inline void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext, WORD fs, WORD gs ) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); + struct ntdll_thread_data * const regs = ntdll_get_thread_data(); FLOATING_SAVE_AREA *fpu = FPU_sig(sigcontext); XMM_SAVE_AREA32 *fpux = FPUX_sig(sigcontext); @@ -1094,7 +1094,7 @@ static inline void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext, */ static inline void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext ) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); + struct ntdll_thread_data * const regs = ntdll_get_thread_data(); FLOATING_SAVE_AREA *fpu = FPU_sig(sigcontext); XMM_SAVE_AREA32 *fpux = FPUX_sig(sigcontext); @@ -1161,13 +1161,12 @@ void set_cpu_context( const CONTEXT *context ) if (flags & CONTEXT_DEBUG_REGISTERS) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); - regs->dr0 = context->Dr0; - regs->dr1 = context->Dr1; - regs->dr2 = context->Dr2; - regs->dr3 = context->Dr3; - regs->dr6 = context->Dr6; - regs->dr7 = context->Dr7; + ntdll_get_thread_data()->dr0 = context->Dr0; + ntdll_get_thread_data()->dr1 = context->Dr1; + ntdll_get_thread_data()->dr2 = context->Dr2; + ntdll_get_thread_data()->dr3 = context->Dr3; + ntdll_get_thread_data()->dr6 = context->Dr6; + ntdll_get_thread_data()->dr7 = context->Dr7; } if (flags & CONTEXT_FULL) { @@ -1694,13 +1693,11 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); - /* when single stepping can't tell whether this is a hw bp or a * single step interrupt. try to avoid as much overhead as possible * and only do a server call if there is any hw bp enabled. */ - if( !(context->EFlags & 0x100) || (regs->dr7 & 0xff) ) + if( !(context->EFlags & 0x100) || (ntdll_get_thread_data()->dr7 & 0xff) ) { /* (possible) hardware breakpoint, fetch the debug registers */ context->ContextFlags = CONTEXT_DEBUG_REGISTERS; @@ -2014,7 +2011,7 @@ NTSTATUS signal_alloc_thread( TEB **teb ) { static size_t sigstack_zero_bits; struct ntdll_thread_data *thread_data; - TEB *parent = NULL; + struct ntdll_thread_data *parent_data = NULL; SIZE_T size; void *addr = NULL; NTSTATUS status; @@ -2028,7 +2025,7 @@ NTSTATUS signal_alloc_thread( TEB **teb ) signal_stack_mask = (1 << sigstack_zero_bits) - 1; signal_stack_size = (1 << sigstack_zero_bits) - teb_size; } - else parent = NtCurrentTeb(); + else parent_data = ntdll_get_thread_data(); size = signal_stack_mask + 1; if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, sigstack_zero_bits, @@ -2037,24 +2034,22 @@ NTSTATUS signal_alloc_thread( TEB **teb ) *teb = addr; (*teb)->Tib.Self = &(*teb)->Tib; (*teb)->Tib.ExceptionList = (void *)~0UL; - thread_data = (struct ntdll_thread_data *)(*teb)->SystemReserved2; + thread_data = (struct ntdll_thread_data *)(*teb)->SpareBytes1; if (!(thread_data->fs = wine_ldt_alloc_fs())) { size = 0; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); status = STATUS_TOO_MANY_THREADS; } - if (parent) + if (parent_data) { /* inherit debug registers from parent thread */ - struct ntdll_thread_regs *parent_regs = (struct ntdll_thread_regs *)parent->SpareBytes1; - struct ntdll_thread_regs *thread_regs = (struct ntdll_thread_regs *)(*teb)->SpareBytes1; - thread_regs->dr0 = parent_regs->dr0; - thread_regs->dr1 = parent_regs->dr1; - thread_regs->dr2 = parent_regs->dr2; - thread_regs->dr3 = parent_regs->dr3; - thread_regs->dr6 = parent_regs->dr6; - thread_regs->dr7 = parent_regs->dr7; + thread_data->dr0 = parent_data->dr0; + thread_data->dr1 = parent_data->dr1; + thread_data->dr2 = parent_data->dr2; + thread_data->dr3 = parent_data->dr3; + thread_data->dr6 = parent_data->dr6; + thread_data->dr7 = parent_data->dr7; } } @@ -2068,7 +2063,7 @@ NTSTATUS signal_alloc_thread( TEB **teb ) void signal_free_thread( TEB *teb ) { SIZE_T size; - struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; if (thread_data) wine_ldt_free_fs( thread_data->fs ); if (teb->DeallocationStack) @@ -2086,7 +2081,7 @@ void signal_free_thread( TEB *teb ) */ void signal_init_thread( 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->SpareBytes1; LDT_ENTRY fs_entry; stack_t ss; diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index c38298a58a..b9529bdfb4 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -278,7 +278,7 @@ HANDLE thread_init(void) teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer; teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer); - thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; thread_data->request_fd = -1; thread_data->reply_fd = -1; thread_data->wait_fd[0] = -1; @@ -389,7 +389,7 @@ void exit_thread( int status ) if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() ))) { - struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; pthread_join( thread_data->pthread_id, NULL ); signal_free_thread( teb ); @@ -411,7 +411,7 @@ void exit_thread( int status ) static void start_thread( struct startup_info *info ) { TEB *teb = info->teb; - struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; PRTL_THREAD_START_ROUTINE func = info->entry_point; void *arg = info->entry_arg; struct debug_info debug_info; @@ -522,7 +522,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * info->entry_point = start; info->entry_arg = param; - thread_data = (struct ntdll_thread_data *)teb->SystemReserved2; + thread_data = (struct ntdll_thread_data *)teb->SpareBytes1; thread_data->request_fd = request_pipe[1]; thread_data->reply_fd = -1; thread_data->wait_fd[0] = -1; @@ -704,10 +704,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) self = (handle == GetCurrentThread()); if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); - self = (regs->dr0 == context->Dr0 && regs->dr1 == context->Dr1 && - regs->dr2 == context->Dr2 && regs->dr3 == context->Dr3 && - regs->dr6 == context->Dr6 && regs->dr7 == context->Dr7); + self = (ntdll_get_thread_data()->dr0 == context->Dr0 && + ntdll_get_thread_data()->dr1 == context->Dr1 && + ntdll_get_thread_data()->dr2 == context->Dr2 && + ntdll_get_thread_data()->dr3 == context->Dr3 && + ntdll_get_thread_data()->dr6 == context->Dr6 && + ntdll_get_thread_data()->dr7 == context->Dr7); } #endif @@ -862,13 +864,12 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) /* update the cached version of the debug registers */ if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)) { - struct ntdll_thread_regs * const regs = ntdll_get_thread_regs(); - regs->dr0 = context->Dr0; - regs->dr1 = context->Dr1; - regs->dr2 = context->Dr2; - regs->dr3 = context->Dr3; - regs->dr6 = context->Dr6; - regs->dr7 = context->Dr7; + ntdll_get_thread_data()->dr0 = context->Dr0; + ntdll_get_thread_data()->dr1 = context->Dr1; + ntdll_get_thread_data()->dr2 = context->Dr2; + ntdll_get_thread_data()->dr3 = context->Dr3; + ntdll_get_thread_data()->dr6 = context->Dr6; + ntdll_get_thread_data()->dr7 = context->Dr7; } #endif } -- 2.32.0.93.g670b81a890