From effe3e2d1a084fde8fae9b91febb28c97781f9e5 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 10 Sep 2006 18:59:03 +0000 Subject: Updated to fedora-glibc-20060910T1832 --- ChangeLog | 33 ++++- fedora/branch.mk | 4 +- fedora/glibc.spec.in | 15 +- malloc/arena.c | 2 +- malloc/malloc.c | 3 +- misc/sys/mman.h | 18 +-- nptl/ChangeLog | 21 +++ nptl/Makefile | 2 +- nptl/sysdeps/pthread/pthread_cond_wait.c | 14 +- .../sysv/linux/i386/i486/pthread_cond_timedwait.S | 18 ++- .../unix/sysv/linux/i386/i486/pthread_cond_wait.S | 18 ++- .../unix/sysv/linux/x86_64/pthread_cond_wait.S | 10 +- nptl/tst-cond22.c | 154 +++++++++++++++++++++ sysdeps/powerpc/powerpc32/fpu/s_lrint.S | 8 +- sysdeps/sparc/sparc64/dl-machine.h | 11 +- time/Makefile | 2 +- time/bug-mktime1.c | 17 +++ time/mktime.c | 11 +- 18 files changed, 314 insertions(+), 47 deletions(-) create mode 100644 nptl/tst-cond22.c create mode 100644 time/bug-mktime1.c diff --git a/ChangeLog b/ChangeLog index 413d398e91..004efe9aba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2006-09-09 Ulrich Drepper + + [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 + + [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 * posix/regex_internal.c (re_string_reconstruct): Handle @@ -36,8 +66,7 @@ 2006-08-31 Jakub Jelinek - * 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 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 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 + + * 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 + + [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 [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 , 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 , 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 , 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 , 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 +#include +#include + + +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 /* 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 +#include + + +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 . 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. -- cgit v1.2.3