diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 3c3585f..9fba661 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -353,6 +353,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. */ @@ -362,11 +371,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 @@ -376,10 +385,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 @@ -391,7 +400,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 @@ -616,7 +625,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) @@ -715,7 +724,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; diff --git a/nptl/pthread_attr_getstack.c b/nptl/pthread_attr_getstack.c index 1db135e..ae02c9d 100644 --- a/nptl/pthread_attr_getstack.c +++ b/nptl/pthread_attr_getstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -33,7 +33,11 @@ __pthread_attr_getstack (attr, stackaddr, stacksize) iattr = (struct pthread_attr *) attr; /* Store the result. */ +#ifdef _STACK_GROWS_DOWN *stackaddr = (char *) iattr->stackaddr - iattr->stacksize; +#else + *stackaddr = (char *) iattr->stackaddr; +#endif *stacksize = iattr->stacksize; return 0; diff --git a/nptl/pthread_attr_setstack.c b/nptl/pthread_attr_setstack.c index be79e32..acf61dd 100644 --- a/nptl/pthread_attr_setstack.c +++ b/nptl/pthread_attr_setstack.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2006, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -48,7 +48,11 @@ __pthread_attr_setstack (attr, stackaddr, stacksize) #endif iattr->stacksize = stacksize; +#if _STACK_GROWS_DOWN iattr->stackaddr = (char *) stackaddr + stacksize; +#else + iattr->stackaddr = (char *) stackaddr; +#endif iattr->flags |= ATTR_FLAG_STACKADDR; return 0; @@ -81,7 +85,11 @@ __old_pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, # endif iattr->stacksize = stacksize; +#if _STACK_GROWS_DOWN iattr->stackaddr = (char *) stackaddr + stacksize; +#else + iattr->stackaddr = (char *) stackaddr; +#endif iattr->flags |= ATTR_FLAG_STACKADDR; return 0; diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c index 9c25caf..72da58c 100644 --- a/nptl/pthread_getattr_np.c +++ b/nptl/pthread_getattr_np.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2006, 2007, + 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -61,7 +62,11 @@ pthread_getattr_np (thread_id, attr) if (__builtin_expect (thread->stackblock != NULL, 1)) { iattr->stacksize = thread->stackblock_size; +#ifdef _STACK_GROWS_DOWN iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize; +#else + iattr->stackaddr = (char *) thread->stackblock; +#endif } else { @@ -110,13 +115,21 @@ pthread_getattr_np (thread_id, attr) { /* Found the entry. Now we have the info we need. */ iattr->stacksize = rl.rlim_cur; +#ifdef _STACK_GROWS_DOWN iattr->stackaddr = (void *) to; /* The limit might be too high. */ if ((size_t) iattr->stacksize > (size_t) iattr->stackaddr - last_to) iattr->stacksize = (size_t) iattr->stackaddr - last_to; +#else + iattr->stackaddr = (void *) from; + /* The limit might be too high. */ + if ((size_t) iattr->stacksize + > to - (size_t) iattr->stackaddr) + iattr->stacksize = to - (size_t) iattr->stackaddr; +#endif /* We succeed and no need to look further. */ ret = 0; break;