mirror of
https://sourceware.org/git/glibc.git
synced 2025-10-27 12:15:39 +03:00
malloc: Remove dumped heap support
Remove support for obsolete dumped heaps. Dumping heaps was discontinued 8 years ago, however loading a dumped heap is still supported. This blocks changes and improvements of the malloc data structures - hence it is time to remove this. Ancient binaries that still call malloc_set_state will now get the -1 error code. Update tst-mallocstate.c to just check for this. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
@@ -150,19 +150,6 @@ memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
|
||||
|
||||
static size_t pagesize;
|
||||
|
||||
/* These variables are used for undumping support. Chunked are marked
|
||||
as using mmap, but we leave them alone if they fall into this
|
||||
range. NB: The chunk size for these chunks only includes the
|
||||
initial size field (of SIZE_SZ bytes), there is no trailing size
|
||||
field (unlike with regular mmapped chunks). */
|
||||
static mchunkptr dumped_main_arena_start; /* Inclusive. */
|
||||
static mchunkptr dumped_main_arena_end; /* Exclusive. */
|
||||
|
||||
/* True if the pointer falls into the dumped arena. Use this after
|
||||
chunk_is_mmapped indicates a chunk is mmapped. */
|
||||
#define DUMPED_MAIN_ARENA_CHUNK(p) \
|
||||
((p) >= dumped_main_arena_start && (p) < dumped_main_arena_end)
|
||||
|
||||
/* The allocator functions. */
|
||||
|
||||
static void *
|
||||
@@ -202,9 +189,7 @@ __debug_free (void *mem)
|
||||
if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
|
||||
mem = free_mcheck (mem);
|
||||
|
||||
if (DUMPED_MAIN_ARENA_CHUNK (mem2chunk (mem)))
|
||||
/* Do nothing. */;
|
||||
else if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
|
||||
if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
|
||||
free_check (mem);
|
||||
else
|
||||
__libc_free (mem);
|
||||
@@ -227,32 +212,7 @@ __debug_realloc (void *oldmem, size_t bytes)
|
||||
if ((!__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK)
|
||||
|| !realloc_mcheck_before (&oldmem, &bytes, &oldsize, &victim)))
|
||||
{
|
||||
mchunkptr oldp = mem2chunk (oldmem);
|
||||
|
||||
/* If this is a faked mmapped chunk from the dumped main arena,
|
||||
always make a copy (and do not free the old chunk). */
|
||||
if (DUMPED_MAIN_ARENA_CHUNK (oldp))
|
||||
{
|
||||
if (bytes == 0 && oldmem != NULL)
|
||||
victim = NULL;
|
||||
else
|
||||
{
|
||||
const INTERNAL_SIZE_T osize = chunksize (oldp);
|
||||
/* Must alloc, copy, free. */
|
||||
victim = __debug_malloc (bytes);
|
||||
/* Copy as many bytes as are available from the old chunk
|
||||
and fit into the new size. NB: The overhead for faked
|
||||
mmapped chunks is only SIZE_SZ, not CHUNK_HDR_SZ as for
|
||||
regular mmapped chunks. */
|
||||
if (victim != NULL)
|
||||
{
|
||||
if (bytes > osize - SIZE_SZ)
|
||||
bytes = osize - SIZE_SZ;
|
||||
memcpy (victim, oldmem, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
|
||||
if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
|
||||
victim = realloc_check (oldmem, bytes);
|
||||
else
|
||||
victim = __libc_realloc (oldmem, bytes);
|
||||
@@ -414,10 +374,6 @@ malloc_usable_size (void *mem)
|
||||
if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
|
||||
return malloc_check_get_size (mem);
|
||||
|
||||
mchunkptr p = mem2chunk (mem);
|
||||
if (DUMPED_MAIN_ARENA_CHUNK (p))
|
||||
return chunksize (p) - SIZE_SZ;
|
||||
|
||||
return musable (mem);
|
||||
}
|
||||
|
||||
@@ -517,43 +473,10 @@ malloc_trim (size_t s)
|
||||
|
||||
#if SHLIB_COMPAT (libc_malloc_debug, GLIBC_2_0, GLIBC_2_25)
|
||||
|
||||
/* Support for restoring dumped heaps contained in historic Emacs
|
||||
executables. The heap saving feature (malloc_get_state) is no
|
||||
longer implemented in this version of glibc, but we have a heap
|
||||
rewriter in malloc_set_state which transforms the heap into a
|
||||
version compatible with current malloc. */
|
||||
|
||||
#define MALLOC_STATE_MAGIC 0x444c4541l
|
||||
#define MALLOC_STATE_VERSION (0 * 0x100l + 5l) /* major*0x100 + minor */
|
||||
|
||||
struct malloc_save_state
|
||||
{
|
||||
long magic;
|
||||
long version;
|
||||
mbinptr av[NBINS * 2 + 2];
|
||||
char *sbrk_base;
|
||||
int sbrked_mem_bytes;
|
||||
unsigned long trim_threshold;
|
||||
unsigned long top_pad;
|
||||
unsigned int n_mmaps_max;
|
||||
unsigned long mmap_threshold;
|
||||
int check_action;
|
||||
unsigned long max_sbrked_mem;
|
||||
unsigned long max_total_mem; /* Always 0, for backwards compatibility. */
|
||||
unsigned int n_mmaps;
|
||||
unsigned int max_n_mmaps;
|
||||
unsigned long mmapped_mem;
|
||||
unsigned long max_mmapped_mem;
|
||||
int using_malloc_checking;
|
||||
unsigned long max_fast;
|
||||
unsigned long arena_test;
|
||||
unsigned long arena_max;
|
||||
unsigned long narenas;
|
||||
};
|
||||
|
||||
/* Dummy implementation which always fails. We need to provide this
|
||||
symbol so that existing Emacs binaries continue to work with
|
||||
BIND_NOW. */
|
||||
/* Support for saving/restoring dumped heaps in old GLIBCs is no
|
||||
longer implemented - instead we provide dummy implementations
|
||||
which always fail. We need to provide these symbol so that
|
||||
existing Emacs binaries continue to work with BIND_NOW. */
|
||||
void *
|
||||
malloc_get_state (void)
|
||||
{
|
||||
@@ -566,81 +489,7 @@ compat_symbol (libc_malloc_debug, malloc_get_state, malloc_get_state,
|
||||
int
|
||||
malloc_set_state (void *msptr)
|
||||
{
|
||||
struct malloc_save_state *ms = (struct malloc_save_state *) msptr;
|
||||
|
||||
if (ms->magic != MALLOC_STATE_MAGIC)
|
||||
return -1;
|
||||
|
||||
/* Must fail if the major version is too high. */
|
||||
if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
|
||||
return -2;
|
||||
|
||||
if (debug_initialized == 1)
|
||||
return -1;
|
||||
|
||||
bool check_was_enabled = __is_malloc_debug_enabled (MALLOC_CHECK_HOOK);
|
||||
|
||||
/* It's not too late, so disable MALLOC_CHECK_ and all of the hooks. */
|
||||
__malloc_hook = NULL;
|
||||
__realloc_hook = NULL;
|
||||
__free_hook = NULL;
|
||||
__memalign_hook = NULL;
|
||||
__malloc_debug_disable (MALLOC_CHECK_HOOK);
|
||||
|
||||
/* We do not need to perform locking here because malloc_set_state
|
||||
must be called before the first call into the malloc subsystem (usually via
|
||||
__malloc_initialize_hook). pthread_create always calls calloc and thus
|
||||
must be called only afterwards, so there cannot be more than one thread
|
||||
when we reach this point. Also handle initialization if either we ended
|
||||
up being called before the first malloc or through the hook when
|
||||
malloc-check was enabled. */
|
||||
if (debug_initialized < 0)
|
||||
generic_hook_ini ();
|
||||
else if (check_was_enabled)
|
||||
__libc_free (__libc_malloc (0));
|
||||
|
||||
/* Patch the dumped heap. We no longer try to integrate into the
|
||||
existing heap. Instead, we mark the existing chunks as mmapped.
|
||||
Together with the update to dumped_main_arena_start and
|
||||
dumped_main_arena_end, realloc and free will recognize these
|
||||
chunks as dumped fake mmapped chunks and never free them. */
|
||||
|
||||
/* Find the chunk with the lowest address with the heap. */
|
||||
mchunkptr chunk = NULL;
|
||||
{
|
||||
size_t *candidate = (size_t *) ms->sbrk_base;
|
||||
size_t *end = (size_t *) (ms->sbrk_base + ms->sbrked_mem_bytes);
|
||||
while (candidate < end)
|
||||
if (*candidate != 0)
|
||||
{
|
||||
chunk = mem2chunk ((void *) (candidate + 1));
|
||||
break;
|
||||
}
|
||||
else
|
||||
++candidate;
|
||||
}
|
||||
if (chunk == NULL)
|
||||
return 0;
|
||||
|
||||
/* Iterate over the dumped heap and patch the chunks so that they
|
||||
are treated as fake mmapped chunks. */
|
||||
mchunkptr top = ms->av[2];
|
||||
while (chunk < top)
|
||||
{
|
||||
if (inuse (chunk))
|
||||
{
|
||||
/* Mark chunk as mmapped, to trigger the fallback path. */
|
||||
size_t size = chunksize (chunk);
|
||||
set_head (chunk, size | IS_MMAPPED);
|
||||
}
|
||||
chunk = next_chunk (chunk);
|
||||
}
|
||||
|
||||
/* The dumped fake mmapped chunks all lie in this address range. */
|
||||
dumped_main_arena_start = (mchunkptr) ms->sbrk_base;
|
||||
dumped_main_arena_end = top;
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
compat_symbol (libc_malloc_debug, malloc_set_state, malloc_set_state,
|
||||
GLIBC_2_0);
|
||||
|
||||
Reference in New Issue
Block a user