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
|
else
|
||||||
stack_size = ((char *)NtCurrentTeb()->Tib.StackBase
|
stack_size = ((char *)NtCurrentTeb()->Tib.StackBase
|
||||||
- (char *)NtCurrentTeb()->DeallocationStack
|
- (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 */
|
/* 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:
|
/* Memory layout in allocated block:
|
||||||
*
|
*
|
||||||
* size contents
|
* size contents
|
||||||
* 1 page NOACCESS guard page
|
|
||||||
* SIGNAL_STACK_SIZE signal stack
|
* SIGNAL_STACK_SIZE signal stack
|
||||||
* 1 page NOACCESS guard page
|
* stack_size normal stack (including a PAGE_GUARD page at the bottom)
|
||||||
* 1 page PAGE_GUARD guard page
|
|
||||||
* stack_size normal stack
|
|
||||||
* 1 page TEB (except for initial thread)
|
* 1 page TEB (except for initial thread)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
|
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 (!teb) total_size += page_size;
|
||||||
|
|
||||||
if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
|
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->DeallocationStack = base;
|
||||||
teb->signal_stack = (char *)base + page_size;
|
teb->Tib.StackBase = (char *)base + SIGNAL_STACK_SIZE + stack_size;
|
||||||
teb->Tib.StackBase = (char *)base + 3 * page_size + SIGNAL_STACK_SIZE + stack_size;
|
|
||||||
teb->Tib.StackLimit = base; /* note: limit is lower than base since the stack grows down */
|
teb->Tib.StackLimit = base; /* note: limit is lower than base since the stack grows down */
|
||||||
|
|
||||||
/* Setup guard pages */
|
/* Setup guard pages */
|
||||||
|
|
||||||
VirtualProtect( base, 1, PAGE_NOACCESS, &old_prot );
|
VirtualProtect( (char *)base + SIGNAL_STACK_SIZE, 1,
|
||||||
VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE, 1, PAGE_NOACCESS, &old_prot );
|
|
||||||
VirtualProtect( (char *)teb->signal_stack + SIGNAL_STACK_SIZE + page_size, 1,
|
|
||||||
PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_prot );
|
PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old_prot );
|
||||||
return teb;
|
return teb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1172,15 +1172,15 @@ static int set_handler( int sig, int have_sigaltstack, void (*func)() )
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
if (!have_sigaltstack && NtCurrentTeb()->signal_stack)
|
if (!have_sigaltstack)
|
||||||
{
|
{
|
||||||
struct kernel_sigaction sig_act;
|
struct kernel_sigaction sig_act;
|
||||||
sig_act.ksa_handler = func;
|
sig_act.ksa_handler = func;
|
||||||
sig_act.ksa_flags = SA_RESTART;
|
sig_act.ksa_flags = SA_RESTART;
|
||||||
sig_act.ksa_mask = (1 << (SIGINT-1)) |
|
sig_act.ksa_mask = (1 << (SIGINT-1)) |
|
||||||
(1 << (SIGUSR2-1));
|
(1 << (SIGUSR2-1));
|
||||||
/* point to the top of the stack */
|
/* point to the top of the signal stack */
|
||||||
sig_act.ksa_restorer = (char *)NtCurrentTeb()->signal_stack + SIGNAL_STACK_SIZE;
|
sig_act.ksa_restorer = (char *)NtCurrentTeb()->DeallocationStack + SIGNAL_STACK_SIZE;
|
||||||
return wine_sigaction( sig, &sig_act, NULL );
|
return wine_sigaction( sig, &sig_act, NULL );
|
||||||
}
|
}
|
||||||
#endif /* linux */
|
#endif /* linux */
|
||||||
|
@ -1234,18 +1234,16 @@ BOOL SIGNAL_Init(void)
|
||||||
|
|
||||||
#ifdef HAVE_SIGALTSTACK
|
#ifdef HAVE_SIGALTSTACK
|
||||||
struct sigaltstack ss;
|
struct sigaltstack ss;
|
||||||
if ((ss.ss_sp = NtCurrentTeb()->signal_stack))
|
ss.ss_sp = NtCurrentTeb()->DeallocationStack;
|
||||||
{
|
ss.ss_size = SIGNAL_STACK_SIZE;
|
||||||
ss.ss_size = SIGNAL_STACK_SIZE;
|
ss.ss_flags = 0;
|
||||||
ss.ss_flags = 0;
|
if (!sigaltstack(&ss, NULL)) have_sigaltstack = 1;
|
||||||
if (!sigaltstack(&ss, NULL)) have_sigaltstack = 1;
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
/* sigaltstack may fail because the kernel is too old, or
|
/* sigaltstack may fail because the kernel is too old, or
|
||||||
because glibc is brain-dead. In the latter case a
|
because glibc is brain-dead. In the latter case a
|
||||||
direct system call should succeed. */
|
direct system call should succeed. */
|
||||||
else if (!wine_sigaltstack(&ss, NULL)) have_sigaltstack = 1;
|
else if (!wine_sigaltstack(&ss, NULL)) have_sigaltstack = 1;
|
||||||
#endif /* linux */
|
#endif /* linux */
|
||||||
}
|
|
||||||
#endif /* HAVE_SIGALTSTACK */
|
#endif /* HAVE_SIGALTSTACK */
|
||||||
|
|
||||||
if (set_handler( SIGINT, have_sigaltstack, (void (*)())int_handler ) == -1) goto error;
|
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];
|
BYTE vprot = view->prot[((char *)addr - (char *)view->base) >> page_shift];
|
||||||
void *page = (void *)((UINT_PTR)addr & ~page_mask);
|
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)
|
if (vprot & VPROT_GUARD)
|
||||||
{
|
{
|
||||||
VIRTUAL_SetProt( view, page, page_mask + 1, vprot & ~VPROT_GUARD );
|
VIRTUAL_SetProt( view, page, page_mask + 1, vprot & ~VPROT_GUARD );
|
||||||
ret = STATUS_GUARD_PAGE_VIOLATION;
|
ret = STATUS_GUARD_PAGE_VIOLATION;
|
||||||
}
|
}
|
||||||
/* is it inside the stack guard pages? */
|
/* is it inside the stack guard page? */
|
||||||
if (((char *)addr >= stack) && ((char *)addr < stack + 2*(page_mask+1)))
|
if (((char *)addr >= stack) && ((char *)addr < stack + (page_mask+1)))
|
||||||
ret = STATUS_STACK_OVERFLOW;
|
ret = STATUS_STACK_OVERFLOW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ typedef struct _TEB
|
||||||
DWORD unknown3; /* --n 48 */
|
DWORD unknown3; /* --n 48 */
|
||||||
int thread_errno; /* --3 4c Per-thread errno (was: ring0_thread) */
|
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) */
|
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 *exit_stack; /* 1-n 58 Exit stack */
|
||||||
void *emu_data; /* --n 5c Related to 80387 emulation */
|
void *emu_data; /* --n 5c Related to 80387 emulation */
|
||||||
DWORD last_error; /* 1-- 60 Last error code */
|
DWORD last_error; /* 1-- 60 Last error code */
|
||||||
|
@ -141,7 +141,11 @@ typedef struct _TEB
|
||||||
#define TEBF_TRAP 0x0002
|
#define TEBF_TRAP 0x0002
|
||||||
|
|
||||||
/* The per-thread signal stack size */
|
/* The per-thread signal stack size */
|
||||||
|
#ifdef __i386__
|
||||||
#define SIGNAL_STACK_SIZE 0x100000 /* 1Mb FIXME: should be much smaller than that */
|
#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 */
|
/* scheduler/thread.c */
|
||||||
|
|
Loading…
Reference in New Issue