]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Updated to fedora-glibc-20041115T0915
authorJakub Jelinek <jakub@redhat.com>
Mon, 15 Nov 2004 09:47:23 +0000 (09:47 +0000)
committerJakub Jelinek <jakub@redhat.com>
Mon, 15 Nov 2004 09:47:23 +0000 (09:47 +0000)
14 files changed:
ChangeLog
debug/chk_fail.c
debug/test-strcpy_chk.c
debug/tst-chk1.c
elf/elf.h
elf/rtld.c
fedora/branch.mk
fedora/glibc.spec.in
include/stdio.h
malloc/malloc.c
nis/ypclnt.c
posix/Makefile
sysdeps/posix/libc_fatal.c
sysdeps/unix/sysv/linux/libc_fatal.c

index 1ff1338078ac0d1935bff8191fa155bd308166b7..5e1b9169363a8df272b450a10b119f685d8e3ed3 100644 (file)
--- 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>
 
index 70ffa9e40fc1710240924486511ea7188c3de6ee..dc1c3d70b6cf2c1921dd6393fb9f83995995f2a9 100644 (file)
@@ -1,3 +1,4 @@
+
 /* Copyright (C) 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    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)
index 8430ca47041eb2e2dc5197279af0eff660f04ae4..ac9f9448cf66997577c08d43fa8dd46950680bdf 100644 (file)
@@ -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 ();
 
index e01284ae53c725300c9ad312c1c9c50f0cd04f3b..37320c3514f458eca08a554e1e88057a39869ca2 100644 (file)
@@ -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
index db95254f74be8e1b3f49657d9b83b1f8ce4f05ff..0daff76a413775915ffd759e00a9fafda5379756 100644 (file)
--- 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.  */
index e53273c2bb2f592ed2468c91439df0d17bf50630..e442aa257f41f487877efe3570551fccc9d5f882 100644 (file)
@@ -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;
        }
index 2714ad4822778af478bed593f7cdde66f1dcbbed..3add7920d61688806800432c8c4087f098ae1db3 100644 (file)
@@ -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
index 0d97316b37927b6fbd5ca6085207cccec49f0090..1c93fc1e0bd51e23b60b8ae92fab8bafcfc575d7 100644 (file)
@@ -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)
index 05a91b4cb38532fe381cdecc32bac7fbe6681465..ad8f157829eb925f8b89e3c56babb262b95c350c 100644 (file)
@@ -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);
index 6d6294c6e6a8578ff1cd27fa214a6ca68dc0b37c..57074108f1d147c380dde6e8ca125affb607db30 100644 (file)
@@ -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 ();
 }
 
index 65b9c554672ae5db7943b9539d1a06c2e1ae1a85..5ad78eda003dc74b0789f41755572e36ca7c9bee 100644 (file)
@@ -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)
 
index 8bc15ad215b9397f6054d64be153fa76995cd8e0..744f49f5b35d472a3975ac06a20fd761ad38562b 100644 (file)
@@ -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
 
index 7e45174708ae7f4ae3383041cc846e2629aa01cd..fac8cbd0517a11df3e2266d81324a3716b9d6b33 100644 (file)
@@ -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
    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)
index 46347bb20e80093f3cbe69d8ba7f6b99e64ab288..c0482d96f3b0f5066474e3ef9a8986204006e919 100644 (file)
@@ -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
    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)