about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-09-10 18:59:03 +0000
committerJakub Jelinek <jakub@redhat.com>2006-09-10 18:59:03 +0000
commiteffe3e2d1a084fde8fae9b91febb28c97781f9e5 (patch)
tree97749ea80a323592d3d80f24627f9fcb8b8b7297
parentb2adc86677d215d3d8071393d2a69357dd844821 (diff)
downloadglibc-effe3e2d1a084fde8fae9b91febb28c97781f9e5.tar.gz
glibc-effe3e2d1a084fde8fae9b91febb28c97781f9e5.tar.xz
glibc-effe3e2d1a084fde8fae9b91febb28c97781f9e5.zip
Updated to fedora-glibc-20060910T1832 cvs/fedora-glibc-2_4_90-31
-rw-r--r--ChangeLog33
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in15
-rw-r--r--malloc/arena.c2
-rw-r--r--malloc/malloc.c3
-rw-r--r--misc/sys/mman.h18
-rw-r--r--nptl/ChangeLog21
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S10
-rw-r--r--nptl/tst-cond22.c154
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lrint.S8
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h11
-rw-r--r--time/Makefile2
-rw-r--r--time/bug-mktime1.c17
-rw-r--r--time/mktime.c11
18 files changed, 314 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 413d398e91..004efe9aba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2006-09-09  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #2821]
+	* time/mktime.c (guess_time_tm): Fix overflow detection.
+	* time/Makefile (tests): Add bug-mktime1.
+	* time/bug-mktime1.c: New file.
+
+	[BZ #3189, #3188]
+	* misc/sys/mman.h (remap_file_pages): Make available for _GNU_SOURCE.
+	(mremap): Likewise.
+
+2006-09-07  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #1006]
+	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela):
+	Ensure relocation doesn't clobber any bits outside of the
+	immediate field for R_SPARC_TLS_LE_HIX22, R_SPARC_WDISP30,
+	R_SPARC_HI22 and R_SPARC_H44.
+
+	[BZ #2775]
+	* malloc/malloc.c (sYSMALLOc): Only call grow_heap if
+	(long) (MINSIZE + nb - old_size) is positive.
+
+	* malloc/arena.c (grow_heap): When growing bail even if new_size
+	is negative.
+
+	[BZ #3155]
+	* sysdeps/powerpc/powerpc32/fpu/s_lrint.S (__lrint): Don't access
+	stack below r1.
+
 2006-09-06  Jakub Jelinek  <jakub@redhat.com>
 
 	* posix/regex_internal.c (re_string_reconstruct): Handle
@@ -36,8 +66,7 @@
 
 2006-08-31  Jakub Jelinek  <jakub@redhat.com>
 
-	* dlfcn/Makefile (LDLIBS-bug-atexit3-lib.so): Add
-	ld.so.
+	* dlfcn/Makefile (LDLIBS-bug-atexit3-lib.so): Add ld.so.
 
 	* malloc/malloc.c (_int_malloc): Use full list insert and not
 	shortcut which assumes the list is empty for large requests
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 989cd3a688..5ff53ebc4e 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc4
-fedora-sync-date := 2006-09-07 08:53 UTC
-fedora-sync-tag := fedora-glibc-20060907T0853
+fedora-sync-date := 2006-09-10 18:32 UTC
+fedora-sync-tag := fedora-glibc-20060910T1832
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 0ffcae11a8..2cefe4644b 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 30
+%define glibcrelease 31
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -875,9 +875,10 @@ cd build-%{nptl_target_cpu}-linuxnptl && \
 %endif
 
 %ifarch %{rtkaioarches}
+rm -f $RPM_BUILD_ROOT{,%{_prefix}}/%{_lib}/librtkaio.so*
 mkdir -p $RPM_BUILD_ROOT/%{_lib}/rtkaio
-cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/`
-ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` $RPM_BUILD_ROOT/%{_lib}/rtkaio/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*`
+mv $RPM_BUILD_ROOT/%{_lib}/librtkaio-*.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/
+ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/rtkaio/librtkaio-*.so` $RPM_BUILD_ROOT/%{_lib}/rtkaio/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*`
 %endif
 
 %if %{buildxen}
@@ -901,7 +902,7 @@ ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/libthread_db-*.so` $RPM_BUILD_ROOT/%{_l
 %ifarch %{rtkaioarches}
 mkdir -p $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir
 cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/`
-ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*`
+ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/librtkaio-*.so` $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*`
 %endif
 cd ..
 %endif
@@ -1454,6 +1455,12 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Sun Sep 10 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-31
+- fix pthread_cond_{,timed}wait cancellation (BZ#3123)
+- fix lrint on ppc32 (BZ#3155)
+- fix malloc allocating more than half of address space (BZ#2775)
+- fix mktime on 32-bit arches a few years after 2038 (BZ#2821)
+
 * Thu Sep  7 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-30
 - add librtkaio, to use it add /%{lib}/rtkaio to your
   LD_LIBRARY_PATH or /etc/ld.so.conf
diff --git a/malloc/arena.c b/malloc/arena.c
index 6f4b0c497b..2179174d64 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -712,7 +712,7 @@ grow_heap(h, diff) heap_info *h; long diff;
   if(diff >= 0) {
     diff = (diff + page_mask) & ~page_mask;
     new_size = (long)h->size + diff;
-    if(new_size > HEAP_MAX_SIZE)
+    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;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 206f3e1b6a..a369001520 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2970,7 +2970,8 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
     /* First try to extend the current heap. */
     old_heap = heap_for_ptr(old_top);
     old_heap_size = old_heap->size;
-    if (grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {
+    if ((long) (MINSIZE + nb - old_size) > 0
+	&& grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {
       av->system_mem += old_heap->size - old_heap_size;
       arena_mem += old_heap->size - old_heap_size;
 #if 0
diff --git a/misc/sys/mman.h b/misc/sys/mman.h
index d9f4747b7f..4cd8a3fe72 100644
--- a/misc/sys/mman.h
+++ b/misc/sys/mman.h
@@ -116,14 +116,6 @@ extern int mlockall (int __flags) __THROW;
 extern int munlockall (void) __THROW;
 
 #ifdef __USE_MISC
-/* Remap pages mapped by the range [ADDR,ADDR+OLD_LEN) to new length
-   NEW_LEN.  If MREMAP_MAYMOVE is set in FLAGS the returned address
-   may differ from ADDR.  If MREMAP_FIXED is set in FLAGS the function
-   takes another paramter which is a fixed address at which the block
-   resides after a successful call.  */
-extern void *mremap (void *__addr, size_t __old_len, size_t __new_len,
-		     int __flags, ...) __THROW;
-
 /* mincore returns the memory residency status of the pages in the
    current process's address space specified by [start, start + len).
    The status is returned in a vector of bytes.  The least significant
@@ -131,6 +123,16 @@ extern void *mremap (void *__addr, size_t __old_len, size_t __new_len,
    it is zero.  */
 extern int mincore (void *__start, size_t __len, unsigned char *__vec)
      __THROW;
+#endif
+
+#ifdef __USE_GNU
+/* Remap pages mapped by the range [ADDR,ADDR+OLD_LEN) to new length
+   NEW_LEN.  If MREMAP_MAYMOVE is set in FLAGS the returned address
+   may differ from ADDR.  If MREMAP_FIXED is set in FLAGS the function
+   takes another paramter which is a fixed address at which the block
+   resides after a successful call.  */
+extern void *mremap (void *__addr, size_t __old_len, size_t __new_len,
+		     int __flags, ...) __THROW;
 
 /* Remap arbitrary pages of a shared backing store within an existing
    VMA.  */
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 1d89bfa396..159c3bfcf2 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,24 @@
+2006-09-08  Jakub Jelinek  <jakub@redhat.com>
+
+	* tst-cond22.c: Include pthread.h instead of pthreadP.h.
+	Include stdlib.h.
+	* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Only
+	increase FUTEX if increasing WAKEUP_SEQ.  Fix comment typo.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+							
+2006-09-08  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3123]
+	* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Don't
+	increment WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Likewise.
+	* Makefile (tests): Add tst-cond22.
+	* tst-cond22.c: New file.
+
 2006-09-05  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #3124]
diff --git a/nptl/Makefile b/nptl/Makefile
index e907ca0c3a..ef12a80689 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -207,7 +207,7 @@ tests = tst-typesizes \
 	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
-	tst-cond20 tst-cond21 \
+	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 \
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
index 86669458a0..f5f5cec5a8 100644
--- a/nptl/sysdeps/pthread/pthread_cond_wait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -50,10 +50,16 @@ __condvar_cleanup (void *arg)
   if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
     {
       /* This thread is not waiting anymore.  Adjust the sequence counters
-	 appropriately.  */
-      ++cbuffer->cond->__data.__wakeup_seq;
+	 appropriately.  We do not increment WAKEUP_SEQ if this would
+	 bump it over the value of TOTAL_SEQ.  This can happen if a thread
+	 was woken and then canceled.  */
+      if (cbuffer->cond->__data.__wakeup_seq
+	  < cbuffer->cond->__data.__total_seq)
+	{
+	  ++cbuffer->cond->__data.__wakeup_seq;
+	  ++cbuffer->cond->__data.__futex;
+	}
       ++cbuffer->cond->__data.__woken_seq;
-      ++cbuffer->cond->__data.__futex;
     }
 
   cbuffer->cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS;
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 699c2cb227..f481a8e43c 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -406,12 +406,22 @@ __condvar_tw_cleanup:
 	cmpl	20(%esp), %eax
 	jne	3f
 
-	addl	$1, wakeup_seq(%ebx)
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movl	total_seq(%ebx), %eax
+	movl	total_seq+4(%ebx), %edi
+	cmpl	wakeup_seq+4(%ebx), %edi
+	jb	6f
+	ja	7f
+	cmpl	wakeup_seq(%ebx), %eax
+	jbe	7f
+
+6:	addl	$1, wakeup_seq(%ebx)
 	adcl	$0, wakeup_seq+4(%ebx)
-
 	addl	$1, cond_futex(%ebx)
 
-	addl	$1, woken_seq(%ebx)
+7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
 3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index d282785151..f16c7d9198 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -297,12 +297,22 @@ __condvar_w_cleanup:
 	cmpl	12(%esp), %eax
 	jne	3f
 
-	addl	$1, wakeup_seq(%ebx)
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movl	total_seq(%ebx), %eax
+	movl	total_seq+4(%ebx), %edi
+	cmpl	wakeup_seq+4(%ebx), %edi
+	jb	6f
+	ja	7f
+	cmpl	wakeup_seq(%ebx), %eax
+	jbe	7f
+
+6:	addl	$1, wakeup_seq(%ebx)
 	adcl	$0, wakeup_seq+4(%ebx)
-
 	addl	$1, cond_futex(%ebx)
 
-	addl	$1, woken_seq(%ebx)
+7:	addl	$1, woken_seq(%ebx)
 	adcl	$0, woken_seq+4(%ebx)
 
 3:	subl	$(1 << clock_bits), cond_nwaiters(%ebx)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index b837d466b1..969e80da2a 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -67,9 +67,15 @@ __condvar_cleanup:
 	cmpl	4(%r8), %edx
 	jne	3f
 
+	/* We increment the wakeup_seq counter only if it is lower than
+	   total_seq.  If this is not the case the thread was woken and
+	   then canceled.  In this case we ignore the signal.  */
+	movq	total_seq(%rdi), %rax
+	cmpq	wakeup_seq(%rdi), %rax
+	jbe	6f
 	incq	wakeup_seq(%rdi)
-	incq	woken_seq(%rdi)
 	incl	cond_futex(%rdi)
+6:	incq	woken_seq(%rdi)
 
 3:	subl	$(1 << clock_bits), cond_nwaiters(%rdi)
 
diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c
new file mode 100644
index 0000000000..1094c09068
--- /dev/null
+++ b/nptl/tst-cond22.c
@@ -0,0 +1,154 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_barrier_t b;
+static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+
+
+static void
+cl (void *arg)
+{
+  pthread_mutex_unlock (&m);
+}
+
+
+static void *
+tf (void *arg)
+{
+  if (pthread_mutex_lock (&m) != 0)
+    {
+      printf ("%s: mutex_lock failed\n", __func__);
+      exit (1);
+    }
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      printf ("%s: barrier_wait failed\n", __func__);
+      exit (1);
+    }
+  pthread_cleanup_push (cl, NULL);
+  if (pthread_cond_wait (&c, &m) != 0)
+    {
+      printf ("%s: cond_wait failed\n", __func__);
+      exit (1);
+    }
+  pthread_cleanup_pop (0);
+  if (pthread_mutex_unlock (&m) != 0)
+    {
+      printf ("%s: mutex_unlock failed\n", __func__);
+      exit (1);
+    }
+  return NULL;
+}
+
+
+static int
+do_test (void)
+{
+  int status = 0;
+
+  if (pthread_barrier_init (&b, NULL, 2) != 0)
+    {
+      puts ("barrier_init failed");
+      return 1;
+    }
+
+  pthread_t th;
+  if (pthread_create (&th, NULL, tf, NULL) != 0)
+    {
+      puts ("1st create failed");
+      return 1;
+    }
+  int e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("1st barrier_wait failed");
+      return 1;
+    }
+  if (pthread_mutex_lock (&m) != 0)
+    {
+      puts ("1st mutex_lock failed");
+      return 1;
+    }
+  if (pthread_cond_signal (&c) != 0)
+    {
+      puts ("1st cond_signal failed");
+      return 1;
+    }
+  if (pthread_cancel (th) != 0)
+    {
+      puts ("cancel failed");
+      return 1;
+    }
+  if (pthread_mutex_unlock (&m) != 0)
+    {
+      puts ("1st mutex_unlock failed");
+      return 1;
+    }
+  void *res;
+  if (pthread_join (th, &res) != 0)
+    {
+      puts ("1st join failed");
+      return 1;
+    }
+  if (res != PTHREAD_CANCELED)
+    {
+      puts ("first thread not canceled");
+      status = 1;
+    }
+
+  printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
+  	  c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
+	  c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
+	  c.__data.__nwaiters, c.__data.__broadcast_seq);
+
+  if (pthread_create (&th, NULL, tf, NULL) != 0)
+    {
+      puts ("2nd create failed");
+      return 1;
+    }
+  e = pthread_barrier_wait (&b);
+  if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+    {
+      puts ("2nd barrier_wait failed");
+      return 1;
+    }
+  if (pthread_mutex_lock (&m) != 0)
+    {
+      puts ("2nd mutex_lock failed");
+      return 1;
+    }
+  if (pthread_cond_signal (&c) != 0)
+    {
+      puts ("2nd cond_signal failed");
+      return 1;
+    }
+  if (pthread_mutex_unlock (&m) != 0)
+    {
+      puts ("2nd mutex_unlock failed");
+      return 1;
+    }
+  if (pthread_join (th, &res) != 0)
+    {
+      puts ("2nd join failed");
+      return 1;
+    }
+  if (res != NULL)
+    {
+      puts ("2nd thread canceled");
+      status = 1;
+    }
+
+  printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
+  	  c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
+	  c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
+	  c.__data.__nwaiters, c.__data.__broadcast_seq);
+
+  return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
index 55e9de7e2a..da0a1e505a 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
@@ -21,13 +21,15 @@
 #include <math_ldbl_opt.h>
 
 /* long int[r3] __lrint (double x[fp1])  */
-ENTRY (__lrint)	
+ENTRY (__lrint)
+	stwu	r1,-16(r1)
 	fctiw	fp13,fp1
-	stfd	fp13,-8(r1)
+	stfd	fp13,8(r1)
 	nop	/* Insure the following load is in a different dispatch group */
 	nop	/* to avoid pipe stall on POWER4&5.  */
 	nop
-	lwz	r3,-4(r1)	
+	lwz	r3,12(r1)
+	addi	r1,r1,16
 	blr
 	END (__lrint)
 
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index ce9b8c9dd9..314a784dbc 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  Sparc64 version.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -623,7 +623,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  value = sym->st_value - sym_map->l_tls_offset
 	    + reloc->r_addend;
 	  if (r_type == R_SPARC_TLS_LE_HIX22)
-	    *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
+	    *reloc_addr = (*reloc_addr & 0xffc00000)
+	      | (((~value) >> 10) & 0x3fffff);
 	  else
 	    *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
 	      | 0x1c00;
@@ -653,7 +654,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     case R_SPARC_WDISP30:
       *(unsigned int *) reloc_addr =
 	((*(unsigned int *)reloc_addr & 0xc0000000) |
-	 ((value - (Elf64_Addr) reloc_addr) >> 2));
+	 (((value - (Elf64_Addr) reloc_addr) >> 2) & 0x3fffffff));
       break;
 
       /* MEDLOW code model relocs */
@@ -665,7 +666,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     case R_SPARC_HI22:
       *(unsigned int *) reloc_addr =
 	((*(unsigned int *)reloc_addr & 0xffc00000) |
-	 (value >> 10));
+	 ((value >> 10) & 0x3fffff));
       break;
     case R_SPARC_OLO10:
       *(unsigned int *) reloc_addr =
@@ -677,7 +678,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     case R_SPARC_H44:
       *(unsigned int *) reloc_addr =
 	((*(unsigned int *)reloc_addr & 0xffc00000) |
-	 (value >> 22));
+	 ((value >> 22) & 0x3fffff));
       break;
     case R_SPARC_M44:
       *(unsigned int *) reloc_addr =
diff --git a/time/Makefile b/time/Makefile
index 734f0d5373..d93b84bb2f 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -35,7 +35,7 @@ distribute := datemsk
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
 	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
-	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r
+	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1
 
 include ../Rules
 
diff --git a/time/bug-mktime1.c b/time/bug-mktime1.c
new file mode 100644
index 0000000000..e071273f05
--- /dev/null
+++ b/time/bug-mktime1.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <time.h>
+
+
+static int
+do_test (void)
+{
+  struct tm t2 = { 0, 0, 0, 1, 1, 2050 - 1900, 1, 1, 1 };
+  time_t tt2 = mktime (&t2);
+  printf ("%ld\n", (long int) tt2);
+  if (sizeof (time_t) == 4 && tt2 != -1)
+    return 1;
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/time/mktime.c b/time/mktime.c
index 5a326d1e79..8f00c72e09 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -1,7 +1,7 @@
 /* Convert a `struct tm' to a time_t value.
-   Copyright (C) 1993-1999, 2002-2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1993-1999, 2002-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Paul Eggert (eggert@twinsun.com).
+   Contributed by Paul Eggert <eggert@twinsun.com>.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -216,10 +216,11 @@ guess_time_tm (long int year, long int yday, int hour, int min, int sec,
   /* Overflow occurred one way or another.  Return the nearest result
      that is actually in range, except don't report a zero difference
      if the actual difference is nonzero, as that would cause a false
-     match.  */
+     match; and don't oscillate between two values, as that would
+     confuse the spring-forward gap detector.  */
   return (*t < TIME_T_MIDPOINT
-	  ? TIME_T_MIN + (*t == TIME_T_MIN)
-	  : TIME_T_MAX - (*t == TIME_T_MAX));
+	  ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
+	  : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
 }
 
 /* Use CONVERT to convert *T to a broken down time in *TP.