ntdll: Merge the thread data and thread regs structure, and make sure i386 regs are not available on other platforms.
This commit is contained in:
parent
aced1b82ba
commit
16ddc62405
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue