Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 24 Feb 1999 09:40:04 +0000 (09:40 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 24 Feb 1999 09:40:04 +0000 (09:40 +0000)
1999-02-23  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

* malloc/malloc.c (mALLOC_SET_STATe): Handle the case where a
non-checked heap is restored when malloc checking was requested by
the user.
(struct malloc_state): Add using_malloc_checking.
(MALLOC_STATE_VERSION): Increment minor.
(using_malloc_checking, disallow_malloc_check): New variables.
(__malloc_check_init): Use them.
(mALLOC_GET_STATe): Use mALLOc to allocate the malloc_state, so
that it can the chunk is properly instrumented when malloc
checking is enabled.  Set the new using_malloc_checking field.
(malloc_hook_ini): Correct signature when _LIBC is not defined.

1999-02-23  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>

* sysdeps/unix/sysv/linux/i386/dl-librecon.h
(DISTINGUISH_LIB_VERSIONS): Don't relocate DT_STRTAB a second
time.

* elf/rtld.c (dl_main): Rename paths_initialized to rtld_is_main.
Don't call elf_get_dynamic_info and _dl_setup_hash a second time
if ld.so is the main program.

* stdio-common/vfprintf.c (vfprintf): If precision or width is too

ChangeLog
elf/rtld.c
malloc/malloc.c
sysdeps/unix/sysv/linux/i386/dl-librecon.h

index 01737df..5dd30e6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,30 @@
+1999-02-23  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+
+       * malloc/malloc.c (mALLOC_SET_STATe): Handle the case where a
+       non-checked heap is restored when malloc checking was requested by
+       the user.
+       (struct malloc_state): Add using_malloc_checking.
+       (MALLOC_STATE_VERSION): Increment minor.
+       (using_malloc_checking, disallow_malloc_check): New variables.
+       (__malloc_check_init): Use them.
+       (mALLOC_GET_STATe): Use mALLOc to allocate the malloc_state, so
+       that it can the chunk is properly instrumented when malloc
+       checking is enabled.  Set the new using_malloc_checking field.
+       (malloc_hook_ini): Correct signature when _LIBC is not defined.
+
+1999-02-23  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+
+       * sysdeps/unix/sysv/linux/i386/dl-librecon.h
+       (DISTINGUISH_LIB_VERSIONS): Don't relocate DT_STRTAB a second
+       time.
+
+       * elf/rtld.c (dl_main): Rename paths_initialized to rtld_is_main.
+       Don't call elf_get_dynamic_info and _dl_setup_hash a second time
+       if ld.so is the main program.
+
 1999-02-23  Ulrich Drepper  <drepper@cygnus.com>
 
-       * stdio-common/vfprintf.c (vfprintf): If precision or width if too
+       * stdio-common/vfprintf.c (vfprintf): If precision or width is too
        large for work_buffer, allocate new buffer.
        (printf_unknown): Likewise.  [PR libc/988]
 
index 762cdc5..40405d1 100644 (file)
@@ -340,7 +340,7 @@ dl_main (const ElfW(Phdr) *phdr,
   char *file;
   int has_interp = 0;
   unsigned int i;
-  int paths_initialized = 0;
+  int rtld_is_main = 0;
   hp_timing_t start;
   hp_timing_t stop;
   hp_timing_t diff;
@@ -368,6 +368,7 @@ dl_main (const ElfW(Phdr) *phdr,
         pay attention to its PT_INTERP command (we are the interpreter
         ourselves).  This is an easy way to test a new ld.so before
         installing it.  */
+      rtld_is_main = 1;
 
       /* Note the place where the dynamic linker actually came from.  */
       _dl_rtld_map.l_name = _dl_argv[0];
@@ -441,7 +442,6 @@ of this helper program; chances are you did not intend to run this program.\n\
       /* Initialize the data structures for the search paths for shared
         objects.  */
       _dl_init_paths (library_path);
-      paths_initialized = 1;
 
       if (__builtin_expect (mode, normal) == verify)
        {
@@ -574,12 +574,15 @@ of this helper program; chances are you did not intend to run this program.\n\
   else
     assert (_dl_rtld_map.l_libname); /* How else did we get here?  */
 
-  /* Extract the contents of the dynamic section for easy access.  */
-  elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr,
-                       _dl_loaded->l_info);
-  if (_dl_loaded->l_info[DT_HASH])
-    /* Set up our cache of pointers into the hash table.  */
-    _dl_setup_hash (_dl_loaded);
+  if (! rtld_is_main)
+    {
+      /* Extract the contents of the dynamic section for easy access.  */
+      elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr,
+                           _dl_loaded->l_info);
+      if (_dl_loaded->l_info[DT_HASH])
+       /* Set up our cache of pointers into the hash table.  */
+       _dl_setup_hash (_dl_loaded);
+    }
 
   if (__builtin_expect (mode, normal) == verify)
     {
@@ -597,7 +600,7 @@ of this helper program; chances are you did not intend to run this program.\n\
       _exit (has_interp ? 0 : 2);
     }
 
-  if (! paths_initialized)
+  if (! rtld_is_main)
     /* Initialize the data structures for the search paths for shared
        objects.  */
     _dl_init_paths (library_path);
index 2cf2025..03d68b7 100644 (file)
@@ -1691,14 +1691,11 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \
    initialization routine, then do the normal work. */
 
 static Void_t*
-#ifdef _LIBC
-malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
-#else
 #if __STD_C
-malloc_hook_ini(size_t sz)
+malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
 #else
-malloc_hook_ini(sz) size_t sz;
-#endif
+malloc_hook_ini(sz, caller)
+     size_t sz; const __malloc_ptr_t caller;
 #endif
 {
   __malloc_hook = NULL;
@@ -1746,10 +1743,33 @@ __malloc_ptr_t weak_variable (*__memalign_hook)
      = memalign_hook_ini;
 void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
 
+/* Whether we are using malloc checking.  */
+static int using_malloc_checking;
+
+/* A flag that is set by malloc_set_state, to signal that malloc checking
+   must not be enabled on the request from the user (via the MALLOC_CHECK_
+   environment variable).  It is reset by __malloc_check_init to tell
+   malloc_set_state that the user has requested malloc checking.
+
+   The purpose of this flag is to make sure that malloc checking is not
+   enabled when the heap to be restored was constructed without malloc
+   checking, and thus does not contain the required magic bytes.
+   Otherwise the heap would be corrupted by calls to free and realloc.  If
+   it turns out that the heap was created with malloc checking and the
+   user has requested it malloc_set_state just calls __malloc_check_init
+   again to enable it.  On the other hand, reusing such a heap without
+   further malloc checking is safe.  */
+static int disallow_malloc_check;
+
 /* Activate a standard set of debugging hooks. */
 void
 __malloc_check_init()
 {
+  if (disallow_malloc_check) {
+    disallow_malloc_check = 0;
+    return;
+  }
+  using_malloc_checking = 1;
   __malloc_hook = malloc_check;
   __free_hook = free_check;
   __realloc_hook = realloc_check;
@@ -4041,7 +4061,7 @@ int mALLOPt(param_number, value) int param_number; int value;
    functions. */
 
 #define MALLOC_STATE_MAGIC   0x444c4541l
-#define MALLOC_STATE_VERSION (0*0x100l + 0l) /* major*0x100 + minor */
+#define MALLOC_STATE_VERSION (0*0x100l + 1l) /* major*0x100 + minor */
 
 struct malloc_state {
   long          magic;
@@ -4060,24 +4080,20 @@ struct malloc_state {
   unsigned int  max_n_mmaps;
   unsigned long mmapped_mem;
   unsigned long max_mmapped_mem;
+  int          using_malloc_checking;
 };
 
 Void_t*
 mALLOC_GET_STATe()
 {
-  mchunkptr victim;
   struct malloc_state* ms;
   int i;
   mbinptr b;
 
-  ptmalloc_init();
-  (void)mutex_lock(&main_arena.mutex);
-  victim = chunk_alloc(&main_arena, request2size(sizeof(*ms)));
-  if(!victim) {
-    (void)mutex_unlock(&main_arena.mutex);
+  ms = (struct malloc_state*)mALLOc(sizeof(*ms));
+  if (!ms)
     return 0;
-  }
-  ms = (struct malloc_state*)chunk2mem(victim);
+  (void)mutex_lock(&main_arena.mutex);
   ms->magic = MALLOC_STATE_MAGIC;
   ms->version = MALLOC_STATE_VERSION;
   ms->av[0] = main_arena.av[0];
@@ -4108,6 +4124,11 @@ mALLOC_GET_STATe()
   ms->max_n_mmaps = max_n_mmaps;
   ms->mmapped_mem = mmapped_mem;
   ms->max_mmapped_mem = max_mmapped_mem;
+#if defined _LIBC || defined MALLOC_HOOKS
+  ms->using_malloc_checking = using_malloc_checking;
+#else
+  ms->using_malloc_checking = 0;
+#endif
   (void)mutex_unlock(&main_arena.mutex);
   return (Void_t*)ms;
 }
@@ -4123,6 +4144,9 @@ mALLOC_SET_STATe(msptr) Void_t* msptr;
   int i;
   mbinptr b;
 
+#if defined _LIBC || defined MALLOC_HOOKS
+  disallow_malloc_check = 1;
+#endif
   ptmalloc_init();
   if(ms->magic != MALLOC_STATE_MAGIC) return -1;
   /* Must fail if the major version is too high. */
@@ -4160,6 +4184,15 @@ mALLOC_SET_STATe(msptr) Void_t* msptr;
   mmapped_mem = ms->mmapped_mem;
   max_mmapped_mem = ms->max_mmapped_mem;
   /* add version-dependent code here */
+  if (ms->version >= 1) {
+#if defined _LIBC || defined MALLOC_HOOKS
+    /* Check whether it is safe to enable malloc checking.  */
+    if (ms->using_malloc_checking && !using_malloc_checking &&
+       !disallow_malloc_check)
+      __malloc_check_init ();
+#endif
+  }
+
   (void)mutex_unlock(&main_arena.mutex);
   return 0;
 }
index 4ae2e87..84b4396 100644 (file)
@@ -33,8 +33,7 @@
          const ElfW(Dyn) *d;                                                 \
          const char *strtab;                                                 \
                                                                              \
-         strtab = ((void *) _dl_loaded->l_addr                               \
-                   + _dl_loaded->l_info[DT_STRTAB]->d_un.d_ptr);             \
+         strtab = (const char *) _dl_loaded->l_info[DT_STRTAB]->d_un.d_ptr;  \
                                                                              \
          for (d = _dl_loaded->l_ld; d->d_tag != DT_NULL; ++d)                \
            if (d->d_tag == DT_NEEDED                                         \