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
This commit is contained in:
Ulrich Drepper 1999-02-24 09:40:04 +00:00
parent afe426a038
commit 9a51759bdf
4 changed files with 86 additions and 27 deletions

View File

@ -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]

View 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);

View 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
#if __STD_C
malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
#else
#if __STD_C
malloc_hook_ini(size_t sz)
#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;
}

View 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 \