diff options
author | Carlos O'Donell <carlos@systemhalted.org> | 2013-08-16 14:57:59 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2014-02-08 09:21:06 -0500 |
commit | a5760bbb50f3dbfd1e4051a54aae35060cdd639b (patch) | |
tree | 87050392c0d80ee6b56edf4e945e144c9521a62a /nptl/allocatestack.c | |
parent | 6a714e48586aa7f21d2eeef9195cee57c9ebaa60 (diff) | |
download | glibc-a5760bbb50f3dbfd1e4051a54aae35060cdd639b.tar glibc-a5760bbb50f3dbfd1e4051a54aae35060cdd639b.tar.gz glibc-a5760bbb50f3dbfd1e4051a54aae35060cdd639b.tar.bz2 glibc-a5760bbb50f3dbfd1e4051a54aae35060cdd639b.zip |
nptl: support thread stacks that grow up
http://bugs.gentoo.org/301642
Diffstat (limited to 'nptl/allocatestack.c')
-rw-r--r-- | nptl/allocatestack.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 13eca47cf2..ad6d8a9f8b 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -371,6 +371,15 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0)) { uintptr_t adj; +#if _STACK_GROWS_DOWN + char * stackaddr = (char *) attr->stackaddr; +#else + /* Assume the same layout as the _STACK_GROWS_DOWN case, + with struct pthread at the top of the stack block. + Later we adjust the guard location and stack address + to match the _STACK_GROWS_UP case. */ + char * stackaddr = (char *) attr->stackaddr + attr->stacksize; +#endif /* If the user also specified the size of the stack make sure it is large enough. */ @@ -380,11 +389,11 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* Adjust stack size for alignment of the TLS block. */ #if TLS_TCB_AT_TP - adj = ((uintptr_t) attr->stackaddr - TLS_TCB_SIZE) + adj = ((uintptr_t) stackaddr - TLS_TCB_SIZE) & __static_tls_align_m1; assert (size > adj + TLS_TCB_SIZE); #elif TLS_DTV_AT_TP - adj = ((uintptr_t) attr->stackaddr - __static_tls_size) + adj = ((uintptr_t) stackaddr - __static_tls_size) & __static_tls_align_m1; assert (size > adj); #endif @@ -394,10 +403,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, the stack. It is the user's responsibility to do this if it is wanted. */ #if TLS_TCB_AT_TP - pd = (struct pthread *) ((uintptr_t) attr->stackaddr + pd = (struct pthread *) ((uintptr_t) stackaddr - TLS_TCB_SIZE - adj); #elif TLS_DTV_AT_TP - pd = (struct pthread *) (((uintptr_t) attr->stackaddr + pd = (struct pthread *) (((uintptr_t) stackaddr - __static_tls_size - adj) - TLS_PRE_TCB_SIZE); #endif @@ -409,7 +418,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, pd->specific[0] = pd->specific_1stblock; /* Remember the stack-related values. */ - pd->stackblock = (char *) attr->stackaddr - size; + pd->stackblock = (char *) stackaddr - size; pd->stackblock_size = size; /* This is a user-provided stack. It will not be queued in the @@ -635,7 +644,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1); #elif _STACK_GROWS_DOWN char *guard = mem; -# elif _STACK_GROWS_UP +#elif _STACK_GROWS_UP char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1); #endif if (mprotect (guard, guardsize, PROT_NONE) != 0) @@ -731,7 +740,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, *stack = stacktop; #elif _STACK_GROWS_UP *stack = pd->stackblock; - assert (*stack > 0); #endif return 0; |