about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-05-10 06:44:30 +0000
committerJakub Jelinek <jakub@redhat.com>2007-05-10 06:44:30 +0000
commit96bad006f14ac46ca7a59dc4c5ba5ed9ef7a1560 (patch)
tree9e209798f73466fb9622bf0a9b14f4fabf00eb29
parent2a0a747e57ec96bab9d4a6b7c0b32df82a41316e (diff)
downloadglibc-96bad006f14ac46ca7a59dc4c5ba5ed9ef7a1560.tar.gz
glibc-96bad006f14ac46ca7a59dc4c5ba5ed9ef7a1560.tar.xz
glibc-96bad006f14ac46ca7a59dc4c5ba5ed9ef7a1560.zip
Updated to fedora-glibc-20070510T0634 cvs/fedora-glibc-2_5_90-23
-rw-r--r--ChangeLog109
-rw-r--r--elf/dl-addr.c226
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in22
-rw-r--r--locale/programs/linereader.c4
-rw-r--r--localedata/ChangeLog13
-rw-r--r--localedata/SUPPORTED2
-rw-r--r--localedata/locales/as_IN34
-rw-r--r--localedata/locales/ast_ES132
-rw-r--r--malloc/Makefile1
-rw-r--r--malloc/arena.c37
-rw-r--r--nptl/ChangeLog23
-rw-r--r--nptl/allocatestack.c24
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c22
-rw-r--r--nptl/tst-align2.c10
-rw-r--r--nptl/tst-cancel-wrappers.sh3
-rw-r--r--nptl/tst-cancel4.c44
-rw-r--r--nptl/tst-getpid1.c6
-rw-r--r--posix/unistd.h2
-rw-r--r--stdio-common/vfprintf.c5
-rw-r--r--string/strfry.c10
-rw-r--r--sysdeps/alpha/fpu/bits/mathinline.h3
-rw-r--r--sysdeps/alpha/fpu/s_fmax.S4
-rw-r--r--sysdeps/alpha/fpu/s_fmin.S4
-rw-r--r--sysdeps/alpha/fpu/s_isnan.c5
-rw-r--r--sysdeps/alpha/fpu/s_lrint.c6
-rw-r--r--sysdeps/alpha/fpu/s_lround.c6
-rw-r--r--sysdeps/alpha/fpu/s_nearbyint.c4
-rw-r--r--sysdeps/alpha/fpu/s_round.c4
-rw-r--r--sysdeps/alpha/fpu/s_trunc.c4
-rw-r--r--sysdeps/ia64/fpu/fraiseexcpt.c5
-rw-r--r--sysdeps/powerpc/bits/fenv.h18
-rw-r--r--sysdeps/powerpc/fpu/Makefile2
-rw-r--r--sysdeps/powerpc/fpu/fe_mask.c33
-rw-r--r--sysdeps/powerpc/fpu/fe_nomask.c5
-rw-r--r--sysdeps/powerpc/fpu/fedisblxcpt.c8
-rw-r--r--sysdeps/powerpc/fpu/feholdexcpt.c19
-rw-r--r--sysdeps/powerpc/fpu/fesetenv.c22
-rw-r--r--sysdeps/powerpc/fpu/feupdateenv.c22
-rw-r--r--sysdeps/s390/fpu/feholdexcpt.c7
-rw-r--r--sysdeps/unix/sysv/linux/alpha/ioperm.c5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_mask.c68
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_nomask.c (renamed from sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c)0
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_mask.c43
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_nomask.c (renamed from sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c)0
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list2
46 files changed, 817 insertions, 215 deletions
diff --git a/ChangeLog b/ChangeLog
index f6a6cc1675..079a98e839 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,104 @@
+2007-05-09  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/ia64/fpu/fraiseexcpt.c (feraiseexcept): Don't raise overflow
+	exception in addition to inexact when asked to raise only FE_INEXACT.
+
+	[BZ #3427]
+	* sysdeps/s390/fpu/feholdexcpt.c (feholdexcept): Don't clear exceptions
+	in *envp.
+
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4403]
+	* string/strfry.c (strfry): Make result more random.
+
+2007-05-07  Richard Henderson  <rth@redhat.com>
+
+	* sysdeps/alpha/fpu/bits/mathinline.h (__isnanl): Don't define
+	if __NO_LONG_DOUBLE_MATH.
+	* sysdeps/unix/sysv/linux/alpha/ioperm.c: If BWX insns not
+	available in the compiler, add .arch directive to the assembly.
+
+2007-05-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/alpha/fpu/s_nearbyint.c (nearbyintl): Fix version on
+	compat_symbol to GLIBC_2_1.
+	* sysdeps/alpha/fpu/s_fmin.S (fminl): Likewise.
+	* sysdeps/alpha/fpu/s_trunc.c (truncl): Likewise.
+	* sysdeps/alpha/fpu/s_fmax.S (fmaxl): Likewise.
+	* sysdeps/alpha/fpu/s_lrint.c (lrintl, llrintl): Likewise.
+	* sysdeps/alpha/fpu/s_lround.c (lroundl, llroundl): Likewise.
+	* sysdeps/alpha/fpu/s_round.c (roundl): Likewise.
+	* sysdeps/alpha/fpu/s_isnan.c (isnanl): Provide compat_symbol in
+	libc, not libm.
+	(__isnanl): New compat_symbol.
+
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* malloc/arena.c (heap_info): Add mprotect_size field, adjust pad.
+	(new_heap): Initialize mprotect_size.
+	(grow_heap): When growing, only mprotect from mprotect_size till
+	new_size if mprotect_size is smaller.  When shrinking, use PROT_NONE
+	MMAP for __libc_enable_secure only, otherwise use MADV_DONTNEED.
+
+2007-04-30  Steven Munroe  <sjmunroe@us.ibm.com>
+	    Peter Bergner  <bergner@us.ibm.com>
+
+	* sysdeps/powerpc/bits/fenv.h: Declare __fe_mask_env extern.
+	Define FE_NOMASK_ENV as FE_EANBLED_ENV.  Define FE_MASK_ENV.
+	* sysdeps/powerpc/fpu/Makefile: Add fe_mask to libm-support.
+	* sysdeps/powerpc/fpu/fe_mask.c: New file.
+	* sysdeps/powerpc/fpu/fe_nomask.c: Correct comment.
+	* sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept):
+	Call __fe_mask_env() if all FP exceptions disabled.
+	* sysdeps/powerpc/fpu/feholdexcpt.c (feholdexcept): Copy high 32-bits
+	from old FPSCR to new fenv to propagate DFP rounding modes.
+	Call __fe_mask_env() if FP exceptions previously enabled.
+	* sysdeps/powerpc/fpu/fesetenv.c (fesetenv): Change mask to merge
+	exceptions from env.  Use __fe_nomask_env() or __fe_mask_env() when
+	transitioning from all exceptions disabled to any exception enabled
+	or visa versa.
+	* sysdeps/powerpc/fpu/feupdateenv.c (__feupdateenv): Change mask to
+	merge exceptions from env.  Call __fe_nomask_env or __fe_mask_env
+	when transitioning from all exceptions disabled to any exception
+	enabled or visa versa.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c: Moved to...
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_nomask.c: ...here.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c: Moved to...
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_nomask.c: ...here.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_mask.c: New file.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_mask.c: New file.
+
+2007-05-06  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4465]
+	* posix/unistd.h: Remove __THROW from fdatasync.
+
+2007-05-06  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #4465]
+	* sysdeps/unix/sysv/linux/syscalls.list (fdatasync): Add "C" to args.
+
+2007-05-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* stdio-common/vfprintf.c (process_string_arg): Optimize
+	ridiculous precision in wide char code printing multi-byte string.
+	Reported by Jim Meyering <jim@meyering.net>.
+
+	[BZ #4131]
+	* elf/dl-addr.c (_dl_addr): Compare address with actual segment
+	boundaries to work around systems with overlapping binary loading.
+	Based on a patch by Suzuki <suzuki@in.ibm.com>.
+
+2007-05-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* stdio-common/vfprintf.c (process_string_arg): Adjust call to
+	__mbsnrtowcs after last change.
+
+	* locale/programs/linereader.c (get_symname): Fix adding final NUL.
+	(get_ident): Likewise.
+
 2007-05-03  Jakub Jelinek  <jakub@redhat.com>
 
 	* soft-fp/op-common.h (FP_TRUNC): Replace raising of FP_EX_INEXACT
@@ -27,8 +128,10 @@
 	(FP_PACK_SEMIRAW_EP): Use FP_PACK_RAW_EP instead of
 	undefined _FP_PACK_RAW_EP.
 
-	* op-2.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_2.
-	* op-4.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_4.
+	* soft-fp/op-2.h (_FP_FRAC_COPY_2_2): Define as alias to
+	_FP_FRAC_COPY_2.
+	* soft-fp/op-4.h (_FP_FRAC_COPY_2_2): Define as alias to
+	_FP_FRAC_COPY_4.
 
 2007-04-16  Uros Bizjak  <ubizjak@gmail.com>
 	    Jakub Jelinek  <jakub@redhat.com>
@@ -702,7 +805,7 @@
 
 2007-03-13  Richard Henderson  <rth@redhat.com>
 
-        * elf/dl-support.c (_dl_aux_init): Honor DL_PLATFORM_AUXV.
+	* elf/dl-support.c (_dl_aux_init): Honor DL_PLATFORM_AUXV.
 	* sysdeps/unix/sysv/linux/alpha/dl-auxv.h: New file.
 	* sysdeps/unix/sysv/linux/alpha/dl-support.c: New file.
 	* sysdeps/unix/sysv/linux/alpha/dl-sysdep.c (__libc_alpha_cache_shape):
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index e55dc4b46f..e13105572e 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -1,5 +1,5 @@
 /* Locate the shared object symbol nearest a given address.
-   Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 2005, 2006, 2007 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
@@ -22,137 +22,137 @@
 #include <ldsodefs.h>
 
 
-int
-internal_function
-_dl_addr (const void *address, Dl_info *info,
-	  struct link_map **mapp, const ElfW(Sym) **symbolp)
+static void
+__attribute ((always_inline))
+determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
+		struct link_map **mapp, const ElfW(Sym) **symbolp)
 {
-  const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
+  /* Now we know what object the address lies in.  */
+  info->dli_fname = match->l_name;
+  info->dli_fbase = (void *) match->l_map_start;
 
-  /* Protect against concurrent loads and unloads.  */
-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+  /* If this is the main program the information is incomplete.  */
+  if (__builtin_expect (match->l_name[0], 'a') == '\0'
+      && match->l_type == lt_executable)
+    info->dli_fname = _dl_argv[0];
 
-  /* Find the highest-addressed object that ADDRESS is not below.  */
-  struct link_map *match = NULL;
-  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
-    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
-      if (addr >= l->l_map_start && addr < l->l_map_end)
-	{
-	  /* We know ADDRESS lies within L if in any shared object.
-	     Make sure it isn't past the end of L's segments.  */
-	  size_t n = l->l_phnum;
-	  if (n > 0)
-	    {
-	      do
-		--n;
-	      while (l->l_phdr[n].p_type != PT_LOAD);
-	      if (addr >= (l->l_addr +
-			   l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
-		/* Off the end of the highest-addressed shared object.  */
-		continue;
-	    }
+  const ElfW(Sym) *symtab
+    = (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
+  const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);
 
-	  match = l;
-	  break;
-	}
+  ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
 
-  int result = 0;
-  if (match != NULL)
+  const ElfW(Sym) *matchsym = NULL;
+  if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+		    + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
     {
-      /* Now we know what object the address lies in.  */
-      info->dli_fname = match->l_name;
-      info->dli_fbase = (void *) match->l_map_start;
-
-      /* If this is the main program the information is incomplete.  */
-      if (__builtin_expect (match->l_name[0], 'a') == '\0'
-	  && match->l_type == lt_executable)
-	info->dli_fname = _dl_argv[0];
-
-      const ElfW(Sym) *symtab
-	= (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
-      const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);
-
-      ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
-
-      const ElfW(Sym) *matchsym = NULL;
-      if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
-			+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
+      /* We look at all symbol table entries referenced by the hash
+	 table.  */
+      for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
 	{
-	  /* We look at all symbol table entries referenced by the
-	     hash table.  */
-	  for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
+	  Elf32_Word symndx = match->l_gnu_buckets[bucket];
+	  if (symndx != 0)
 	    {
-	      Elf32_Word symndx = match->l_gnu_buckets[bucket];
-	      if (symndx != 0)
+	      const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
+
+	      do
 		{
-		  const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
-
-		  do
-		    {
-		      /* The hash table never references local symbols
-			 so we can omit that test here.  */
-		      if ((symtab[symndx].st_shndx != SHN_UNDEF
-			   || symtab[symndx].st_value != 0)
-			  && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
-			  && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
-						matchsym, addr)
-			  && symtab[symndx].st_name < strtabsize)
-			matchsym = (ElfW(Sym) *) &symtab[symndx];
-
-		      ++symndx;
-		    }
-		  while ((*hasharr++ & 1u) == 0);
+		  /* The hash table never references local symbols so
+		     we can omit that test here.  */
+		  if ((symtab[symndx].st_shndx != SHN_UNDEF
+		       || symtab[symndx].st_value != 0)
+		      && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
+		      && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
+					    matchsym, addr)
+		      && symtab[symndx].st_name < strtabsize)
+		    matchsym = (ElfW(Sym) *) &symtab[symndx];
+
+		  ++symndx;
 		}
+	      while ((*hasharr++ & 1u) == 0);
 	    }
 	}
+    }
+  else
+    {
+      const ElfW(Sym) *symtabend;
+      if (match->l_info[DT_HASH] != NULL)
+	symtabend = (symtab
+		     + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
       else
-	{
-	  const ElfW(Sym) *symtabend;
-	  if (match->l_info[DT_HASH] != NULL)
-	    symtabend = (symtab
-			 + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
-	  else
-	    /* There is no direct way to determine the number of symbols in the
-	       dynamic symbol table and no hash table is present.  The ELF
-	       binary is ill-formed but what shall we do?  Use the beginning of
-	       the string table which generally follows the symbol table.  */
-	    symtabend = (const ElfW(Sym) *) strtab;
-
-	  for (; (void *) symtab < (void *) symtabend; ++symtab)
-	    if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
-		 || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
-		&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
-		&& (symtab->st_shndx != SHN_UNDEF
-		    || symtab->st_value != 0)
-		&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
-		&& symtab->st_name < strtabsize)
-	      matchsym = (ElfW(Sym) *) symtab;
-	}
+	/* There is no direct way to determine the number of symbols in the
+	   dynamic symbol table and no hash table is present.  The ELF
+	   binary is ill-formed but what shall we do?  Use the beginning of
+	   the string table which generally follows the symbol table.  */
+	symtabend = (const ElfW(Sym) *) strtab;
+
+      for (; (void *) symtab < (void *) symtabend; ++symtab)
+	if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
+	     || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+	    && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
+	    && (symtab->st_shndx != SHN_UNDEF
+		|| symtab->st_value != 0)
+	    && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
+	    && symtab->st_name < strtabsize)
+	  matchsym = (ElfW(Sym) *) symtab;
+    }
 
-      if (mapp)
-	*mapp = match;
-      if (symbolp)
-	*symbolp = matchsym;
+  if (mapp)
+    *mapp = match;
+  if (symbolp)
+    *symbolp = matchsym;
 
-      if (matchsym)
-	{
-	  /* We found a symbol close by.  Fill in its name and exact
-	     address.  */
-	  lookup_t matchl = LOOKUP_VALUE (match);
+  if (matchsym)
+    {
+      /* We found a symbol close by.  Fill in its name and exact
+	 address.  */
+      lookup_t matchl = LOOKUP_VALUE (match);
 
-	  info->dli_sname = strtab + matchsym->st_name;
-	  info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
-	}
-      else
+      info->dli_sname = strtab + matchsym->st_name;
+      info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
+    }
+  else
+    {
+      /* No symbol matches.  We return only the containing object.  */
+      info->dli_sname = NULL;
+      info->dli_saddr = NULL;
+    }
+}
+
+
+int
+internal_function
+_dl_addr (const void *address, Dl_info *info,
+	  struct link_map **mapp, const ElfW(Sym) **symbolp)
+{
+  const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
+  int result = 0;
+
+  /* Protect against concurrent loads and unloads.  */
+  __rtld_lock_lock_recursive (GL(dl_load_lock));
+
+  /* Find the highest-addressed object that ADDRESS is not below.  */
+  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
+    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
+      if (addr >= l->l_map_start && addr < l->l_map_end)
 	{
-	  /* No symbol matches.  We return only the containing object.  */
-	  info->dli_sname = NULL;
-	  info->dli_saddr = NULL;
+	  /* Make sure it lies within one of L's segments.  */
+	  int n = l->l_phnum;
+	  const ElfW(Addr) reladdr = addr - l->l_addr;
+	  while (--n >= 0)
+	    if (l->l_phdr[n].p_type == PT_LOAD)
+	      {
+		if (reladdr - l->l_phdr[n].p_vaddr >= 0
+		    && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
+		  {
+		    determine_info (addr, l, info, mapp, symbolp);
+		    result = 1;
+		    goto out;
+		  }
+	      }
 	}
 
-      result = 1;
-    }
-
+ out:
   __rtld_lock_unlock_recursive (GL(dl_load_lock));
 
   return result;
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 981be49636..1fcd7aba45 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc7
-fedora-sync-date := 2007-05-04 09:17 UTC
-fedora-sync-tag := fedora-glibc-20070504T0917
+fedora-sync-date := 2007-05-10 06:34 UTC
+fedora-sync-tag := fedora-glibc-20070510T0634
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 4dfee568e5..4cb50465b1 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 22
+%define glibcrelease 23
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -1561,12 +1561,22 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Thu May 10 2007 Jakub Jelinek <jakub@redhat.com> 2.5.90-23
+- use madvise MADV_DONTNEED in malloc
+- fix ia64 feraiseexcept
+- fix s390{,x} feholdexcept (BZ#3427)
+- ppc fenv fixes
+- make fdatasync a cancellation point (BZ#4465)
+- fix *printf for huge precisions with wide char code and multi-byte
+  strings
+- fix dladdr (#232224, BZ#4131)
+
 * Fri May  4 2007 Jakub Jelinek <jakub@redhat.com> 2.5.90-22
-- add transliteration for <U2044> (BZ#3213)                                                                                    
-- fix *scanf with %f on hexadecimal floats without exponent (BZ#4342)                                                          
-- fix *printf with very large precisions for %s (#238406, BZ#4438)                                                             
-- fix inet_ntop size checking for AF_INET (BZ#4439)                                                                            
-- for *printf %e avoid 1.000e-00, for exponent 0 always use + sign (#238431)                                                   
+- add transliteration for <U2044> (BZ#3213)
+- fix *scanf with %f on hexadecimal floats without exponent (BZ#4342)
+- fix *printf with very large precisions for %s (#238406, BZ#4438)
+- fix inet_ntop size checking for AF_INET (BZ#4439)
+- for *printf %e avoid 1.000e-00, for exponent 0 always use + sign (#238431)
 - fix a regression introduced in #223467 changes
 - gethostby*_r alignment fixes (BZ#4381)
 - fix ifaddrs error handling
diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
index 6587f7305b..4b38fd283c 100644
--- a/locale/programs/linereader.c
+++ b/locale/programs/linereader.c
@@ -523,8 +523,8 @@ get_symname (struct linereader *lr)
     {
       lr->token.tok = tok_bsymbol;
 
-      buf[bufact] = '\0';
       buf = xrealloc (buf, bufact + 1);
+      buf[bufact] = '\0';
 
       lr->token.val.str.startmb = buf;
       lr->token.val.str.lenmb = bufact - 1;
@@ -576,8 +576,8 @@ get_ident (struct linereader *lr)
     {
       lr->token.tok = tok_ident;
 
-      buf[bufact] = '\0';
       buf = xrealloc (buf, bufact + 1);
+      buf[bufact] = '\0';
 
       lr->token.val.str.startmb = buf;
       lr->token.val.str.lenmb = bufact;
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 6b35c2b568..301eabaa04 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,16 @@
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* locales/as_IN: Fix currency_symbol, abday for Sunday, abmon for
+	January, February, and September to December, mon for January,
+	February, September, and December, am_pm, and name_*.
+	Patch by Amitakhya Phukan <aphukan@redhat.com>.
+
+2007-05-04  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4114]
+	* locales/ast_ES: New file.
+	* SUPPORTED (SUPPORTED-LOCALES): Add ast_ES.UTF-8 and ast_ES.
+
 2007-04-27  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #4024]
diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
index 62c34fe086..8fb561185e 100644
--- a/localedata/SUPPORTED
+++ b/localedata/SUPPORTED
@@ -48,6 +48,8 @@ ar_YE.UTF-8/UTF-8 \
 ar_YE/ISO-8859-6 \
 az_AZ.UTF-8/UTF-8 \
 as_IN.UTF-8/UTF-8 \
+ast_ES.UTF-8/UTF-8 \
+ast_ES/ISO-8859-15 \
 be_BY.UTF-8/UTF-8 \
 be_BY/CP1251 \
 be_BY@latin/UTF-8 \
diff --git a/localedata/locales/as_IN b/localedata/locales/as_IN
index 2ab76f8477..d3c779b7a6 100644
--- a/localedata/locales/as_IN
+++ b/localedata/locales/as_IN
@@ -610,7 +610,7 @@ END LC_NUMERIC
 %%%%%%%%%%%%%
 LC_MONETARY
 int_curr_symbol       "<U0049><U004E><U0052><U0020>"
-currency_symbol       "<U0052><U0073><U002E>"
+currency_symbol       "<U099F><U0995><U09BE>"
 mon_decimal_point     "<U002E>"
 mon_thousands_sep     "<U002C>"
 mon_grouping          3;2
@@ -634,7 +634,7 @@ END LC_MONETARY
 
 %%%%%%%%%%%%%
 LC_TIME
-abday   "<U09F0><U09AC><U09BF>";/
+abday   "<U09A6><U09C7><U0993>";/
         "<U09B8><U09CB><U09AE>";/
         "<U09AE><U0999><U09CD><U0997><U09B2>";/
         "<U09AC><U09C1><U09A7>";/
@@ -648,37 +648,37 @@ day     "<U09A6><U09C7><U0993><U09AC><U09BE><U09F0>";/
         "<U09AC><U09C3><U09B9><U09B7><U09CD><U09AA><U09A4><U09BF><U09AC><U09BE><U09F0>";/
         "<U09B6><U09C1><U0995><U09CD><U09F0><U09AC><U09BE><U09F0>";/
         "<U09B6><U09A8><U09BF><U09AC><U09BE><U09F0>"
-abmon   "<U099C><U09BE><U09A8><U09C1>";/
-        "<U09AB><U09C7><U09AC><U09CD><U09F0><U09C1>";/
+abmon   "<U099C><U09BE><U09A8><U09C1><U09F1><U09BE><U09F0><U09C0>";/
+        "<U09AB><U09C7><U09AC><U09CD><U09F0><U09C1><U09F1><U09BE><U09F0><U09C0>";/
         "<U09AE><U09BE><U09F0><U09CD><U099A>";/
         "<U098F><U09AA><U09CD><U09F0><U09BF><U09B2>";/
         "<U09AE><U09C7>";/
         "<U099C><U09C1><U09A8>";/
         "<U099C><U09C1><U09B2><U09BE><U0987>";/
         "<U0986><U0997>";/
-        "<U09B8><U09C7><U09AA><U09CD><U099F>";/
-        "<U0985><U0995><U09CD><U099F><U09CB>";/
-        "<U09A8><U09AD><U09C7>";/
-        "<U09A1><U09BF><U09B8><U09C7>"
-mon     "<U099C><U09BE><U09A8><U09C1><U09DF><U09BE><U09F0><U09C0>";/
-        "<U09AB><U09C7><U09AC><U09CD><U09F0><U09C1><U09DF><U09BE><U09F0><U09C0>";/
+        "<U099A><U09C7><U09AA><U09CD><U09A4><U09C7><U09AE><U09CD><U09AC><U09F0>";/
+        "<U0985><U0995><U09CD><U099F><U09CB><U09AC><U09F0>";/
+        "<U09A8><U09AD><U09C7><U09AE><U09CD><U09AC><U09F0>";/
+        "<U09A1><U09BF><U099A><U09C7><U09AE><U09CD><U09AC><U09F0>"
+mon     "<U099C><U09BE><U09A8><U09C1><U09F1><U09BE><U09F0><U09C0>";/
+        "<U09AB><U09C7><U09AC><U09CD><U09F0><U09C1><U09F1><U09BE><U09F0><U09C0>";/
         "<U09AE><U09BE><U09F0><U09CD><U099A>";/
         "<U098F><U09AA><U09CD><U09F0><U09BF><U09B2>";/
         "<U09AE><U09C7>";/
         "<U099C><U09C1><U09A8>";/
         "<U099C><U09C1><U09B2><U09BE><U0987>";/
         "<U0986><U0997><U09B7><U09CD><U099F>";/
-        "<U09B8><U09C7><U09AA><U09CD><U099F><U09C7><U09AE><U09CD><U09AC><U09F0>";/
+        "<U099A><U09C7><U09AA><U09CD><U09A4><U09C7><U09AE><U09CD><U09AC><U09F0>";/
         "<U0985><U0995><U09CD><U099F><U09CB><U09AC><U09F0>";/
         "<U09A8><U09AD><U09C7><U09AE><U09CD><U09AC><U09F0>";/
-        "<U09A1><U09BF><U09B8><U09C7><U09AE><U09CD><U09AC><U09F0>"
+        "<U09A1><U09BF><U099A><U09C7><U09AE><U09CD><U09AC><U09F0>"
 % d_fmt  "%e-%m-%Y"
 d_fmt    "<U0025><U0065><U002D><U0025><U006D><U002D><U0025><U0059>"
 % t_fmt  "%I.%M.%S %p"
 t_fmt    "<U0025><U0049><U002E><U0025><U004D><U002E><U0025><U0053><U0020><U0025><U0070>"
 % d_t_fmt"%e %B, %Y %I.%M.%S %p %Z"
 d_t_fmt  "<U0025><U0065><U0020><U0025><U0042><U002C><U0020><U0025><U0059><U0020><U0025><U0049><U002E><U0025><U004D><U002E><U0025><U0053><U0020><U0025><U0070><U0020><U0025><U005A>"
-am_pm    "<U09AA><U09C2><U09F0><U09CD><U09AC><U09BE>";"<U0985><U09AA>"
+am_pm    "<U09AA><U09C2><U09F0><U09CD><U09AC><U09CD><U09AC><U09BE><U09B9><U09CD><U09A8>";"<U0985><U09AA><U09F0><U09BE><U09B9><U09CD><U09A8>"  
 % t_fmt_ampm  "%I.%M.%S %p"
 t_fmt_ampm  "<U0025><U0049><U002E><U0025><U004D><U002E><U0025><U0053><U0020><U0025><U0070>"
 END LC_TIME
@@ -704,10 +704,10 @@ LC_NAME
 name_fmt    "<U0025><U0070><U0025><U0074><U0025><U0066><U0025><U0074>/
 <U0025><U0067>"
 name_gen    ""
-name_mr     "<U004D><U0072><U002E>"
-name_mrs    "<U004D><U0072><U0073><U002E>"
-name_miss   "<U004D><U0069><U0073><U0073><U002E>"
-name_ms     "<U004D><U0073><U002E>"
+name_mr     "<U09B6><U09CD><U09F0><U09C0>"
+name_mrs    "<U09B6><U09CD><U09F0><U09C0><U09AE><U09A4><U09C0>"
+name_miss   "<U0995><U09C1><U09AE><U09BE><U09F0><U09C0>"
+name_ms     "<U0995><U09C1><U09AE><U09BE><U09F0><U09C0>"
 END LC_NAME
 
 %%%%%%%%%%%%%
diff --git a/localedata/locales/ast_ES b/localedata/locales/ast_ES
new file mode 100644
index 0000000000..249571cd3e
--- /dev/null
+++ b/localedata/locales/ast_ES
@@ -0,0 +1,132 @@
+comment_char %
+escape_char  /
+%
+% Asturian Language Locale for Spain
+% Source:
+% Address:
+% Contact: Jordi Mallach
+% Email: jordi@gnu.org
+% Language: ast
+% Territory: ES
+% Revision: 1.0
+% Date: 2005-08-26
+% Application: general
+% Users: general
+%
+% This file is under the
+% GNU General Public License.
+% Based in the an_ES Locale
+
+LC_IDENTIFICATION
+title      "Asturian locale for Spain"
+source     ""
+address    ""
+contact    "Jordi Mallach"
+email      "jordi@gnu.org"
+tel        ""
+fax        ""
+language   "Asturian"
+territory  "Spain"
+revision   "1.0"
+date       "2005-08-26"
+%
+category  "ast_ES:2000";LC_IDENTIFICATION
+category  "ast_ES:2000";LC_CTYPE
+category  "ast_ES:2000";LC_COLLATE
+category  "ast_ES:2000";LC_TIME
+category  "ast_ES:2000";LC_NUMERIC
+category  "ast_ES:2000";LC_MONETARY
+category  "ast_ES:2000";LC_MESSAGES
+category  "ast_ES:2000";LC_PAPER
+category  "ast_ES:2000";LC_NAME
+category  "ast_ES:2000";LC_ADDRESS
+category  "ast_ES:2000";LC_TELEPHONE
+END LC_IDENTIFICATION
+
+LC_COLLATE
+copy "es_ES"
+END LC_COLLATE
+
+LC_CTYPE
+copy "es_ES"
+END LC_CTYPE
+
+LC_MESSAGES
+yesexpr "<U005E><U005B><U0073><U0053><U0079><U0059><U005D><U002E><U002A>"
+noexpr  "<U005E><U005B><U006E><U004E><U005D><U002E><U002A>"
+END LC_MESSAGES
+
+LC_MONETARY
+copy "es_ES"
+END LC_MONETARY
+
+LC_NUMERIC
+copy "es_ES"
+END LC_NUMERIC
+
+LC_TIME
+% Days of week in Asturian
+% llunes, martes, miércoles, xueves, vienres, sábadu, domingu
+% llu, mar, mié, xue, vie, sáb, dom
+abday   "<U0064><U006F><U006D>";"<U006C><U006C><U0075>";/
+        "<U006D><U0061><U0072>";"<U006D><U0069><U00E9>";/
+        "<U0078><U0075><U0065>";"<U0076><U0069><U0065>";/
+        "<U0073><U00E1><U0062>"
+day     "<U0064><U006F><U006D><U0069><U006E><U0067><U0075>";/
+        "<U006C><U006C><U0075><U006E><U0065><U0073>";/
+        "<U006D><U0061><U0072><U0074><U0065><U0073>";/
+        "<U006D><U0069><U00E9><U0072><U0063><U006F><U006C><U0065><U0073>";/
+        "<U0078><U0075><U0065><U0076><U0065><U0073>";/
+        "<U0076><U0069><U0065><U006E><U0072><U0065><U0073>";/
+        "<U0073><U00E1><U0062><U0061><U0064><U0075>"
+% Month names in Asturian
+% xineru, febreru, marzu, abril, mayu, xunu, xunetu, agostu, setiembre,
+% ochobre, payares, avientu
+% Abbreviated form of xunetu is "xnt"
+abmon   "<U0078><U0069><U006E>";"<U0066><U0065><U0062>";/
+        "<U006D><U0061><U0072>";"<U0061><U0062><U0072>";/
+        "<U006D><U0061><U0079>";"<U0078><U0075><U006E>";/
+        "<U0078><U006E><U0074>";"<U0061><U0067><U006F>";/
+        "<U0073><U0065><U0074>";"<U006F><U0063><U0068>";/
+        "<U0070><U0061><U0079>";"<U0061><U0076><U0069>"
+mon     "<U0078><U0069><U006E><U0065><U0072><U0075>";/
+        "<U0066><U0065><U0062><U0072><U0065><U0072><U0075>";/
+        "<U006D><U0061><U0072><U007A><U0075>";/
+        "<U0061><U0062><U0072><U0069><U006C>";/
+        "<U006D><U0061><U0079><U0075>";/
+        "<U0078><U0075><U006E><U0075>";/
+        "<U0078><U0075><U006E><U0065><U0074><U0075>";/
+        "<U0061><U0067><U006F><U0073><U0074><U0075>";/
+        "<U0073><U0065><U0074><U0069><U0065><U006D><U0062><U0072><U0065>";/
+        "<U006F><U0063><U0068><U006F><U0062><U0072><U0065>";/
+        "<U0070><U0061><U0079><U0061><U0072><U0065><U0073>";/
+        "<U0061><U0076><U0069><U0065><U006E><U0074><U0075>"
+d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
+d_fmt   "<U0025><U0064><U002F><U0025><U006D><U002F><U0025><U0079>"
+t_fmt   "<U0025><U0054>"
+am_pm   "";""
+t_fmt_ampm ""
+date_fmt       "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
+<U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U005A><U0020><U0025><U0059>"
+END LC_TIME
+
+LC_PAPER
+copy "es_ES"
+END LC_PAPER
+
+LC_TELEPHONE
+copy "es_ES"
+END LC_TELEPHONE
+
+LC_MEASUREMENT
+copy "es_ES"
+END LC_MEASUREMENT
+
+LC_NAME
+copy "es_ES"
+END LC_NAME
+
+LC_ADDRESS
+copy "es_ES"
+END LC_ADDRESS
diff --git a/malloc/Makefile b/malloc/Makefile
index c39eae5474..c251bcfb9d 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -104,6 +104,7 @@ $(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
 include ../Rules
 
 CFLAGS-mcheck-init.c = $(PIC-ccflag)
+CFLAGS-malloc.c += -DMALLOC_DEBUG
 
 $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
 	-rm -f $@
diff --git a/malloc/arena.c b/malloc/arena.c
index 1d9f952112..ce64335567 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -1,5 +1,6 @@
 /* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 2001,2002,2003,2004,2005,2006,2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
 
@@ -59,10 +60,12 @@ typedef struct _heap_info {
   mstate ar_ptr; /* Arena for this heap. */
   struct _heap_info *prev; /* Previous heap. */
   size_t size;   /* Current size in bytes. */
+  size_t mprotect_size;	/* Size in bytes that has been mprotected
+			   PROT_READ|PROT_WRITE.  */
   /* Make sure the following data is properly aligned, particularly
      that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
-     MALLOG_ALIGNMENT. */
-  char pad[-5 * SIZE_SZ & MALLOC_ALIGN_MASK];
+     MALLOC_ALIGNMENT. */
+  char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK];
 } heap_info;
 
 /* Get a compile-time error if the heap_info padding is not correct
@@ -692,6 +695,7 @@ new_heap(size, top_pad) size_t size, top_pad;
   }
   h = (heap_info *)p2;
   h->size = size;
+  h->mprotect_size = size;
   THREAD_STAT(stat_n_heaps++);
   return h;
 }
@@ -714,17 +718,34 @@ grow_heap(h, diff) heap_info *h; long diff;
     new_size = (long)h->size + diff;
     if((unsigned long) new_size > (unsigned long) HEAP_MAX_SIZE)
       return -1;
-    if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0)
-      return -2;
+    if((unsigned long) new_size > h->mprotect_size) {
+      if (mprotect((char *)h + h->mprotect_size,
+		   (unsigned long) new_size - h->mprotect_size,
+		   PROT_READ|PROT_WRITE) != 0)
+	return -2;
+      h->mprotect_size = new_size;
+    }
   } else {
     new_size = (long)h->size + diff;
     if(new_size < (long)sizeof(*h))
       return -1;
     /* Try to re-map the extra heap space freshly to save memory, and
        make it inaccessible. */
-    if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE,
-                    MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
-      return -2;
+#ifdef _LIBC
+    if (__builtin_expect (__libc_enable_secure, 0))
+#else
+    if (1)
+#endif
+      {
+	if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE,
+			MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
+	  return -2;
+	h->mprotect_size = new_size;
+      }
+#ifdef _LIBC
+    else
+      madvise ((char *)h + new_size, -diff, MADV_DONTNEED);
+#endif
     /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
   }
   h->size = new_size;
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 4976ba8741..6cbb87adeb 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,26 @@
+2007-05-02  Carlos O'Donell  <carlos@systemhalted.org>
+
+	[BZ #4455]
+	* tst-align2.c (do_test): Add _STACK_GROWS_UP case.
+	* tst-getpid1.c (do_test): Likewise.
+
+	[BZ #4456]
+	* allocatestack.c (change_stack_perm): Add _STACK_GROWS_UP case.
+	(allocate_stack): Likewise.
+
+2007-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+	(__lll_robust_lock_wait): Fix race caused by reloading of futex value.
+	(__lll_robust_timedlock_wait): Likewise.
+	Reported by Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>.
+
+2007-05-06  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #4465]
+	* tst-cancel-wrappers.sh: Set C["fdatasync"] to 1.
+	* tst-cancel4.c (tf_fdatasync): New test.
+
 2007-04-27  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #4392]
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index c05cd47dff..6b60642042 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -288,9 +288,14 @@ change_stack_perm (struct pthread *pd
 		 + (((((pd->stackblock_size - pd->guardsize) / 2)
 		      & pagemask) + pd->guardsize) & pagemask));
   size_t len = pd->stackblock + pd->stackblock_size - stack;
-#else
+#elif _STACK_GROWS_DOWN
   void *stack = pd->stackblock + pd->guardsize;
   size_t len = pd->stackblock_size - pd->guardsize;
+#elif _STACK_GROWS_UP
+  void *stack = pd->stackblock;
+  size_t len = (uintptr_t) pd - pd->guardsize - (uintptr_t) pd->stackblock;
+#else
+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
 #endif
   if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
     return errno;
@@ -570,8 +575,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	{
 #ifdef NEED_SEPARATE_REGISTER_STACK
 	  char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
-#else
+#elif _STACK_GROWS_DOWN
 	  char *guard = mem;
+# elif _STACK_GROWS_UP
+	  char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1);
 #endif
 	  if (mprotect (guard, guardsize, PROT_NONE) != 0)
 	    {
@@ -618,10 +625,14 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 			oldguard + pd->guardsize - guard - guardsize,
 			prot) != 0)
 	    goto mprot_error;
-#else
+#elif _STACK_GROWS_DOWN
 	  if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize,
 			prot) != 0)
 	    goto mprot_error;
+#elif _STACK_GROWS_UP
+	  if (mprotect ((char *) pd - pd->guardsize,
+			pd->guardsize - guardsize, prot) != 0)
+	    goto mprot_error;
 #endif
 
 	  pd->guardsize = guardsize;
@@ -661,8 +672,11 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 #ifdef NEED_SEPARATE_REGISTER_STACK
   *stack = pd->stackblock;
   *stacksize = stacktop - *stack;
-#else
+#elif _STACK_GROWS_DOWN
   *stack = stacktop;
+#elif _STACK_GROWS_UP
+  *stack = pd->stackblock;
+  assert (*stack > 0);
 #endif
 
   return 0;
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 3e88ee1866..30ef991bd0 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
 
@@ -30,6 +30,10 @@ __lll_robust_lock_wait (int *futex)
   int oldval = *futex;
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
 
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
+
   do
     {
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
@@ -41,6 +45,9 @@ __lll_robust_lock_wait (int *futex)
 	continue;
 
       lll_futex_wait (futex, newval);
+
+    try:
+      ;
     }
   while ((oldval = atomic_compare_and_exchange_val_acq (futex,
 							tid | FUTEX_WAITERS,
@@ -57,6 +64,11 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
     return EINVAL;
 
   int tid = THREAD_GETMEM (THREAD_SELF, tid);
+  int oldval = *futex;
+
+  /* If the futex changed meanwhile try locking again.  */
+  if (oldval == 0)
+    goto try;
 
   do
     {
@@ -80,7 +92,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	return ETIMEDOUT;
 
       /* Wait.  */
-      int oldval = *futex;
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
 	return oldval;
 
@@ -90,8 +101,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime)
 	continue;
 
       lll_futex_timed_wait (futex, newval, &rt);
+
+    try:
+      ;
     }
-  while (atomic_compare_and_exchange_bool_acq (futex, tid | FUTEX_WAITERS, 0));
+  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
+							tid | FUTEX_WAITERS,
+							0)) != 0);
 
   return 0;
 }
diff --git a/nptl/tst-align2.c b/nptl/tst-align2.c
index ec85f435b6..4685c201e4 100644
--- a/nptl/tst-align2.c
+++ b/nptl/tst-align2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2004, 2007 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
@@ -53,8 +53,14 @@ do_test (void)
   char st[256 * 1024];
   pid_t p = __clone2 (f, st, sizeof (st), 0, 0);
 #else
-  char st[128 * 1024];
+  char st[128 * 1024] __attribute__ ((aligned));
+# if _STACK_GROWS_DOWN
   pid_t p = clone (f, st + sizeof (st), 0, 0);
+# elif _STACK_GROWS_UP
+  pid_t p = clone (f, st, 0, 0);
+# else
+#  error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+# endif
 #endif
   if (p == -1)
     {
diff --git a/nptl/tst-cancel-wrappers.sh b/nptl/tst-cancel-wrappers.sh
index d6f16d1ed2..61b9fb52de 100644
--- a/nptl/tst-cancel-wrappers.sh
+++ b/nptl/tst-cancel-wrappers.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Test whether all cancelable functions are cancelable.
-# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -26,6 +26,7 @@ C["close"]=1
 C["connect"]=1
 C["creat"]=1
 C["fcntl"]=1
+C["fdatasync"]=1
 C["fsync"]=1
 C["msgrcv"]=1
 C["msgsnd"]=1
diff --git a/nptl/tst-cancel4.c b/nptl/tst-cancel4.c
index 73cfa44614..45df6ce076 100644
--- a/nptl/tst-cancel4.c
+++ b/nptl/tst-cancel4.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -1571,6 +1571,47 @@ tf_fsync (void *arg)
 
 
 static void *
+tf_fdatasync (void *arg)
+{
+  if (arg == NULL)
+    // XXX If somebody can provide a portable test case in which fdatasync()
+    // blocks we can enable this test to run in both rounds.
+    abort ();
+
+  tempfd = open ("Makefile", O_RDONLY);
+  if (tempfd == -1)
+    {
+      printf ("%s: cannot open Makefile\n", __FUNCTION__);
+      exit (1);
+    }
+
+  int r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  r = pthread_barrier_wait (&b2);
+  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
+      exit (1);
+    }
+
+  pthread_cleanup_push (cl, NULL);
+
+  fdatasync (tempfd);
+
+  pthread_cleanup_pop (0);
+
+  printf ("%s: fdatasync returned\n", __FUNCTION__);
+
+  exit (1);
+}
+
+
+static void *
 tf_msync (void *arg)
 {
   if (arg == NULL)
@@ -2078,6 +2119,7 @@ static struct
   ADD_TEST (pread, 2, 1),
   ADD_TEST (pwrite, 2, 1),
   ADD_TEST (fsync, 2, 1),
+  ADD_TEST (fdatasync, 2, 1),
   ADD_TEST (msync, 2, 1),
   ADD_TEST (sendto, 2, 1),
   ADD_TEST (sendmsg, 2, 1),
diff --git a/nptl/tst-getpid1.c b/nptl/tst-getpid1.c
index f9fd4fc0ca..e15cb61151 100644
--- a/nptl/tst-getpid1.c
+++ b/nptl/tst-getpid1.c
@@ -48,7 +48,13 @@ do_test (void)
   pid_t p = __clone2 (f, st, sizeof (st), TEST_CLONE_FLAGS, 0);
 #else
   char st[128 * 1024] __attribute__ ((aligned));
+# if _STACK_GROWS_DOWN
   pid_t p = clone (f, st + sizeof (st), TEST_CLONE_FLAGS, 0);
+# elif _STACK_GROWS_UP
+  pid_t p = clone (f, st, TEST_CLONE_FLAGS, 0);
+# else
+#  error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
+# endif
 #endif
   if (p == -1)
     {
diff --git a/posix/unistd.h b/posix/unistd.h
index 577925c0fa..a86968a8db 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -1062,7 +1062,7 @@ extern int lockf64 (int __fd, int __cmd, __off64_t __len) __wur;
 #if defined __USE_POSIX199309 || defined __USE_UNIX98
 /* Synchronize at least the data part of a file with the underlying
    media.  */
-extern int fdatasync (int __fildes) __THROW;
+extern int fdatasync (int __fildes);
 #endif /* Use POSIX199309 */
 
 
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 4f0d971c55..20638ad1fd 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1026,10 +1026,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    const char *mbs = (const char *) string;			      \
 	    mbstate_t mbstate;						      \
 									      \
-	    len = prec != -1 ? (size_t) prec : strlen (mbs);		      \
+	    len = prec != -1 ? __strnlen (mbs, (size_t) prec) : strlen (mbs); \
 									      \
 	    /* Allocate dynamically an array which definitely is long	      \
-	       enough for the wide character version.  */		      \
+	       enough for the wide character version.  Each byte in the	      \
+	       multi-byte string can produce at most one wide character.  */  \
 	    if (__libc_use_alloca (len * sizeof (wchar_t)))		      \
 	      string = (CHAR_T *) alloca (len * sizeof (wchar_t));	      \
 	    else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t)))    \
diff --git a/string/strfry.c b/string/strfry.c
index 112dd4adb3..a8b202d176 100644
--- a/string/strfry.c
+++ b/string/strfry.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996, 1999, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1996, 1999, 2002, 2007 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
@@ -37,16 +37,14 @@ strfry (char *string)
       init = 1;
     }
 
-  len = strlen (string);
+  len = strlen (string) - 1;
   for (i = 0; i < len; ++i)
     {
       int32_t j;
-      char c;
-
       __random_r (&rdata, &j);
-      j %= len;
+      j = j % len + 1;
 
-      c = string[i];
+      char c = string[i];
       string[i] = string[j];
       string[j] = c;
     }
diff --git a/sysdeps/alpha/fpu/bits/mathinline.h b/sysdeps/alpha/fpu/bits/mathinline.h
index a126dcf056..250171eeb4 100644
--- a/sysdeps/alpha/fpu/bits/mathinline.h
+++ b/sysdeps/alpha/fpu/bits/mathinline.h
@@ -137,11 +137,14 @@ __NTH (__isnan (double __x))
   return isunordered (__x, __x);
 }
 
+#ifndef __NO_LONG_DOUBLE_MATH
 __MATH_INLINE int
 __NTH (__isnanl (long double __x))
 {
   return isunordered (__x, __x);
 }
+#endif
+
 #endif /* C99 */
 
 #endif /* __NO_MATH_INLINES */
diff --git a/sysdeps/alpha/fpu/s_fmax.S b/sysdeps/alpha/fpu/s_fmax.S
index 4f2ace7d11..d638eec805 100644
--- a/sysdeps/alpha/fpu/s_fmax.S
+++ b/sysdeps/alpha/fpu/s_fmax.S
@@ -53,6 +53,6 @@ weak_alias (__fmax, fmax)
 strong_alias (__fmax, __fmaxl)
 weak_alias (__fmaxl, fmaxl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __fmax, fmaxl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_fmin.S b/sysdeps/alpha/fpu/s_fmin.S
index 10de52940e..d70fab625a 100644
--- a/sysdeps/alpha/fpu/s_fmin.S
+++ b/sysdeps/alpha/fpu/s_fmin.S
@@ -53,6 +53,6 @@ weak_alias (__fmin, fmin)
 strong_alias (__fmin, __fminl)
 weak_alias (__fminl, fminl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __fmin, fminl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmin, fminl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_isnan.c b/sysdeps/alpha/fpu/s_isnan.c
index 4403a50bb0..a9230329c5 100644
--- a/sysdeps/alpha/fpu/s_isnan.c
+++ b/sysdeps/alpha/fpu/s_isnan.c
@@ -53,6 +53,7 @@ weak_alias (__isnanf, isnanf)
 strong_alias (__isnan, __isnanl)
 weak_alias (__isnan, isnanl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __isnan, isnanl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
 #endif
diff --git a/sysdeps/alpha/fpu/s_lrint.c b/sysdeps/alpha/fpu/s_lrint.c
index 4c32f61093..1696408705 100644
--- a/sysdeps/alpha/fpu/s_lrint.c
+++ b/sysdeps/alpha/fpu/s_lrint.c
@@ -42,7 +42,7 @@ strong_alias (__lrint, __llrintl)
 weak_alias (__lrintl, lrintl)
 weak_alias (__llrintl, llrintl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __lrint, lrintl, GLIBC_2_0);
-compat_symbol (libm, __llrint, llrintl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1);
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_lround.c b/sysdeps/alpha/fpu/s_lround.c
index bc5cb88ed2..0e0e98806c 100644
--- a/sysdeps/alpha/fpu/s_lround.c
+++ b/sysdeps/alpha/fpu/s_lround.c
@@ -42,7 +42,7 @@ strong_alias (__lround, __llroundl)
 weak_alias (__lroundl, lroundl)
 weak_alias (__llroundl, llroundl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __lround, lroundl, GLIBC_2_0);
-compat_symbol (libm, __llround, llroundl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1);
+compat_symbol (libm, __llround, llroundl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_nearbyint.c b/sysdeps/alpha/fpu/s_nearbyint.c
index 7a91bd115b..b18db8ba79 100644
--- a/sysdeps/alpha/fpu/s_nearbyint.c
+++ b/sysdeps/alpha/fpu/s_nearbyint.c
@@ -43,6 +43,6 @@ weak_alias (__nearbyint, nearbyint)
 strong_alias (__nearbyint, __nearbyintl)
 weak_alias (__nearbyint, nearbyintl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_round.c b/sysdeps/alpha/fpu/s_round.c
index 3999e6110a..71763cf4ab 100644
--- a/sysdeps/alpha/fpu/s_round.c
+++ b/sysdeps/alpha/fpu/s_round.c
@@ -44,6 +44,6 @@ weak_alias (__round, round)
 strong_alias (__round, __roundl)
 weak_alias (__roundl, roundl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __round, roundl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __round, roundl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/alpha/fpu/s_trunc.c b/sysdeps/alpha/fpu/s_trunc.c
index 1c1a66673f..11a279a53f 100644
--- a/sysdeps/alpha/fpu/s_trunc.c
+++ b/sysdeps/alpha/fpu/s_trunc.c
@@ -48,6 +48,6 @@ weak_alias (__trunc, trunc)
 strong_alias (__trunc, __truncl)
 weak_alias (__trunc, truncl)
 #endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __trunc, truncl, GLIBC_2_0);
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __trunc, truncl, GLIBC_2_1);
 #endif
diff --git a/sysdeps/ia64/fpu/fraiseexcpt.c b/sysdeps/ia64/fpu/fraiseexcpt.c
index 3086ded812..12b29ee5a6 100644
--- a/sysdeps/ia64/fpu/fraiseexcpt.c
+++ b/sysdeps/ia64/fpu/fraiseexcpt.c
@@ -1,5 +1,6 @@
 /* Raise given exceptions.
-   Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2001, 2002, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jes Sorensen <Jes.Sorensen@cern.ch>, 2000.
 
@@ -70,7 +71,7 @@ feraiseexcept (int excepts)
   if (FE_INEXACT & excepts)
     {
       dummy = DBL_MAX;
-      __asm__ __volatile__ ("fadd.d.s0 %0=%1,f1" : "=f" (dummy) : "0" (dummy));
+      __asm__ __volatile__ ("fsub.d.s0 %0=%1,f1" : "=f" (dummy) : "0" (dummy));
     }
 
   /* Success.  */
diff --git a/sysdeps/powerpc/bits/fenv.h b/sysdeps/powerpc/bits/fenv.h
index 8509b4b0c3..10582a6ff6 100644
--- a/sysdeps/powerpc/bits/fenv.h
+++ b/sysdeps/powerpc/bits/fenv.h
@@ -137,9 +137,19 @@ extern const fenv_t __fe_nonieee_env;
 # define FE_NONIEEE_ENV	(&__fe_nonieee_env)
 
 /* Floating-point environment with all exceptions enabled.  Note that
-   just evaluating this value will set the processor into 'FPU
-   exceptions imprecise recoverable' mode, which may cause a significant
-   performance penalty (but have no other visible effect).  */
+   just evaluating this value does not change the processor exception mode.
+   Passing this mask to fesetenv will result in a prctl syscall to change
+   the MSR FE0/FE1 bits to "Precise Mode".  On some processors this will
+   result in slower floating point execution.  This will last until an
+   fenv or exception mask is installed that disables all FP exceptions.  */
 extern const fenv_t *__fe_nomask_env (void);
-# define FE_NOMASK_ENV	(__fe_nomask_env ())
+# define FE_NOMASK_ENV	FE_ENABLED_ENV
+
+/* Floating-point environment with all exceptions disabled.  Note that
+   just evaluating this value does not change the processor exception mode.
+   Passing this mask to fesetenv will result in a prctl syscall to change
+   the MSR FE0/FE1 bits to "Ignore Exceptions Mode".  On most processors
+   this allows the fastest possible floating point execution.*/
+extern const fenv_t *__fe_mask_env (void);
+# define FE_MASK_ENV	FE_DFL_ENV
 #endif
diff --git a/sysdeps/powerpc/fpu/Makefile b/sysdeps/powerpc/fpu/Makefile
index d0fe4a8ba1..060c952d15 100644
--- a/sysdeps/powerpc/fpu/Makefile
+++ b/sysdeps/powerpc/fpu/Makefile
@@ -1,5 +1,5 @@
 ifeq ($(subdir),math)
-libm-support += fenv_const fe_nomask t_sqrt
+libm-support += fenv_const fe_nomask fe_mask t_sqrt
 
 # libm needs ld.so to access dl_hwcap
 $(objpfx)libm.so: $(elfobjdir)/ld.so
diff --git a/sysdeps/powerpc/fpu/fe_mask.c b/sysdeps/powerpc/fpu/fe_mask.c
new file mode 100644
index 0000000000..d7ee5551ff
--- /dev/null
+++ b/sysdeps/powerpc/fpu/fe_mask.c
@@ -0,0 +1,33 @@
+/* Procedure definition for FE_MASK_ENV.
+   Copyright (C) 2007 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+
+/* This is a generic stub. An OS specific override is required to clear
+   the FE0/FE1 bits in the MSR.  MSR update is privileged, so this will
+   normally involve a syscall.  */
+
+const fenv_t *
+__fe_mask_env(void)
+{
+  __set_errno (ENOSYS);
+  return FE_DFL_ENV;
+}
+stub_warning (__fe_mask_env)
diff --git a/sysdeps/powerpc/fpu/fe_nomask.c b/sysdeps/powerpc/fpu/fe_nomask.c
index ba45d85709..3cccee1d06 100644
--- a/sysdeps/powerpc/fpu/fe_nomask.c
+++ b/sysdeps/powerpc/fpu/fe_nomask.c
@@ -20,8 +20,9 @@
 #include <fenv.h>
 #include <errno.h>
 
-/* This is presently a stub, until it's decided how the kernels should
-   support this.  */
+/* This is a generic stub. An OS specific override is required to set
+   the FE0/FE1 bits in the MSR.  MSR update is privileged, so this will
+   normally involve a syscall.  */
 
 const fenv_t *
 __fe_nomask_env(void)
diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c
index 633a6e6e36..3002b1b4cc 100644
--- a/sysdeps/powerpc/fpu/fedisblxcpt.c
+++ b/sysdeps/powerpc/fpu/fedisblxcpt.c
@@ -24,7 +24,7 @@ int
 fedisableexcept (int excepts)
 {
   fenv_union_t fe;
-  int result;
+  int result, new;
 
   result = fegetexcept ();
 
@@ -44,7 +44,11 @@ fedisableexcept (int excepts)
     fe.l[1] &= ~(1 << (31 - FPSCR_VE));
   fesetenv_register (fe.fenv);
 
-  if ((fegetexcept () & excepts) != 0)
+  new = fegetexcept ();
+  if (new == 0 && result != 0)
+    (void)__fe_mask_env ();
+
+  if ((new & excepts) != 0)
     result = -1;
   return result;
 }
diff --git a/sysdeps/powerpc/fpu/feholdexcpt.c b/sysdeps/powerpc/fpu/feholdexcpt.c
index 150becd678..c9432248db 100644
--- a/sysdeps/powerpc/fpu/feholdexcpt.c
+++ b/sysdeps/powerpc/fpu/feholdexcpt.c
@@ -22,17 +22,24 @@
 int
 feholdexcept (fenv_t *envp)
 {
-  fenv_union_t u;
+  fenv_union_t old, new;
 
-  /* Get the current state.  */
-  u.fenv = *envp = fegetenv_register ();
+  /* Save the currently set exceptions.  */
+  old.fenv = *envp = fegetenv_register ();
 
-  /* Clear everything except for the rounding mode and non-IEEE arithmetic
+  /* Clear everything except for the rounding modes and non-IEEE arithmetic
      flag.  */
-  u.l[1] = u.l[1] & 7;
+  new.l[1] = old.l[1] & 7;
+  new.l[0] = old.l[0];
+  
+  /* If the old env had any eabled exceptions, then mask SIGFPE in the
+     MSR FE0/FE1 bits.  This may allow the FPU to run faster because it
+     always takes the default action and can not generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0)
+    (void)__fe_mask_env ();
 
   /* Put the new state in effect.  */
-  fesetenv_register (u.fenv);
+  fesetenv_register (new.fenv);
 
   return 0;
 }
diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c
index ff82dfd176..5a0c742ffe 100644
--- a/sysdeps/powerpc/fpu/fesetenv.c
+++ b/sysdeps/powerpc/fpu/fesetenv.c
@@ -1,5 +1,5 @@
 /* Install given floating-point environment.
-   Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,02,07 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
@@ -23,6 +23,26 @@
 int
 __fesetenv (const fenv_t *envp)
 {
+  fenv_union_t old, new;
+
+  /* get the currently set exceptions.  */
+  new.fenv = *envp;
+  old.fenv = fegetenv_register ();
+  
+  /* If the old env has no eabled exceptions and the new env has any enabled
+     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+     the hardware into "precise mode" and may cause the FPU to run slower on
+     some hardware.  */
+  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
+    (void)__fe_nomask_env ();
+  
+  /* If the old env had any eabled exceptions and the new env has no enabled
+     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+     FPU to run faster because it always takes the default action and can not 
+     generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
+    (void)__fe_mask_env ();
+    
   fesetenv_register (*envp);
 
   /* Success.  */
diff --git a/sysdeps/powerpc/fpu/feupdateenv.c b/sysdeps/powerpc/fpu/feupdateenv.c
index 3a60d0f33d..5a4000f599 100644
--- a/sysdeps/powerpc/fpu/feupdateenv.c
+++ b/sysdeps/powerpc/fpu/feupdateenv.c
@@ -1,5 +1,5 @@
 /* Install given floating-point environment and raise exceptions.
-   Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+   Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -30,8 +30,24 @@ __feupdateenv (const fenv_t *envp)
   new.fenv = *envp;
   old.fenv = fegetenv_register ();
 
-  /* Copy the set exceptions from `old' to `new'.  */
-  new.l[1] = (new.l[1] & 0xE00000FF) | (old.l[1] & 0x1FFFFF00);
+  /* Restore rounding mode and exception enable from *envp and merge
+     exceptions.  Leave fraction rounded/inexact and FP result/CC bits
+     unchanged.  */
+  new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF);
+  
+  /* If the old env has no eabled exceptions and the new env has any enabled
+     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put
+     the hardware into "precise mode" and may cause the FPU to run slower on
+     some hardware.  */
+  if ((old.l[1] & 0x000000F8) == 0 && (new.l[1] & 0x000000F8) != 0)
+    (void)__fe_nomask_env ();
+  
+  /* If the old env had any eabled exceptions and the new env has no enabled
+     exceptions, then mask SIGFPE in the MSR FE0/FE1 bits.  This may allow the
+     FPU to run faster because it always takes the default action and can not 
+     generate SIGFPE. */
+  if ((old.l[1] & 0x000000F8) != 0 && (new.l[1] & 0x000000F8) == 0)
+    (void)__fe_mask_env ();
 
   /* Atomically enable and raise (if appropriate) exceptions set in `new'. */
   fesetenv_register (new.fenv);
diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c
index dee44dcee3..5631560bcd 100644
--- a/sysdeps/s390/fpu/feholdexcpt.c
+++ b/sysdeps/s390/fpu/feholdexcpt.c
@@ -1,5 +1,5 @@
 /* Store current floating-point environment and clear exceptions.
-   Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
 
@@ -23,13 +23,14 @@
 
 int feholdexcept (fenv_t *envp)
 {
+  fexcept_t fpc;
   /* Store the environment.  */
   fegetenv (envp);
   /* Clear the current sticky bits as more than one exception
      may be generated.  */
-  envp->fpc &= ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
+  fpc = envp->fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
   /* Hold from generating fpu exceptions temporarily.  */
-  _FPU_SETCW ((envp->fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
+  _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
   return 0;
 }
 libm_hidden_def (feholdexcept)
diff --git a/sysdeps/unix/sysv/linux/alpha/ioperm.c b/sysdeps/unix/sysv/linux/alpha/ioperm.c
index 6c4115d1c8..32e96ec2f2 100644
--- a/sysdeps/unix/sysv/linux/alpha/ioperm.c
+++ b/sysdeps/unix/sysv/linux/alpha/ioperm.c
@@ -32,6 +32,11 @@
    sparse address space would work (e.g., the Low Cost Alpha chip has an
    I/O address space that's 512MB large!).  */
 
+/* Make sure the ldbu/stb asms below are not expaneded to macros.  */
+#ifndef __alpha_bwx__
+asm(".arch ev56");
+#endif
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_mask.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_mask.c
new file mode 100644
index 0000000000..c2452c7bc5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_mask.c
@@ -0,0 +1,68 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc.
+   Copyright (C) 2007 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+/* This is rather fiddly under Linux.  We don't have direct access,
+   and there is no system call, but we can change the bits
+   in a signal handler's context...  */
+
+static struct sigaction oact;
+
+static void
+fe_mask_handler (int signum, struct sigcontext *sc)
+{
+  sc->regs->msr &= ~0x900ul;  /* FE0 | FE1 */
+  sigaction (SIGUSR1, &oact, NULL);
+}
+#endif
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if __ASSUME_NEW_PRCTL_SYSCALL == 0
+# if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result = INLINE_SYSCALL (prctl, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+
+  if (result == -1 && errno == EINVAL)
+# endif
+    {
+      struct sigaction act;
+
+      act.sa_handler = (sighandler_t) fe_mask_handler;
+      sigemptyset (&act.sa_mask);
+      act.sa_flags = 0;
+
+      sigaction (SIGUSR1, &act, &oact);
+      raise (SIGUSR1);
+    }
+#else
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+#endif
+
+  return FE_DFL_ENV;
+}
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_nomask.c
index 8d3b9ad1f4..8d3b9ad1f4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fe_nomask.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/fe_nomask.c
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_mask.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_mask.c
new file mode 100644
index 0000000000..4c31c63c5c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_mask.c
@@ -0,0 +1,43 @@
+/* Procedure definition for FE_MASK_ENV for Linux/ppc64.
+   Copyright (C) 2007 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv.h>
+#include <errno.h>
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <kernel-features.h>
+
+const fenv_t *
+__fe_mask_env (void)
+{
+#if defined PR_SET_FPEXC && defined PR_FP_EXC_DISABLED
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+  result = INTERNAL_SYSCALL (prctl, err, 2, PR_SET_FPEXC, PR_FP_EXC_DISABLED);
+# ifndef __ASSUME_NEW_PRCTL_SYSCALL
+  if (INTERNAL_SYSCALL_ERROR_P (result, err)
+      && INTERNAL_SYSCALL_ERRNO (result, err) == EINVAL)
+    __set_errno (ENOSYS);
+# endif
+#else
+  __set_errno (ENOSYS);
+#endif
+  return FE_DFL_ENV;
+}
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_nomask.c
index 62f735514a..62f735514a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fe_nomask.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/fe_nomask.c
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index 38103f0c68..d1226ef82b 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -11,7 +11,7 @@ epoll_create	EXTRA	epoll_create	i:i	epoll_create
 epoll_ctl	EXTRA	epoll_ctl	i:iiip	epoll_ctl
 epoll_wait	EXTRA	epoll_wait	Ci:ipii	epoll_wait
 epoll_pwait	EXTRA	epoll_pwait	Ci:ipiipi	epoll_pwait
-fdatasync	-	fdatasync	i:i	fdatasync
+fdatasync	-	fdatasync	Ci:i	fdatasync
 flock		-	flock		i:ii	__flock		flock
 fork		-	fork		i:	__libc_fork	__fork fork
 get_kernel_syms	EXTRA	get_kernel_syms	i:p	get_kernel_syms