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

Alexandre Julliard julliard at winehq.org
Wed Jul 15 16:44:45 CDT 2020


Module: wine
Branch: master
Commit: 99851ca4c2edd4b921c91327540d69dec77c5df7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=99851ca4c2edd4b921c91327540d69dec77c5df7

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 15 10:23:00 2020 +0200

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

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/server.c        |  9 +++++++--
 dlls/ntdll/unix/signal_arm64.c  |  9 ---------
 dlls/ntdll/unix/signal_i386.c   | 18 ------------------
 dlls/ntdll/unix/signal_x86_64.c | 19 -------------------
 dlls/ntdll/unix/unix_private.h  |  6 ++++++
 dlls/ntdll/unix/virtual.c       | 23 +++++++++++------------
 6 files changed, 24 insertions(+), 60 deletions(-)

diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index faca7da5c9..452094ff5d 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -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" );
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index 3a3afb5ad5..6c86ec265e 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -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) );
 
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 44195fc205..be041f3fb2 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -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();
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index a2240900ab..f4d64ed4e5 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -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
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 3d56ea5d40..1e8f82a8a7 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -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;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 63efb74382..9ba1053a0d 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -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();




More information about the wine-cvs mailing list