summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2009-08-24 10:15:51 +0200
committerAndreas Schwab <schwab@redhat.com>2009-08-24 10:15:51 +0200
commit255acd161cc2d7752a4e79234dcba5d929c3e0a4 (patch)
tree94c1d111cce2137ee948ff0e9d735f7a3643ef78
parent593eff0f9e5bed517e0a8434507ee9f3f4d45b87 (diff)
parenta0e25a886a9128b280b4c05bc9c6dd12377ea868 (diff)
downloadglibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.tar.gz
glibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.tar.xz
glibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.zip
Merge commit 'origin/master' into fedora/master
Conflicts:
	sysdeps/powerpc/powerpc64/____longjmp_chk.S
	sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
-rw-r--r--ChangeLog41
-rw-r--r--locale/locale.h2
-rw-r--r--nptl/ChangeLog4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h10
-rw-r--r--nptl_db/ChangeLog7
-rw-r--r--nptl_db/td_ta_map_lwp2thr.c14
-rw-r--r--posix/Makefile1
-rw-r--r--posix/bug-regex29.c15
-rw-r--r--posix/regcomp.c2
-rw-r--r--posix/unistd.h40
-rw-r--r--stdio-common/printf_fp.c9
-rw-r--r--stdio-common/printf_fphex.c4
-rw-r--r--stdio-common/tstdiomisc.c132
-rw-r--r--sysdeps/generic/elf/backtracesyms.c71
-rw-r--r--sysdeps/generic/elf/backtracesymsfd.c58
-rw-r--r--sysdeps/powerpc/powerpc32/__longjmp-common.S15
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S15
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S (renamed from sysdeps/powerpc/powerpc32/____longjmp_chk.S)33
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S (renamed from sysdeps/powerpc/powerpc64/____longjmp_chk.S)30
19 files changed, 386 insertions, 117 deletions
diff --git a/ChangeLog b/ChangeLog
index 4eadfbb89b..1b11dd1678 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2009-08-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* posix/regcomp.c (parse_dup_op): Verify the expression is correctly
+	terminated.
+	* posix/Makefile (tests): Add bug-regex29.
+	* posix/bug-regex29.c: New file.
+
+	* posix/unistd.h: Define _POSIX_VERSION and _POSIX2_* correctly if
+	older POSIX versions are selected.
+
+	* stdio-common/printf_fp.c: ISO C expects to print the sign of NaN
+	as well.
+	* stdio-common/printf_fphex.c: Likewise.
+	* stdio-common/tstdiomisc.c: Add more tests.
+
+	* locale/locale.h: Include xlocale.h and the thread-local locale
+	declarations for XPG7, not XPG6.
+
+2009-08-21  Andreas Schwab  <schwab@redhat.com>
+
+	* sysdeps/powerpc/powerpc32/____longjmp_chk.S: Removed.
+	* sysdeps/powerpc/powerpc64/____longjmp_chk.S: Removed.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S: New file.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S: New file.
+	* sysdeps/powerpc/powerpc32/__longjmp-common.S: Move CHECK_SP earlier.
+	* sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: Likewise.
+
+2009-08-20  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/generic/elf/backtracesyms.c (__backtrace_symbols):
+	Use l_addr instead of l_map_start (dli_fbase).
+	Print "FILE([+-]OFFSET) [ADDRESS]" with the file-relative
+	address when there is no proximate symbol.
+	* sysdeps/generic/elf/backtracesymsfd.c (__backtrace_symbols_fd):
+	Likewise.
+
 2009-08-16  Ulrich Drepper  <drepper@redhat.com>
 
 	* scripts/gen-as-const.awk: Fix test for 64-bit platform.
@@ -665,11 +701,6 @@
 	* timezone/zic.c (stringzone): Don't try to generate a POSIX TZ
 	string when the timezone ends in DST.
 
-	* sysdeps/powerpc/powerpc32/____longjmp_chk.S (CHECK_SP): Save lr
-	before call.
-	* sysdeps/powerpc/powerpc64/____longjmp_chk.S (CHECK_SP):
-	Likewise.
-
 2009-06-26  Ulrich Drepper  <drepper@redhat.com>
 
 	* resolv/resolv.h: Define RES_SNGLKUPREOP.
diff --git a/locale/locale.h b/locale/locale.h
index b24ae245fe..2aa19e76ac 100644
--- a/locale/locale.h
+++ b/locale/locale.h
@@ -130,7 +130,7 @@ extern struct lconv *localeconv (void) __THROW;
 __END_NAMESPACE_STD
 
 
-#ifdef	__USE_XOPEN2K
+#ifdef	__USE_XOPEN2K8
 /* The concept of one static locale per category is not very well
    thought out.  Many applications will need to process its data using
    information from several different locales.  Another application is
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 59a77528e4..193756d45e 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,7 @@
+2009-08-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/bits/posix_opt.h: Clean up namespace.
+
 2009-08-11  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Add CFI
diff --git a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
index e23ad29e3e..e4f002a5c8 100644
--- a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
+++ b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -85,15 +85,17 @@
 /* We support priority inheritence.  */
 #define _POSIX_THREAD_PRIO_INHERIT	200809L
 
-/* We support priority inheritence for robust mutexes.  */
-#define _POSIX_THREAD_ROBUST_PRIO_INHERIT	200809L
-
 /* We support priority protection, though only for non-robust
    mutexes.  */
 #define _POSIX_THREAD_PRIO_PROTECT	200809L
 
+#ifdef __USE_XOPEN2K8
+/* We support priority inheritence for robust mutexes.  */
+# define _POSIX_THREAD_ROBUST_PRIO_INHERIT	200809L
+
 /* We do not support priority protection for robust mutexes.  */
-#define _POSIX_THREAD_ROBUST_PRIO_PROTECT	-1
+# define _POSIX_THREAD_ROBUST_PRIO_PROTECT	-1
+#endif
 
 /* We support POSIX.1b semaphores.  */
 #define _POSIX_SEMAPHORES	200809L
diff --git a/nptl_db/ChangeLog b/nptl_db/ChangeLog
index 1ade1968a7..f79fc18e4b 100644
--- a/nptl_db/ChangeLog
+++ b/nptl_db/ChangeLog
@@ -1,3 +1,10 @@
+2009-08-23  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_map_lwp2thr.c (__td_ta_lookup_th_unique): Move ta_ok check
+	and LOG call back to ...
+	(td_ta_map_lwp2thr): ... here.
+	Reported by Maciej W. Rozycki <macro@codesourcery.com>.
+
 2009-05-25  Aurelien Jarno  <aurelien@aurel32.net>
 
 	[BZ #10200]
diff --git a/nptl_db/td_ta_map_lwp2thr.c b/nptl_db/td_ta_map_lwp2thr.c
index 78cfcab769..4835f31f94 100644
--- a/nptl_db/td_ta_map_lwp2thr.c
+++ b/nptl_db/td_ta_map_lwp2thr.c
@@ -1,5 +1,5 @@
 /* Which thread is running on an LWP?
-   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003,2004,2007,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -33,12 +33,6 @@ __td_ta_lookup_th_unique (const td_thragent_t *ta_arg,
   prgregset_t regs;
   psaddr_t addr;
 
-  LOG ("td_ta_map_lwp2thr");
-
-  /* Test whether the TA parameter is ok.  */
-  if (! ta_ok (ta))
-    return TD_BADTA;
-
   if (ta->ta_howto == ta_howto_unknown)
     {
       /* We need to read in from the inferior the instructions what to do.  */
@@ -181,6 +175,12 @@ td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
 {
   td_thragent_t *const ta = (td_thragent_t *) ta_arg;
 
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
   /* We cannot rely on thread registers and such information at all
      before __pthread_initialize_minimal has gotten far enough.  They
      sometimes contain garbage that would confuse us, left by the kernel
diff --git a/posix/Makefile b/posix/Makefile
index 3c3ccfad55..c0164effa8 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -82,6 +82,7 @@ tests		:= tstgetopt testfnm runtests runptests	     \
 		   bug-regex17 bug-regex18 bug-regex19 bug-regex20 \
 		   bug-regex21 bug-regex22 bug-regex23 bug-regex24 \
 		   bug-regex25 bug-regex26 bug-regex27 bug-regex28 \
+		   bug-regex29 \
 		   tst-nice tst-nanosleep tst-regex2 \
 		   transbug tst-rxspencer tst-pcre tst-boost \
 		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
diff --git a/posix/bug-regex29.c b/posix/bug-regex29.c
new file mode 100644
index 0000000000..70a6c94cc6
--- /dev/null
+++ b/posix/bug-regex29.c
@@ -0,0 +1,15 @@
+#include <regex.h>
+
+static int
+do_test (void)
+{
+  regex_t r;
+  int e = regcomp(&r, "xy\\{4,5,7\\}zabc", 0);
+  char buf[100];
+  regerror(e, &r, buf, sizeof (buf));
+  printf ("e = %d (%s)\n", e, buf);
+  return e != REG_BADBR;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 4843cfea33..446fed5445 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -2481,7 +2481,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
 	  return elem;
 	}
 
-      if (BE (end != -1 && start > end, 0))
+      if (BE ((end != -1 && start > end) || token->type != OP_CLOSE_DUP_NUM, 0))
 	{
 	  /* First number greater than second.  */
 	  *err = REG_BADBR;
diff --git a/posix/unistd.h b/posix/unistd.h
index cbab9f939e..d9ecb5e788 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -30,30 +30,58 @@ __BEGIN_DECLS
 /* These may be used to determine what facilities are present at compile time.
    Their values can be obtained at run time from `sysconf'.  */
 
+#ifdef __USE_XOPEN2K8
 /* POSIX Standard approved as ISO/IEC 9945-1 as of September 2008.  */
-#define	_POSIX_VERSION	200809L
+# define _POSIX_VERSION	200809L
+#elif defined __USE_XOPEN2K
+/* POSIX Standard approved as ISO/IEC 9945-1 as of December 2001.  */
+# define _POSIX_VERSION	200112L
+#elif defined __USE_POSIX199506
+/* POSIX Standard approved as ISO/IEC 9945-1 as of June 1995.  */
+# define _POSIX_VERSION	199506L
+#elif defined __USE_POSIX199309
+/* POSIX Standard approved as ISO/IEC 9945-1 as of September 1993.  */
+# define _POSIX_VERSION	199309L
+#else
+/* POSIX Standard approved as ISO/IEC 9945-1 as of September 1990.  */
+# define _POSIX_VERSION	199009L
+#endif
 
 /* These are not #ifdef __USE_POSIX2 because they are
    in the theoretically application-owned namespace.  */
 
+#ifdef __USE_XOPEN2K8
+# define __POSIX2_THIS_VERSION	200809L
+/* The utilities on GNU systems also correspond to this version.  */
+#elif defined __USE_XOPEN2K
+/* The utilities on GNU systems also correspond to this version.  */
+# define __POSIX2_THIS_VERSION	200112L
+#elif defined __USE_POSIX199506
+/* The utilities on GNU systems also correspond to this version.  */
+# define __POSIX2_THIS_VERSION	199506L
+#else
+/* The utilities on GNU systems also correspond to this version.  */
+# define __POSIX2_THIS_VERSION	199209L
+#endif
+
 /* The utilities on GNU systems also correspond to this version.  */
-#define _POSIX2_VERSION	200809L
+#define _POSIX2_VERSION	__POSIX2_THIS_VERSION
 
 /* If defined, the implementation supports the
    C Language Bindings Option.  */
-#define	_POSIX2_C_BIND	200809L
+#define	_POSIX2_C_BIND	__POSIX2_THIS_VERSION
 
 /* If defined, the implementation supports the
    C Language Development Utilities Option.  */
-#define	_POSIX2_C_DEV	200809L
+#define	_POSIX2_C_DEV	__POSIX2_THIS_VERSION
 
 /* If defined, the implementation supports the
    Software Development Utilities Option.  */
-#define	_POSIX2_SW_DEV	200809L
+#define	_POSIX2_SW_DEV	__POSIX2_THIS_VERSION
 
 /* If defined, the implementation supports the
    creation of locales with the localedef utility.  */
-#define _POSIX2_LOCALEDEF       200809L
+#define _POSIX2_LOCALEDEF       __POSIX2_THIS_VERSION
 
 /* X/Open version number to which the library conforms.  It is selectable.  */
 #ifdef __USE_XOPEN2K8
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 43c43c2039..cd3ada6441 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -28,6 +28,7 @@
 #include <float.h>
 #include <gmp-mparam.h>
 #include <gmp.h>
+#include <ieee754.h>
 #include <stdlib/gmp-impl.h>
 #include <stdlib/longlong.h>
 #include <stdlib/fpioconst.h>
@@ -335,6 +336,8 @@ ___printf_fp (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnanl (fpnum.ldbl))
 	{
+	  union ieee854_long_double u = { .d = fpnum.ldbl };
+	  is_neg = u.ieee.negative != 0;
 	  if (isupper (info->spec))
 	    {
 	      special = "NAN";
@@ -345,10 +348,10 @@ ___printf_fp (FILE *fp,
 		special = "nan";
 		wspecial = L"nan";
 	      }
-	  is_neg = 0;
 	}
       else if (__isinfl (fpnum.ldbl))
 	{
+	  is_neg = fpnum.ldbl < 0;
 	  if (isupper (info->spec))
 	    {
 	      special = "INF";
@@ -359,7 +362,6 @@ ___printf_fp (FILE *fp,
 	      special = "inf";
 	      wspecial = L"inf";
 	    }
-	  is_neg = fpnum.ldbl < 0;
 	}
       else
 	{
@@ -379,7 +381,8 @@ ___printf_fp (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnan (fpnum.dbl))
 	{
-	  is_neg = 0;
+	  union ieee754_double u = { .d = fpnum.dbl };
+	  is_neg = u.ieee.negative != 0;
 	  if (isupper (info->spec))
 	    {
 	      special = "NAN";
diff --git a/stdio-common/printf_fphex.c b/stdio-common/printf_fphex.c
index 4e30d94c61..551c873c5e 100644
--- a/stdio-common/printf_fphex.c
+++ b/stdio-common/printf_fphex.c
@@ -172,6 +172,7 @@ __printf_fphex (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnanl (fpnum.ldbl.d))
 	{
+	  negative = fpnum.ldbl.ieee.negative != 0;
 	  if (isupper (info->spec))
 	    {
 	      special = "NAN";
@@ -182,7 +183,6 @@ __printf_fphex (FILE *fp,
 	      special = "nan";
 	      wspecial = L"nan";
 	    }
-	  negative = 0;
 	}
       else
 	{
@@ -211,6 +211,7 @@ __printf_fphex (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnan (fpnum.dbl.d))
 	{
+	  negative = fpnum.dbl.ieee.negative != 0;
 	  if (isupper (info->spec))
 	    {
 	      special = "NAN";
@@ -221,7 +222,6 @@ __printf_fphex (FILE *fp,
 	      special = "nan";
 	      wspecial = L"nan";
 	    }
-	  negative = 0;
 	}
       else
 	{
diff --git a/stdio-common/tstdiomisc.c b/stdio-common/tstdiomisc.c
index db038fa2b0..c1c68955bd 100644
--- a/stdio-common/tstdiomisc.c
+++ b/stdio-common/tstdiomisc.c
@@ -47,33 +47,129 @@ t2 (void)
 }
 
 volatile double nanval;
+volatile double infval;
+volatile long double lnanval;
+volatile long double linfval;
 
 
 static int
 F (void)
 {
-  char buf[20];
-  wchar_t wbuf[10];
+  char buf[80];
+  wchar_t wbuf[40];
   int result;
 
   nanval = NAN;
 
-  snprintf (buf, sizeof buf, "%f %F", nanval, nanval);
-  result = strcmp (buf, "nan NAN") != 0;
-  printf ("expected \"nan NAN\", got \"%s\"\n", buf);
-
-  snprintf (buf, sizeof buf, "%f %F", DBL_MAX * DBL_MAX, DBL_MAX * DBL_MAX);
-  result |= strcmp (buf, "inf INF") != 0;
-  printf ("expected \"inf INF\", got \"%s\"\n", buf);
-
-  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%f %F", nanval, nanval);
-  result |= wcscmp (wbuf, L"nan NAN") != 0;
-  printf ("expected L\"nan NAN\", got L\"%S\"\n", wbuf);
-
-  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%f %F",
-	    DBL_MAX * DBL_MAX, DBL_MAX * DBL_MAX);
-  result |= wcscmp (wbuf, L"inf INF") != 0;
-  printf ("expected L\"inf INF\", got L\"%S\"\n", wbuf);
+  snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
+	    nanval, nanval, nanval, nanval, nanval, nanval, nanval, nanval);
+  result = strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
+  printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
+
+  snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
+	    -nanval, -nanval, -nanval, -nanval,
+	    -nanval, -nanval, -nanval, -nanval);
+  result = strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
+  printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
+	  buf);
+
+  infval = DBL_MAX * DBL_MAX;
+
+  snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
+	    infval, infval, infval, infval, infval, infval, infval, infval);
+  result |= strcmp (buf, "inf INF inf INF inf INF inf INF") != 0;
+  printf ("expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n", buf);
+
+  snprintf (buf, sizeof buf, "%a %A %e %E %f %F %g %G",
+	    -infval, -infval, -infval, -infval,
+	    -infval, -infval, -infval, -infval);
+  result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+  printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+	  buf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+	    nanval, nanval, nanval, nanval, nanval, nanval, nanval, nanval);
+  result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
+  printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+	    -nanval, -nanval, -nanval, -nanval,
+	    -nanval, -nanval, -nanval, -nanval);
+  result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
+  printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
+	  wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+	    infval, infval, infval, infval, infval, infval, infval, infval);
+  result |= wcscmp (wbuf, L"inf INF inf INF inf INF inf INF") != 0;
+  printf ("expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n", wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]), L"%a %A %e %E %f %F %g %G",
+	    -infval, -infval, -infval, -infval,
+	    -infval, -infval, -infval, -infval);
+  result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+  printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+	  wbuf);
+
+  lnanval = NAN;
+
+  snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    lnanval, lnanval, lnanval, lnanval,
+	    lnanval, lnanval, lnanval, lnanval);
+  result = strcmp (buf, "nan NAN nan NAN nan NAN nan NAN") != 0;
+  printf ("expected \"nan NAN nan NAN nan NAN nan NAN\", got \"%s\"\n", buf);
+
+  snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    -lnanval, -lnanval, -lnanval, -lnanval,
+	    -lnanval, -lnanval, -lnanval, -lnanval);
+  result = strcmp (buf, "-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
+  printf ("expected \"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got \"%s\"\n",
+	  buf);
+
+  linfval = LDBL_MAX * LDBL_MAX;
+
+  snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    linfval, linfval, linfval, linfval,
+	    linfval, linfval, linfval, linfval);
+  result |= strcmp (buf, "inf INF inf INF inf INF inf INF") != 0;
+  printf ("expected \"inf INF inf INF inf INF inf INF\", got \"%s\"\n", buf);
+
+  snprintf (buf, sizeof buf, "%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    -linfval, -linfval, -linfval, -linfval,
+	    -linfval, -linfval, -linfval, -linfval);
+  result |= strcmp (buf, "-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+  printf ("expected \"-inf -INF -inf -INF -inf -INF -inf -INF\", got \"%s\"\n",
+	  buf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    lnanval, lnanval, lnanval, lnanval,
+	    lnanval, lnanval, lnanval, lnanval);
+  result |= wcscmp (wbuf, L"nan NAN nan NAN nan NAN nan NAN") != 0;
+  printf ("expected L\"nan NAN nan NAN nan NAN nan NAN\", got L\"%S\"\n", wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    -lnanval, -lnanval, -lnanval, -lnanval,
+	    -lnanval, -lnanval, -lnanval, -lnanval);
+  result |= wcscmp (wbuf, L"-nan -NAN -nan -NAN -nan -NAN -nan -NAN") != 0;
+  printf ("expected L\"-nan -NAN -nan -NAN -nan -NAN -nan -NAN\", got L\"%S\"\n",
+	  wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    linfval, linfval, linfval, linfval,
+	    linfval, linfval, linfval, linfval);
+  result |= wcscmp (wbuf, L"inf INF inf INF inf INF inf INF") != 0;
+  printf ("expected L\"inf INF inf INF inf INF inf INF\", got L\"%S\"\n", wbuf);
+
+  swprintf (wbuf, sizeof wbuf / sizeof (wbuf[0]),
+	    L"%La %LA %Le %LE %Lf %LF %Lg %LG",
+	    -linfval, -linfval, -linfval, -linfval,
+	    -linfval, -linfval, -linfval, -linfval);
+  result |= wcscmp (wbuf, L"-inf -INF -inf -INF -inf -INF -inf -INF") != 0;
+  printf ("expected L\"-inf -INF -inf -INF -inf -INF -inf -INF\", got L\"%S\"\n",
+	  wbuf);
 
   return result;
 }
diff --git a/sysdeps/generic/elf/backtracesyms.c b/sysdeps/generic/elf/backtracesyms.c
index b31be6ac5d..319b207605 100644
--- a/sysdeps/generic/elf/backtracesyms.c
+++ b/sysdeps/generic/elf/backtracesyms.c
@@ -1,5 +1,5 @@
 /* Return list with names for address in backtrace.
-   Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc.
+   Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -48,15 +48,22 @@ __backtrace_symbols (array, size)
   /* Fill in the information we can get from `dladdr'.  */
   for (cnt = 0; cnt < size; ++cnt)
     {
-      status[cnt] = _dl_addr (array[cnt], &info[cnt], NULL, NULL);
+      struct link_map *map;
+      status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL);
       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
-	/* We have some info, compute the length of the string which will be
-	   "<file-name>(<sym-name>) [+offset].  */
-	total += (strlen (info[cnt].dli_fname ?: "")
-		  + (info[cnt].dli_sname
-		     ? strlen (info[cnt].dli_sname) + 3 + WORD_WIDTH + 3
-		     : 1)
-		  + WORD_WIDTH + 5);
+	{
+	  /* We have some info, compute the length of the string which will be
+	     "<file-name>(<sym-name>+offset) [address].  */
+	  total += (strlen (info[cnt].dli_fname ?: "")
+		    + strlen (info[cnt].dli_sname ?: "")
+		    + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+	  /* The load bias is more useful to the user than the load
+	     address.  The use of these addresses is to calculate an
+	     address in the ELF file, so its prelinked bias is not
+	     something we want to subtract out.  */
+	  info[cnt].dli_fbase = (void *) map->l_addr;
+	}
       else
 	total += 5 + WORD_WIDTH;
     }
@@ -71,25 +78,39 @@ __backtrace_symbols (array, size)
 	{
 	  result[cnt] = last;
 
-	  if (status[cnt] && info[cnt].dli_fname
-	      && info[cnt].dli_fname[0] != '\0')
+	  if (status[cnt]
+	      && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
 	    {
-	      char buf[20];
+	      if (info[cnt].dli_sname == NULL)
+		/* We found no symbol name to use, so describe it as
+		   relative to the file.  */
+		info[cnt].dli_saddr = info[cnt].dli_fbase;
 
-	      if (array[cnt] >= (void *) info[cnt].dli_saddr)
-		sprintf (buf, "+%#lx",
-			 (unsigned long)(array[cnt] - info[cnt].dli_saddr));
+	      if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+		last += 1 + sprintf (last, "%s(%s) [%p]",
+				     info[cnt].dli_fname ?: "",
+				     info[cnt].dli_sname ?: "",
+				     array[cnt]);
 	      else
-		sprintf (buf, "-%#lx",
-			 (unsigned long)(info[cnt].dli_saddr - array[cnt]));
-
-	      last += 1 + sprintf (last, "%s%s%s%s%s[%p]",
-				   info[cnt].dli_fname ?: "",
-				   info[cnt].dli_sname ? "(" : "",
-				   info[cnt].dli_sname ?: "",
-				   info[cnt].dli_sname ? buf : "",
-				   info[cnt].dli_sname ? ") " : " ",
-				   array[cnt]);
+		{
+		  char sign;
+		  ptrdiff_t offset;
+		  if (array[cnt] >= (void *) info[cnt].dli_saddr)
+		    {
+		      sign = '+';
+		      offset = array[cnt] - info[cnt].dli_saddr;
+		    }
+		  else
+		    {
+		      sign = '-';
+		      offset = info[cnt].dli_saddr - array[cnt];
+		    }
+
+		  last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]",
+				       info[cnt].dli_fname ?: "",
+				       info[cnt].dli_sname ?: "",
+				       sign, offset, array[cnt]);
+		}
 	    }
 	  else
 	    last += 1 + sprintf (last, "[%p]", array[cnt]);
diff --git a/sysdeps/generic/elf/backtracesymsfd.c b/sysdeps/generic/elf/backtracesymsfd.c
index 6754d145b0..f0ab71587f 100644
--- a/sysdeps/generic/elf/backtracesymsfd.c
+++ b/sysdeps/generic/elf/backtracesymsfd.c
@@ -1,5 +1,5 @@
 /* Write formatted list with names for addresses in backtrace to a file.
-   Copyright (C) 1998, 2000, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1998,2000,2003,2005,2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -46,47 +46,63 @@ __backtrace_symbols_fd (array, size, fd)
     {
       char buf[WORD_WIDTH];
       Dl_info info;
+      struct link_map *map;
       size_t last = 0;
 
-      if (_dl_addr (array[cnt], &info, NULL, NULL)
-	  && info.dli_fname && info.dli_fname[0] != '\0')
+      if (_dl_addr (array[cnt], &info, &map, NULL)
+	  && info.dli_fname != NULL && info.dli_fname[0] != '\0')
 	{
 	  /* Name of the file.  */
 	  iov[0].iov_base = (void *) info.dli_fname;
 	  iov[0].iov_len = strlen (info.dli_fname);
 	  last = 1;
 
-	  /* Symbol name.  */
-	  if (info.dli_sname != NULL)
+	  if (info.dli_sname != NULL || map->l_addr != 0)
 	    {
 	      char buf2[WORD_WIDTH];
 	      size_t diff;
 
-	      iov[1].iov_base = (void *) "(";
-	      iov[1].iov_len = 1;
-	      iov[2].iov_base = (void *) info.dli_sname;
-	      iov[2].iov_len = strlen (info.dli_sname);
+	      iov[last].iov_base = (void *) "(";
+	      iov[last].iov_len = 1;
+	      ++last;
+
+	      if (info.dli_sname != NULL)
+		{
+		  /* We have a symbol name.  */
+		  iov[last].iov_base = (void *) info.dli_sname;
+		  iov[last].iov_len = strlen (info.dli_sname);
+		  ++last;
+		}
+	      else
+		/* We have no symbol, so describe it as relative to the file.
+		   The load bias is more useful to the user than the load
+		   address.  The use of these addresses is to calculate an
+		   address in the ELF file, so its prelinked bias is not
+		   something we want to subtract out.  */
+		info.dli_saddr = (void *) map->l_addr;
 
 	      if (array[cnt] >= (void *) info.dli_saddr)
 		{
-		  iov[3].iov_base = (void *) "+0x";
+		  iov[last].iov_base = (void *) "+0x";
 		  diff = array[cnt] - info.dli_saddr;
 		}
 	      else
 		{
-		  iov[3].iov_base = (void *) "-0x";
+		  iov[last].iov_base = (void *) "-0x";
 		  diff = info.dli_saddr - array[cnt];
 		}
-	      iov[3].iov_len = 3;
-
-	      iov[4].iov_base = _itoa_word ((unsigned long int) diff,
-					    &buf2[WORD_WIDTH], 16, 0);
-	      iov[4].iov_len = &buf2[WORD_WIDTH] - (char *) iov[4].iov_base;
-
-	      iov[5].iov_base = (void *) ")";
-	      iov[5].iov_len = 1;
-
-	      last = 6;
+	      iov[last].iov_len = 3;
+	      ++last;
+
+	      iov[last].iov_base = _itoa_word ((unsigned long int) diff,
+					       &buf2[WORD_WIDTH], 16, 0);
+	      iov[last].iov_len = (&buf2[WORD_WIDTH]
+				   - (char *) iov[last].iov_base);
+	      ++last;
+
+	      iov[last].iov_base = (void *) ")";
+	      iov[last].iov_len = 1;
+	      ++last;
 	    }
 	}
 
diff --git a/sysdeps/powerpc/powerpc32/__longjmp-common.S b/sysdeps/powerpc/powerpc32/__longjmp-common.S
index 7b1c017837..955161ef2b 100644
--- a/sysdeps/powerpc/powerpc32/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/__longjmp-common.S
@@ -33,6 +33,13 @@ ENTRY (BP_SYM (__longjmp))
 
 #if defined PTR_DEMANGLE || defined CHECK_SP
 	lwz r24,(JB_GPR1*4)(r3)
+# ifdef CHECK_SP
+#  ifdef PTR_DEMANGLE
+	PTR_DEMANGLE3 (r24, r24, r25)
+#  endif
+	CHECK_SP (r24)
+	mr r1,r24
+# endif
 #else
 	lwz r1,(JB_GPR1*4)(r3)
 #endif
@@ -45,17 +52,11 @@ ENTRY (BP_SYM (__longjmp))
 	lwz r19,((JB_GPRS+5)*4)(r3)
 	lwz r20,((JB_GPRS+6)*4)(r3)
 #ifdef PTR_DEMANGLE
-# ifdef CHECK_SP
-	PTR_DEMANGLE3 (r24, r24, r25)
-# else
+# ifndef CHECK_SP
 	PTR_DEMANGLE3 (r1, r24, r25)
 # endif
 	PTR_DEMANGLE2 (r0, r25)
 #endif
-#ifdef CHECK_SP
-	CHECK_SP (r24)
-	mr r1,r24
-#endif
 	mtlr r0
 	lwz r21,((JB_GPRS+7)*4)(r3)
 	lwz r22,((JB_GPRS+8)*4)(r3)
diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
index f105815b9c..04ed6da68b 100644
--- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
@@ -116,6 +116,13 @@ L(no_vmx):
 #endif
 #if defined PTR_DEMANGLE || defined CHECK_SP
 	lwz r24,(JB_GPR1*4)(r3)
+# ifdef CHECK_SP
+#  ifdef PTR_DEMANGLE
+	PTR_DEMANGLE3 (r24, r24, r25)
+#  endif
+	CHECK_SP (r24)
+	mr r1,r24
+# endif
 #else
 	lwz r1,(JB_GPR1*4)(r3)
 #endif
@@ -135,17 +142,11 @@ L(no_vmx):
 	lwz r20,((JB_GPRS+6)*4)(r3)
 	lfd fp20,((JB_FPRS+6*2)*4)(r3)
 #ifdef PTR_DEMANGLE
-# ifdef CHECK_SP
-	PTR_DEMANGLE3 (r24, r24, r25)
-# else
+# ifndef CHECK_SP
 	PTR_DEMANGLE3 (r1, r24, r25)
 # endif
 	PTR_DEMANGLE2 (r0, r25)
 #endif
-#ifdef CHECK_SP
-	CHECK_SP (r24)
-	mr r1,r24
-#endif
 	mtlr r0
 	lwz r21,((JB_GPRS+7)*4)(r3)
 	lfd fp21,((JB_FPRS+7*2)*4)(r3)
diff --git a/sysdeps/powerpc/powerpc32/____longjmp_chk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S
index 128899a532..4cb968505d 100644
--- a/sysdeps/powerpc/powerpc32/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S
@@ -19,7 +19,8 @@
 #include <sysdep.h>
 #include <rtld-global-offsets.h>
 
-	.section .rodata.str1.1,"aMS",@progbits,1
+	.section .rodata.str1.4,"aMS",@progbits,1
+	.align 2
 .LC0:
 	.string "longjmp causes uninitialized stack frame"
 	.text
@@ -49,15 +50,35 @@
 #define CHECK_SP(reg) \
 	cmplw	reg, r1;				\
 	bge+	.Lok;					\
-	cfi_remember_state;				\
 	mflr	r0;					\
-	stwu	r1,-16(r1);				\
-	cfi_adjust_cfa_offset (16);			\
-	stw	r0,20(r1);				\
+	stwu	r1,-32(r1);				\
+	cfi_remember_state;				\
+	cfi_adjust_cfa_offset (32);			\
+	stw	r0,36(r1);				\
 	cfi_offset (lr, 4);				\
+	mr	r31,r3;					\
+	mr	r30,r4;					\
+	li	r3,0;					\
+	addi	r4,r1,8;				\
+	li	r0,__NR_sigaltstack;			\
+	sc;						\
+	/* Without working sigaltstack we cannot perform the test.  */ \
+	bso	.Lok2;					\
+	lwz	r0,12(r1);				\
+	andi.	r3,r0,1;				\
+	beq	.Lfail;					\
+	lwz	r0,16(r1);				\
+	lwz	r3,8(r1);				\
+	add	r3,r3,r0;				\
+	sub	r3,r3,reg;				\
+	cmplw	r3,r0;					\
+	bge+	.Lok2;					\
+.Lfail:							\
 	LOAD_ARG;					\
 	bl	HIDDEN_JUMPTARGET (__fortify_fail);	\
-	nop;						\
+.Lok2:							\
+	mr	r3,r31;					\
+	mr	r4,r30;					\
 	cfi_restore_state;				\
 .Lok:
 
diff --git a/sysdeps/powerpc/powerpc64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
index f1b7d85e46..936ace5f69 100644
--- a/sysdeps/powerpc/powerpc64/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
@@ -19,7 +19,8 @@
 #include <sysdep.h>
 #include <rtld-global-offsets.h>
 
-	.section .rodata.str1.1,"aMS",@progbits,1
+	.section .rodata.str1.8,"aMS",@progbits,1
+	.align 3
 .LC0:
 	.string "longjmp causes uninitialized stack frame"
 	.section .toc,"aw"
@@ -32,15 +33,36 @@
 #define CHECK_SP(reg) \
 	cmpld	reg, r1;				\
 	bge+	.Lok;					\
-	cfi_remember_state;				\
 	mflr	r0;					\
 	std	r0,16(r1);				\
-	stdu	r1,-112(r1);				\
-	cfi_adjust_cfa_offset (112);			\
+	mr	r31,r3;					\
+	mr	r30,r4;					\
+	stdu	r1,-144(r1);				\
+	cfi_remember_state;				\
+	cfi_adjust_cfa_offset (144);			\
 	cfi_offset (lr, 16);				\
+	li	r3,0;					\
+	addi	r4,r1,112;				\
+	li	r0,__NR_sigaltstack;			\
+	sc;						\
+	/* Without working sigaltstack we cannot perform the test.  */ \
+	bso	.Lok2;					\
+	lwz	r0,112+8(r1);				\
+	andi.	r4,r0,1;				\
+	beq	.Lfail;					\
+	ld	r0,112+16(r1);				\
+	ld	r4,112(r1);				\
+	add	r4,r4,r0;				\
+	sub	r3,r3,reg;				\
+	cmpld	r3,r0;					\
+	bge+	.Lok2;					\
+.Lfail:							\
 	ld	r3,.LC1@toc(2);				\
 	bl	HIDDEN_JUMPTARGET (__fortify_fail);	\
 	nop;						\
+.Lok2:							\
+	mr	r3,r31;					\
+	mr	r4,r30;					\
 	cfi_restore_state;				\
 .Lok: