Simplified signal stack allocation a bit, and avoid allocating it on

non-i386 platforms.
This commit is contained in:
Alexandre Julliard 2003-10-22 03:26:53 +00:00
parent 5e4e0de15f
commit 8824c38e9e
4 changed files with 24 additions and 28 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 */