about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-05-21 20:01:15 +0000
committerJakub Jelinek <jakub@redhat.com>2007-05-21 20:01:15 +0000
commit75831cc48d3fef9b0bb247aabbcdaceef85efa23 (patch)
tree49952b4916fa5d21f944970fa0ff5392742e9378
parent473e6b3f8fcf9c937d5a85da70b95f5c13f4a28f (diff)
downloadglibc-75831cc48d3fef9b0bb247aabbcdaceef85efa23.tar.gz
glibc-75831cc48d3fef9b0bb247aabbcdaceef85efa23.tar.xz
glibc-75831cc48d3fef9b0bb247aabbcdaceef85efa23.zip
Backported selected fixes from 2007-05-{17,18,21}. cvs/fedora-glibc-2_6-2
-rw-r--r--ChangeLog55
-rw-r--r--fedora/glibc.spec.in11
-rw-r--r--malloc/Makefile1
-rw-r--r--malloc/arena.c3
-rw-r--r--malloc/hooks.c27
-rw-r--r--malloc/malloc.c30
-rw-r--r--malloc/mcheck.c8
-rw-r--r--nptl/ChangeLog13
-rw-r--r--nptl/Makefile8
-rw-r--r--nptl/pthread_mutex_lock.c4
-rw-r--r--nptl/pthread_mutex_timedlock.c8
-rw-r--r--nptl/pthread_mutex_trylock.c6
-rw-r--r--nptl/tst-robust9.c87
-rw-r--r--nptl/tst-robustpi9.c2
-rw-r--r--rt/tst-shm.c15
-rw-r--r--stdio-common/tst-sprintf.c21
-rw-r--r--stdio-common/vfprintf.c11
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/epoll_pwait.c69
-rw-r--r--sysdeps/unix/sysv/linux/i386/epoll_pwait.S80
-rw-r--r--sysdeps/unix/sysv/linux/i386/sync_file_range.S6
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sys/epoll.h20
-rw-r--r--sysdeps/x86_64/fpu/k_cosl.c1
-rw-r--r--sysdeps/x86_64/fpu/k_rem_pio2l.c1
-rw-r--r--sysdeps/x86_64/fpu/k_sinl.c1
-rw-r--r--sysdeps/x86_64/fpu/k_tanl.c1
27 files changed, 422 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index d23f2efe96..34b411dfca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2007-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/epoll_pwait.S: New file.
+
+2007-05-21  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #4525]
+	* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add epoll_pwait.
+	* sysdeps/unix/sysv/linux/epoll_pwait.c: New file.
+	* sysdeps/unix/sysv/linux/syscalls.list (epoll_pwait): Remove.
+
+	* sysdeps/unix/sysv/linux/x86_64/sys/epoll.h (epoll_pwait): Declare.
+
+	[BZ #4514]
+	* stdio-common/vfprintf.c (vfprintf): Don't shadow workstart variable,
+	reinitialize workend at the start of each do_positional format spec
+	loop, free workstart before do_positional loops.
+	(printf_unknown): Fix size of work_buffer.
+	* stdio-common/tst-sprintf.c (main): Add 3 new testcases.
+
+	* malloc/hooks.c (MALLOC_STATE_VERSION): Bump.
+	(public_sET_STATe): If ms->version < 3, put all chunks into
+	unsorted chunks and clear {fd,bk}_nextsize fields of largebin
+	chunks.
+
+	* malloc/malloc.c [MALLOC_DEBUG]: Revert 2007-05-13 changes.
+	* malloc/hooks.c: Likewise.
+	* malloc/arena.c: Likewise.
+	* malloc/malloc.c (do_check_malloc_state): Don't assert
+	n_mmaps is not greater than n_mmaps_max.  This removes the need
+	for the previous change.
+
+	* malloc/Makefile (CFLAGS-malloc.c): Revert accidental
+	2007-05-07 commit.
+
+2007-05-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* malloc/malloc.c (do_check_chunk): Correct check for mmaped block
+	not overlapping with arena.
+
+	* malloc/mcheck.c (reallochook): If size==0, free the block.
+
+	* rt/tst-shm.c: Use fstat64 instead of fstat.
+
+	* sysdeps/unix/sysv/linux/i386/sync_file_range.S: Fix case where
+	__NR_sync_file_range is not defined.
+
+2007-05-17  Ulrich Drepper  <drepper@redhat.com>
+
+	Dummy files to prevent stub versions from being used.
+	* sysdeps/x86_64/fpu/k_cosl.c: New file.
+	* sysdeps/x86_64/fpu/k_rem_pio2l.c: New file.
+	* sysdeps/x86_64/fpu/k_sinl.c: New file.
+	* sysdeps/x86_64/fpu/k_tanl.c: New file.
+
 2007-05-14  Ulrich Drepper  <drepper@redhat.com>
 
 	* version.h (VERSION): Define to 6.
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 02ce901128..201d0753ac 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 1
+%define glibcrelease 2
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -1561,7 +1561,14 @@ rm -f *.filelist*
 %endif
 
 %changelog
-* Tue May 15 2007 Roland McGrath <roland@redhat.com> - 2.6-1
+* Mon May 21 2007 Jakub Jelinek <jakub@redhat.com> 2.6-2
+- restore malloc_set_state backwards compatibility (#239344)
+- fix epoll_pwait (BZ#4525)
+- fix printf with unknown format spec or positional arguments
+  and large width and/or precision (BZ#4514)
+- robust mutexes fix (BZ#4512)
+
+* Tue May 15 2007 Roland McGrath <roland@redhat.com> 2.6-1
 - glibc 2.6 release
 
 * Fri May 11 2007 Jakub Jelinek <jakub@redhat.com> 2.5.90-24
diff --git a/malloc/Makefile b/malloc/Makefile
index c251bcfb9d..c39eae5474 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -104,7 +104,6 @@ $(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 9e3ff47347..ce64335567 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -370,9 +370,6 @@ ptmalloc_init_minimal (void)
   mp_.top_pad        = DEFAULT_TOP_PAD;
 #endif
   mp_.n_mmaps_max    = DEFAULT_MMAP_MAX;
-#if MALLOC_DEBUG
-  mp_.n_mmaps_cmax   = DEFAULT_MMAP_MAX;
-#endif
   mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
   mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
   mp_.pagesize       = malloc_getpagesize;
diff --git a/malloc/hooks.c b/malloc/hooks.c
index cde3e18cbd..1e01b73afd 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -496,7 +496,7 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller;
    then the hooks are reset to 0.  */
 
 #define MALLOC_STATE_MAGIC   0x444c4541l
-#define MALLOC_STATE_VERSION (0*0x100l + 2l) /* major*0x100 + minor */
+#define MALLOC_STATE_VERSION (0*0x100l + 3l) /* major*0x100 + minor */
 
 struct malloc_save_state {
   long          magic;
@@ -507,9 +507,6 @@ struct malloc_save_state {
   unsigned long trim_threshold;
   unsigned long top_pad;
   unsigned int  n_mmaps_max;
-#if MALLOC_DEBUG
-  unsigned int  n_mmaps_cmax;
-#endif
   unsigned long mmap_threshold;
   int           check_action;
   unsigned long max_sbrked_mem;
@@ -553,9 +550,6 @@ public_gET_STATe(void)
   ms->trim_threshold = mp_.trim_threshold;
   ms->top_pad = mp_.top_pad;
   ms->n_mmaps_max = mp_.n_mmaps_max;
-#if MALLOC_DEBUG
-  ms->n_mmaps_cmax = mp_.n_mmaps_cmax;
-#endif
   ms->mmap_threshold = mp_.mmap_threshold;
   ms->check_action = check_action;
   ms->max_sbrked_mem = main_arena.max_system_mem;
@@ -601,8 +595,9 @@ public_sET_STATe(Void_t* msptr)
       assert(ms->av[2*i+3] == 0);
       first(b) = last(b) = b;
     } else {
-      if(i<NSMALLBINS || (largebin_index(chunksize(ms->av[2*i+2]))==i &&
-			  largebin_index(chunksize(ms->av[2*i+3]))==i)) {
+      if(ms->version >= 3 &&
+	 (i<NSMALLBINS || (largebin_index(chunksize(ms->av[2*i+2]))==i &&
+			   largebin_index(chunksize(ms->av[2*i+3]))==i))) {
 	first(b) = ms->av[2*i+2];
 	last(b) = ms->av[2*i+3];
 	/* Make sure the links to the bins within the heap are correct.  */
@@ -622,14 +617,22 @@ public_sET_STATe(Void_t* msptr)
       }
     }
   }
+  if (ms->version < 3) {
+    /* Clear fd_nextsize and bk_nextsize fields.  */
+    b = unsorted_chunks(&main_arena)->fd;
+    while (b != unsorted_chunks(&main_arena)) {
+      if (!in_smallbin_range(chunksize(b))) {
+	b->fd_nextsize = NULL;
+	b->bk_nextsize = NULL;
+      }
+      b = b->fd;
+    }
+  }
   mp_.sbrk_base = ms->sbrk_base;
   main_arena.system_mem = ms->sbrked_mem_bytes;
   mp_.trim_threshold = ms->trim_threshold;
   mp_.top_pad = ms->top_pad;
   mp_.n_mmaps_max = ms->n_mmaps_max;
-#if MALLOC_DEBUG
-  mp_.n_mmaps_cmax = ms->n_mmaps_cmax;
-#endif
   mp_.mmap_threshold = ms->mmap_threshold;
   check_action = ms->check_action;
   main_arena.max_system_mem = ms->max_sbrked_mem;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index e061db94d6..0755fd8f8d 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2358,9 +2358,6 @@ struct malloc_par {
   /* Memory map support */
   int              n_mmaps;
   int              n_mmaps_max;
-#if MALLOC_DEBUG
-  int              n_mmaps_cmax;
-#endif
   int              max_n_mmaps;
   /* the mmap_threshold is dynamic, until the user sets
      it manually, at which point we need to disable any
@@ -2572,7 +2569,7 @@ static void do_check_chunk(av, p) mstate av; mchunkptr p;
 #if HAVE_MMAP
     /* address is outside main heap  */
     if (contiguous(av) && av->top != initial_top(av)) {
-      assert(((char*)p) < min_address || ((char*)p) > max_address);
+      assert(((char*)p) < min_address || ((char*)p) >= max_address);
     }
     /* chunk is page-aligned */
     assert(((p->prev_size + sz) & (mp_.pagesize-1)) == 0);
@@ -2876,8 +2873,6 @@ static void do_check_malloc_state(mstate av)
   assert(total <= (unsigned long)(mp_.max_total_mem));
   assert(mp_.n_mmaps >= 0);
 #endif
-  assert(mp_.n_mmaps <= mp_.n_mmaps_cmax);
-  assert(mp_.n_mmaps_max <= mp_.n_mmaps_cmax);
   assert(mp_.n_mmaps <= mp_.max_n_mmaps);
 
   assert((unsigned long)(av->system_mem) <=
@@ -3475,13 +3470,6 @@ munmap_chunk(p) mchunkptr p;
     }
 
   mp_.n_mmaps--;
-#if MALLOC_DEBUG
-  if (mp_.n_mmaps_cmax > mp_.n_mmaps_max)
-    {
-      assert (mp_.n_mmaps_cmax == mp_.n_mmaps + 1);
-      mp_.n_mmaps_cmax = mp_.n_mmaps;
-    }
-#endif
   mp_.mmapped_mem -= total_size;
 
   int ret __attribute__ ((unused)) = munmap((char *)block, total_size);
@@ -5397,9 +5385,6 @@ mstate av; size_t n_elements; size_t* sizes; int opts; Void_t* chunks[];
   mp_.n_mmaps_max = 0;
   mem = _int_malloc(av, size);
   mp_.n_mmaps_max = mmx;   /* reset mmap */
-#if MALLOC_DEBUG
-  mp_.n_mmaps_cmax = mmx;
-#endif
   if (mem == 0)
     return 0;
 
@@ -5725,17 +5710,8 @@ int mALLOPt(param_number, value) int param_number; int value;
       res = 0;
     else
 #endif
-      {
-#if MALLOC_DEBUG
-	if (mp_.n_mmaps <= value)
-	  mp_.n_mmaps_cmax = value;
-	else
-	  mp_.n_mmaps_cmax = mp_.n_mmaps;
-#endif
-
-	mp_.n_mmaps_max = value;
-	mp_.no_dyn_threshold = 1;
-      }
+      mp_.n_mmaps_max = value;
+      mp_.no_dyn_threshold = 1;
     break;
 
   case M_CHECK_ACTION:
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 9f88843445..28210068ff 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -1,5 +1,5 @@
 /* Standard debugging hooks for `malloc'.
-   Copyright (C) 1990-1997,99,2000,01,02 Free Software Foundation, Inc.
+   Copyright (C) 1990-1997,1999,2000-2002,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written May 1989 by Mike Haertel.
 
@@ -280,6 +280,12 @@ memalignhook (__malloc_size_t alignment, __malloc_size_t size,
 static __ptr_t
 reallochook (__ptr_t ptr, __malloc_size_t size, const __ptr_t caller)
 {
+  if (size == 0)
+    {
+      freehook (ptr, caller);
+      return NULL;
+    }
+
   struct hdr *hdr;
   __malloc_size_t osize;
 
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 0671f4a459..9b5ac1053e 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,16 @@
+2007-05-17  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4512]
+	* pthread_mutex_lock.c: Preserve FUTEX_WAITERS bit when dead owner
+	is detected.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	Patch in part by Atsushi Nemoto <anemo@mba.ocn.ne.jp>.
+
+	* Makefile (tests): Add tst-robust9 and tst-robustpi9.
+	* tst-robust9.c: New file.
+	* tst-robustpi9.c: New file.
+
 2007-05-14  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary
diff --git a/nptl/Makefile b/nptl/Makefile
index 8c1f74e2bb..f3142b64b0 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -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.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -209,9 +209,9 @@ tests = tst-typesizes \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
 	tst-cond20 tst-cond21 tst-cond22 \
 	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
-	tst-robust6 tst-robust7 tst-robust8 \
-	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
-	tst-robustpi5 tst-robustpi6 tst-robustpi7 tst-robustpi8 \
+	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
+	tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
+	tst-robustpi6 tst-robustpi7 tst-robustpi8 tst-robustpi9 \
 	tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
 	tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
 	tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index 52cc47f4cc..1c3ee4fe25 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.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.
 
@@ -127,6 +127,8 @@ __pthread_mutex_lock (mutex)
 	      int newval = id;
 #ifdef NO_INCR
 	      newval |= FUTEX_WAITERS;
+#else
+	      newval |= (oldval & FUTEX_WAITERS);
 #endif
 
 	      newval
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index c8e6b8507a..8fd681c6ef 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.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.
 
@@ -119,9 +119,11 @@ pthread_mutex_timedlock (mutex, abstime)
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval
+	      int newval = id | (oldval & FUTEX_WAITERS);
+
+	      newval
 		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-						       id, oldval);
+						       newval, oldval);
 	      if (newval != oldval)
 		{
 		  oldval = newval;
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 4990ecd711..9db904c60b 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -84,9 +84,11 @@ __pthread_mutex_trylock (mutex)
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval
+	      int newval = id | (oldval & FUTEX_WAITERS);
+
+	      newval
 		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-						       id, oldval);
+						       newval, oldval);
 
 	      if (newval != oldval)
 		{
diff --git a/nptl/tst-robust9.c b/nptl/tst-robust9.c
new file mode 100644
index 0000000000..20cbd062dc
--- /dev/null
+++ b/nptl/tst-robust9.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+static pthread_mutex_t m;
+
+static void *
+tf (void *data)
+{
+  int err = pthread_mutex_lock (&m);
+  if (err == EOWNERDEAD)
+    {
+      err = pthread_mutex_consistent_np (&m);
+      if (err)
+	{
+	  puts ("pthread_mutex_consistent_np");
+	  exit (1);
+	}
+    }
+  else if (err)
+    {
+      puts ("pthread_mutex_lock");
+      exit (1);
+    }
+  printf ("thread%ld got the lock.\n", (long int) data);
+  sleep (1);
+  /* exit without unlock */
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  int err, i;
+  pthread_t t[3];
+  pthread_mutexattr_t ma;
+
+  pthread_mutexattr_init (&ma);
+  err = pthread_mutexattr_setrobust_np (&ma, PTHREAD_MUTEX_ROBUST_NP);
+  if (err)
+    {
+      puts ("pthread_mutexattr_setrobust_np");
+      return 1;
+    }
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+  err = pthread_mutex_init (&m, &ma);
+  if (err)
+    {
+      puts ("pthread_mutex_init");
+      return 1;
+    }
+
+  for (i = 0; i < sizeof (t) / sizeof (t[0]); i++)
+    {
+      err = pthread_create (&t[i], NULL, tf, (void *) (long int) i);
+      if (err)
+	{
+	  puts ("pthread_create");
+	  return 1;
+	}
+    }
+
+  for (i = 0; i < sizeof (t) / sizeof (t[0]); i++)
+    {
+      err = pthread_join (t[i], NULL);
+      if (err)
+	{
+	  puts ("pthread_join");
+	  return 1;
+	}
+    }
+  return 0;
+}
+
+#define TIMEOUT 5
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/tst-robustpi9.c b/nptl/tst-robustpi9.c
new file mode 100644
index 0000000000..d059aa7d88
--- /dev/null
+++ b/nptl/tst-robustpi9.c
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust9.c"
diff --git a/rt/tst-shm.c b/rt/tst-shm.c
index 01bf89fa74..5838b0ee1d 100644
--- a/rt/tst-shm.c
+++ b/rt/tst-shm.c
@@ -60,7 +60,7 @@ static void
 worker (int write_now)
 {
   struct timespec ts;
-  struct stat st;
+  struct stat64 st;
   int i;
   int fd = do_open ();
   char *mem;
@@ -68,8 +68,10 @@ worker (int write_now)
   if (fd == -1)
     exit (fd);
 
-  if (fstat (fd, &st) == -1 || st.st_size != 4000)
+  if (fstat64 (fd, &st) == -1)
     error (EXIT_FAILURE, 0, "stat failed");
+  if (st.st_size != 4000)
+    error (EXIT_FAILURE, 0, "size incorrect");
 
   mem = mmap (NULL, 4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
   if (mem == NULL)
@@ -131,7 +133,7 @@ do_test (void)
   pid_t pid2;
   int status1;
   int status2;
-  struct stat st;
+  struct stat64 st;
 
   /* Create the shared memory object.  */
   fd = shm_open ("/shm-test", O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600);
@@ -155,11 +157,16 @@ do_test (void)
       return 0;
     }
 
-  if (fstat (fd, &st) == -1 || st.st_size != 4000)
+  if (fstat64 (fd, &st) == -1)
     {
       shm_unlink ("/shm-test");
       error (EXIT_FAILURE, 0, "initial stat failed");
     }
+  if (st.st_size != 4000)
+    {
+      shm_unlink ("/shm-test");
+      error (EXIT_FAILURE, 0, "initial size not correct");
+    }
 
   /* Spawn to processes which will do the work.  */
   pid1 = fork ();
diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c
index c61d3b50e4..c04fef18f4 100644
--- a/stdio-common/tst-sprintf.c
+++ b/stdio-common/tst-sprintf.c
@@ -37,5 +37,26 @@ main (void)
       free (dst);
     }
 
+  if (sprintf (buf, "%1$d%3$.*2$s%4$d", 7, 67108863, "x", 8) != 3
+      || strcmp (buf, "7x8") != 0)
+    {
+      printf ("sprintf (buf, \"%%1$d%%3$.*2$s%%4$d\", 7, 67108863, \"x\", 8) produced `%s' output", buf);
+      result = 1;
+    }
+
+  if (sprintf (buf, "%67108863.16\"%d", 7) != 14
+      || strcmp (buf, "%67108863.16\"7") != 0)
+    {
+      printf ("sprintf (buf, \"%%67108863.16\\\"%%d\", 7) produced `%s' output", buf);
+      result = 1;
+    }
+
+  if (sprintf (buf, "%*\"%d", 0x3ffffff, 7) != 11
+      || strcmp (buf, "%67108863\"7") != 0)
+    {
+      printf ("sprintf (buf, \"%%*\\\"%%d\", 0x3ffffff, 7) produced `%s' output", buf);
+      result = 1;
+    }
+
   return result;
 }
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 20638ad1fd..25edde7511 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1627,6 +1627,8 @@ do_positional:
     /* Just a counter.  */
     size_t cnt;
 
+    free (workstart);
+    workstart = NULL;
 
     if (grouping == (const char *) -1)
       {
@@ -1801,7 +1803,9 @@ do_positional:
 	int use_outdigits = specs[nspecs_done].info.i18n;
 	char pad = specs[nspecs_done].info.pad;
 	CHAR_T spec = specs[nspecs_done].info.spec;
-	CHAR_T *workstart = NULL;
+
+	workstart = NULL;
+	workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
 
 	/* Fill in last information.  */
 	if (specs[nspecs_done].width_arg != -1)
@@ -1897,8 +1901,7 @@ do_positional:
 	    break;
 	  }
 
-	if (__builtin_expect (workstart != NULL, 0))
-	  free (workstart);
+	free (workstart);
 	workstart = NULL;
 
 	/* Write the following constant string.  */
@@ -1926,7 +1929,7 @@ printf_unknown (FILE *s, const struct printf_info *info,
 
 {
   int done = 0;
-  CHAR_T work_buffer[MAX (info->width, info->spec) + 32];
+  CHAR_T work_buffer[MAX (sizeof (info->width), sizeof (info->prec)) * 3];
   CHAR_T *const workend
     = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)];
   register CHAR_T *w;
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index a063b33389..f59e340f8e 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -13,7 +13,7 @@ endif
 
 ifeq ($(subdir),misc)
 sysdep_routines += sysctl clone llseek umount umount2 readahead \
-		   setfsuid setfsgid makedev
+		   setfsuid setfsgid makedev epoll_pwait
 
 CFLAGS-gethostid.c = -fexceptions
 
diff --git a/sysdeps/unix/sysv/linux/epoll_pwait.c b/sysdeps/unix/sysv/linux/epoll_pwait.c
new file mode 100644
index 0000000000..e689073d18
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/epoll_pwait.c
@@ -0,0 +1,69 @@
+/* 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 <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_epoll_pwait
+
+/* Wait for events on an epoll instance "epfd". Returns the number of
+   triggered events returned in "events" buffer. Or -1 in case of
+   error with the "errno" variable set to the specific error code. The
+   "events" parameter is a buffer that will contain triggered
+   events. The "maxevents" is the maximum number of events to be
+   returned ( usually size of "events" ). The "timeout" parameter
+   specifies the maximum wait time in milliseconds (-1 == infinite).
+   The thread's signal mask is temporarily and atomically replaced with
+   the one provided as parameter.  */
+
+int epoll_pwait (int epfd, struct epoll_event *events,
+		 int maxevents, int timeout,
+		 const sigset_t *set)
+{
+  if (SINGLE_THREAD_P)
+    return INLINE_SYSCALL (epoll_pwait, 6, epfd, events, maxevents, timeout,
+			   set, _NSIG / 8);
+
+  int oldtype = LIBC_CANCEL_ASYNC ();
+
+  int result = INLINE_SYSCALL (epoll_pwait, 6, epfd, events, maxevents,
+			       timeout, set, _NSIG / 8);
+
+  LIBC_CANCEL_RESET (oldtype);
+
+  return result;
+}
+
+#else
+
+int epoll_pwait (int epfd, struct epoll_event *events,
+		 int maxevents, int timeout,
+		 const sigset_t *set)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (epoll_pwait)
+
+# include <stub-tag.h>
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/epoll_pwait.S b/sysdeps/unix/sysv/linux/i386/epoll_pwait.S
new file mode 100644
index 0000000000..5f51db229f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/epoll_pwait.S
@@ -0,0 +1,80 @@
+/* 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 <sysdep.h>
+#define _ERRNO_H
+#include <bits/errno.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+
+	.text
+ENTRY (epoll_pwait)
+
+#ifdef __NR_epoll_pwait
+
+	/* Save registers.  */
+	pushl %ebp
+	cfi_adjust_cfa_offset (4)
+	pushl %ebx
+	cfi_adjust_cfa_offset (4)
+	pushl %esi
+	cfi_adjust_cfa_offset (4)
+	pushl %edi
+	cfi_adjust_cfa_offset (4)
+	cfi_rel_offset (edi, 0)
+	cfi_rel_offset (esi, 4)
+	cfi_rel_offset (ebx, 8)
+	cfi_rel_offset (ebp, 12)
+
+	movl 20(%esp), %ebx
+	movl 24(%esp), %ecx
+	movl 28(%esp), %edx
+	movl 32(%esp), %esi
+	movl 36(%esp), %edi
+	movl $_NSIG/8, %ebp
+	movl $__NR_epoll_pwait, %eax
+
+	ENTER_KERNEL
+
+	/* Restore registers.  */
+	popl %edi
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (edi)
+	popl %esi
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (esi)
+	popl %ebx
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (ebx)
+	popl %ebp
+	cfi_adjust_cfa_offset (-4)
+	cfi_restore (ebp)
+
+	/* If 0 > %eax > -4096 there was an error.  */
+	cmpl $-4096, %eax
+	ja SYSCALL_ERROR_LABEL
+
+	/* Successful; return the syscall's value.  */
+#else
+	movl $-ENOSYS, %eax
+	jmp SYSCALL_ERROR_LABEL
+#endif
+L(pseudo_end):
+	ret
+PSEUDO_END (epoll_pwait)
diff --git a/sysdeps/unix/sysv/linux/i386/sync_file_range.S b/sysdeps/unix/sysv/linux/i386/sync_file_range.S
index f39e8a00d7..8544703d56 100644
--- a/sysdeps/unix/sysv/linux/i386/sync_file_range.S
+++ b/sysdeps/unix/sysv/linux/i386/sync_file_range.S
@@ -1,5 +1,5 @@
 /* Selective file content synch'ing.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -63,10 +63,10 @@ ENTRY (sync_file_range)
 
 	cmpl	$-4095, %eax
 	jae	SYSCALL_ERROR_LABEL
-L(pseudo_end):
-	ret
 #else
 	movl	$-ENOSYS, %eax
 	jmp	SYSCALL_ERROR_LABEL
 #endif
+L(pseudo_end):
+	ret
 PSEUDO_END (sync_file_range)
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index d1226ef82b..e16110480f 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -10,7 +10,6 @@ delete_module	EXTRA	delete_module	3	delete_module
 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	Ci:i	fdatasync
 flock		-	flock		i:ii	__flock		flock
 fork		-	fork		i:	__libc_fork	__fork fork
diff --git a/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h b/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h
index 02672d3c75..26f23da403 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h
@@ -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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -22,6 +22,14 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+/* Get __sigset_t.  */
+#include <bits/sigset.h>
+
+#ifndef __sigset_t_defined
+# define __sigset_t_defined
+typedef __sigset_t sigset_t;
+#endif
+
 
 enum EPOLL_EVENTS
   {
@@ -105,6 +113,16 @@ extern int epoll_ctl (int __epfd, int __op, int __fd,
 extern int epoll_wait (int __epfd, struct epoll_event *__events,
 		       int __maxevents, int __timeout);
 
+
+/* Same as epoll_wait, but the thread's signal mask is temporarily
+   and atomically replaced with the one provided as parameter.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int epoll_pwait (int __epfd, struct epoll_event *__events,
+			int __maxevents, int __timeout,
+			__const __sigset_t *__ss);
+
 __END_DECLS
 
 #endif /* sys/epoll.h */
diff --git a/sysdeps/x86_64/fpu/k_cosl.c b/sysdeps/x86_64/fpu/k_cosl.c
new file mode 100644
index 0000000000..eea55a98d2
--- /dev/null
+++ b/sysdeps/x86_64/fpu/k_cosl.c
@@ -0,0 +1 @@
+/*  Not needed.  */
diff --git a/sysdeps/x86_64/fpu/k_rem_pio2l.c b/sysdeps/x86_64/fpu/k_rem_pio2l.c
new file mode 100644
index 0000000000..eea55a98d2
--- /dev/null
+++ b/sysdeps/x86_64/fpu/k_rem_pio2l.c
@@ -0,0 +1 @@
+/*  Not needed.  */
diff --git a/sysdeps/x86_64/fpu/k_sinl.c b/sysdeps/x86_64/fpu/k_sinl.c
new file mode 100644
index 0000000000..eea55a98d2
--- /dev/null
+++ b/sysdeps/x86_64/fpu/k_sinl.c
@@ -0,0 +1 @@
+/*  Not needed.  */
diff --git a/sysdeps/x86_64/fpu/k_tanl.c b/sysdeps/x86_64/fpu/k_tanl.c
new file mode 100644
index 0000000000..eea55a98d2
--- /dev/null
+++ b/sysdeps/x86_64/fpu/k_tanl.c
@@ -0,0 +1 @@
+/*  Not needed.  */