Simplified signal stack allocation a bit, and avoid allocating it on
non-i386 platforms.
This commit is contained in:
parent
5e4e0de15f
commit
8824c38e9e
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue