diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-05-04 11:15:57 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2007-05-04 11:15:57 +0000 |
commit | e2f920f6100658d8f2f6d25d31e9cc725b518e53 (patch) | |
tree | f781611b7d32a57696851bb306c5bf2ef195c2e5 | |
parent | 5293aa15c999a3b5071a4f08b409a22126330db2 (diff) | |
download | eglibc2-e2f920f6100658d8f2f6d25d31e9cc725b518e53.tar.gz |
Merge changes between r2107 and r2162 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@2163 7b3dc134-2b1b-0410-93df-9e9f96275f8d
-rw-r--r-- | libc/ChangeLog | 91 | ||||
-rw-r--r-- | libc/malloc/malloc.c | 135 | ||||
-rw-r--r-- | libc/math/test-misc.c | 80 | ||||
-rw-r--r-- | libc/resolv/Makefile | 4 | ||||
-rw-r--r-- | libc/resolv/inet_ntop.c | 2 | ||||
-rw-r--r-- | libc/resolv/tst-inet_ntop.c | 111 | ||||
-rw-r--r-- | libc/soft-fp/extended.h | 38 | ||||
-rw-r--r-- | libc/soft-fp/floatundidf.c | 5 | ||||
-rw-r--r-- | libc/soft-fp/floatundisf.c | 5 | ||||
-rw-r--r-- | libc/soft-fp/floatunsidf.c | 5 | ||||
-rw-r--r-- | libc/soft-fp/floatunsisf.c | 5 | ||||
-rw-r--r-- | libc/soft-fp/op-2.h | 4 | ||||
-rw-r--r-- | libc/soft-fp/op-4.h | 4 | ||||
-rw-r--r-- | libc/soft-fp/op-common.h | 33 | ||||
-rw-r--r-- | libc/stdio-common/printf_fp.c | 8 | ||||
-rw-r--r-- | libc/stdio-common/test-vfprintf.c | 8 | ||||
-rw-r--r-- | libc/stdio-common/tfformat.c | 2 | ||||
-rw-r--r-- | libc/stdio-common/vfprintf.c | 25 | ||||
-rw-r--r-- | libc/sysdeps/posix/getaddrinfo.c | 82 | ||||
-rw-r--r-- | ports/ChangeLog.hppa | 6 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h | 3 |
21 files changed, 559 insertions, 97 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog index 4f27af326..e89e7a740 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,3 +1,94 @@ +2007-05-03 Jakub Jelinek <jakub@redhat.com> + + * soft-fp/op-common.h (FP_TRUNC): Replace raising of FP_EX_INEXACT + with setting the sticky bit. + * math/test-misc.c (main): Add more truncation tests. + +2007-04-14 Uros Bizjak <ubizjak@gmail.com> + + * soft-fp/floatunsidf.c (__floatunsidf): Use DFtype instead of + double in the function declaration. + * soft-fp/floatundidf.c (__floatundidf): Use DFtype instead of + double in the function declaration. + * soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of + float in the function declaration. + * soft-fp/floatunsisf.c (__floatunsisf): Use SFtype instead of + float in the function declaration. + + * soft-fp/extended.h (FP_UNPACK_RAW_E): Do not increase X##_e for + denormal operands. Do not generate FP_EX_DENORM exception. + (FP_UNPACK_RAW_EP): Ditto. + (FP_UNPACK_SEMIRAW_E): Use FP_UNPACK_RAW_E instead of + undefined _FP_UNPACK_RAW_E. + (FP_UNPACK_SEMIRAW_EP): Use FP_UNPACK_RAW_EP instead of + undefined _FP_UNPACK_RAW_EP. + (FP_PACK_SEMIRAW_E): Use FP_PACK_RAW_E instead of + undefined _FP_PACK_RAW_E. + (FP_PACK_SEMIRAW_EP): Use FP_PACK_RAW_EP instead of + undefined _FP_PACK_RAW_EP. + + * op-2.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_2. + * op-4.h (_FP_FRAC_COPY_2_2): Define as alias to _FP_FRAC_COPY_4. + +2007-04-16 Uros Bizjak <ubizjak@gmail.com> + Jakub Jelinek <jakub@redhat.com> + + * soft-fp/op-common.h (FP_EXTEND): Do not abort when + _FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs. Handle denormals for + this case. + * soft-fp/op-common.h (FP_TRUNC): Ditto. + +2007-05-03 Jakub Jelinek <jakub@redhat.com> + + * math/test-misc.c (main): Add tests for rounding long double + values close to smallest double denormalized value to double. + +2007-04-30 Joseph Myers <joseph@codesourcery.com> + + * soft-fp/op-common.h (FP_TRUNC): Correct off-by-one error in + condition for truncating to 0. Set sticky bit for such + truncation. + +2007-05-02 Jakub Jelinek <jakub@redhat.com> + + * stdio-common/vfprintf.c (process_string_arg): Use a VLA rather than + fixed length array for ignore. + +2007-04-30 Ulrich Drepper <drepper@redhat.com> + + [BZ #4438] + * stdio-common/vfprintf.c (process_string_arg): Don't overflow the + stack for large precisions. + * stdio-common/test-vfprintf.c (main): Add test for large + precision. + +2007-04-30 Jakub Jelinek <jakub@redhat.com> + + * stdio-common/printf_fp.c (___printf_fp): Don't print negative sign + for exponent 0. + * stdio-common/tfformat.c (sprint_doubles): Add a new test. + + [BZ #4439] + * resolv/inet_ntop.c (inet_ntop4): Take terminating '\0' into + account in the size check. + * resolv/tst-inet_ntop.c: New test. + * resolv/Makefile (tests): Add tst-inet_ntop. + +2007-04-30 Ulrich Drepper <drepper@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + [BZ #4349] + * malloc/malloc.c: Keep separate list for first blocks on the bin + lists with a given size. This helps skipping over list elements + we know won't fit in two places. + Inspired by a patch by Tomash Brechko <tomash.brechko@gmail.com>. + +2007-04-28 Ulrich Drepper <drepper@redhat.com> + + [BZ #4102] + * sysdeps/posix/getaddrinfo.c (default_labels): Assign separate + label to Teredo tunnel addresses 2001://32. + 2007-04-27 Ulrich Drepper <drepper@redhat.com> * locale/programs/ld-collate.c (collate_read): Allow order_start diff --git a/libc/malloc/malloc.c b/libc/malloc/malloc.c index 6427608a7..8ae941c59 100644 --- a/libc/malloc/malloc.c +++ b/libc/malloc/malloc.c @@ -1,5 +1,5 @@ /* Malloc implementation for multiple threads without lock contention. - Copyright (C) 1996-2002,2003,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 1996-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Wolfram Gloger <wg@malloc.de> and Doug Lea <dl@cs.oswego.edu>, 2001. @@ -27,10 +27,6 @@ based on: VERSION 2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - Note: There may be an updated version of this malloc obtainable at - http://www.malloc.de/malloc/ptmalloc2.tar.gz - Check before installing! - * Quickstart In order to compile this implementation, a Makefile is provided with @@ -1781,6 +1777,10 @@ struct malloc_chunk { struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; + + /* Only used for large blocks: pointer to next larger size. */ + struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */ + struct malloc_chunk* bk_nextsize; }; @@ -1881,7 +1881,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ)) /* The smallest possible chunk */ -#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk)) +#define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize)) /* The smallest size we can malloc is an aligned minimal chunk */ @@ -2081,6 +2081,24 @@ typedef struct malloc_chunk* mbinptr; else { \ FD->bk = BK; \ BK->fd = FD; \ + if (!in_smallbin_range (P->size) \ + && __builtin_expect (P->fd_nextsize != NULL, 0)) { \ + assert (P->fd_nextsize->bk_nextsize == P); \ + assert (P->bk_nextsize->fd_nextsize == P); \ + if (FD->fd_nextsize == NULL) { \ + if (P->fd_nextsize == P) \ + FD->fd_nextsize = FD->bk_nextsize = FD; \ + else { \ + FD->fd_nextsize = P->fd_nextsize; \ + FD->bk_nextsize = P->bk_nextsize; \ + P->fd_nextsize->bk_nextsize = FD; \ + P->bk_nextsize->fd_nextsize = FD; \ + } \ + } else { \ + P->fd_nextsize->bk_nextsize = P->bk_nextsize; \ + P->bk_nextsize->fd_nextsize = P->fd_nextsize; \ + } \ + } \ } \ } @@ -2797,7 +2815,31 @@ static void do_check_malloc_state(mstate av) /* lists are sorted */ assert(p->bk == b || (unsigned long)chunksize(p->bk) >= (unsigned long)chunksize(p)); - } + + if (!in_smallbin_range(size)) + { + if (p->fd_nextsize != NULL) + { + if (p->fd_nextsize == p) + assert (p->bk_nextsize == p); + else + { + if (p->fd_nextsize == first (b)) + assert (chunksize (p) < chunksize (p->fd_nextsize)); + else + assert (chunksize (p) > chunksize (p->fd_nextsize)); + + if (p == first (b)) + assert (chunksize (p) > chunksize (p->bk_nextsize)); + else + assert (chunksize (p) < chunksize (p->bk_nextsize)); + } + } + else + assert (p->bk_nextsize == NULL); + } + } else if (!in_smallbin_range(size)) + assert (p->fd_nextsize == NULL && p->bk_nextsize == NULL); /* chunk is followed by a legal chain of inuse chunks */ for (q = next_chunk(p); (q != av->top && inuse(q) && @@ -4149,6 +4191,11 @@ _int_malloc(mstate av, size_t bytes) unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; av->last_remainder = remainder; remainder->bk = remainder->fd = unsorted_chunks(av); + if (!in_smallbin_range(remainder_size)) + { + remainder->fd_nextsize = NULL; + remainder->bk_nextsize = NULL; + } set_head(victim, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); @@ -4197,19 +4244,36 @@ _int_malloc(mstate av, size_t bytes) size |= PREV_INUSE; /* if smaller than smallest, bypass loop below */ assert((bck->bk->size & NON_MAIN_ARENA) == 0); - if ((unsigned long)(size) <= (unsigned long)(bck->bk->size)) { + if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) { fwd = bck; bck = bck->bk; + + victim->fd_nextsize = fwd->fd; + victim->bk_nextsize = fwd->fd->bk_nextsize; + fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; } else { assert((fwd->size & NON_MAIN_ARENA) == 0); - while ((unsigned long)(size) < (unsigned long)(fwd->size)) { - fwd = fwd->fd; - assert((fwd->size & NON_MAIN_ARENA) == 0); - } - bck = fwd->bk; + while ((unsigned long) size < fwd->size) + { + fwd = fwd->fd_nextsize; + assert((fwd->size & NON_MAIN_ARENA) == 0); + } + + if ((unsigned long) size == (unsigned long) fwd->size) + /* Always insert in the second position. */ + fwd = fwd->fd; + else + { + victim->fd_nextsize = fwd; + victim->bk_nextsize = fwd->bk_nextsize; + fwd->bk_nextsize = victim; + victim->bk_nextsize->fd_nextsize = victim; + } + bck = fwd->bk; } - } + } else + victim->fd_nextsize = victim->bk_nextsize = victim; } mark_bin(av, victim_index); @@ -4225,21 +4289,25 @@ _int_malloc(mstate av, size_t bytes) /* If a large request, scan through the chunks of current bin in - sorted order to find smallest that fits. This is the only step - where an unbounded number of chunks might be scanned without doing - anything useful with them. However the lists tend to be short. + sorted order to find smallest that fits. Use the skip list for this. */ if (!in_smallbin_range(nb)) { bin = bin_at(av, idx); /* skip scan if empty or largest chunk is too small */ - if ((victim = last(bin)) != bin && - (unsigned long)(first(bin)->size) >= (unsigned long)(nb)) { + if ((victim = first(bin)) != bin && + (unsigned long)(victim->size) >= (unsigned long)(nb)) { + victim = victim->bk_nextsize; while (((unsigned long)(size = chunksize(victim)) < (unsigned long)(nb))) - victim = victim->bk; + victim = victim->bk_nextsize; + + /* Avoid removing the first entry for a size so that the skip + list does not have to be rerouted. */ + if (victim != last(bin) && victim->size == victim->fd->size) + victim = victim->fd; remainder_size = size - nb; unlink(victim, bck, fwd); @@ -4261,6 +4329,11 @@ _int_malloc(mstate av, size_t bytes) remainder->fd = fwd; bck->fd = remainder; fwd->bk = remainder; + if (!in_smallbin_range(remainder_size)) + { + remainder->fd_nextsize = NULL; + remainder->bk_nextsize = NULL; + } set_head(victim, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); set_head(remainder, remainder_size | PREV_INUSE); @@ -4330,9 +4403,7 @@ _int_malloc(mstate av, size_t bytes) remainder_size = size - nb; /* unlink */ - bck = victim->bk; - bin->bk = bck; - bck->fd = bin; + unlink(victim, bck, fwd); /* Exhaust */ if (remainder_size < MINSIZE) { @@ -4357,7 +4428,11 @@ _int_malloc(mstate av, size_t bytes) /* advertise as last remainder */ if (in_smallbin_range(nb)) av->last_remainder = remainder; - + if (!in_smallbin_range(remainder_size)) + { + remainder->fd_nextsize = NULL; + remainder->bk_nextsize = NULL; + } set_head(victim, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); set_head(remainder, remainder_size | PREV_INUSE); @@ -4580,8 +4655,13 @@ _int_free(mstate av, Void_t* mem) bck = unsorted_chunks(av); fwd = bck->fd; - p->bk = bck; p->fd = fwd; + p->bk = bck; + if (!in_smallbin_range(size)) + { + p->fd_nextsize = NULL; + p->bk_nextsize = NULL; + } bck->fd = p; fwd->bk = p; @@ -4749,6 +4829,11 @@ static void malloc_consolidate(av) mstate av; unsorted_bin->fd = p; first_unsorted->bk = p; + if (!in_smallbin_range (size)) { + p->fd_nextsize = NULL; + p->bk_nextsize = NULL; + } + set_head(p, size | PREV_INUSE); p->bk = unsorted_bin; p->fd = first_unsorted; diff --git a/libc/math/test-misc.c b/libc/math/test-misc.c index 862e11f0c..a1ad6885d 100644 --- a/libc/math/test-misc.c +++ b/libc/math/test-misc.c @@ -1235,5 +1235,85 @@ main (void) } #endif +#if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG >= DBL_MANT_DIG + 4 + int oldmode = fegetround (); + int j; + for (j = 0; j < 4; j++) + { + int mode; + int i; + int k = 0; + const char *mstr; + switch (j) + { +#ifdef FE_TONEAREST + case 0: + mode = FE_TONEAREST; + mstr = "nearest"; + k = 8; + break; +#endif +#ifdef FE_DOWNWARD + case 1: + mode = FE_DOWNWARD; + mstr = "-inf"; + break; +#endif +#ifdef FE_UPWARD + case 2: + mode = FE_UPWARD; + mstr = "+inf"; + k = 15; + break; +#endif +#ifdef FE_TOWARDZERO + case 3: + mode = FE_TOWARDZERO; + mstr = "0"; + break; +#endif + default: + continue; + } + + volatile long double ld5 = nextafter (0.0, 1.0) / 16.0L; + volatile double d5; + (void) &ld5; + for (i = 0; i <= 32; i++) + { + if (fesetround (mode)) + { + printf ("failed to set rounding mode to %s\n", mstr); + result = 1; + break; + } + d5 = ld5 * i; + (void) &d5; + fesetround (oldmode); + if (d5 != ((j == 0 && i == 8) ? 0 : (i + k) / 16) + * nextafter (0.0, 1.0)) + { + printf ("%La incorrectly rounded to %s as %a\n", + ld5 * i, mstr, d5); + result = 1; + } + } + } + + volatile long double ld7 = nextafterl (0.0L, 1.0L); + volatile double d7; + (void) &ld7; + fesetround (FE_UPWARD); + d7 = ld7; + (void) &d7; + fesetround (oldmode); + + if (d7 != nextafter (0.0, 1.0)) + { + printf ("%La incorrectly rounded upward to %a\n", ld7, d7); + result = 1; + } +#endif + return result; } diff --git a/libc/resolv/Makefile b/libc/resolv/Makefile index 217439200..a7a13c6f3 100644 --- a/libc/resolv/Makefile +++ b/libc/resolv/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003,2004 +# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2003,2004,2007 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -32,7 +32,7 @@ distribute := ../conf/portability.h mapv4v6addr.h mapv4v6hostent.h \ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ res_hconf res_libc res-state -tests = tst-aton tst-leaks +tests = tst-aton tst-leaks tst-inet_ntop xtests = tst-leaks2 generate := mtrace-tst-leaks tst-leaks.mtrace tst-leaks2.mtrace diff --git a/libc/resolv/inet_ntop.c b/libc/resolv/inet_ntop.c index e5553a1d3..1222d08bd 100644 --- a/libc/resolv/inet_ntop.c +++ b/libc/resolv/inet_ntop.c @@ -96,7 +96,7 @@ inet_ntop4(src, dst, size) static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; - if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) { + if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) { __set_errno (ENOSPC); return (NULL); } diff --git a/libc/resolv/tst-inet_ntop.c b/libc/resolv/tst-inet_ntop.c new file mode 100644 index 000000000..a042c74c9 --- /dev/null +++ b/libc/resolv/tst-inet_ntop.c @@ -0,0 +1,111 @@ +#include <arpa/inet.h> +#include <errno.h> +#include <netinet/in.h> +#include <stdio.h> +#include <string.h> + +int +main (void) +{ + struct in_addr addr4; + struct in6_addr addr6; + char buf[64]; + int result = 0; + + addr4.s_addr = 0xe0e0e0e0; + addr6.s6_addr16[0] = 0; + addr6.s6_addr16[1] = 0; + addr6.s6_addr16[2] = 0; + addr6.s6_addr16[3] = 0; + addr6.s6_addr16[4] = 0; + addr6.s6_addr16[5] = 0xffff; + addr6.s6_addr32[3] = 0xe0e0e0e0; + memset (buf, 'x', sizeof buf); + + if (inet_ntop (AF_INET, &addr4, buf, 15) != NULL) + { + puts ("1st inet_ntop returned non-NULL"); + result++; + } + else if (errno != ENOSPC) + { + puts ("1st inet_ntop didn't fail with ENOSPC"); + result++; + } + if (buf[15] != 'x') + { + puts ("1st inet_ntop wrote past the end of buffer"); + result++; + } + + if (inet_ntop (AF_INET, &addr4, buf, 16) != buf) + { + puts ("2nd inet_ntop did not return buf"); + result++; + } + if (memcmp (buf, "224.224.224.224\0" "xxxxxxxx", 24) != 0) + { + puts ("2nd inet_ntop wrote past the end of buffer"); + result++; + } + + if (inet_ntop (AF_INET6, &addr6, buf, 22) != NULL) + { + puts ("3rd inet_ntop returned non-NULL"); + result++; + } + else if (errno != ENOSPC) + { + puts ("3rd inet_ntop didn't fail with ENOSPC"); + result++; + } + if (buf[22] != 'x') + { + puts ("3rd inet_ntop wrote past the end of buffer"); + result++; + } + + if (inet_ntop (AF_INET6, &addr6, buf, 23) != buf) + { + puts ("4th inet_ntop did not return buf"); + result++; + } + if (memcmp (buf, "::ffff:224.224.224.224\0" "xxxxxxxx", 31) != 0) + { + puts ("4th inet_ntop wrote past the end of buffer"); + result++; + } + + memset (&addr6.s6_addr, 0xe0, sizeof (addr6.s6_addr)); + + if (inet_ntop (AF_INET6, &addr6, buf, 39) != NULL) + { + puts ("5th inet_ntop returned non-NULL"); + result++; + } + else if (errno != ENOSPC) + { + puts ("5th inet_ntop didn't fail with ENOSPC"); + result++; + } + if (buf[39] != 'x') + { + puts ("5th inet_ntop wrote past the end of buffer"); + result++; + } + + if (inet_ntop (AF_INET6, &addr6, buf, 40) != buf) + { + puts ("6th inet_ntop did not return buf"); + result++; + } + if (memcmp (buf, "e0e0:e0e0:e0e0:e0e0:e0e0:e0e0:e0e0:e0e0\0" + "xxxxxxxx", 48) != 0) + { + puts ("6th inet_ntop wrote past the end of buffer"); + result++; + } + + + return result; +} diff --git a/libc/soft-fp/extended.h b/libc/soft-fp/extended.h index 0e2a90c08..e5f16debe 100644 --- a/libc/soft-fp/extended.h +++ b/libc/soft-fp/extended.h @@ -94,12 +94,6 @@ union _FP_UNION_E X##_f[1] = _flo.bits.frac1; \ X##_e = _flo.bits.exp; \ X##_s = _flo.bits.sign; \ - if (!X##_e && (X##_f[1] || X##_f[0]) \ - && !(X##_f[1] & _FP_IMPLBIT_E)) \ - { \ - X##_e++; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ } while (0) #define FP_UNPACK_RAW_EP(X, val) \ @@ -112,12 +106,6 @@ union _FP_UNION_E X##_f[1] = _flo->bits.frac1; \ X##_e = _flo->bits.exp; \ X##_s = _flo->bits.sign; \ - if (!X##_e && (X##_f[1] || X##_f[0]) \ - && !(X##_f[1] & _FP_IMPLBIT_E)) \ - { \ - X##_e++; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ } while (0) #define FP_PACK_RAW_E(val, X) \ @@ -164,13 +152,13 @@ union _FP_UNION_E #define FP_UNPACK_SEMIRAW_E(X,val) \ do { \ - _FP_UNPACK_RAW_E(X,val); \ + FP_UNPACK_RAW_E(X,val); \ _FP_UNPACK_SEMIRAW(E,4,X); \ } while (0) #define FP_UNPACK_SEMIRAW_EP(X,val) \ do { \ - _FP_UNPACK_RAW_EP(X,val); \ + FP_UNPACK_RAW_EP(X,val); \ _FP_UNPACK_SEMIRAW(E,4,X); \ } while (0) @@ -189,13 +177,13 @@ union _FP_UNION_E #define FP_PACK_SEMIRAW_E(val,X) \ do { \ _FP_PACK_SEMIRAW(E,4,X); \ - _FP_PACK_RAW_E(val,X); \ + FP_PACK_RAW_E(val,X); \ } while (0) #define FP_PACK_SEMIRAW_EP(val,X) \ do { \ _FP_PACK_SEMIRAW(E,4,X); \ - _FP_PACK_RAW_EP(val,X); \ + FP_PACK_RAW_EP(val,X); \ } while (0) #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) @@ -299,11 +287,6 @@ union _FP_UNION_E X##_f1 = 0; \ X##_e = _flo.bits.exp; \ X##_s = _flo.bits.sign; \ - if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ - { \ - X##_e++; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ } while (0) #define FP_UNPACK_RAW_EP(X, val) \ @@ -315,11 +298,6 @@ union _FP_UNION_E X##_f1 = 0; \ X##_e = _flo->bits.exp; \ X##_s = _flo->bits.sign; \ - if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ - { \ - X##_e++; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ } while (0) #define FP_PACK_RAW_E(val, X) \ @@ -365,13 +343,13 @@ union _FP_UNION_E #define FP_UNPACK_SEMIRAW_E(X,val) \ do { \ - _FP_UNPACK_RAW_E(X,val); \ + FP_UNPACK_RAW_E(X,val); \ _FP_UNPACK_SEMIRAW(E,2,X); \ } while (0) #define FP_UNPACK_SEMIRAW_EP(X,val) \ do { \ - _FP_UNPACK_RAW_EP(X,val); \ + FP_UNPACK_RAW_EP(X,val); \ _FP_UNPACK_SEMIRAW(E,2,X); \ } while (0) @@ -390,13 +368,13 @@ union _FP_UNION_E #define FP_PACK_SEMIRAW_E(val,X) \ do { \ _FP_PACK_SEMIRAW(E,2,X); \ - _FP_PACK_RAW_E(val,X); \ + FP_PACK_RAW_E(val,X); \ } while (0) #define FP_PACK_SEMIRAW_EP(val,X) \ do { \ _FP_PACK_SEMIRAW(E,2,X); \ - _FP_PACK_RAW_EP(val,X); \ + FP_PACK_RAW_EP(val,X); \ } while (0) #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) diff --git a/libc/soft-fp/floatundidf.c b/libc/soft-fp/floatundidf.c index 2169a3f19..af8e4a5ae 100644 --- a/libc/soft-fp/floatundidf.c +++ b/libc/soft-fp/floatundidf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 64bit unsigned integer to IEEE double - Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,8 +32,7 @@ #include "soft-fp.h" #include "double.h" -double -__floatundidf(UDItype i) +DFtype __floatundidf(UDItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/libc/soft-fp/floatundisf.c b/libc/soft-fp/floatundisf.c index 5f08764dc..977f7dfc7 100644 --- a/libc/soft-fp/floatundisf.c +++ b/libc/soft-fp/floatundisf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 64bit unsigned integer to IEEE single - Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,8 +32,7 @@ #include "soft-fp.h" #include "single.h" -float -__floatundisf(UDItype i) +SFtype __floatundisf(UDItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/libc/soft-fp/floatunsidf.c b/libc/soft-fp/floatunsidf.c index 97b488ab6..12d0f25bf 100644 --- a/libc/soft-fp/floatunsidf.c +++ b/libc/soft-fp/floatunsidf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 32bit unsigned integer to IEEE double - Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,8 +32,7 @@ #include "soft-fp.h" #include "double.h" -double -__floatunsidf(USItype i) +DFtype __floatunsidf(USItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/libc/soft-fp/floatunsisf.c b/libc/soft-fp/floatunsisf.c index 2ec16ba7b..80c5d3d35 100644 --- a/libc/soft-fp/floatunsisf.c +++ b/libc/soft-fp/floatunsisf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 32bit unsigned integer to IEEE single - Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1999, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com) and Jakub Jelinek (jj@ultra.linux.cz). @@ -32,8 +32,7 @@ #include "soft-fp.h" #include "single.h" -float -__floatunsisf(USItype i) +SFtype __floatunsisf(USItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/libc/soft-fp/op-2.h b/libc/soft-fp/op-2.h index 5c9bce4c1..3a3b3aa06 100644 --- a/libc/soft-fp/op-2.h +++ b/libc/soft-fp/op-2.h @@ -1,6 +1,6 @@ /* Software floating-point emulation. Basic two-word fraction declaration and manipulation. - Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. + Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com), Jakub Jelinek (jj@ultra.linux.cz), @@ -613,3 +613,5 @@ #define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0) #define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) + +#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) diff --git a/libc/soft-fp/op-4.h b/libc/soft-fp/op-4.h index 1b90535c5..70b9fafbe 100644 --- a/libc/soft-fp/op-4.h +++ b/libc/soft-fp/op-4.h @@ -1,6 +1,6 @@ /* Software floating-point emulation. Basic four-word fraction declaration and manipulation. - Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc. + Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson (rth@cygnus.com), Jakub Jelinek (jj@ultra.linux.cz), @@ -684,3 +684,5 @@ do { \ D##_f[1] = S##_f1; \ D##_f[2] = D##_f[3] = 0; \ } while (0) + +#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) diff --git a/libc/soft-fp/op-common.h b/libc/soft-fp/op-common.h index 1f58b8947..ef11b527b 100644 --- a/libc/soft-fp/op-common.h +++ b/libc/soft-fp/op-common.h @@ -1153,7 +1153,8 @@ do { \ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ - || _FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ + || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ + && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ abort(); \ D##_s = S##_s; \ _FP_FRAC_COPY_##dwc##_##swc(D, S); \ @@ -1168,6 +1169,14 @@ do { \ { \ if (_FP_FRAC_ZEROP_##swc(S)) \ D##_e = 0; \ + else if (_FP_EXPBIAS_##dfs \ + < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ + - _FP_FRACBITS_##sfs)); \ + D##_e = 0; \ + } \ else \ { \ int _lz; \ @@ -1199,7 +1208,8 @@ do { \ #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ do { \ if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ - || _FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ + || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ + && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ abort(); \ D##_s = S##_s; \ if (_FP_EXP_NORMAL(sfs, swc, S)) \ @@ -1237,11 +1247,24 @@ do { \ if (S##_e == 0) \ { \ D##_e = 0; \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - if (!_FP_FRAC_ZEROP_##swc(S)) \ + if (_FP_FRAC_ZEROP_##swc(S)) \ + _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ + else \ { \ FP_SET_EXCEPTION(FP_EX_DENORM); \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ + if (_FP_EXPBIAS_##sfs \ + < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ + { \ + _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + _FP_FRAC_COPY_##dwc##_##swc(D, S); \ + } \ + else \ + { \ + _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ + _FP_FRAC_LOW_##dwc(D) |= 1; \ + } \ } \ } \ else \ diff --git a/libc/stdio-common/printf_fp.c b/libc/stdio-common/printf_fp.c index 9b796eac2..6e5ff5855 100644 --- a/libc/stdio-common/printf_fp.c +++ b/libc/stdio-common/printf_fp.c @@ -793,7 +793,7 @@ ___printf_fp (FILE *fp, else { /* This is a special case. We don't need a factor because the - numbers are in the range of 0.0 <= fp < 8.0. We simply + numbers are in the range of 1.0 <= |fp| < 8.0. We simply shift it to the right place and divide it by 1.0 to get the leading digit. (Of course this division is not really made.) */ assert (0 <= exponent && exponent < 3 && @@ -1013,6 +1013,12 @@ ___printf_fp (FILE *fp, { *wstartp = '1'; exponent += expsign == 0 ? 1 : -1; + + /* The above exponent adjustment could lead to 1.0e-00, + e.g. for 0.999999999. Make sure exponent 0 always + uses + sign. */ + if (exponent == 0) + expsign = 0; } else if (intdig_no == dig_max) { diff --git a/libc/stdio-common/test-vfprintf.c b/libc/stdio-common/test-vfprintf.c index a683eac77..342ac471d 100644 --- a/libc/stdio-common/test-vfprintf.c +++ b/libc/stdio-common/test-vfprintf.c @@ -1,5 +1,5 @@ /* Tests of *printf for very large strings. - Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -94,6 +94,7 @@ main (void) fprintf (fp, "%.*s", 30000, large); large[20000] = '\0'; fprintf (fp, large); + fprintf (fp, "%-1.300000000s", "hello"); if (fflush (fp) != 0 || ferror (fp) != 0 || fclose (fp) != 0) { @@ -108,11 +109,12 @@ main (void) setlocale (LC_ALL, NULL)); exit (1); } - else if (st.st_size != 99999) + else if (st.st_size != 50000 + 30000 + 19999 + 5) { printf ("file size incorrect for locale %s: %jd instead of %jd\n", setlocale (LC_ALL, NULL), - (intmax_t) st.st_size, (intmax_t) 99999); + (intmax_t) st.st_size, + (intmax_t) 50000 + 30000 + 19999 + 5); res = 1; } else diff --git a/libc/stdio-common/tfformat.c b/libc/stdio-common/tfformat.c index 259e2e0b1..d67b3b504 100644 --- a/libc/stdio-common/tfformat.c +++ b/libc/stdio-common/tfformat.c @@ -4021,6 +4021,8 @@ sprint_double_type sprint_doubles[] = {__LINE__, 0.000098, "0.0001", "%#.0g"}, {__LINE__, 0.0000996, "0.00010", "%#.2g"}, {__LINE__, 9.999999999999999e-05, "0.0001", "%g"}, + {__LINE__, 1.0, "1.000000e+00", "%e"}, + {__LINE__, .9999999999999999, "1.000000e+00", "%e"}, {0 } diff --git a/libc/stdio-common/vfprintf.c b/libc/stdio-common/vfprintf.c index 946551f2d..20c07ce73 100644 --- a/libc/stdio-common/vfprintf.c +++ b/libc/stdio-common/vfprintf.c @@ -1160,19 +1160,26 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) else \ { \ /* In case we have a multibyte character set the \ - situation is more compilcated. We must not copy \ + situation is more complicated. We must not copy \ bytes at the end which form an incomplete character. */\ - wchar_t ignore[prec]; \ + size_t ignore_size = (unsigned) prec > 1024 ? 1024 : prec;\ + wchar_t ignore[ignore_size]; \ const char *str2 = string; \ - mbstate_t ps; \ + const char *strend = string + prec; \ + if (strend < string) \ + strend = (const char *) UINTPTR_MAX; \ \ + mbstate_t ps; \ memset (&ps, '\0', sizeof (ps)); \ - if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps) \ - == (size_t) -1) \ - { \ - done = -1; \ - goto all_done; \ - } \ + \ + while (str2 != NULL && str2 < strend) \ + if (__mbsnrtowcs (ignore, &str2, strend - str2, 1024, \ + &ps) == (size_t) -1) \ + { \ + done = -1; \ + goto all_done; \ + } \ + \ if (str2 == NULL) \ len = strlen (string); \ else \ diff --git a/libc/sysdeps/posix/getaddrinfo.c b/libc/sysdeps/posix/getaddrinfo.c index 298755f8e..adb3c4f96 100644 --- a/libc/sysdeps/posix/getaddrinfo.c +++ b/libc/sysdeps/posix/getaddrinfo.c @@ -61,6 +61,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <nscd/nscd-client.h> #include <nscd/nscd_proto.h> +#ifdef HAVE_NETLINK_ROUTE +# include <kernel-features.h> +#endif + #ifdef HAVE_LIBIDN extern int __idna_to_ascii_lz (const char *input, char **output, int flags); extern int __idna_to_unicode_lzlz (const char *input, char **output, @@ -1095,6 +1099,10 @@ static const struct prefixentry default_labels[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 7, 6 }, { { .in6_u + = { .u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, + 32, 7 }, + { { .in6_u = { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 0, 1 } @@ -1728,6 +1736,16 @@ gaiconf_reload (void) } +#if HAVE_NETLINK_ROUTE +# if __ASSUME_NETLINK_SUPPORT == 0 +/* Defined in ifaddrs.c. */ +extern int __no_netlink_support attribute_hidden; +# else +# define __no_netlink_support 0 +# endif +#endif + + int getaddrinfo (const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **pai) @@ -1763,20 +1781,74 @@ getaddrinfo (const char *name, const char *service, return EAI_BADFLAGS; struct in6addrinfo *in6ai = NULL; - size_t in6ailen; + size_t in6ailen = 0; bool seen_ipv4 = false; bool seen_ipv6 = false; +#ifdef HAVE_NETLINK_ROUTE + int sockfd = -1; + pid_t nl_pid; +#endif /* We might need information about what kind of interfaces are available. But even if AI_ADDRCONFIG is not used, if the user requested IPv6 addresses we have to know whether an address is deprecated or temporary. */ if ((hints->ai_flags & AI_ADDRCONFIG) || hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET6) - /* Determine whether we have IPv4 or IPv6 interfaces or both. We - cannot cache the results since new interfaces could be added at - any time. */ - __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); + { + /* Determine whether we have IPv4 or IPv6 interfaces or both. We + cannot cache the results since new interfaces could be added at + any time. */ + __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); +#ifdef HAVE_NETLINK_ROUTE + if (! __no_netlink_support) + { + sockfd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + struct sockaddr_nl nladdr; + memset (&nladdr, '\0', sizeof (nladdr)); + nladdr.nl_family = AF_NETLINK; + + socklen_t addr_len = sizeof (nladdr); + + if (sockfd >= 0 + && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0 + && __getsockname (sockfd, (struct sockaddr *) &nladdr, + &addr_len) == 0 + && make_request (sockfd, nladdr.nl_pid, &seen_ipv4, &seen_ipv6, + in6ai, in6ailen) == 0) + { + /* It worked. */ + nl_pid = nladdr.nl_pid; + goto got_netlink_socket; + } + + if (sockfd >= 0) + close_not_cancel_no_status (sockfd); + +#if __ASSUME_NETLINK_SUPPORT == 0 + /* Remember that there is no netlink support. */ + if (errno != EMFILE && errno != ENFILE) + __no_netlink_support = 1; +#else + else + { + if (errno != EMFILE && errno != ENFILE) + sockfd = -2; + + /* We cannot determine what interfaces are available. Be + pessimistic. */ + seen_ipv4 = true; + seen_ipv6 = true; + return; + } +#endif + } +#endif + } + +#ifdef HAVE_NETLINK_ROUTE + got_netlink_socket: +#endif if (hints->ai_flags & AI_ADDRCONFIG) { /* Now make a decision on what we return, if anything. */ diff --git a/ports/ChangeLog.hppa b/ports/ChangeLog.hppa index 068044add..7d38ab0fd 100644 --- a/ports/ChangeLog.hppa +++ b/ports/ChangeLog.hppa @@ -1,3 +1,9 @@ +2007-05-01 Carlos O'Donell <carlos@systemhalted.org> + + * sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h + [__USE_XOPEN2K]: Define pthread_rwlock_t and + pthread_rwlockattr_t. + 2007-02-02 Carlos O'Donell <carlos@systemhalted.org> * sysdeps/unix/sysv/linux/hppa/sysdep.h (PTR_MANGLE): Define. diff --git a/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h b/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h index e2c6f5957..717371831 100644 --- a/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h +++ b/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/bits/pthreadtypes.h @@ -111,8 +111,7 @@ typedef struct /* Once-only execution */ typedef int pthread_once_t; - -#ifdef __USE_UNIX98 +#if defined __USE_UNIX98 || defined __USE_XOPEN2K /* Read-write locks. */ typedef struct _pthread_rwlock_t { |