@@ -730,6 +730,9 @@ do_test (void)
exit (1);
}
+ /* We purposely test gets, so ignore the warnings. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
FAIL ();
if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
@@ -741,6 +744,7 @@ do_test (void)
FAIL ();
CHK_FAIL_END
#endif
+#pragma GCC diagnostic pop
rewind (stdin);
@@ -1144,6 +1148,9 @@ do_test (void)
CHK_FAIL_END
#endif
+ /* We purposely test getwd, so ignore the warnings. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (getwd (getcwdbuf) != getcwdbuf
|| strcmp (getcwdbuf, fname) != 0)
FAIL ();
@@ -1158,6 +1165,7 @@ do_test (void)
FAIL ();
CHK_FAIL_END
#endif
+#pragma GCC diagnostic pop
}
if (chdir (cwd1) != 0)
@@ -444,7 +444,7 @@ CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
libof-ldconfig = ldconfig
CFLAGS-dl-cache.c = $(SYSCONF-FLAGS)
CFLAGS-cache.c = $(SYSCONF-FLAGS)
-CFLAGS-rtld.c = $(SYSCONF-FLAGS)
+CFLAGS-rtld.c += $(SYSCONF-FLAGS)
cpp-srcs-left := $(all-rtld-routines:=.os)
lib := rtld
@@ -856,6 +856,11 @@ $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so
endif
ifeq ($(have-z-execstack),yes)
+# On hppa with gcc 4.6 the nested function callback generates
+# a stack trampoline and that generates the warning:
+# warning: trampoline generated for nested function 'callback' [-Wtrampolines]
+CFLAGS-tst-execstack-mod.c = -Wno-error
+
$(objpfx)tst-execstack: $(libdl)
$(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
LDFLAGS-tst-execstack = -Wl,-z,noexecstack
@@ -1230,12 +1230,15 @@ of this helper program; chances are you did not intend to run this program.\n\
segment that also includes the phdrs. If that's not available, we use
the old method that assumes the beginning of the file is part of the
lowest-addressed PT_LOAD segment. */
+#if 0
#ifdef HAVE_EHDR_START
extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden")));
rtld_ehdr = &__ehdr_start;
#else
rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start;
#endif
+#endif
+ rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start;
assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <libc-internal.h>
void callme (void (*callback) (void));
@@ -610,6 +610,11 @@ endif
tst-exec4-ARGS = $(host-test-program-cmd)
+# On hppa with gcc 4.6 the nested function callback generates
+# a stack trampoline and that generates the warning:
+# warning: trampoline generated for nested function 'callback' [-Wtrampolines]
+CFLAGS-tst-execstack-mod.c = -Wno-error
+
$(objpfx)tst-execstack: $(libdl)
$(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
LDFLAGS-tst-execstack = -Wl,-z,noexecstack
@@ -352,7 +352,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
struct pthread *pd;
size_t size;
size_t pagesize_m1 = __getpagesize () - 1;
+#ifndef _STACK_GROWS_UP
void *stacktop;
+#endif
assert (powerof2 (pagesize_m1 + 1));
assert (TCB_ALIGNMENT >= STACK_ALIGN);
@@ -372,6 +374,15 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
if (__glibc_unlikely (attr->flags & ATTR_FLAG_STACKADDR))
{
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. */
@@ -381,11 +392,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
@@ -395,10 +406,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
@@ -410,7 +421,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
@@ -634,7 +645,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)
@@ -684,9 +695,13 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
prot) != 0)
goto mprot_error;
#elif _STACK_GROWS_UP
- if (mprotect ((char *) pd - pd->guardsize,
- pd->guardsize - guardsize, prot) != 0)
- goto mprot_error;
+ char *new_guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1);
+ char *old_guard = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
+ /* The guard size difference might be > 0, but once rounded
+ to the nearest page the size difference might be zero. */
+ if (old_guard - new_guard > 0)
+ if (mprotect (old_guard, new_guard - old_guard, prot) != 0)
+ goto mprot_error;
#endif
pd->guardsize = guardsize;
@@ -716,11 +731,13 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* We place the thread descriptor at the end of the stack. */
*pdp = pd;
-#if TLS_TCB_AT_TP
+#ifndef _STACK_GROWS_UP
+# if TLS_TCB_AT_TP
/* The stack begins before the TCB and the static TLS block. */
stacktop = ((char *) (pd + 1) - __static_tls_size);
-#elif TLS_DTV_AT_TP
+# elif TLS_DTV_AT_TP
stacktop = (char *) (pd - 1);
+# endif
#endif
#ifdef NEED_SEPARATE_REGISTER_STACK
@@ -729,8 +746,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
#elif _STACK_GROWS_DOWN
*stack = stacktop;
#elif _STACK_GROWS_UP
+ /* We don't use stacktop. In _STACK_GROWS_UP the start
+ of the stack is simply stackblock (lowest address of
+ the stored block of memory for the stack). */
*stack = pd->stackblock;
- assert (*stack > 0);
#endif
return 0;
@@ -426,13 +426,26 @@ START_THREAD_DEFN
#ifdef _STACK_GROWS_DOWN
char *sp = CURRENT_STACK_FRAME;
size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
-#else
-# error "to do"
-#endif
assert (freesize < pd->stackblock_size);
if (freesize > PTHREAD_STACK_MIN)
__madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
-
+#else
+ /* Page aligned start of memory to free (higher than or equal
+ to current sp plus the minimum stack size). */
+ void *freeblock = (void*)((size_t)(CURRENT_STACK_FRAME
+ + PTHREAD_STACK_MIN
+ + pagesize_m1)
+ & ~pagesize_m1);
+ char *free_end = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
+ /* Is there any space to free? */
+ if (free_end > (char *)freeblock)
+ {
+ size_t freesize = (size_t)(free_end - (char *)freeblock);
+ assert (freesize < pd->stackblock_size);
+ __madvise (freeblock, freesize, MADV_DONTNEED);
+ }
+#endif
+
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))
/* Free the TCB. */
@@ -60,7 +60,11 @@ pthread_getattr_np (thread_id, attr)
if (__glibc_likely (thread->stackblock != NULL))
{
iattr->stacksize = thread->stackblock_size;
+#ifdef _STACK_GROWS_DOWN
iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
+#else
+ iattr->stackaddr = (char *) thread->stackblock;
+#endif
}
else
{
@@ -105,7 +109,9 @@ pthread_getattr_np (thread_id, attr)
char *line = NULL;
size_t linelen = 0;
+#if _STACK_GROWS_DOWN
uintptr_t last_to = 0;
+#endif
while (! feof_unlocked (fp))
{
@@ -129,17 +135,24 @@ pthread_getattr_np (thread_id, attr)
stack extension request. */
iattr->stacksize = (iattr->stacksize
& -(intptr_t) GLRO(dl_pagesize));
-
+#if _STACK_GROWS_DOWN
/* 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
+ /* 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;
}
+#if _STACK_GROWS_DOWN
last_to = to;
+#endif
}
free (line);
@@ -261,7 +261,8 @@ __pthread_mutex_trylock (mutex)
private), 0, 0);
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
- && INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+ && ((INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+ || (INTERNAL_SYSCALL_ERRNO (e, __err) == EAGAIN)))
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
@@ -51,7 +51,7 @@ __old_sem_wait (sem_t *sem)
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
}
- while (err == 0 || err == -EWOULDBLOCK);
+ while (err == 0 || err == -EWOULDBLOCK || err == -EAGAIN);
__set_errno (-err);
return -1;
@@ -348,7 +348,7 @@ fnmatch (pattern, string, flags)
memset (&ps, '\0', sizeof (ps));
p = pattern;
#ifdef _LIBC
- n = strnlen (pattern, 1024);
+ n = __strnlen (pattern, 1024);
#else
n = strlen (pattern);
#endif
@@ -29,6 +29,7 @@
#include <_itoa.h>
#include <locale/localeinfo.h>
#include <stdio.h>
+#include <libc-internal.h>
/* This code is shared between the standard stdio implementation found
in GNU C library and the libio implementation originally found in
@@ -20,9 +20,6 @@
int
pthread_spin_init (pthread_spinlock_t *lock, int pshared)
{
- int tmp = 0;
- /* This should be a memory barrier to newer compilers */
- __asm__ __volatile__ ("stw,ma %1,0(%0)"
- : : "r" (lock), "r" (tmp) : "memory");
+ atomic_exchange_acq (lock, 0);
return 0;
}
@@ -20,9 +20,6 @@
int
pthread_spin_unlock (pthread_spinlock_t *lock)
{
- int tmp = 0;
- /* This should be a memory barrier to newer compilers */
- __asm__ __volatile__ ("stw,ma %1,0(%0)"
- : : "r" (lock), "r" (tmp) : "memory");
+ atomic_exchange_rel (lock, 0);
return 0;
}
@@ -35,8 +35,17 @@
#define SHM_LOCK 11 /* lock segment (root only) */
#define SHM_UNLOCK 12 /* unlock segment (root only) */
+/* There are two things to consider for SHMLBA, and a single value can't
+ account for both of them. There is a value at which the mapping must
+ be aligned, and then there is a colouring or offset at which the next
+ mapping of the same data becomes valid. For PARISC the alignment can
+ be page alignment e.g. 4096, but the colour must be 4MB. There is no
+ way to express both of these thigns in one value so we use 4kb here.
+ It is the best way to get semi-working results from a userspace that
+ doesn't have to normally care about this. We used to use a value of
+ 4MB, but that caused a lot of waste and problems. */
/* Segment low boundary address multiple. */
-#define SHMLBA 0x00400000 /* address needs to be 4 Mb aligned */
+#define SHMLBA 0x00001000
/* Type to count number of attaches. */
typedef unsigned long int shmatt_t;