[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r2127 - in /fsf/trunk/libc: ./ malloc/ resolv/ stdio-common/
- To: commits@xxxxxxxxxx
- Subject: [commits] r2127 - in /fsf/trunk/libc: ./ malloc/ resolv/ stdio-common/
- From: eglibc@xxxxxxxxxx
- Date: Tue, 01 May 2007 07:01:44 -0000
Author: eglibc
Date: Tue May 1 00:01:44 2007
New Revision: 2127
Log:
Import glibc-mainline for 2007-05-01
Added:
fsf/trunk/libc/resolv/tst-inet_ntop.c
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/malloc/malloc.c
fsf/trunk/libc/resolv/Makefile
fsf/trunk/libc/resolv/inet_ntop.c
fsf/trunk/libc/stdio-common/printf_fp.c
fsf/trunk/libc/stdio-common/tfformat.c
fsf/trunk/libc/stdio-common/vfprintf.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Tue May 1 00:01:44 2007
@@ -1,3 +1,30 @@
+2007-04-30 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ [BZ #4438]
+ * stdio-common/vfprintf.c (process_string_arg): Don't overflow the
+ stack for large precisions.
+
+2007-04-30 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * 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@xxxxxxxxxx>
+ Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ [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@xxxxxxxxx>.
+
2007-04-28 Ulrich Drepper <drepper@xxxxxxxxxx>
[BZ #4102]
Modified: fsf/trunk/libc/malloc/malloc.c
==============================================================================
--- fsf/trunk/libc/malloc/malloc.c (original)
+++ fsf/trunk/libc/malloc/malloc.c Tue May 1 00:01:44 2007
@@ -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@xxxxxxxxx>
and Doug Lea <dl@xxxxxxxxxxxxx>, 2001.
@@ -26,10 +26,6 @@
* Version ptmalloc2-20011215
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
@@ -1781,6 +1777,10 @@
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 @@
#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 @@
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 @@
/* 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 @@
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 @@
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 @@
/*
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 @@
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 @@
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 @@
/* 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 @@
bck = unsorted_chunks(av);
fwd = bck->fd;
+ p->fd = fwd;
p->bk = bck;
- p->fd = fwd;
+ if (!in_smallbin_range(size))
+ {
+ p->fd_nextsize = NULL;
+ p->bk_nextsize = NULL;
+ }
bck->fd = p;
fwd->bk = p;
@@ -4748,6 +4828,11 @@
first_unsorted = unsorted_bin->fd;
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;
Modified: fsf/trunk/libc/resolv/Makefile
==============================================================================
--- fsf/trunk/libc/resolv/Makefile (original)
+++ fsf/trunk/libc/resolv/Makefile Tue May 1 00:01:44 2007
@@ -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 @@
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
Modified: fsf/trunk/libc/resolv/inet_ntop.c
==============================================================================
--- fsf/trunk/libc/resolv/inet_ntop.c (original)
+++ fsf/trunk/libc/resolv/inet_ntop.c Tue May 1 00:01:44 2007
@@ -96,7 +96,7 @@
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);
}
Added: fsf/trunk/libc/resolv/tst-inet_ntop.c
==============================================================================
--- fsf/trunk/libc/resolv/tst-inet_ntop.c (added)
+++ fsf/trunk/libc/resolv/tst-inet_ntop.c Tue May 1 00:01:44 2007
@@ -1,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;
+}
Modified: fsf/trunk/libc/stdio-common/printf_fp.c
==============================================================================
--- fsf/trunk/libc/stdio-common/printf_fp.c (original)
+++ fsf/trunk/libc/stdio-common/printf_fp.c Tue May 1 00:01:44 2007
@@ -793,7 +793,7 @@
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 @@
{
*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)
{
Modified: fsf/trunk/libc/stdio-common/tfformat.c
==============================================================================
--- fsf/trunk/libc/stdio-common/tfformat.c (original)
+++ fsf/trunk/libc/stdio-common/tfformat.c Tue May 1 00:01:44 2007
@@ -4021,6 +4021,8 @@
{__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 }
Modified: fsf/trunk/libc/stdio-common/vfprintf.c
==============================================================================
--- fsf/trunk/libc/stdio-common/vfprintf.c (original)
+++ fsf/trunk/libc/stdio-common/vfprintf.c Tue May 1 00:01:44 2007
@@ -1160,19 +1160,25 @@
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]; \
+ wchar_t ignore[1024]; \
const char *str2 = string; \
+ 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 \