* Makefile.in (clean): Remove non-existant regexp dir.

* collate.h: New header.
	(__collate_range_cmp): Declare.
	(__collate_load_error): Define.
	* glob.cc: Pull in latest version from FreeBSD.  Simplify and reduce
	Cygwin-specific changes.
	* regex/regcomp.c: Include collate.h on Cygwin as well.
	(__collate_range_cmp): Move from here...
	* nlsfuncs.cc (__collate_range_cmp): ...to here.

	* miscfuncs.cc (thread_wrapper): Fix typo in comment.
	(CygwinCreateThread): Take dead zone of Windows stack into account.
	Change the way how the stack is commited and how to handle guardpages.
	Explain how and why.
	* thread.h (PTHREAD_DEFAULT_STACKSIZE): Change definition.  Explain why.
This commit is contained in:
Corinna Vinschen
2012-02-13 13:12:37 +00:00
parent e633eaec08
commit d7bcd2a16f
8 changed files with 167 additions and 121 deletions

View File

@ -527,7 +527,7 @@ thread_wrapper (VOID *arg)
xorl %%ebp, %%ebp # Set ebp to 0 \n\
# Make gcc 3.x happy and align the stack so that it is \n\
# 16 byte aligned right before the final call opcode. \n\
andl $-16, %%esp # 16 bit align \n\
andl $-16, %%esp # 16 byte align \n\
addl $-12, %%esp # 12 bytes + 4 byte arg = 16 \n\
# Now we moved to the new stack. Save thread func address\n\
# and thread arg on new stack \n\
@ -578,11 +578,17 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg,
}
else
{
char *commitaddr;
/* If not, we have to create the stack here. */
real_stacksize = roundup2 (stacksize, wincap.page_size ());
real_guardsize = roundup2 (guardsize, wincap.page_size ());
/* Add the guardsize to the stacksize */
real_stacksize += real_guardsize;
/* If we use the default Windows guardpage method, we have to take
the 2 pages dead zone into account. */
if (real_guardsize == wincap.page_size ())
real_stacksize += 2 * wincap.page_size ();
/* Now roundup the result to the next allocation boundary. */
real_stacksize = roundup2 (real_stacksize,
wincap.allocation_granularity ());
@ -596,28 +602,43 @@ CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, PVOID thread_arg,
PAGE_READWRITE);
if (!real_stackaddr)
return NULL;
/* Set up committed region. In contrast to the OS we commit 64K and
set up just a single guard page at the end. */
char *commitaddr = (char *) real_stackaddr
+ real_stacksize
- wincap.allocation_granularity ();
if (!VirtualAlloc (commitaddr, wincap.page_size (), MEM_COMMIT,
PAGE_READWRITE | PAGE_GUARD))
goto err;
commitaddr += wincap.page_size ();
if (!VirtualAlloc (commitaddr, wincap.allocation_granularity ()
- wincap.page_size (), MEM_COMMIT,
PAGE_READWRITE))
goto err;
/* If the guardsize is != 0 (which is the default), set up a POSIX
guardpage at the end of the stack. This isn't the same as the
Windows guardpage, which is used to convert reserved stack to
commited stack if necessary. Rather, the POSIX guardpage consists
of one or more memory pages with NOACCESS protection. It's supposed
to safeguard memory areas beyond the stack against stack overflow. */
if (real_guardsize)
VirtualAlloc (real_stackaddr, real_guardsize, MEM_COMMIT,
PAGE_NOACCESS);
/* Set up committed region. Two cases: */
if (real_guardsize != wincap.page_size ())
{
/* If guardsize is set to something other than the page size, we
commit the entire stack and, if guardsize is > 0, we set up a
POSIX guardpage. We don't set up a Windows guardpage. */
if (!VirtualAlloc (real_stackaddr, real_guardsize, MEM_COMMIT,
PAGE_NOACCESS))
goto err;
commitaddr = (char *) real_stackaddr + real_guardsize;
if (!VirtualAlloc (commitaddr, real_stacksize - real_guardsize,
MEM_COMMIT, PAGE_READWRITE))
goto err;
}
else
{
/* If guardsize is exactly the page_size, we can assume that the
application will behave Windows conformant in terms of stack usage.
We can especially assume that it never allocates more than one
page at a time (alloca/_chkstk). Therefore, this is the default
case which allows a Windows compatible stack setup with a
reserved region, a guard page, and a commited region. We don't
need to set up a POSIX guardpage since Windows already handles
stack overflow: Trying to extend the stack into the last three
pages of the stack results in a SEGV.
We always commit 64K here, starting with the guardpage. */
commitaddr = (char *) real_stackaddr + real_stacksize
- wincap.allocation_granularity ();
if (!VirtualAlloc (commitaddr, wincap.page_size (), MEM_COMMIT,
PAGE_READWRITE | PAGE_GUARD))
goto err;
commitaddr += wincap.page_size ();
if (!VirtualAlloc (commitaddr, wincap.allocation_granularity ()
- wincap.page_size (), MEM_COMMIT,
PAGE_READWRITE))
goto err;
}
wrapper_arg->stackaddr = (char *) real_stackaddr;
wrapper_arg->stackbase = (char *) real_stackaddr + real_stacksize;
wrapper_arg->commitaddr = commitaddr;