aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 413d398..004efe9 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 989cd3a..5ff53eb 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 0ffcae1..2cefe46 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 6f4b0c4..2179174 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 206f3e1..a369001 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 d9f4747..4cd8a3f 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 1d89bfa..159c3bf 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 e907ca0..ef12a80 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 8666945..f5f5cec 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 699c2cb..f481a8e 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 d282785..f16c7d9 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 b837d46..969e80d 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 0000000..1094c09
--- /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 55e9de7..da0a1e5 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 ce9b8c9..314a784 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 734f0d5..d93b84b 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 0000000..e071273
--- /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 5a326d1..8f00c72 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.