From 8824c38e9e5e63102c32408a6e6279c78f5b74d3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 22 Oct 2003 03:26:53 +0000 Subject: [PATCH] Simplified signal stack allocation a bit, and avoid allocating it on non-i386 platforms. --- dlls/kernel/thread.c | 16 +++++----------- dlls/ntdll/signal_i386.c | 24 +++++++++++------------- dlls/ntdll/virtual.c | 6 +++--- include/thread.h | 6 +++++- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/dlls/kernel/thread.c b/dlls/kernel/thread.c index 98851824151..984203ae153 100644 --- a/dlls/kernel/thread.c +++ b/dlls/kernel/thread.c @@ -93,7 +93,7 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size ) else stack_size = ((char *)NtCurrentTeb()->Tib.StackBase - (char *)NtCurrentTeb()->DeallocationStack - - SIGNAL_STACK_SIZE - 3 * page_size); + - SIGNAL_STACK_SIZE); } /* FIXME: some Wine functions use a lot of stack, so we add 64Kb here */ @@ -102,16 +102,13 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size ) /* Memory layout in allocated block: * * size contents - * 1 page NOACCESS guard page * SIGNAL_STACK_SIZE signal stack - * 1 page NOACCESS guard page - * 1 page PAGE_GUARD guard page - * stack_size normal stack + * stack_size normal stack (including a PAGE_GUARD page at the bottom) * 1 page TEB (except for initial thread) */ stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1); - total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size; + total_size = stack_size + SIGNAL_STACK_SIZE; if (!teb) total_size += page_size; if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE ))) @@ -128,15 +125,12 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size ) } teb->DeallocationStack = base; - teb->signal_stack = (char *)base + page_size; - teb->Tib.StackBase = (char *)base + 3 * page_size + SIGNAL_STACK_SIZE + stack_size; + teb->Tib.StackBase = (char *)base + SIGNAL_STACK_SIZE + stack_size; teb->Tib.StackLimit = base; /* note: limit is lower than base since the stack grows down */ /* Setup guard pages */ - VirtualProtect( base, 1, PAGE_NOACCESS, &old_prot ); - VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE, 1, PAGE_NOACCESS, &old_prot ); - VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE + page_size, 1, + VirtualProtect( (char *)base + SIGNAL_STACK_SIZE, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_prot ); return teb; } diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index c325994f431..696308528ed 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1172,15 +1172,15 @@ static int set_handler( int sig, int have_sigaltstack, void (*func)() ) struct sigaction sig_act; #ifdef linux - if (!have_sigaltstack && NtCurrentTeb()->signal_stack) + if (!have_sigaltstack) { struct kernel_sigaction sig_act; sig_act.ksa_handler = func; sig_act.ksa_flags = SA_RESTART; sig_act.ksa_mask = (1 << (SIGINT-1)) | (1 << (SIGUSR2-1)); - /* point to the top of the stack */ - sig_act.ksa_restorer = (char *)NtCurrentTeb()->signal_stack + SIGNAL_STACK_SIZE; + /* point to the top of the signal stack */ + sig_act.ksa_restorer = (char *)NtCurrentTeb()->DeallocationStack + SIGNAL_STACK_SIZE; return wine_sigaction( sig, &sig_act, NULL ); } #endif /* linux */ @@ -1234,18 +1234,16 @@ BOOL SIGNAL_Init(void) #ifdef HAVE_SIGALTSTACK struct sigaltstack ss; - if ((ss.ss_sp = NtCurrentTeb()->signal_stack)) - { - ss.ss_size = SIGNAL_STACK_SIZE; - ss.ss_flags = 0; - if (!sigaltstack(&ss, NULL)) have_sigaltstack = 1; + ss.ss_sp = NtCurrentTeb()->DeallocationStack; + ss.ss_size = SIGNAL_STACK_SIZE; + ss.ss_flags = 0; + if (!sigaltstack(&ss, NULL)) have_sigaltstack = 1; #ifdef linux - /* sigaltstack may fail because the kernel is too old, or - because glibc is brain-dead. In the latter case a - direct system call should succeed. */ - else if (!wine_sigaltstack(&ss, NULL)) have_sigaltstack = 1; + /* sigaltstack may fail because the kernel is too old, or + because glibc is brain-dead. In the latter case a + direct system call should succeed. */ + else if (!wine_sigaltstack(&ss, NULL)) have_sigaltstack = 1; #endif /* linux */ - } #endif /* HAVE_SIGALTSTACK */ if (set_handler( SIGINT, have_sigaltstack, (void (*)())int_handler ) == -1) goto error; diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index e50315d0aaf..bb27336c06d 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -832,14 +832,14 @@ DWORD VIRTUAL_HandleFault( LPCVOID addr ) { BYTE vprot = view->prot[((char *)addr - (char *)view->base) >> page_shift]; void *page = (void *)((UINT_PTR)addr & ~page_mask); - char *stack = (char *)NtCurrentTeb()->DeallocationStack + SIGNAL_STACK_SIZE + page_mask + 1; + char *stack = (char *)NtCurrentTeb()->DeallocationStack + SIGNAL_STACK_SIZE; if (vprot & VPROT_GUARD) { VIRTUAL_SetProt( view, page, page_mask + 1, vprot & ~VPROT_GUARD ); ret = STATUS_GUARD_PAGE_VIOLATION; } - /* is it inside the stack guard pages? */ - if (((char *)addr >= stack) && ((char *)addr < stack + 2*(page_mask+1))) + /* is it inside the stack guard page? */ + if (((char *)addr >= stack) && ((char *)addr < stack + (page_mask+1))) ret = STATUS_STACK_OVERFLOW; } } diff --git a/include/thread.h b/include/thread.h index 727807e0131..69a23106444 100644 --- a/include/thread.h +++ b/include/thread.h @@ -77,7 +77,7 @@ typedef struct _TEB DWORD unknown3; /* --n 48 */ int thread_errno; /* --3 4c Per-thread errno (was: ring0_thread) */ int thread_h_errno; /* --3 50 Per-thread h_errno (was: ptr to tdbx structure) */ - void *signal_stack; /* --3 54 Signal stack (was: stack_base) */ + void *stack_base; /* 1-n 54 Stack base (unused) */ void *exit_stack; /* 1-n 58 Exit stack */ void *emu_data; /* --n 5c Related to 80387 emulation */ DWORD last_error; /* 1-- 60 Last error code */ @@ -141,7 +141,11 @@ typedef struct _TEB #define TEBF_TRAP 0x0002 /* The per-thread signal stack size */ +#ifdef __i386__ #define SIGNAL_STACK_SIZE 0x100000 /* 1Mb FIXME: should be much smaller than that */ +#else +#define SIGNAL_STACK_SIZE 0 /* we don't need a signal stack on non-i386 */ +#endif /* scheduler/thread.c */