Simplified signal stack allocation a bit, and avoid allocating it on
non-i386 platforms.
diff --git a/dlls/kernel/thread.c b/dlls/kernel/thread.c
index 9885182..984203a 100644
--- a/dlls/kernel/thread.c
+++ b/dlls/kernel/thread.c
@@ -93,7 +93,7 @@
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 @@
/* 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->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 c325994..6963085 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1172,15 +1172,15 @@
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 @@
#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 e50315d..bb27336 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -832,14 +832,14 @@
{
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 727807e..69a2310 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -77,7 +77,7 @@
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 @@
#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 */