summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-11-15 09:47:23 +0000
committerJakub Jelinek <jakub@redhat.com>2004-11-15 09:47:23 +0000
commitb3c20a361d75caf75f670b2fcd64ab8668c16ca5 (patch)
treecac006e13628dcbf5a48cb618417ae708906db89
parent87ffc9aca119436c8530d6605483a49cfb16668e (diff)
Updated to fedora-glibc-20041115T0915
-rw-r--r--ChangeLog51
-rw-r--r--debug/chk_fail.c18
-rw-r--r--debug/test-strcpy_chk.c36
-rw-r--r--debug/tst-chk1.c16
-rw-r--r--elf/elf.h7
-rw-r--r--elf/rtld.c20
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in7
-rw-r--r--include/stdio.h2
-rw-r--r--malloc/malloc.c354
-rw-r--r--nis/ypclnt.c2
-rw-r--r--posix/Makefile1
-rw-r--r--sysdeps/posix/libc_fatal.c125
-rw-r--r--sysdeps/unix/sysv/linux/libc_fatal.c144
14 files changed, 501 insertions, 286 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ff1338078..5e1b916936 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2004-11-13 Ulrich Drepper <drepper@redhat.com>
+
+ * malloc/malloc.c (malloc_state): stat_lock_* elements need only
+ be defined if THREAD_STATS is defined. Remove pad0_ since it does
+ not align with cache line sizes in general anyway.
+
+2004-11-13 Jakub Jelinek <jakub@redhat.com>
+
+ * elf/rtld.c (print_statistics): Avoid segfaults if not all namespaces
+ are used. Fix computation of num_relative_relocations on RELA
+ architectures other than IA-64 and Alpha.
+
+2004-11-13 Ulrich Drepper <drepper@redhat.com>
+
+ * malloc/malloc.c (_int_free): Use munmap_chunk for handling
+ mmaped memory.
+
+2004-11-12 Ulrich Drepper <drepper@redhat.com>
+
+ * malloc/malloc.c (_int_free): Remove test for NULL parameter.
+ (_int_realloc): Call _int_free only if memory parameter is not NULL.
+
+ * sysdeps/unix/sysv/linux/libc_fatal.c: Add new function __libc_message
+ which performs the printing and simple format string handling. The
+ string is written to tty, stderr, syslog in this order, stopping after
+ the first successful output.
+ (__libc_fatal): Call __libc_message.
+ * include/stdio.h: Declare __libc_message.
+ * malloc/malloc.c (malloc_printerr): Use __libc_message.
+ * debug/chk_fail.c: Also print message with __libc_message.
+ * debug/test-strcpy_chk.c: Ensure that debug messages are not printed
+ to the terminal or stderr.
+ * debug/tst-chk1.c: Likewise.
+
+ * posix/Makefile: Remove gpl2lgpl variable.
+
+2004-11-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf/elf.h: Add 20 bit relocations R_390_*20.
+
2004-11-12 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/i386/setuid.c: Include linux/posix_types.h.
@@ -7,16 +47,9 @@
* sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setresgid.c: Likewise.
-2004-11-11 Jakub Jelinek <jakub@redhat.com>
+2004-11-12 Andreas Schwab <schwab@suse.de>
- * debug/chk_fail.c: Include errno.h and string.h.
- (__chk_fail): Write a short message to stderr.
- * debug/tst-chk1.c: Include fcntl.h.
- (do_test): Redirect stderr to /dev/null.
- * debug/test-strcpy_chk.c: Include fcntl.h.
- (test_main): Redirect stderr to /dev/null.
- (do_one_test, do_random_tests): Use printf instead of
- error.
+ * nis/ypclnt.c (ypprot_err): Fix "minor optimizations".
2004-11-12 Ulrich Drepper <drepper@redhat.com>
diff --git a/debug/chk_fail.c b/debug/chk_fail.c
index 70ffa9e40f..dc1c3d70b6 100644
--- a/debug/chk_fail.c
+++ b/debug/chk_fail.c
@@ -1,3 +1,4 @@
+
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,27 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <abort-instr.h>
void
__attribute__ ((noreturn))
__chk_fail (void)
{
- while (1)
- {
- const char *text = "*** buffer overflow detected ***\n";
- TEMP_FAILURE_RETRY (write (STDERR_FILENO, text, strlen (text)));
- /* This will leave a nice backtrace. */
- abort ();
-#ifdef ABORT_INSTRUCTION
- ABORT_INSTRUCTION;
-#endif
- _exit (127);
- }
+ __libc_fatal ("*** buffer overflow detected ***\n");
}
libc_hidden_def (__chk_fail)
diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c
index 8430ca4704..ac9f9448cf 100644
--- a/debug/test-strcpy_chk.c
+++ b/debug/test-strcpy_chk.c
@@ -46,9 +46,10 @@ simple_strcpy_chk (char *dst, const char *src, size_t len)
}
#endif
+#include <fcntl.h>
+#include <paths.h>
#include <setjmp.h>
#include <signal.h>
-#include <fcntl.h>
volatile int chk_fail_ok;
jmp_buf chk_fail_buf;
@@ -81,8 +82,8 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (setjmp (chk_fail_buf) == 0)
{
res = CALL (impl, dst, src, dlen);
- printf ("*** Function %s (%zd; %zd) did not __chk_fail",
- impl->name, len, dlen);
+ printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
+ impl->name, len, dlen);
chk_fail_ok = 0;
ret = 1;
}
@@ -93,7 +94,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (res != STRCPY_RESULT (dst, len))
{
- printf ("*** Wrong result in function %s %p %p", impl->name,
+ printf ("Wrong result in function %s %p %p\n", impl->name,
res, STRCPY_RESULT (dst, len));
ret = 1;
return;
@@ -101,7 +102,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (strcmp (dst, src) != 0)
{
- printf ("*** Wrong result in function %s dst \"%s\" src \"%s\"",
+ printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
impl->name, dst, src);
ret = 1;
return;
@@ -233,7 +234,7 @@ do_random_tests (void)
if (setjmp (chk_fail_buf) == 0)
{
res = CALL (impl, p2 + align2, p1 + align1, dlen);
- printf ("*** Iteration %zd - did not __chk_fail", n);
+ printf ("Iteration %zd - did not __chk_fail\n", n);
chk_fail_ok = 0;
ret = 1;
}
@@ -244,7 +245,8 @@ do_random_tests (void)
res = CALL (impl, p2 + align2, p1 + align1, dlen);
if (res != STRCPY_RESULT (p2 + align2, len))
{
- printf ("*** Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
+ printf ("\
+Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n",
n, impl->name, align1, align2, len, res,
STRCPY_RESULT (p2 + align2, len));
ret = 1;
@@ -253,7 +255,8 @@ do_random_tests (void)
{
if (p2[j - 64] != '\1')
{
- printf ("*** Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
+ printf ("\
+Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
break;
@@ -263,7 +266,8 @@ do_random_tests (void)
{
if (p2[j] != '\1')
{
- printf ("*** Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
+ printf ("\
+Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
break;
@@ -271,7 +275,8 @@ do_random_tests (void)
}
if (memcmp (p1 + align1, p2 + align2, len + 1))
{
- printf ("*** Iteration %zd - different strings, %s (%zd, %zd, %zd)",
+ printf ("\
+Iteration %zd - different strings, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
}
@@ -292,8 +297,15 @@ test_main (void)
sigaction (SIGABRT, &sa, NULL);
/* Avoid all the buffer overflow messages on stderr. */
- close (STDERR_FILENO);
- open ("/dev/null", O_WRONLY);
+ int fd = open (_PATH_DEVNULL, O_WRONLY);
+ if (fd == -1)
+ close (STDERR_FILENO);
+ else
+ {
+ dup2 (fd, STDERR_FILENO);
+ close (fd);
+ }
+ setenv ("LIBC_FATAL_STDERR_", "1", 1);
test_init ();
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index e01284ae53..37320c3514 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <fcntl.h>
+#include <paths.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
@@ -108,8 +109,15 @@ do_test (void)
sigaction (SIGABRT, &sa, NULL);
/* Avoid all the buffer overflow messages on stderr. */
- close (STDERR_FILENO);
- open ("/dev/null", O_WRONLY);
+ int fd = open (_PATH_DEVNULL, O_WRONLY);
+ if (fd == -1)
+ close (STDERR_FILENO);
+ else
+ {
+ dup2 (fd, STDERR_FILENO);
+ close (fd);
+ }
+ setenv ("LIBC_FATAL_STDERR_", "1", 1);
struct A { char buf1[9]; char buf2[1]; } a;
@@ -205,7 +213,7 @@ do_test (void)
if (memcmp (a.buf1, "aabcdabcjj", 10))
FAIL ();
-#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
+#if __USE_FORTIFY_LEVEL < 2
/* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
and sufficient GCC support, as the string operations overflow
from a.buf1 into a.buf2. */
@@ -304,7 +312,7 @@ do_test (void)
memset (a.buf1 + 9, 'j', l0 + 2);
CHK_FAIL_END
-#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
+#if __USE_FORTIFY_LEVEL >= 2
# define O 0
#else
# define O 1
diff --git a/elf/elf.h b/elf/elf.h
index db95254f74..0daff76a41 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2402,8 +2402,13 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
block. */
+#define R_390_20 57 /* Direct 20 bit. */
+#define R_390_GOT20 58 /* 20 bit GOT offset. */
+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
+ block offset. */
/* Keep this the last entry. */
-#define R_390_NUM 57
+#define R_390_NUM 61
/* CRIS relocations. */
diff --git a/elf/rtld.c b/elf/rtld.c
index e53273c2bb..e442aa257f 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2444,19 +2444,29 @@ print_statistics (hp_timing_t *rtld_total_timep)
unsigned long int num_relative_relocations = 0;
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
{
+ if (GL(dl_ns)[ns]._ns_loaded == NULL)
+ continue;
+
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist;
for (unsigned int i = 0; i < scope->r_nlist; i++)
{
struct link_map *l = scope->r_list [i];
- if (!l->l_addr)
- continue;
-
- if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
+ if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
- if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#ifndef ELF_MACHINE_REL_RELATIVE
+ /* Relative relocations are processed on these architectures if
+ library is loaded to different address than p_vaddr or
+ if not prelinked. */
+ if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)])
+ && l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#else
+ /* On e.g. IA-64 or Alpha, relative relocations are processed
+ only if library is loaded to different address than p_vaddr. */
+ if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#endif
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
}
diff --git a/fedora/branch.mk b/fedora/branch.mk
index 2714ad4822..3add7920d6 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -1,5 +1,5 @@
# This file is updated automatically by Makefile.
glibc-branch := fedora
glibc-base := HEAD
-fedora-sync-date := 2004-11-12 16:40 UTC
-fedora-sync-tag := fedora-glibc-20041112T1640
+fedora-sync-date := 2004-11-15 09:15 UTC
+fedora-sync-tag := fedora-glibc-20041115T0915
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index 0d97316b37..1c93fc1e0b 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 77
+%define glibcrelease 78
%define auxarches i586 i686 athlon sparcv9 alphaev6
%define prelinkarches noarch
%define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@@ -1256,6 +1256,11 @@ rm -f *.filelist*
%endif
%changelog
+* Mon Nov 15 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-78
+- update from CVS
+ - issue error message before aborting in __chk_fail ()
+ - some more free () checking
+
* Fri Nov 12 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-77
- update from CVS
- speedup regex on palindromes (BZ #429)
diff --git a/include/stdio.h b/include/stdio.h
index 05a91b4cb3..ad8f157829 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -62,6 +62,8 @@ extern int __gen_tempname (char *__tmpl, int __kind);
/* Print out MESSAGE on the error output and abort. */
extern void __libc_fatal (__const char *__message)
__attribute__ ((__noreturn__));
+extern void __libc_message (int do_abort, __const char *__fnt, ...)
+ __attribute__ ((__noreturn__));
/* Acquire ownership of STREAM. */
extern void __flockfile (FILE *__stream);
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6d6294c6e6..57074108f1 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2192,10 +2192,12 @@ typedef struct malloc_chunk* mfastbinptr;
struct malloc_state {
/* Serialize access. */
mutex_t mutex;
+ // Should we have padding to move the mutex to its own cache line?
+#if THREAD_STATS
/* Statistics for locking. Only used if THREAD_STATS is defined. */
long stat_lock_direct, stat_lock_loop, stat_lock_wait;
- long pad0_[1]; /* try to give the mutex its own cacheline */
+#endif
/* The maximum chunk size to be eligible for fastbin */
INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */
@@ -4196,191 +4198,182 @@ _int_free(mstate av, Void_t* mem)
mchunkptr fwd; /* misc temp for linking */
- /* free(0) has no effect */
- if (mem != 0) {
- const char *errstr = NULL;
+ const char *errstr = NULL;
- p = mem2chunk(mem);
- size = chunksize(p);
+ p = mem2chunk(mem);
+ size = chunksize(p);
- /* Little security check which won't hurt performance: the
- allocator never wrapps around at the end of the address space.
- Therefore we can exclude some size values which might appear
- here by accident or by "design" from some intruder. */
- if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
- {
- errstr = "free(): invalid pointer";
- errout:
- malloc_printerr (check_action, errstr, mem);
- return;
- }
+ /* Little security check which won't hurt performance: the
+ allocator never wrapps around at the end of the address space.
+ Therefore we can exclude some size values which might appear
+ here by accident or by "design" from some intruder. */
+ if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
+ {
+ errstr = "free(): invalid pointer";
+ errout:
+ malloc_printerr (check_action, errstr, mem);
+ return;
+ }
- check_inuse_chunk(av, p);
+ check_inuse_chunk(av, p);
- /*
- If eligible, place chunk on a fastbin so it can be found
- and used quickly in malloc.
- */
+ /*
+ If eligible, place chunk on a fastbin so it can be found
+ and used quickly in malloc.
+ */
- if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
+ if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
#if TRIM_FASTBINS
- /*
- If TRIM_FASTBINS set, don't place chunks
- bordering top into fastbins
- */
- && (chunk_at_offset(p, size) != av->top)
-#endif
- ) {
-
- set_fastchunks(av);
- fb = &(av->fastbins[fastbin_index(size)]);
- /* Another simple check: make sure the top of the bin is not the
- record we are going to add (i.e., double free). */
- if (__builtin_expect (*fb == p, 0))
- {
- errstr = "double free or corruption (fasttop)";
- goto errout;
- }
- p->fd = *fb;
- *fb = p;
- }
-
- /*
- Consolidate other non-mmapped chunks as they arrive.
- */
+ /*
+ If TRIM_FASTBINS set, don't place chunks
+ bordering top into fastbins
+ */
+ && (chunk_at_offset(p, size) != av->top)
+#endif
+ ) {
- else if (!chunk_is_mmapped(p)) {
- nextchunk = chunk_at_offset(p, size);
+ set_fastchunks(av);
+ fb = &(av->fastbins[fastbin_index(size)]);
+ /* Another simple check: make sure the top of the bin is not the
+ record we are going to add (i.e., double free). */
+ if (__builtin_expect (*fb == p, 0))
+ {
+ errstr = "double free or corruption (fasttop)";
+ goto errout;
+ }
+ p->fd = *fb;
+ *fb = p;
+ }
- /* Lightweight tests: check whether the block is already the
- top block. */
- if (__builtin_expect (p == av->top, 0))
- {
- errstr = "double free or corruption (top)";
- goto errout;
- }
- /* Or whether the next chunk is beyond the boundaries of the arena. */
- if (__builtin_expect (contiguous (av)
- && (char *) nextchunk
- >= ((char *) av->top + chunksize(av->top)), 0))
- {
- errstr = "double free or corruption (out)";
- goto errout;
- }
- /* Or whether the block is actually not marked used. */
- if (__builtin_expect (!prev_inuse(nextchunk), 0))
- {
- errstr = "double free or corruption (!prev)";
- goto errout;
- }
+ /*
+ Consolidate other non-mmapped chunks as they arrive.
+ */
- nextsize = chunksize(nextchunk);
- assert(nextsize > 0);
+ else if (!chunk_is_mmapped(p)) {
+ nextchunk = chunk_at_offset(p, size);
- /* consolidate backward */
- if (!prev_inuse(p)) {
- prevsize = p->prev_size;
- size += prevsize;
- p = chunk_at_offset(p, -((long) prevsize));
- unlink(p, bck, fwd);
+ /* Lightweight tests: check whether the block is already the
+ top block. */
+ if (__builtin_expect (p == av->top, 0))
+ {
+ errstr = "double free or corruption (top)";
+ goto errout;
+ }
+ /* Or whether the next chunk is beyond the boundaries of the arena. */
+ if (__builtin_expect (contiguous (av)
+ && (char *) nextchunk
+ >= ((char *) av->top + chunksize(av->top)), 0))
+ {
+ errstr = "double free or corruption (out)";
+ goto errout;
+ }
+ /* Or whether the block is actually not marked used. */
+ if (__builtin_expect (!prev_inuse(nextchunk), 0))
+ {
+ errstr = "double free or corruption (!prev)";
+ goto errout;
}
- if (nextchunk != av->top) {
- /* get and clear inuse bit */
- nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
-
- /* consolidate forward */
- if (!nextinuse) {
- unlink(nextchunk, bck, fwd);
- size += nextsize;
- } else
- clear_inuse_bit_at_offset(nextchunk, 0);
-
- /*
- Place the chunk in unsorted chunk list. Chunks are
- not placed into regular bins until after they have
- been given one chance to be used in malloc.
- */
+ nextsize = chunksize(nextchunk);
+ assert(nextsize > 0);
- bck = unsorted_chunks(av);
- fwd = bck->fd;
- p->bk = bck;
- p->fd = fwd;
- bck->fd = p;
- fwd->bk = p;
+ /* consolidate backward */
+ if (!prev_inuse(p)) {
+ prevsize = p->prev_size;
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ unlink(p, bck, fwd);
+ }
- set_head(p, size | PREV_INUSE);
- set_foot(p, size);
+ if (nextchunk != av->top) {
+ /* get and clear inuse bit */
+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
- check_free_chunk(av, p);
- }
+ /* consolidate forward */
+ if (!nextinuse) {
+ unlink(nextchunk, bck, fwd);
+ size += nextsize;
+ } else
+ clear_inuse_bit_at_offset(nextchunk, 0);
/*
- If the chunk borders the current high end of memory,
- consolidate into top
+ Place the chunk in unsorted chunk list. Chunks are
+ not placed into regular bins until after they have
+ been given one chance to be used in malloc.
*/
- else {
- size += nextsize;
- set_head(p, size | PREV_INUSE);
- av->top = p;
- check_chunk(av, p);
- }
+ bck = unsorted_chunks(av);
+ fwd = bck->fd;
+ p->bk = bck;
+ p->fd = fwd;
+ bck->fd = p;
+ fwd->bk = p;
- /*
- If freeing a large space, consolidate possibly-surrounding
- chunks. Then, if the total unused topmost memory exceeds trim
- threshold, ask malloc_trim to reduce top.
-
- Unless max_fast is 0, we don't know if there are fastbins
- bordering top, so we cannot tell for sure whether threshold
- has been reached unless fastbins are consolidated. But we
- don't want to consolidate on each free. As a compromise,
- consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
- is reached.
- */
+ set_head(p, size | PREV_INUSE);
+ set_foot(p, size);
+
+ check_free_chunk(av, p);
+ }
+
+ /*
+ If the chunk borders the current high end of memory,
+ consolidate into top
+ */
- if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
- if (have_fastchunks(av))
- malloc_consolidate(av);
+ else {
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ check_chunk(av, p);
+ }
- if (av == &main_arena) {
+ /*
+ If freeing a large space, consolidate possibly-surrounding
+ chunks. Then, if the total unused topmost memory exceeds trim
+ threshold, ask malloc_trim to reduce top.
+
+ Unless max_fast is 0, we don't know if there are fastbins
+ bordering top, so we cannot tell for sure whether threshold
+ has been reached unless fastbins are consolidated. But we
+ don't want to consolidate on each free. As a compromise,
+ consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
+ is reached.
+ */
+
+ if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
+ if (have_fastchunks(av))
+ malloc_consolidate(av);
+
+ if (av == &main_arena) {
#ifndef MORECORE_CANNOT_TRIM
- if ((unsigned long)(chunksize(av->top)) >=
- (unsigned long)(mp_.trim_threshold))
- sYSTRIm(mp_.top_pad, av);
+ if ((unsigned long)(chunksize(av->top)) >=
+ (unsigned long)(mp_.trim_threshold))
+ sYSTRIm(mp_.top_pad, av);
#endif
- } else {
- /* Always try heap_trim(), even if the top chunk is not
- large, because the corresponding heap might go away. */
- heap_info *heap = heap_for_ptr(top(av));
+ } else {
+ /* Always try heap_trim(), even if the top chunk is not
+ large, because the corresponding heap might go away. */
+ heap_info *heap = heap_for_ptr(top(av));
- assert(heap->ar_ptr == av);
- heap_trim(heap, mp_.top_pad);
- }
+ assert(heap->ar_ptr == av);
+ heap_trim(heap, mp_.top_pad);
}
-
}
- /*
- If the chunk was allocated via mmap, release via munmap(). Note
- that if HAVE_MMAP is false but chunk_is_mmapped is true, then
- user must have overwritten memory. There's nothing we can do to
- catch this error unless MALLOC_DEBUG is set, in which case
- check_inuse_chunk (above) will have triggered error.
- */
- else {
+ }
+ /*
+ If the chunk was allocated via mmap, release via munmap(). Note
+ that if HAVE_MMAP is false but chunk_is_mmapped is true, then
+ user must have overwritten memory. There's nothing we can do to
+ catch this error unless MALLOC_DEBUG is set, in which case
+ check_inuse_chunk (above) will have triggered error.
+ */
+
+ else {
#if HAVE_MMAP
- int ret;
- INTERNAL_SIZE_T offset = p->prev_size;
- mp_.n_mmaps--;
- mp_.mmapped_mem -= (size + offset);
- ret = munmap((char*)p - offset, size + offset);
- /* munmap returns non-zero on failure */
- assert(ret == 0);
+ munmap_chunk (p);
#endif
- }
}
}
@@ -4528,7 +4521,8 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
#if REALLOC_ZERO_BYTES_FREES
if (bytes == 0) {
- _int_free(av, oldmem);
+ if (oldmem != 0)
+ _int_free(av, oldmem);
return 0;
}
#endif
@@ -5474,45 +5468,19 @@ malloc_printerr(int action, const char *str, void *ptr)
{
if (action & 1)
{
- /* output string will be ": ADDR ***\n" */
- static const char suffix[] = " ***\n";
- static const char prefix[] = ": 0x";
- char buf[sizeof (prefix) - 1 + sizeof (void *) * 2 + sizeof (suffix)];
- char *cp;
- if (action & 4)
- cp = memcpy (&buf[sizeof (buf) - 2], "\n", 2);
- else
- {
- cp = memcpy (&buf[sizeof (buf) - sizeof (suffix)], suffix,
- sizeof (suffix));
- cp = _itoa_word ((unsigned long int) ptr, cp, 16, 0);
- while (cp > &buf[sizeof (prefix) - 1])
- *--cp = '0';
- cp = memcpy (buf, prefix, sizeof (prefix) - 1);
- }
+ char buf[2 * sizeof (uintptr_t) + 1];
- struct iovec iov[3];
- int n = 0;
- if ((action & 4) == 0)
- {
- iov[0].iov_base = (char *) "*** glibc detected *** ";
- iov[0].iov_len = strlen (iov[0].iov_base);
- ++n;
- }
- iov[n].iov_base = (char *) str;
- iov[n].iov_len = strlen (str);
- ++n;
- iov[n].iov_base = cp;
- iov[n].iov_len = &buf[sizeof (buf) - 1] - cp;
- ++n;
- if (TEMP_FAILURE_RETRY (__writev (STDERR_FILENO, iov, n)) == -1
- && errno == EBADF)
- /* Standard error is not opened. Try using syslog. */
- syslog (LOG_ERR, "%s%s%s", (char *) iov[0].iov_base,
- (char *) iov[1].iov_base,
- n == 3 ? (const char *) iov[2].iov_base : "");
+ buf[sizeof (buf) - 1] = '\0';
+ char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
+ while (cp > buf)
+ *--cp = '0';
+
+ __libc_message (action & 2,
+ action & 4
+ ? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n",
+ str, cp);
}
- if (action & 2)
+ else if (action & 2)
abort ();
}
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index 65b9c55467..5ad78eda00 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -846,7 +846,7 @@ ypprot_err (const int code)
{
if (code < YP_VERS || code > YP_NOKEY)
return YPERR_YPERR;
- return yp_2_yperr[code];
+ return yp_2_yperr[code - YP_VERS];
}
libnsl_hidden_def (ypprot_err)
diff --git a/posix/Makefile b/posix/Makefile
index 8bc15ad215..744f49f5b3 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -91,7 +91,6 @@ tests += wordexp-test tst-exec tst-spawn
endif
others := getconf
install-bin := getconf
-gpl2lgpl := getopt.c getopt1.c getopt.h regex.c regex.h
before-compile := testcases.h ptestcases.h
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index 7e45174708..fac8cbd051 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1994,1995,1997,2000,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,44 +16,131 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sysdep.h>
#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/syslog.h>
+#include <not-cancel.h>
#ifdef FATAL_PREPARE_INCLUDE
#include FATAL_PREPARE_INCLUDE
#endif
+struct str_list
+{
+ const char *str;
+ size_t len;
+ struct str_list *next;
+};
+
+
/* Abort with an error message. */
void
-__libc_fatal (message)
- const char *message;
+__libc_message (int do_abort, const char *fmt, ...)
{
- size_t len = strlen (message);
+ va_list ap;
+ va_list ap_copy;
+ int fd = -1;
+
+ va_start (ap, fmt);
+ va_copy (ap_copy, ap);
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
- while (len > 0)
+ /* Open a descriptor for /dev/tty unless the user explicitly
+ requests errors on standard error. */
+ const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
+ if (on_2 == NULL || *on_2 == '\0')
+ fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ if (fd == -1)
+ fd = STDERR_FILENO;
+
+ struct str_list *list = NULL;
+ int nlist = 0;
+
+ const char *cp = fmt;
+ while (*cp != '\0')
{
- register int count = __write (STDERR_FILENO, message, len);
- if (count > 0)
+ /* Find the next "%s" or the end of the string. */
+ char *next = cp;
+ while (next[0] != '%' || next[1] != 's')
{
- message += count;
- len -= count;
+ next = __strchrnul (next + 1, '%');
+
+ if (next[0] == '\0')
+ break;
}
- else if (count < 0
-#ifdef EINTR
- && errno != EINTR
-#endif
- )
- break;
+
+ /* Determine what to print. */
+ const char *str;
+ size_t len;
+ if (cp[0] == '%' && cp[1] == 's')
+ {
+ str = va_arg (ap, const char *);
+ len = strlen (str);
+ cp += 2;
+ }
+ else
+ {
+ str = cp;
+ len = next - cp;
+ cp = next;
+ }
+
+ struct str_list *newp = alloca (sizeof (struct str_list));
+ newp->str = str;
+ newp->len = len;
+ newp->next = list;
+ list = newp;
+ ++nlist;
+ }
+
+ bool written = false;
+ if (nlist > 0)
+ {
+ struct iovec *iov = alloca (nlist * sizeof (struct iovec));
+ ssize_t total = 0;
+
+ for (int cnt = nlist - 1; cnt >= 0; --cnt)
+ {
+ iov[cnt].iov_base = list->str;
+ iov[cnt].iov_len = list->len;
+ total += list->len;
+ list = list->next;
+ }
+
+ if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
+ written = true;
}
- abort ();
+ va_end (ap);
+
+ /* If we had no success writing the message, use syslog. */
+ if (! written)
+ vsyslog (LOG_ERR, fmt, ap_copy);
+
+ va_end (ap_copy);
+
+ if (do_abort()
+ /* Kill the application. */
+ abort ();
+}
+
+
+void
+__libc_fatal (message)
+ const char *message;
+{
+ __libc_message (1, "%s", message);
}
libc_hidden_def (__libc_fatal)
diff --git a/sysdeps/unix/sysv/linux/libc_fatal.c b/sysdeps/unix/sysv/linux/libc_fatal.c
index 46347bb20e..c0482d96f3 100644
--- a/sysdeps/unix/sysv/linux/libc_fatal.c
+++ b/sysdeps/unix/sysv/linux/libc_fatal.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993-1995,1997,2000,2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1993-1995,1997,2000,2002-2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,45 +16,143 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sysdep.h>
#include <string.h>
-#include <abort-instr.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/syslog.h>
#ifndef ABORT_INSTRUCTION
/* No such instruction is available. */
# define ABORT_INSTRUCTION
#endif
/* Abort with an error message. */
+#include <not-cancel.h>
+
+#ifdef FATAL_PREPARE_INCLUDE
+#include FATAL_PREPARE_INCLUDE
+#endif
+
+struct str_list
+{
+ const char *str;
+ size_t len;
+ struct str_list *next;
+};
+
+
+/* Abort with an error message. */
void
-__libc_fatal (message)
- const char *message;
+__libc_message (int do_abort, const char *fmt, ...)
{
- size_t len = strlen (message);
+ va_list ap;
+ va_list ap_copy;
+ int fd = -1;
+
+ va_start (ap, fmt);
+ va_copy (ap_copy, ap);
+
+#ifdef FATAL_PREPARE
+ FATAL_PREPARE;
+#endif
- while (len > 0)
+ /* Open a descriptor for /dev/tty unless the user explicitly
+ requests errors on standard error. */
+ const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
+ if (on_2 == NULL || *on_2 == '\0')
+ fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ if (fd == -1)
+ fd = STDERR_FILENO;
+
+ struct str_list *list = NULL;
+ int nlist = 0;
+
+ const char *cp = fmt;
+ while (*cp != '\0')
{
- INTERNAL_SYSCALL_DECL (err);
- ssize_t count = INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO,
- message, len);
- if (! INTERNAL_SYSCALL_ERROR_P (count, err))
+ /* Find the next "%s" or the end of the string. */
+ const char *next = cp;
+ while (next[0] != '%' || next[1] != 's')
{
- message += count;
- len -= count;
+ next = __strchrnul (next + 1, '%');
+
+ if (next[0] == '\0')
+ break;
}
- else if (INTERNAL_SYSCALL_ERRNO (count, err) != EINTR)
- break;
+
+ /* Determine what to print. */
+ const char *str;
+ size_t len;
+ if (cp[0] == '%' && cp[1] == 's')
+ {
+ str = va_arg (ap, const char *);
+ len = strlen (str);
+ cp += 2;
+ }
+ else
+ {
+ str = cp;
+ len = next - cp;
+ cp = next;
+ }
+
+ struct str_list *newp = alloca (sizeof (struct str_list));
+ newp->str = str;
+ newp->len = len;
+ newp->next = list;
+ list = newp;
+ ++nlist;
}
- /* Terminate the process. */
- _exit (127);
+ bool written = false;
+ if (nlist > 0)
+ {
+ struct iovec *iov = alloca (nlist * sizeof (struct iovec));
+ ssize_t total = 0;
+
+ for (int cnt = nlist - 1; cnt >= 0; --cnt)
+ {
+ iov[cnt].iov_base = (void *) list->str;
+ iov[cnt].iov_len = list->len;
+ total += list->len;
+ list = list->next;
+ }
+
+ INTERNAL_SYSCALL_DECL (err);
+ ssize_t cnt;
+ do
+ cnt = INTERNAL_SYSCALL (writev, err, 3, fd, iov, nlist);
+ while (INTERNAL_SYSCALL_ERROR_P (cnt, err)
+ && INTERNAL_SYSCALL_ERRNO (cnt, err) == EINTR);
- /* The previous call should never have returned. */
- while (1)
- /* Try for ever and ever. */
- ABORT_INSTRUCTION;
+ if (cnt == total)
+ written = true;
+ }
+
+ va_end (ap);
+
+ /* If we had no success writing the message, use syslog. */
+ if (! written)
+ vsyslog (LOG_ERR, fmt, ap_copy);
+
+ va_end (ap_copy);
+
+ if (do_abort)
+ /* Terminate the process. */
+ abort ();
+}
+
+
+void
+__libc_fatal (message)
+ const char *message;
+{
+ __libc_message (1, "%s", message);
}
libc_hidden_def (__libc_fatal)