diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 53559e6..1507cf8 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -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)
diff --git a/elf/Makefile b/elf/Makefile
index 711beed..89eeb9e 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -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
diff --git a/elf/rtld.c b/elf/rtld.c
index 69873c2..ecca9f9 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -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)));
 
diff --git a/elf/tst-execstack-mod.c b/elf/tst-execstack-mod.c
index 038e655..82c42a8 100644
--- a/elf/tst-execstack-mod.c
+++ b/elf/tst-execstack-mod.c
@@ -4,6 +4,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <libc-internal.h>
 
 void callme (void (*callback) (void));
 
diff --git a/nptl/Makefile b/nptl/Makefile
index 89fdc8b..488e949 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -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
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 3c8e046..cf87b7a 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -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;
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 71a5619..8ed6acc 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -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.  */
diff --git a/nptl/pthread_getattr_np.c b/nptl/pthread_getattr_np.c
index 52a4602..8a0aef5 100644
--- a/nptl/pthread_getattr_np.c
+++ b/nptl/pthread_getattr_np.c
@@ -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);
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 33df384..8582152 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -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);
 
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index c1fd10c..9ccea1b 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -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;
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index a707847..e71ec42 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -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
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index a41449d..4253f81 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -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
diff --git a/sysdeps/hppa/nptl/pthread_spin_init.c b/sysdeps/hppa/nptl/pthread_spin_init.c
index 865ef2b..b444d75 100644
--- a/sysdeps/hppa/nptl/pthread_spin_init.c
+++ b/sysdeps/hppa/nptl/pthread_spin_init.c
@@ -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;
 }
diff --git a/sysdeps/hppa/nptl/pthread_spin_unlock.c b/sysdeps/hppa/nptl/pthread_spin_unlock.c
index a183fed..eecf0f5 100644
--- a/sysdeps/hppa/nptl/pthread_spin_unlock.c
+++ b/sysdeps/hppa/nptl/pthread_spin_unlock.c
@@ -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;
 }
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/shm.h b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
index a6a86f7..1ff846a 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/shm.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
@@ -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;
