ntdll: Initialize the thread signal stack in the common code.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-15 10:23:00 +02:00
parent 114832224f
commit 99851ca4c2
6 changed files with 24 additions and 60 deletions

View File

@ -1508,15 +1508,20 @@ size_t server_init_thread( void *entry_point, BOOL *suspend )
int ret;
int reply_pipe[2];
struct sigaction sig_act;
stack_t ss;
size_t info_size;
/* ignore SIGPIPE so that we get an EPIPE error instead */
sig_act.sa_handler = SIG_IGN;
sig_act.sa_flags = 0;
sigemptyset( &sig_act.sa_mask );
/* ignore SIGPIPE so that we get an EPIPE error instead */
sigaction( SIGPIPE, &sig_act, NULL );
ss.ss_sp = get_signal_stack();
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;
sigaltstack( &ss, NULL );
/* create the server->client communication pipes */
if (server_pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
if (server_pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );

View File

@ -114,8 +114,6 @@ static DWORD64 get_fault_esr( ucontext_t *sigcontext )
static pthread_key_t teb_key;
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
typedef void (*raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context );
/* stack layout when calling an exception raise function */
@ -863,13 +861,6 @@ void signal_free_thread( TEB *teb )
*/
void signal_init_thread( TEB *teb )
{
stack_t ss;
ss.ss_sp = (char *)teb + teb_size;
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;
if (sigaltstack( &ss, NULL ) == -1) perror( "sigaltstack" );
/* Win64/ARM applications expect the TEB pointer to be in the x18 platform register. */
__asm__ __volatile__( "mov x18, %0" : : "r" (teb) );

View File

@ -436,7 +436,6 @@ struct stack_layout
DWORD eip;
};
static const size_t teb_size = 4096; /* we reserve one page for the TEB */
static ULONG first_ldt_entry = 32;
enum i386_trap_code
@ -542,17 +541,6 @@ static inline int ldt_is_system( WORD sel )
}
/***********************************************************************
* get_signal_stack
*
* Get the base of the signal stack for the current thread.
*/
static inline void *get_signal_stack(void)
{
return (char *)NtCurrentTeb() + 4096;
}
/***********************************************************************
* get_current_teb
*
@ -2205,12 +2193,6 @@ void signal_init_thread( TEB *teb )
{
const WORD fpu_cw = 0x27f;
struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2;
stack_t ss;
ss.ss_sp = (char *)teb + teb_size;
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) == -1) perror( "sigaltstack" );
ldt_set_fs( thread_data->fs, teb );
thread_data->gs = get_gs();

View File

@ -225,8 +225,6 @@ enum i386_trap_code
TRAP_x86_CACHEFLT = 19 /* Cache flush exception */
};
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
typedef void (*raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context );
/* stack layout when calling an exception raise function */
@ -1379,17 +1377,6 @@ static inline void set_sigcontext( const CONTEXT *context, ucontext_t *sigcontex
}
/***********************************************************************
* get_signal_stack
*
* Get the base of the signal stack for the current thread.
*/
static inline void *get_signal_stack(void)
{
return (char *)NtCurrentTeb() + teb_size;
}
/***********************************************************************
* is_inside_signal_stack
*
@ -2451,7 +2438,6 @@ static void *mac_thread_gsbase(void)
void signal_init_thread( TEB *teb )
{
const WORD fpu_cw = 0x27f;
stack_t ss;
#if defined __linux__
arch_prctl( ARCH_SET_GS, teb );
@ -2475,11 +2461,6 @@ void signal_init_thread( TEB *teb )
# error Please define setting %gs for your architecture
#endif
ss.ss_sp = (char *)teb + teb_size;
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;
if (sigaltstack(&ss, NULL) == -1) perror( "sigaltstack" );
#ifdef __GNUC__
__asm__ volatile ("fninit; fldcw %0" : : "m" (fpu_cw));
#else

View File

@ -145,6 +145,7 @@ extern timeout_t server_start_time DECLSPEC_HIDDEN;
extern sigset_t server_block_set DECLSPEC_HIDDEN;
extern SIZE_T signal_stack_size DECLSPEC_HIDDEN;
extern SIZE_T signal_stack_mask DECLSPEC_HIDDEN;
static const SIZE_T teb_size = 0x1000 * sizeof(void *) / 4;
extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;
#ifdef __i386__
extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN;
@ -270,6 +271,11 @@ static inline IMAGE_NT_HEADERS *get_exe_nt_header(void)
return (IMAGE_NT_HEADERS *)((char *)module + module->e_lfanew);
}
static inline void *get_signal_stack(void)
{
return (char *)NtCurrentTeb() + teb_size;
}
static inline size_t ntdll_wcslen( const WCHAR *str )
{
const WCHAR *s = str;

View File

@ -156,7 +156,6 @@ struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000;
SIZE_T signal_stack_size = 0;
SIZE_T signal_stack_mask = 0;
static SIZE_T signal_stack_align;
/* TEB allocation blocks */
static TEB *teb_block;
@ -2355,7 +2354,7 @@ void virtual_init(void)
const struct preload_info **preload_info = dlsym( RTLD_DEFAULT, "wine_main_preload_info" );
const char *preload = getenv( "WINEPRELOADRESERVE" );
struct alloc_virtual_heap alloc_views;
size_t size;
size_t size, align;
int i;
pthread_mutexattr_t attr;
@ -2383,12 +2382,12 @@ void virtual_init(void)
}
}
size = ROUND_SIZE( 0, sizeof(TEB) ) + max( MINSIGSTKSZ, 8192 );
size = teb_size + max( MINSIGSTKSZ, 8192 );
/* find the first power of two not smaller than size */
signal_stack_align = page_shift;
while ((1u << signal_stack_align) < size) signal_stack_align++;
signal_stack_mask = (1 << signal_stack_align) - 1;
signal_stack_size = (1 << signal_stack_align) - ROUND_SIZE( 0, sizeof(TEB) );
align = page_shift;
while ((1u << align) < size) align++;
signal_stack_mask = (1 << align) - 1;
signal_stack_size = (1 << align) - teb_size;
/* try to find space in a reserved area for the views and pages protection table */
#ifdef _WIN64
@ -2584,8 +2583,8 @@ TEB *virtual_alloc_first_teb(void)
NTSTATUS status;
SIZE_T data_size = page_size;
SIZE_T peb_size = page_size;
SIZE_T teb_size = signal_stack_mask + 1;
SIZE_T total = 32 * teb_size;
SIZE_T block_size = signal_stack_size + teb_size;
SIZE_T total = 32 * block_size;
/* reserve space for shared user data */
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&user_shared_data, 0, &data_size,
@ -2599,9 +2598,9 @@ TEB *virtual_alloc_first_teb(void)
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb_block, 0, &total,
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE );
teb_block_pos = 30;
teb = (TEB *)((char *)teb_block + 30 * teb_size);
peb = (PEB *)((char *)teb_block + 32 * teb_size - peb_size);
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb, 0, &teb_size, MEM_COMMIT, PAGE_READWRITE );
teb = (TEB *)((char *)teb_block + 30 * block_size);
peb = (PEB *)((char *)teb_block + 32 * block_size - peb_size);
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb, 0, &block_size, MEM_COMMIT, PAGE_READWRITE );
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&peb, 0, &peb_size, MEM_COMMIT, PAGE_READWRITE );
init_teb( teb, peb );
*(ULONG_PTR *)peb->Reserved = get_image_address();