Reformat malloc to gnu style.

This commit is contained in:
Ondřej Bílka 2014-01-02 09:38:18 +01:00
parent 9a3c6a6ff6
commit 6c8dbf00f5
18 changed files with 3843 additions and 3559 deletions

View File

@ -1,3 +1,37 @@
2013-01-02 Ondřej Bílka <neleai@seznam.cz>
* malloc/arena.c (malloc_atfork, free_atfork, ptmalloc_lock_all,
ptmalloc_unlock_all, ptmalloc_unlock_all2, next_env_entry,
__failing_morecore, ptmalloc_init, dump_heap, new_heap, grow_heap,
heap_trim, _int_new_arena, get_free_list, reused_arena, arena_get2):
Convert to GNU style.
* malloc/hooks.c (memalign_hook_ini, __malloc_check_init,
mem2mem_check, mem2chunk_check, top_check, realloc_check,
memalign_check, __malloc_set_state): Likewise.
* malloc/mallocbug.c (main): Likewise.
* malloc/malloc.c (__malloc_assert, malloc_init_state, free_perturb,
do_check_malloced_chunk, do_check_malloc_state, sysmalloc, systrim,
mremap_chunk, __libc_malloc, __libc_free, __libc_realloc, _mid_memalign,
_int_malloc, malloc_consolidate, _int_realloc, _int_memalign, mtrim,
musable, __libc_mallopt, __posix_memalign, malloc_info): Likewise.
* malloc/malloc.h: Likewise.
* malloc/mcheck.c (checkhdr, unlink_blk, link_blk, freehook, mallochook,
memalignhook, reallochook, mabort): Likewise.
* malloc/mcheck.h: Likewise.
* malloc/memusage.c (update_data, me, malloc, realloc, calloc, free, mmap,
mmap64, mremap, munmap, dest): Likewise.
* malloc/memusagestat.c (main, parse_opt, more_help): Likewise.
* malloc/morecore.c (__default_morecore): Likewise.
* malloc/mtrace.c (tr_break, lock_and_info, mtrace): Likewise.
* malloc/obstack.c (_obstack_begin, _obstack_newchunk,
_obstack_allocated_p, obstack_free, _obstack_memory_used,
print_and_abort): Likewise.
* malloc/obstack.h: Likewise.
* malloc/set-freeres.c (__libc_freeres): Likewise.
* malloc/tst-mallocstate.c (main): Likewise.
* malloc/tst-mtrace.c (main): Likewise.
* malloc/tst-realloc.c (do_test): Likewise.
2013-01-02 Siddhesh Poyarekar <siddhesh@redhat.com> 2013-01-02 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #16366] [BZ #16366]

View File

@ -21,12 +21,12 @@
/* Compile-time constants. */ /* Compile-time constants. */
#define HEAP_MIN_SIZE (32*1024) #define HEAP_MIN_SIZE (32 * 1024)
#ifndef HEAP_MAX_SIZE #ifndef HEAP_MAX_SIZE
# ifdef DEFAULT_MMAP_THRESHOLD_MAX # ifdef DEFAULT_MMAP_THRESHOLD_MAX
# define HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX) # define HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX)
# else # else
# define HEAP_MAX_SIZE (1024*1024) /* must be a power of two */ # define HEAP_MAX_SIZE (1024 * 1024) /* must be a power of two */
# endif # endif
#endif #endif
@ -39,7 +39,7 @@
#ifndef THREAD_STATS #ifndef THREAD_STATS
#define THREAD_STATS 0 # define THREAD_STATS 0
#endif #endif
/* If THREAD_STATS is non-zero, some statistics on mutex locking are /* If THREAD_STATS is non-zero, some statistics on mutex locking are
@ -53,7 +53,8 @@
malloc_chunks. It is allocated with mmap() and always starts at an malloc_chunks. It is allocated with mmap() and always starts at an
address aligned to HEAP_MAX_SIZE. */ address aligned to HEAP_MAX_SIZE. */
typedef struct _heap_info { typedef struct _heap_info
{
mstate ar_ptr; /* Arena for this heap. */ mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */ struct _heap_info *prev; /* Previous heap. */
size_t size; /* Current size in bytes. */ size_t size; /* Current size in bytes. */
@ -80,9 +81,9 @@ static mstate free_list;
#if THREAD_STATS #if THREAD_STATS
static int stat_n_heaps; static int stat_n_heaps;
#define THREAD_STAT(x) x # define THREAD_STAT(x) x
#else #else
#define THREAD_STAT(x) do ; while(0) # define THREAD_STAT(x) do ; while (0)
#endif #endif
/* Mapped memory in non-main arenas (reliable only for NO_THREADS). */ /* Mapped memory in non-main arenas (reliable only for NO_THREADS). */
@ -103,28 +104,28 @@ int __malloc_initialized = -1;
in the new arena. */ in the new arena. */
#define arena_get(ptr, size) do { \ #define arena_get(ptr, size) do { \
arena_lookup(ptr); \ arena_lookup (ptr); \
arena_lock(ptr, size); \ arena_lock (ptr, size); \
} while(0) } while (0)
#define arena_lookup(ptr) do { \ #define arena_lookup(ptr) do { \
void *vptr = NULL; \ void *vptr = NULL; \
ptr = (mstate)tsd_getspecific(arena_key, vptr); \ ptr = (mstate) tsd_getspecific (arena_key, vptr); \
} while(0) } while (0)
# define arena_lock(ptr, size) do { \ #define arena_lock(ptr, size) do { \
if(ptr) \ if (ptr) \
(void)mutex_lock(&ptr->mutex); \ (void) mutex_lock (&ptr->mutex); \
else \ else \
ptr = arena_get2(ptr, (size), NULL); \ ptr = arena_get2 (ptr, (size), NULL); \
} while(0) } while (0)
/* find the heap and corresponding arena for a given ptr */ /* find the heap and corresponding arena for a given ptr */
#define heap_for_ptr(ptr) \ #define heap_for_ptr(ptr) \
((heap_info *)((unsigned long)(ptr) & ~(HEAP_MAX_SIZE-1))) ((heap_info *) ((unsigned long) (ptr) & ~(HEAP_MAX_SIZE - 1)))
#define arena_for_chunk(ptr) \ #define arena_for_chunk(ptr) \
(chunk_non_main_arena(ptr) ? heap_for_ptr(ptr)->ar_ptr : &main_arena) (chunk_non_main_arena (ptr) ? heap_for_ptr (ptr)->ar_ptr : &main_arena)
/**************************************************************************/ /**************************************************************************/
@ -133,51 +134,58 @@ int __malloc_initialized = -1;
/* atfork support. */ /* atfork support. */
static void *(*save_malloc_hook) (size_t __size, const void *); static void *(*save_malloc_hook)(size_t __size, const void *);
static void (*save_free_hook) (void *__ptr, const void *); static void (*save_free_hook) (void *__ptr, const void *);
static void *save_arena; static void *save_arena;
#ifdef ATFORK_MEM # ifdef ATFORK_MEM
ATFORK_MEM; ATFORK_MEM;
#endif # endif
/* Magic value for the thread-specific arena pointer when /* Magic value for the thread-specific arena pointer when
malloc_atfork() is in use. */ malloc_atfork() is in use. */
#define ATFORK_ARENA_PTR ((void*)-1) # define ATFORK_ARENA_PTR ((void *) -1)
/* The following hooks are used while the `atfork' handling mechanism /* The following hooks are used while the `atfork' handling mechanism
is active. */ is active. */
static void* static void *
malloc_atfork(size_t sz, const void *caller) malloc_atfork (size_t sz, const void *caller)
{ {
void *vptr = NULL; void *vptr = NULL;
void *victim; void *victim;
tsd_getspecific(arena_key, vptr); tsd_getspecific (arena_key, vptr);
if(vptr == ATFORK_ARENA_PTR) { if (vptr == ATFORK_ARENA_PTR)
{
/* We are the only thread that may allocate at all. */ /* We are the only thread that may allocate at all. */
if(save_malloc_hook != malloc_check) { if (save_malloc_hook != malloc_check)
return _int_malloc(&main_arena, sz); {
} else { return _int_malloc (&main_arena, sz);
if(top_check()<0)
return 0;
victim = _int_malloc(&main_arena, sz+1);
return mem2mem_check(victim, sz);
} }
} else { else
{
if (top_check () < 0)
return 0;
victim = _int_malloc (&main_arena, sz + 1);
return mem2mem_check (victim, sz);
}
}
else
{
/* Suspend the thread until the `atfork' handlers have completed. /* Suspend the thread until the `atfork' handlers have completed.
By that time, the hooks will have been reset as well, so that By that time, the hooks will have been reset as well, so that
mALLOc() can be used again. */ mALLOc() can be used again. */
(void)mutex_lock(&list_lock); (void) mutex_lock (&list_lock);
(void)mutex_unlock(&list_lock); (void) mutex_unlock (&list_lock);
return __libc_malloc(sz); return __libc_malloc (sz);
} }
} }
static void static void
free_atfork(void* mem, const void *caller) free_atfork (void *mem, const void *caller)
{ {
void *vptr = NULL; void *vptr = NULL;
mstate ar_ptr; mstate ar_ptr;
@ -186,17 +194,17 @@ free_atfork(void* mem, const void *caller)
if (mem == 0) /* free(0) has no effect */ if (mem == 0) /* free(0) has no effect */
return; return;
p = mem2chunk(mem); /* do not bother to replicate free_check here */ p = mem2chunk (mem); /* do not bother to replicate free_check here */
if (chunk_is_mmapped(p)) /* release mmapped memory. */ if (chunk_is_mmapped (p)) /* release mmapped memory. */
{ {
munmap_chunk(p); munmap_chunk (p);
return; return;
} }
ar_ptr = arena_for_chunk(p); ar_ptr = arena_for_chunk (p);
tsd_getspecific(arena_key, vptr); tsd_getspecific (arena_key, vptr);
_int_free(ar_ptr, p, vptr == ATFORK_ARENA_PTR); _int_free (ar_ptr, p, vptr == ATFORK_ARENA_PTR);
} }
@ -214,33 +222,36 @@ ptmalloc_lock_all (void)
{ {
mstate ar_ptr; mstate ar_ptr;
if(__malloc_initialized < 1) if (__malloc_initialized < 1)
return; return;
if (mutex_trylock(&list_lock))
if (mutex_trylock (&list_lock))
{ {
void *my_arena; void *my_arena;
tsd_getspecific(arena_key, my_arena); tsd_getspecific (arena_key, my_arena);
if (my_arena == ATFORK_ARENA_PTR) if (my_arena == ATFORK_ARENA_PTR)
/* This is the same thread which already locks the global list. /* This is the same thread which already locks the global list.
Just bump the counter. */ Just bump the counter. */
goto out; goto out;
/* This thread has to wait its turn. */ /* This thread has to wait its turn. */
(void)mutex_lock(&list_lock); (void) mutex_lock (&list_lock);
} }
for(ar_ptr = &main_arena;;) { for (ar_ptr = &main_arena;; )
(void)mutex_lock(&ar_ptr->mutex); {
(void) mutex_lock (&ar_ptr->mutex);
ar_ptr = ar_ptr->next; ar_ptr = ar_ptr->next;
if(ar_ptr == &main_arena) break; if (ar_ptr == &main_arena)
break;
} }
save_malloc_hook = __malloc_hook; save_malloc_hook = __malloc_hook;
save_free_hook = __free_hook; save_free_hook = __free_hook;
__malloc_hook = malloc_atfork; __malloc_hook = malloc_atfork;
__free_hook = free_atfork; __free_hook = free_atfork;
/* Only the current thread may perform malloc/free calls now. */ /* Only the current thread may perform malloc/free calls now. */
tsd_getspecific(arena_key, save_arena); tsd_getspecific (arena_key, save_arena);
tsd_setspecific(arena_key, ATFORK_ARENA_PTR); tsd_setspecific (arena_key, ATFORK_ARENA_PTR);
out: out:
++atfork_recursive_cntr; ++atfork_recursive_cntr;
} }
@ -249,19 +260,23 @@ ptmalloc_unlock_all (void)
{ {
mstate ar_ptr; mstate ar_ptr;
if(__malloc_initialized < 1) if (__malloc_initialized < 1)
return; return;
if (--atfork_recursive_cntr != 0) if (--atfork_recursive_cntr != 0)
return; return;
tsd_setspecific(arena_key, save_arena);
tsd_setspecific (arena_key, save_arena);
__malloc_hook = save_malloc_hook; __malloc_hook = save_malloc_hook;
__free_hook = save_free_hook; __free_hook = save_free_hook;
for(ar_ptr = &main_arena;;) { for (ar_ptr = &main_arena;; )
(void)mutex_unlock(&ar_ptr->mutex); {
(void) mutex_unlock (&ar_ptr->mutex);
ar_ptr = ar_ptr->next; ar_ptr = ar_ptr->next;
if(ar_ptr == &main_arena) break; if (ar_ptr == &main_arena)
break;
} }
(void)mutex_unlock(&list_lock); (void) mutex_unlock (&list_lock);
} }
# ifdef __linux__ # ifdef __linux__
@ -276,31 +291,33 @@ ptmalloc_unlock_all2 (void)
{ {
mstate ar_ptr; mstate ar_ptr;
if(__malloc_initialized < 1) if (__malloc_initialized < 1)
return; return;
tsd_setspecific(arena_key, save_arena);
tsd_setspecific (arena_key, save_arena);
__malloc_hook = save_malloc_hook; __malloc_hook = save_malloc_hook;
__free_hook = save_free_hook; __free_hook = save_free_hook;
free_list = NULL; free_list = NULL;
for(ar_ptr = &main_arena;;) { for (ar_ptr = &main_arena;; )
mutex_init(&ar_ptr->mutex); {
if (ar_ptr != save_arena) { mutex_init (&ar_ptr->mutex);
if (ar_ptr != save_arena)
{
ar_ptr->next_free = free_list; ar_ptr->next_free = free_list;
free_list = ar_ptr; free_list = ar_ptr;
} }
ar_ptr = ar_ptr->next; ar_ptr = ar_ptr->next;
if(ar_ptr == &main_arena) break; if (ar_ptr == &main_arena)
break;
} }
mutex_init(&list_lock); mutex_init (&list_lock);
atfork_recursive_cntr = 0; atfork_recursive_cntr = 0;
} }
# else # else
# define ptmalloc_unlock_all2 ptmalloc_unlock_all # define ptmalloc_unlock_all2 ptmalloc_unlock_all
# endif # endif
#endif /* !NO_THREADS */ #endif /* !NO_THREADS */
/* Initialization routine. */ /* Initialization routine. */
@ -353,7 +370,9 @@ libc_hidden_proto (_dl_open_hook);
static void static void
ptmalloc_init (void) ptmalloc_init (void)
{ {
if(__malloc_initialized >= 0) return; if (__malloc_initialized >= 0)
return;
__malloc_initialized = 0; __malloc_initialized = 0;
#ifdef SHARED #ifdef SHARED
@ -368,9 +387,9 @@ ptmalloc_init (void)
__morecore = __failing_morecore; __morecore = __failing_morecore;
#endif #endif
tsd_key_create(&arena_key, NULL); tsd_key_create (&arena_key, NULL);
tsd_setspecific(arena_key, (void *)&main_arena); tsd_setspecific (arena_key, (void *) &main_arena);
thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2); thread_atfork (ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
const char *s = NULL; const char *s = NULL;
if (__builtin_expect (_environ != NULL, 1)) if (__builtin_expect (_environ != NULL, 1))
{ {
@ -395,37 +414,37 @@ ptmalloc_init (void)
s = &envline[7]; s = &envline[7];
break; break;
case 8: case 8:
if (! __builtin_expect (__libc_enable_secure, 0)) if (!__builtin_expect (__libc_enable_secure, 0))
{ {
if (memcmp (envline, "TOP_PAD_", 8) == 0) if (memcmp (envline, "TOP_PAD_", 8) == 0)
__libc_mallopt(M_TOP_PAD, atoi(&envline[9])); __libc_mallopt (M_TOP_PAD, atoi (&envline[9]));
else if (memcmp (envline, "PERTURB_", 8) == 0) else if (memcmp (envline, "PERTURB_", 8) == 0)
__libc_mallopt(M_PERTURB, atoi(&envline[9])); __libc_mallopt (M_PERTURB, atoi (&envline[9]));
} }
break; break;
case 9: case 9:
if (! __builtin_expect (__libc_enable_secure, 0)) if (!__builtin_expect (__libc_enable_secure, 0))
{ {
if (memcmp (envline, "MMAP_MAX_", 9) == 0) if (memcmp (envline, "MMAP_MAX_", 9) == 0)
__libc_mallopt(M_MMAP_MAX, atoi(&envline[10])); __libc_mallopt (M_MMAP_MAX, atoi (&envline[10]));
else if (memcmp (envline, "ARENA_MAX", 9) == 0) else if (memcmp (envline, "ARENA_MAX", 9) == 0)
__libc_mallopt(M_ARENA_MAX, atoi(&envline[10])); __libc_mallopt (M_ARENA_MAX, atoi (&envline[10]));
} }
break; break;
case 10: case 10:
if (! __builtin_expect (__libc_enable_secure, 0)) if (!__builtin_expect (__libc_enable_secure, 0))
{ {
if (memcmp (envline, "ARENA_TEST", 10) == 0) if (memcmp (envline, "ARENA_TEST", 10) == 0)
__libc_mallopt(M_ARENA_TEST, atoi(&envline[11])); __libc_mallopt (M_ARENA_TEST, atoi (&envline[11]));
} }
break; break;
case 15: case 15:
if (! __builtin_expect (__libc_enable_secure, 0)) if (!__builtin_expect (__libc_enable_secure, 0))
{ {
if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0) if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0)
__libc_mallopt(M_TRIM_THRESHOLD, atoi(&envline[16])); __libc_mallopt (M_TRIM_THRESHOLD, atoi (&envline[16]));
else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0) else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0)
__libc_mallopt(M_MMAP_THRESHOLD, atoi(&envline[16])); __libc_mallopt (M_MMAP_THRESHOLD, atoi (&envline[16]));
} }
break; break;
default: default:
@ -433,10 +452,11 @@ ptmalloc_init (void)
} }
} }
} }
if(s && s[0]) { if (s && s[0])
__libc_mallopt(M_CHECK_ACTION, (int)(s[0] - '0')); {
__libc_mallopt (M_CHECK_ACTION, (int) (s[0] - '0'));
if (check_action != 0) if (check_action != 0)
__malloc_check_init(); __malloc_check_init ();
} }
void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook); void (*hook) (void) = atomic_forced_read (__malloc_initialize_hook);
if (hook != NULL) if (hook != NULL)
@ -446,11 +466,11 @@ ptmalloc_init (void)
/* There are platforms (e.g. Hurd) with a link-time hook mechanism. */ /* There are platforms (e.g. Hurd) with a link-time hook mechanism. */
#ifdef thread_atfork_static #ifdef thread_atfork_static
thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \ thread_atfork_static (ptmalloc_lock_all, ptmalloc_unlock_all, \
ptmalloc_unlock_all2) ptmalloc_unlock_all2)
#endif #endif
/* Managing heaps and arenas (for concurrent threads) */ /* Managing heaps and arenas (for concurrent threads) */
@ -459,30 +479,33 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \
/* Print the complete contents of a single heap to stderr. */ /* Print the complete contents of a single heap to stderr. */
static void static void
dump_heap(heap_info *heap) dump_heap (heap_info *heap)
{ {
char *ptr; char *ptr;
mchunkptr p; mchunkptr p;
fprintf(stderr, "Heap %p, size %10lx:\n", heap, (long)heap->size); fprintf (stderr, "Heap %p, size %10lx:\n", heap, (long) heap->size);
ptr = (heap->ar_ptr != (mstate)(heap+1)) ? ptr = (heap->ar_ptr != (mstate) (heap + 1)) ?
(char*)(heap + 1) : (char*)(heap + 1) + sizeof(struct malloc_state); (char *) (heap + 1) : (char *) (heap + 1) + sizeof (struct malloc_state);
p = (mchunkptr)(((unsigned long)ptr + MALLOC_ALIGN_MASK) & p = (mchunkptr) (((unsigned long) ptr + MALLOC_ALIGN_MASK) &
~MALLOC_ALIGN_MASK); ~MALLOC_ALIGN_MASK);
for(;;) { for (;; )
fprintf(stderr, "chunk %p size %10lx", p, (long)p->size); {
if(p == top(heap->ar_ptr)) { fprintf (stderr, "chunk %p size %10lx", p, (long) p->size);
fprintf(stderr, " (top)\n"); if (p == top (heap->ar_ptr))
break; {
} else if(p->size == (0|PREV_INUSE)) { fprintf (stderr, " (top)\n");
fprintf(stderr, " (fence)\n");
break; break;
} }
fprintf(stderr, "\n"); else if (p->size == (0 | PREV_INUSE))
p = next_chunk(p); {
fprintf (stderr, " (fence)\n");
break;
}
fprintf (stderr, "\n");
p = next_chunk (p);
} }
} }
#endif /* MALLOC_DEBUG > 1 */ #endif /* MALLOC_DEBUG > 1 */
/* If consecutive mmap (0, HEAP_MAX_SIZE << 1, ...) calls return decreasing /* If consecutive mmap (0, HEAP_MAX_SIZE << 1, ...) calls return decreasing
@ -500,18 +523,18 @@ static char *aligned_heap_area;
static heap_info * static heap_info *
internal_function internal_function
new_heap(size_t size, size_t top_pad) new_heap (size_t size, size_t top_pad)
{ {
size_t page_mask = GLRO(dl_pagesize) - 1; size_t page_mask = GLRO (dl_pagesize) - 1;
char *p1, *p2; char *p1, *p2;
unsigned long ul; unsigned long ul;
heap_info *h; heap_info *h;
if(size+top_pad < HEAP_MIN_SIZE) if (size + top_pad < HEAP_MIN_SIZE)
size = HEAP_MIN_SIZE; size = HEAP_MIN_SIZE;
else if(size+top_pad <= HEAP_MAX_SIZE) else if (size + top_pad <= HEAP_MAX_SIZE)
size += top_pad; size += top_pad;
else if(size > HEAP_MAX_SIZE) else if (size > HEAP_MAX_SIZE)
return 0; return 0;
else else
size = HEAP_MAX_SIZE; size = HEAP_MAX_SIZE;
@ -522,46 +545,55 @@ new_heap(size_t size, size_t top_pad)
mapping (on Linux, this is the case for all non-writable mappings mapping (on Linux, this is the case for all non-writable mappings
anyway). */ anyway). */
p2 = MAP_FAILED; p2 = MAP_FAILED;
if(aligned_heap_area) { if (aligned_heap_area)
p2 = (char *)MMAP(aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE, {
p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
MAP_NORESERVE); MAP_NORESERVE);
aligned_heap_area = NULL; aligned_heap_area = NULL;
if (p2 != MAP_FAILED && ((unsigned long)p2 & (HEAP_MAX_SIZE-1))) { if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)))
__munmap(p2, HEAP_MAX_SIZE); {
__munmap (p2, HEAP_MAX_SIZE);
p2 = MAP_FAILED; p2 = MAP_FAILED;
} }
} }
if(p2 == MAP_FAILED) { if (p2 == MAP_FAILED)
p1 = (char *)MMAP(0, HEAP_MAX_SIZE<<1, PROT_NONE, MAP_NORESERVE); {
if(p1 != MAP_FAILED) { p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE);
p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) if (p1 != MAP_FAILED)
& ~(HEAP_MAX_SIZE-1)); {
p2 = (char *) (((unsigned long) p1 + (HEAP_MAX_SIZE - 1))
& ~(HEAP_MAX_SIZE - 1));
ul = p2 - p1; ul = p2 - p1;
if (ul) if (ul)
__munmap(p1, ul); __munmap (p1, ul);
else else
aligned_heap_area = p2 + HEAP_MAX_SIZE; aligned_heap_area = p2 + HEAP_MAX_SIZE;
__munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul);
} else { }
else
{
/* Try to take the chance that an allocation of only HEAP_MAX_SIZE /* Try to take the chance that an allocation of only HEAP_MAX_SIZE
is already aligned. */ is already aligned. */
p2 = (char *)MMAP(0, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE); p2 = (char *) MMAP (0, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE);
if(p2 == MAP_FAILED) if (p2 == MAP_FAILED)
return 0; return 0;
if((unsigned long)p2 & (HEAP_MAX_SIZE-1)) {
__munmap(p2, HEAP_MAX_SIZE); if ((unsigned long) p2 & (HEAP_MAX_SIZE - 1))
{
__munmap (p2, HEAP_MAX_SIZE);
return 0; return 0;
} }
} }
} }
if(__mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) { if (__mprotect (p2, size, PROT_READ | PROT_WRITE) != 0)
__munmap(p2, HEAP_MAX_SIZE); {
__munmap (p2, HEAP_MAX_SIZE);
return 0; return 0;
} }
h = (heap_info *)p2; h = (heap_info *) p2;
h->size = size; h->size = size;
h->mprotect_size = size; h->mprotect_size = size;
THREAD_STAT(stat_n_heaps++); THREAD_STAT (stat_n_heaps++);
LIBC_PROBE (memory_heap_new, 2, h, h->size); LIBC_PROBE (memory_heap_new, 2, h, h->size);
return h; return h;
} }
@ -570,20 +602,23 @@ new_heap(size_t size, size_t top_pad)
multiple of the page size. */ multiple of the page size. */
static int static int
grow_heap(heap_info *h, long diff) grow_heap (heap_info *h, long diff)
{ {
size_t page_mask = GLRO(dl_pagesize) - 1; size_t page_mask = GLRO (dl_pagesize) - 1;
long new_size; long new_size;
diff = (diff + page_mask) & ~page_mask; diff = (diff + page_mask) & ~page_mask;
new_size = (long)h->size + diff; new_size = (long) h->size + diff;
if((unsigned long) new_size > (unsigned long) HEAP_MAX_SIZE) if ((unsigned long) new_size > (unsigned long) HEAP_MAX_SIZE)
return -1; return -1;
if((unsigned long) new_size > h->mprotect_size) {
if (__mprotect((char *)h + h->mprotect_size, if ((unsigned long) new_size > h->mprotect_size)
{
if (__mprotect ((char *) h + h->mprotect_size,
(unsigned long) new_size - h->mprotect_size, (unsigned long) new_size - h->mprotect_size,
PROT_READ|PROT_WRITE) != 0) PROT_READ | PROT_WRITE) != 0)
return -2; return -2;
h->mprotect_size = new_size; h->mprotect_size = new_size;
} }
@ -595,24 +630,26 @@ grow_heap(heap_info *h, long diff)
/* Shrink a heap. */ /* Shrink a heap. */
static int static int
shrink_heap(heap_info *h, long diff) shrink_heap (heap_info *h, long diff)
{ {
long new_size; long new_size;
new_size = (long)h->size - diff; new_size = (long) h->size - diff;
if(new_size < (long)sizeof(*h)) if (new_size < (long) sizeof (*h))
return -1; return -1;
/* Try to re-map the extra heap space freshly to save memory, and make it /* Try to re-map the extra heap space freshly to save memory, and make it
inaccessible. See malloc-sysdep.h to know when this is true. */ inaccessible. See malloc-sysdep.h to know when this is true. */
if (__builtin_expect (check_may_shrink_heap (), 0)) if (__builtin_expect (check_may_shrink_heap (), 0))
{ {
if((char *)MMAP((char *)h + new_size, diff, PROT_NONE, if ((char *) MMAP ((char *) h + new_size, diff, PROT_NONE,
MAP_FIXED) == (char *) MAP_FAILED) MAP_FIXED) == (char *) MAP_FAILED)
return -2; return -2;
h->mprotect_size = new_size; h->mprotect_size = new_size;
} }
else else
__madvise ((char *)h + new_size, diff, MADV_DONTNEED); __madvise ((char *) h + new_size, diff, MADV_DONTNEED);
/*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
h->size = new_size; h->size = new_size;
@ -624,65 +661,69 @@ shrink_heap(heap_info *h, long diff)
#define delete_heap(heap) \ #define delete_heap(heap) \
do { \ do { \
if ((char *)(heap) + HEAP_MAX_SIZE == aligned_heap_area) \ if ((char *) (heap) + HEAP_MAX_SIZE == aligned_heap_area) \
aligned_heap_area = NULL; \ aligned_heap_area = NULL; \
__munmap((char*)(heap), HEAP_MAX_SIZE); \ __munmap ((char *) (heap), HEAP_MAX_SIZE); \
} while (0) } while (0)
static int static int
internal_function internal_function
heap_trim(heap_info *heap, size_t pad) heap_trim (heap_info *heap, size_t pad)
{ {
mstate ar_ptr = heap->ar_ptr; mstate ar_ptr = heap->ar_ptr;
unsigned long pagesz = GLRO(dl_pagesize); unsigned long pagesz = GLRO (dl_pagesize);
mchunkptr top_chunk = top(ar_ptr), p, bck, fwd; mchunkptr top_chunk = top (ar_ptr), p, bck, fwd;
heap_info *prev_heap; heap_info *prev_heap;
long new_size, top_size, extra, prev_size, misalign; long new_size, top_size, extra, prev_size, misalign;
/* Can this heap go away completely? */ /* Can this heap go away completely? */
while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) { while (top_chunk == chunk_at_offset (heap, sizeof (*heap)))
{
prev_heap = heap->prev; prev_heap = heap->prev;
prev_size = prev_heap->size - (MINSIZE-2*SIZE_SZ); prev_size = prev_heap->size - (MINSIZE - 2 * SIZE_SZ);
p = chunk_at_offset(prev_heap, prev_size); p = chunk_at_offset (prev_heap, prev_size);
/* fencepost must be properly aligned. */ /* fencepost must be properly aligned. */
misalign = ((long) p) & MALLOC_ALIGN_MASK; misalign = ((long) p) & MALLOC_ALIGN_MASK;
p = chunk_at_offset(prev_heap, prev_size - misalign); p = chunk_at_offset (prev_heap, prev_size - misalign);
assert(p->size == (0|PREV_INUSE)); /* must be fencepost */ assert (p->size == (0 | PREV_INUSE)); /* must be fencepost */
p = prev_chunk(p); p = prev_chunk (p);
new_size = chunksize(p) + (MINSIZE-2*SIZE_SZ) + misalign; new_size = chunksize (p) + (MINSIZE - 2 * SIZE_SZ) + misalign;
assert(new_size>0 && new_size<(long)(2*MINSIZE)); assert (new_size > 0 && new_size < (long) (2 * MINSIZE));
if(!prev_inuse(p)) if (!prev_inuse (p))
new_size += p->prev_size; new_size += p->prev_size;
assert(new_size>0 && new_size<HEAP_MAX_SIZE); assert (new_size > 0 && new_size < HEAP_MAX_SIZE);
if(new_size + (HEAP_MAX_SIZE - prev_heap->size) < pad + MINSIZE + pagesz) if (new_size + (HEAP_MAX_SIZE - prev_heap->size) < pad + MINSIZE + pagesz)
break; break;
ar_ptr->system_mem -= heap->size; ar_ptr->system_mem -= heap->size;
arena_mem -= heap->size; arena_mem -= heap->size;
LIBC_PROBE (memory_heap_free, 2, heap, heap->size); LIBC_PROBE (memory_heap_free, 2, heap, heap->size);
delete_heap(heap); delete_heap (heap);
heap = prev_heap; heap = prev_heap;
if(!prev_inuse(p)) { /* consolidate backward */ if (!prev_inuse (p)) /* consolidate backward */
p = prev_chunk(p); {
unlink(p, bck, fwd); p = prev_chunk (p);
unlink (p, bck, fwd);
} }
assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0); assert (((unsigned long) ((char *) p + new_size) & (pagesz - 1)) == 0);
assert( ((char*)p + new_size) == ((char*)heap + heap->size) ); assert (((char *) p + new_size) == ((char *) heap + heap->size));
top(ar_ptr) = top_chunk = p; top (ar_ptr) = top_chunk = p;
set_head(top_chunk, new_size | PREV_INUSE); set_head (top_chunk, new_size | PREV_INUSE);
/*check_chunk(ar_ptr, top_chunk);*/ /*check_chunk(ar_ptr, top_chunk);*/
} }
top_size = chunksize(top_chunk); top_size = chunksize (top_chunk);
extra = (top_size - pad - MINSIZE - 1) & ~(pagesz - 1); extra = (top_size - pad - MINSIZE - 1) & ~(pagesz - 1);
if(extra < (long)pagesz) if (extra < (long) pagesz)
return 0; return 0;
/* Try to shrink. */ /* Try to shrink. */
if(shrink_heap(heap, extra) != 0) if (shrink_heap (heap, extra) != 0)
return 0; return 0;
ar_ptr->system_mem -= extra; ar_ptr->system_mem -= extra;
arena_mem -= extra; arena_mem -= extra;
/* Success. Adjust top accordingly. */ /* Success. Adjust top accordingly. */
set_head(top_chunk, (top_size - extra) | PREV_INUSE); set_head (top_chunk, (top_size - extra) | PREV_INUSE);
/*check_chunk(ar_ptr, top_chunk);*/ /*check_chunk(ar_ptr, top_chunk);*/
return 1; return 1;
} }
@ -690,52 +731,53 @@ heap_trim(heap_info *heap, size_t pad)
/* Create a new arena with initial size "size". */ /* Create a new arena with initial size "size". */
static mstate static mstate
_int_new_arena(size_t size) _int_new_arena (size_t size)
{ {
mstate a; mstate a;
heap_info *h; heap_info *h;
char *ptr; char *ptr;
unsigned long misalign; unsigned long misalign;
h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT), h = new_heap (size + (sizeof (*h) + sizeof (*a) + MALLOC_ALIGNMENT),
mp_.top_pad); mp_.top_pad);
if(!h) { if (!h)
{
/* Maybe size is too large to fit in a single heap. So, just try /* Maybe size is too large to fit in a single heap. So, just try
to create a minimally-sized arena and let _int_malloc() attempt to create a minimally-sized arena and let _int_malloc() attempt
to deal with the large request via mmap_chunk(). */ to deal with the large request via mmap_chunk(). */
h = new_heap(sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT, mp_.top_pad); h = new_heap (sizeof (*h) + sizeof (*a) + MALLOC_ALIGNMENT, mp_.top_pad);
if(!h) if (!h)
return 0; return 0;
} }
a = h->ar_ptr = (mstate)(h+1); a = h->ar_ptr = (mstate) (h + 1);
malloc_init_state(a); malloc_init_state (a);
/*a->next = NULL;*/ /*a->next = NULL;*/
a->system_mem = a->max_system_mem = h->size; a->system_mem = a->max_system_mem = h->size;
arena_mem += h->size; arena_mem += h->size;
/* Set up the top chunk, with proper alignment. */ /* Set up the top chunk, with proper alignment. */
ptr = (char *)(a + 1); ptr = (char *) (a + 1);
misalign = (unsigned long)chunk2mem(ptr) & MALLOC_ALIGN_MASK; misalign = (unsigned long) chunk2mem (ptr) & MALLOC_ALIGN_MASK;
if (misalign > 0) if (misalign > 0)
ptr += MALLOC_ALIGNMENT - misalign; ptr += MALLOC_ALIGNMENT - misalign;
top(a) = (mchunkptr)ptr; top (a) = (mchunkptr) ptr;
set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE); set_head (top (a), (((char *) h + h->size) - ptr) | PREV_INUSE);
LIBC_PROBE (memory_arena_new, 2, a, size); LIBC_PROBE (memory_arena_new, 2, a, size);
tsd_setspecific(arena_key, (void *)a); tsd_setspecific (arena_key, (void *) a);
mutex_init(&a->mutex); mutex_init (&a->mutex);
(void)mutex_lock(&a->mutex); (void) mutex_lock (&a->mutex);
(void)mutex_lock(&list_lock); (void) mutex_lock (&list_lock);
/* Add the new arena to the global list. */ /* Add the new arena to the global list. */
a->next = main_arena.next; a->next = main_arena.next;
atomic_write_barrier (); atomic_write_barrier ();
main_arena.next = a; main_arena.next = a;
(void)mutex_unlock(&list_lock); (void) mutex_unlock (&list_lock);
THREAD_STAT(++(a->stat_lock_loop)); THREAD_STAT (++(a->stat_lock_loop));
return a; return a;
} }
@ -747,18 +789,18 @@ get_free_list (void)
mstate result = free_list; mstate result = free_list;
if (result != NULL) if (result != NULL)
{ {
(void)mutex_lock(&list_lock); (void) mutex_lock (&list_lock);
result = free_list; result = free_list;
if (result != NULL) if (result != NULL)
free_list = result->next_free; free_list = result->next_free;
(void)mutex_unlock(&list_lock); (void) mutex_unlock (&list_lock);
if (result != NULL) if (result != NULL)
{ {
LIBC_PROBE (memory_arena_reuse_free_list, 1, result); LIBC_PROBE (memory_arena_reuse_free_list, 1, result);
(void)mutex_lock(&result->mutex); (void) mutex_lock (&result->mutex);
tsd_setspecific(arena_key, (void *)result); tsd_setspecific (arena_key, (void *) result);
THREAD_STAT(++(result->stat_lock_loop)); THREAD_STAT (++(result->stat_lock_loop));
} }
} }
@ -779,7 +821,7 @@ reused_arena (mstate avoid_arena)
result = next_to_use; result = next_to_use;
do do
{ {
if (!mutex_trylock(&result->mutex)) if (!mutex_trylock (&result->mutex))
goto out; goto out;
result = result->next; result = result->next;
@ -793,12 +835,12 @@ reused_arena (mstate avoid_arena)
/* No arena available. Wait for the next in line. */ /* No arena available. Wait for the next in line. */
LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena); LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
(void)mutex_lock(&result->mutex); (void) mutex_lock (&result->mutex);
out: out:
LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena); LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);
tsd_setspecific(arena_key, (void *)result); tsd_setspecific (arena_key, (void *) result);
THREAD_STAT(++(result->stat_lock_loop)); THREAD_STAT (++(result->stat_lock_loop));
next_to_use = result->next; next_to_use = result->next;
return result; return result;
@ -806,7 +848,7 @@ reused_arena (mstate avoid_arena)
static mstate static mstate
internal_function internal_function
arena_get2(mstate a_tsd, size_t size, mstate avoid_arena) arena_get2 (mstate a_tsd, size_t size, mstate avoid_arena)
{ {
mstate a; mstate a;
@ -863,15 +905,18 @@ static mstate
arena_get_retry (mstate ar_ptr, size_t bytes) arena_get_retry (mstate ar_ptr, size_t bytes)
{ {
LIBC_PROBE (memory_arena_retry, 2, bytes, ar_ptr); LIBC_PROBE (memory_arena_retry, 2, bytes, ar_ptr);
if(ar_ptr != &main_arena) { if (ar_ptr != &main_arena)
(void)mutex_unlock(&ar_ptr->mutex); {
(void) mutex_unlock (&ar_ptr->mutex);
ar_ptr = &main_arena; ar_ptr = &main_arena;
(void)mutex_lock(&ar_ptr->mutex); (void) mutex_lock (&ar_ptr->mutex);
} else { }
else
{
/* Grab ar_ptr->next prior to releasing its lock. */ /* Grab ar_ptr->next prior to releasing its lock. */
mstate prev = ar_ptr->next ? ar_ptr : 0; mstate prev = ar_ptr->next ? ar_ptr : 0;
(void)mutex_unlock(&ar_ptr->mutex); (void) mutex_unlock (&ar_ptr->mutex);
ar_ptr = arena_get2(prev, bytes, ar_ptr); ar_ptr = arena_get2 (prev, bytes, ar_ptr);
} }
return ar_ptr; return ar_ptr;
@ -881,15 +926,15 @@ static void __attribute__ ((section ("__libc_thread_freeres_fn")))
arena_thread_freeres (void) arena_thread_freeres (void)
{ {
void *vptr = NULL; void *vptr = NULL;
mstate a = tsd_getspecific(arena_key, vptr); mstate a = tsd_getspecific (arena_key, vptr);
tsd_setspecific(arena_key, NULL); tsd_setspecific (arena_key, NULL);
if (a != NULL) if (a != NULL)
{ {
(void)mutex_lock(&list_lock); (void) mutex_lock (&list_lock);
a->next_free = free_list; a->next_free = free_list;
free_list = a; free_list = a;
(void)mutex_unlock(&list_lock); (void) mutex_unlock (&list_lock);
} }
} }
text_set_element (__libc_thread_subfreeres, arena_thread_freeres); text_set_element (__libc_thread_subfreeres, arena_thread_freeres);

View File

@ -24,29 +24,29 @@
/* Hooks for debugging versions. The initial hooks just call the /* Hooks for debugging versions. The initial hooks just call the
initialization routine, then do the normal work. */ initialization routine, then do the normal work. */
static void* static void *
malloc_hook_ini(size_t sz, const void *caller) malloc_hook_ini (size_t sz, const void *caller)
{ {
__malloc_hook = NULL; __malloc_hook = NULL;
ptmalloc_init(); ptmalloc_init ();
return __libc_malloc(sz); return __libc_malloc (sz);
} }
static void* static void *
realloc_hook_ini(void* ptr, size_t sz, const void *caller) realloc_hook_ini (void *ptr, size_t sz, const void *caller)
{ {
__malloc_hook = NULL; __malloc_hook = NULL;
__realloc_hook = NULL; __realloc_hook = NULL;
ptmalloc_init(); ptmalloc_init ();
return __libc_realloc(ptr, sz); return __libc_realloc (ptr, sz);
} }
static void* static void *
memalign_hook_ini(size_t alignment, size_t sz, const void *caller) memalign_hook_ini (size_t alignment, size_t sz, const void *caller)
{ {
__memalign_hook = NULL; __memalign_hook = NULL;
ptmalloc_init(); ptmalloc_init ();
return __libc_memalign(alignment, sz); return __libc_memalign (alignment, sz);
} }
/* Whether we are using malloc checking. */ /* Whether we are using malloc checking. */
@ -71,7 +71,8 @@ static int disallow_malloc_check;
void void
__malloc_check_init (void) __malloc_check_init (void)
{ {
if (disallow_malloc_check) { if (disallow_malloc_check)
{
disallow_malloc_check = 0; disallow_malloc_check = 0;
return; return;
} }
@ -87,7 +88,7 @@ __malloc_check_init (void)
overruns. The goal here is to avoid obscure crashes due to invalid overruns. The goal here is to avoid obscure crashes due to invalid
usage, unlike in the MALLOC_DEBUG code. */ usage, unlike in the MALLOC_DEBUG code. */
#define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF ) #define MAGICBYTE(p) ((((size_t) p >> 3) ^ ((size_t) p >> 11)) & 0xFF)
/* Visualize the chunk as being partitioned into blocks of 256 bytes from the /* Visualize the chunk as being partitioned into blocks of 256 bytes from the
highest address of the chunk, downwards. The beginning of each block tells highest address of the chunk, downwards. The beginning of each block tells
@ -96,53 +97,58 @@ __malloc_check_init (void)
must reach it with this iteration, otherwise we have witnessed a memory must reach it with this iteration, otherwise we have witnessed a memory
corruption. */ corruption. */
static size_t static size_t
malloc_check_get_size(mchunkptr p) malloc_check_get_size (mchunkptr p)
{ {
size_t size; size_t size;
unsigned char c; unsigned char c;
unsigned char magic = MAGICBYTE(p); unsigned char magic = MAGICBYTE (p);
assert(using_malloc_checking == 1); assert (using_malloc_checking == 1);
for (size = chunksize(p) - 1 + (chunk_is_mmapped(p) ? 0 : SIZE_SZ); for (size = chunksize (p) - 1 + (chunk_is_mmapped (p) ? 0 : SIZE_SZ);
(c = ((unsigned char*)p)[size]) != magic; (c = ((unsigned char *) p)[size]) != magic;
size -= c) { size -= c)
if(c<=0 || size<(c+2*SIZE_SZ)) { {
malloc_printerr(check_action, "malloc_check_get_size: memory corruption", if (c <= 0 || size < (c + 2 * SIZE_SZ))
chunk2mem(p)); {
malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
chunk2mem (p));
return 0; return 0;
} }
} }
/* chunk2mem size. */ /* chunk2mem size. */
return size - 2*SIZE_SZ; return size - 2 * SIZE_SZ;
} }
/* Instrument a chunk with overrun detector byte(s) and convert it /* Instrument a chunk with overrun detector byte(s) and convert it
into a user pointer with requested size sz. */ into a user pointer with requested size sz. */
static void* static void *
internal_function internal_function
mem2mem_check(void *ptr, size_t sz) mem2mem_check (void *ptr, size_t sz)
{ {
mchunkptr p; mchunkptr p;
unsigned char* m_ptr = ptr; unsigned char *m_ptr = ptr;
size_t i; size_t i;
if (!ptr) if (!ptr)
return ptr; return ptr;
p = mem2chunk(ptr);
for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1); p = mem2chunk (ptr);
for (i = chunksize (p) - (chunk_is_mmapped (p) ? 2 * SIZE_SZ + 1 : SIZE_SZ + 1);
i > sz; i > sz;
i -= 0xFF) { i -= 0xFF)
if(i-sz < 0x100) { {
m_ptr[i] = (unsigned char)(i-sz); if (i - sz < 0x100)
{
m_ptr[i] = (unsigned char) (i - sz);
break; break;
} }
m_ptr[i] = 0xFF; m_ptr[i] = 0xFF;
} }
m_ptr[sz] = MAGICBYTE(p); m_ptr[sz] = MAGICBYTE (p);
return (void*)m_ptr; return (void *) m_ptr;
} }
/* Convert a pointer to be free()d or realloc()ed to a valid chunk /* Convert a pointer to be free()d or realloc()ed to a valid chunk
@ -150,53 +156,64 @@ mem2mem_check(void *ptr, size_t sz)
static mchunkptr static mchunkptr
internal_function internal_function
mem2chunk_check(void* mem, unsigned char **magic_p) mem2chunk_check (void *mem, unsigned char **magic_p)
{ {
mchunkptr p; mchunkptr p;
INTERNAL_SIZE_T sz, c; INTERNAL_SIZE_T sz, c;
unsigned char magic; unsigned char magic;
if(!aligned_OK(mem)) return NULL; if (!aligned_OK (mem))
p = mem2chunk(mem); return NULL;
if (!chunk_is_mmapped(p)) {
/* Must be a chunk in conventional heap memory. */ p = mem2chunk (mem);
int contig = contiguous(&main_arena); if (!chunk_is_mmapped (p))
sz = chunksize(p); {
if((contig && /* Must be a chunk in conventional heap memory. */
((char*)p<mp_.sbrk_base || int contig = contiguous (&main_arena);
((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) || sz = chunksize (p);
sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) || if ((contig &&
( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK || ((char *) p < mp_.sbrk_base ||
(contig && (char*)prev_chunk(p)<mp_.sbrk_base) || ((char *) p + sz) >= (mp_.sbrk_base + main_arena.system_mem))) ||
next_chunk(prev_chunk(p))!=p) )) sz < MINSIZE || sz & MALLOC_ALIGN_MASK || !inuse (p) ||
(!prev_inuse (p) && (p->prev_size & MALLOC_ALIGN_MASK ||
(contig && (char *) prev_chunk (p) < mp_.sbrk_base) ||
next_chunk (prev_chunk (p)) != p)))
return NULL;
magic = MAGICBYTE (p);
for (sz += SIZE_SZ - 1; (c = ((unsigned char *) p)[sz]) != magic; sz -= c)
{
if (c <= 0 || sz < (c + 2 * SIZE_SZ))
return NULL; return NULL;
magic = MAGICBYTE(p);
for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
} }
} else { }
unsigned long offset, page_mask = GLRO(dl_pagesize)-1; else
{
unsigned long offset, page_mask = GLRO (dl_pagesize) - 1;
/* mmap()ed chunks have MALLOC_ALIGNMENT or higher power-of-two /* mmap()ed chunks have MALLOC_ALIGNMENT or higher power-of-two
alignment relative to the beginning of a page. Check this alignment relative to the beginning of a page. Check this
first. */ first. */
offset = (unsigned long)mem & page_mask; offset = (unsigned long) mem & page_mask;
if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 && if ((offset != MALLOC_ALIGNMENT && offset != 0 && offset != 0x10 &&
offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 && offset != 0x20 && offset != 0x40 && offset != 0x80 && offset != 0x100 &&
offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 && offset != 0x200 && offset != 0x400 && offset != 0x800 && offset != 0x1000 &&
offset<0x2000) || offset < 0x2000) ||
!chunk_is_mmapped(p) || (p->size & PREV_INUSE) || !chunk_is_mmapped (p) || (p->size & PREV_INUSE) ||
( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) || ((((unsigned long) p - p->prev_size) & page_mask) != 0) ||
( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) ) ((sz = chunksize (p)), ((p->prev_size + sz) & page_mask) != 0))
return NULL;
magic = MAGICBYTE (p);
for (sz -= 1; (c = ((unsigned char *) p)[sz]) != magic; sz -= c)
{
if (c <= 0 || sz < (c + 2 * SIZE_SZ))
return NULL; return NULL;
magic = MAGICBYTE(p);
for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
} }
} }
((unsigned char*)p)[sz] ^= 0xFF; ((unsigned char *) p)[sz] ^= 0xFF;
if (magic_p) if (magic_p)
*magic_p = (unsigned char *)p + sz; *magic_p = (unsigned char *) p + sz;
return p; return p;
} }
@ -205,32 +222,32 @@ mem2chunk_check(void* mem, unsigned char **magic_p)
static int static int
internal_function internal_function
top_check(void) top_check (void)
{ {
mchunkptr t = top(&main_arena); mchunkptr t = top (&main_arena);
char* brk, * new_brk; char *brk, *new_brk;
INTERNAL_SIZE_T front_misalign, sbrk_size; INTERNAL_SIZE_T front_misalign, sbrk_size;
unsigned long pagesz = GLRO(dl_pagesize); unsigned long pagesz = GLRO (dl_pagesize);
if (t == initial_top(&main_arena) || if (t == initial_top (&main_arena) ||
(!chunk_is_mmapped(t) && (!chunk_is_mmapped (t) &&
chunksize(t)>=MINSIZE && chunksize (t) >= MINSIZE &&
prev_inuse(t) && prev_inuse (t) &&
(!contiguous(&main_arena) || (!contiguous (&main_arena) ||
(char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem))) (char *) t + chunksize (t) == mp_.sbrk_base + main_arena.system_mem)))
return 0; return 0;
malloc_printerr (check_action, "malloc: top chunk is corrupt", t); malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
/* Try to set up a new top chunk. */ /* Try to set up a new top chunk. */
brk = MORECORE(0); brk = MORECORE (0);
front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK; front_misalign = (unsigned long) chunk2mem (brk) & MALLOC_ALIGN_MASK;
if (front_misalign > 0) if (front_misalign > 0)
front_misalign = MALLOC_ALIGNMENT - front_misalign; front_misalign = MALLOC_ALIGNMENT - front_misalign;
sbrk_size = front_misalign + mp_.top_pad + MINSIZE; sbrk_size = front_misalign + mp_.top_pad + MINSIZE;
sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1)); sbrk_size += pagesz - ((unsigned long) (brk + sbrk_size) & (pagesz - 1));
new_brk = (char*)(MORECORE (sbrk_size)); new_brk = (char *) (MORECORE (sbrk_size));
if (new_brk == (char*)(MORECORE_FAILURE)) if (new_brk == (char *) (MORECORE_FAILURE))
{ {
__set_errno (ENOMEM); __set_errno (ENOMEM);
return -1; return -1;
@ -238,128 +255,148 @@ top_check(void)
/* Call the `morecore' hook if necessary. */ /* Call the `morecore' hook if necessary. */
void (*hook) (void) = atomic_forced_read (__after_morecore_hook); void (*hook) (void) = atomic_forced_read (__after_morecore_hook);
if (hook) if (hook)
(*hook) (); (*hook)();
main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size; main_arena.system_mem = (new_brk - mp_.sbrk_base) + sbrk_size;
top(&main_arena) = (mchunkptr)(brk + front_misalign); top (&main_arena) = (mchunkptr) (brk + front_misalign);
set_head(top(&main_arena), (sbrk_size - front_misalign) | PREV_INUSE); set_head (top (&main_arena), (sbrk_size - front_misalign) | PREV_INUSE);
return 0; return 0;
} }
static void* static void *
malloc_check(size_t sz, const void *caller) malloc_check (size_t sz, const void *caller)
{ {
void *victim; void *victim;
if (sz+1 == 0) { if (sz + 1 == 0)
{
__set_errno (ENOMEM); __set_errno (ENOMEM);
return NULL; return NULL;
} }
(void)mutex_lock(&main_arena.mutex); (void) mutex_lock (&main_arena.mutex);
victim = (top_check() >= 0) ? _int_malloc(&main_arena, sz+1) : NULL; victim = (top_check () >= 0) ? _int_malloc (&main_arena, sz + 1) : NULL;
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
return mem2mem_check(victim, sz); return mem2mem_check (victim, sz);
} }
static void static void
free_check(void* mem, const void *caller) free_check (void *mem, const void *caller)
{ {
mchunkptr p; mchunkptr p;
if(!mem) return; if (!mem)
(void)mutex_lock(&main_arena.mutex); return;
p = mem2chunk_check(mem, NULL);
if(!p) {
(void)mutex_unlock(&main_arena.mutex);
malloc_printerr(check_action, "free(): invalid pointer", mem); (void) mutex_lock (&main_arena.mutex);
p = mem2chunk_check (mem, NULL);
if (!p)
{
(void) mutex_unlock (&main_arena.mutex);
malloc_printerr (check_action, "free(): invalid pointer", mem);
return; return;
} }
if (chunk_is_mmapped(p)) { if (chunk_is_mmapped (p))
(void)mutex_unlock(&main_arena.mutex); {
munmap_chunk(p); (void) mutex_unlock (&main_arena.mutex);
munmap_chunk (p);
return; return;
} }
_int_free(&main_arena, p, 1); _int_free (&main_arena, p, 1);
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
} }
static void* static void *
realloc_check(void* oldmem, size_t bytes, const void *caller) realloc_check (void *oldmem, size_t bytes, const void *caller)
{ {
INTERNAL_SIZE_T nb; INTERNAL_SIZE_T nb;
void* newmem = 0; void *newmem = 0;
unsigned char *magic_p; unsigned char *magic_p;
if (bytes+1 == 0) { if (bytes + 1 == 0)
{
__set_errno (ENOMEM); __set_errno (ENOMEM);
return NULL; return NULL;
} }
if (oldmem == 0) return malloc_check(bytes, NULL); if (oldmem == 0)
if (bytes == 0) { return malloc_check (bytes, NULL);
if (bytes == 0)
{
free_check (oldmem, NULL); free_check (oldmem, NULL);
return NULL; return NULL;
} }
(void)mutex_lock(&main_arena.mutex); (void) mutex_lock (&main_arena.mutex);
const mchunkptr oldp = mem2chunk_check(oldmem, &magic_p); const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
if(!oldp) { if (!oldp)
malloc_printerr(check_action, "realloc(): invalid pointer", oldmem); {
return malloc_check(bytes, NULL); malloc_printerr (check_action, "realloc(): invalid pointer", oldmem);
return malloc_check (bytes, NULL);
} }
const INTERNAL_SIZE_T oldsize = chunksize(oldp); const INTERNAL_SIZE_T oldsize = chunksize (oldp);
checked_request2size(bytes+1, nb); checked_request2size (bytes + 1, nb);
(void)mutex_lock(&main_arena.mutex); (void) mutex_lock (&main_arena.mutex);
if (chunk_is_mmapped(oldp)) { if (chunk_is_mmapped (oldp))
{
#if HAVE_MREMAP #if HAVE_MREMAP
mchunkptr newp = mremap_chunk(oldp, nb); mchunkptr newp = mremap_chunk (oldp, nb);
if(newp) if (newp)
newmem = chunk2mem(newp); newmem = chunk2mem (newp);
else else
#endif #endif
{ {
/* Note the extra SIZE_SZ overhead. */ /* Note the extra SIZE_SZ overhead. */
if(oldsize - SIZE_SZ >= nb) if (oldsize - SIZE_SZ >= nb)
newmem = oldmem; /* do nothing */ newmem = oldmem; /* do nothing */
else { else
{
/* Must alloc, copy, free. */ /* Must alloc, copy, free. */
if (top_check() >= 0) if (top_check () >= 0)
newmem = _int_malloc(&main_arena, bytes+1); newmem = _int_malloc (&main_arena, bytes + 1);
if (newmem) { if (newmem)
memcpy(newmem, oldmem, oldsize - 2*SIZE_SZ); {
munmap_chunk(oldp); memcpy (newmem, oldmem, oldsize - 2 * SIZE_SZ);
munmap_chunk (oldp);
} }
} }
} }
} else { }
if (top_check() >= 0) { else
{
if (top_check () >= 0)
{
INTERNAL_SIZE_T nb; INTERNAL_SIZE_T nb;
checked_request2size(bytes + 1, nb); checked_request2size (bytes + 1, nb);
newmem = _int_realloc(&main_arena, oldp, oldsize, nb); newmem = _int_realloc (&main_arena, oldp, oldsize, nb);
} }
} }
/* mem2chunk_check changed the magic byte in the old chunk. /* mem2chunk_check changed the magic byte in the old chunk.
If newmem is NULL, then the old chunk will still be used though, If newmem is NULL, then the old chunk will still be used though,
so we need to invert that change here. */ so we need to invert that change here. */
if (newmem == NULL) *magic_p ^= 0xFF; if (newmem == NULL)
*magic_p ^= 0xFF;
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
return mem2mem_check(newmem, bytes); return mem2mem_check (newmem, bytes);
} }
static void* static void *
memalign_check(size_t alignment, size_t bytes, const void *caller) memalign_check (size_t alignment, size_t bytes, const void *caller)
{ {
void* mem; void *mem;
if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL); if (alignment <= MALLOC_ALIGNMENT)
if (alignment < MINSIZE) alignment = MINSIZE; return malloc_check (bytes, NULL);
if (alignment < MINSIZE)
alignment = MINSIZE;
/* If the alignment is greater than SIZE_MAX / 2 + 1 it cannot be a /* If the alignment is greater than SIZE_MAX / 2 + 1 it cannot be a
power of 2 and will cause overflow in the check below. */ power of 2 and will cause overflow in the check below. */
@ -377,17 +414,19 @@ memalign_check(size_t alignment, size_t bytes, const void *caller)
} }
/* Make sure alignment is power of 2. */ /* Make sure alignment is power of 2. */
if (!powerof2(alignment)) { if (!powerof2 (alignment))
{
size_t a = MALLOC_ALIGNMENT * 2; size_t a = MALLOC_ALIGNMENT * 2;
while (a < alignment) a <<= 1; while (a < alignment)
a <<= 1;
alignment = a; alignment = a;
} }
(void)mutex_lock(&main_arena.mutex); (void) mutex_lock (&main_arena.mutex);
mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) : mem = (top_check () >= 0) ? _int_memalign (&main_arena, alignment, bytes + 1) :
NULL; NULL;
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
return mem2mem_check(mem, bytes); return mem2mem_check (mem, bytes);
} }
@ -408,13 +447,14 @@ memalign_check(size_t alignment, size_t bytes, const void *caller)
then the hooks are reset to 0. */ then the hooks are reset to 0. */
#define MALLOC_STATE_MAGIC 0x444c4541l #define MALLOC_STATE_MAGIC 0x444c4541l
#define MALLOC_STATE_VERSION (0*0x100l + 4l) /* major*0x100 + minor */ #define MALLOC_STATE_VERSION (0 * 0x100l + 4l) /* major*0x100 + minor */
struct malloc_save_state { struct malloc_save_state
{
long magic; long magic;
long version; long version;
mbinptr av[NBINS * 2 + 2]; mbinptr av[NBINS * 2 + 2];
char* sbrk_base; char *sbrk_base;
int sbrked_mem_bytes; int sbrked_mem_bytes;
unsigned long trim_threshold; unsigned long trim_threshold;
unsigned long top_pad; unsigned long top_pad;
@ -434,31 +474,34 @@ struct malloc_save_state {
unsigned long narenas; unsigned long narenas;
}; };
void* void *
__malloc_get_state(void) __malloc_get_state (void)
{ {
struct malloc_save_state* ms; struct malloc_save_state *ms;
int i; int i;
mbinptr b; mbinptr b;
ms = (struct malloc_save_state*)__libc_malloc(sizeof(*ms)); ms = (struct malloc_save_state *) __libc_malloc (sizeof (*ms));
if (!ms) if (!ms)
return 0; return 0;
(void)mutex_lock(&main_arena.mutex);
malloc_consolidate(&main_arena); (void) mutex_lock (&main_arena.mutex);
malloc_consolidate (&main_arena);
ms->magic = MALLOC_STATE_MAGIC; ms->magic = MALLOC_STATE_MAGIC;
ms->version = MALLOC_STATE_VERSION; ms->version = MALLOC_STATE_VERSION;
ms->av[0] = 0; ms->av[0] = 0;
ms->av[1] = 0; /* used to be binblocks, now no longer used */ ms->av[1] = 0; /* used to be binblocks, now no longer used */
ms->av[2] = top(&main_arena); ms->av[2] = top (&main_arena);
ms->av[3] = 0; /* used to be undefined */ ms->av[3] = 0; /* used to be undefined */
for(i=1; i<NBINS; i++) { for (i = 1; i < NBINS; i++)
b = bin_at(&main_arena, i); {
if(first(b) == b) b = bin_at (&main_arena, i);
ms->av[2*i+2] = ms->av[2*i+3] = 0; /* empty bin */ if (first (b) == b)
else { ms->av[2 * i + 2] = ms->av[2 * i + 3] = 0; /* empty bin */
ms->av[2*i+2] = first(b); else
ms->av[2*i+3] = last(b); {
ms->av[2 * i + 2] = first (b);
ms->av[2 * i + 3] = last (b);
} }
} }
ms->sbrk_base = mp_.sbrk_base; ms->sbrk_base = mp_.sbrk_base;
@ -475,72 +518,86 @@ __malloc_get_state(void)
ms->mmapped_mem = mp_.mmapped_mem; ms->mmapped_mem = mp_.mmapped_mem;
ms->max_mmapped_mem = mp_.max_mmapped_mem; ms->max_mmapped_mem = mp_.max_mmapped_mem;
ms->using_malloc_checking = using_malloc_checking; ms->using_malloc_checking = using_malloc_checking;
ms->max_fast = get_max_fast(); ms->max_fast = get_max_fast ();
ms->arena_test = mp_.arena_test; ms->arena_test = mp_.arena_test;
ms->arena_max = mp_.arena_max; ms->arena_max = mp_.arena_max;
ms->narenas = narenas; ms->narenas = narenas;
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
return (void*)ms; return (void *) ms;
} }
int int
__malloc_set_state(void* msptr) __malloc_set_state (void *msptr)
{ {
struct malloc_save_state* ms = (struct malloc_save_state*)msptr; struct malloc_save_state *ms = (struct malloc_save_state *) msptr;
size_t i; size_t i;
mbinptr b; mbinptr b;
disallow_malloc_check = 1; disallow_malloc_check = 1;
ptmalloc_init(); ptmalloc_init ();
if(ms->magic != MALLOC_STATE_MAGIC) return -1; if (ms->magic != MALLOC_STATE_MAGIC)
return -1;
/* Must fail if the major version is too high. */ /* Must fail if the major version is too high. */
if((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl)) return -2; if ((ms->version & ~0xffl) > (MALLOC_STATE_VERSION & ~0xffl))
(void)mutex_lock(&main_arena.mutex); return -2;
(void) mutex_lock (&main_arena.mutex);
/* There are no fastchunks. */ /* There are no fastchunks. */
clear_fastchunks(&main_arena); clear_fastchunks (&main_arena);
if (ms->version >= 4) if (ms->version >= 4)
set_max_fast(ms->max_fast); set_max_fast (ms->max_fast);
else else
set_max_fast(64); /* 64 used to be the value we always used. */ set_max_fast (64); /* 64 used to be the value we always used. */
for (i=0; i<NFASTBINS; ++i) for (i = 0; i < NFASTBINS; ++i)
fastbin (&main_arena, i) = 0; fastbin (&main_arena, i) = 0;
for (i=0; i<BINMAPSIZE; ++i) for (i = 0; i < BINMAPSIZE; ++i)
main_arena.binmap[i] = 0; main_arena.binmap[i] = 0;
top(&main_arena) = ms->av[2]; top (&main_arena) = ms->av[2];
main_arena.last_remainder = 0; main_arena.last_remainder = 0;
for(i=1; i<NBINS; i++) { for (i = 1; i < NBINS; i++)
b = bin_at(&main_arena, i); {
if(ms->av[2*i+2] == 0) { b = bin_at (&main_arena, i);
assert(ms->av[2*i+3] == 0); if (ms->av[2 * i + 2] == 0)
first(b) = last(b) = b; {
} else { assert (ms->av[2 * i + 3] == 0);
if(ms->version >= 3 && first (b) = last (b) = b;
(i<NSMALLBINS || (largebin_index(chunksize(ms->av[2*i+2]))==i && }
largebin_index(chunksize(ms->av[2*i+3]))==i))) { else
first(b) = ms->av[2*i+2]; {
last(b) = ms->av[2*i+3]; if (ms->version >= 3 &&
(i < NSMALLBINS || (largebin_index (chunksize (ms->av[2 * i + 2])) == i &&
largebin_index (chunksize (ms->av[2 * i + 3])) == i)))
{
first (b) = ms->av[2 * i + 2];
last (b) = ms->av[2 * i + 3];
/* Make sure the links to the bins within the heap are correct. */ /* Make sure the links to the bins within the heap are correct. */
first(b)->bk = b; first (b)->bk = b;
last(b)->fd = b; last (b)->fd = b;
/* Set bit in binblocks. */ /* Set bit in binblocks. */
mark_bin(&main_arena, i); mark_bin (&main_arena, i);
} else { }
else
{
/* Oops, index computation from chunksize must have changed. /* Oops, index computation from chunksize must have changed.
Link the whole list into unsorted_chunks. */ Link the whole list into unsorted_chunks. */
first(b) = last(b) = b; first (b) = last (b) = b;
b = unsorted_chunks(&main_arena); b = unsorted_chunks (&main_arena);
ms->av[2*i+2]->bk = b; ms->av[2 * i + 2]->bk = b;
ms->av[2*i+3]->fd = b->fd; ms->av[2 * i + 3]->fd = b->fd;
b->fd->bk = ms->av[2*i+3]; b->fd->bk = ms->av[2 * i + 3];
b->fd = ms->av[2*i+2]; b->fd = ms->av[2 * i + 2];
} }
} }
} }
if (ms->version < 3) { if (ms->version < 3)
{
/* Clear fd_nextsize and bk_nextsize fields. */ /* Clear fd_nextsize and bk_nextsize fields. */
b = unsorted_chunks(&main_arena)->fd; b = unsorted_chunks (&main_arena)->fd;
while (b != unsorted_chunks(&main_arena)) { while (b != unsorted_chunks (&main_arena))
if (!in_smallbin_range(chunksize(b))) { {
if (!in_smallbin_range (chunksize (b)))
{
b->fd_nextsize = NULL; b->fd_nextsize = NULL;
b->bk_nextsize = NULL; b->bk_nextsize = NULL;
} }
@ -560,13 +617,15 @@ __malloc_set_state(void* msptr)
mp_.mmapped_mem = ms->mmapped_mem; mp_.mmapped_mem = ms->mmapped_mem;
mp_.max_mmapped_mem = ms->max_mmapped_mem; mp_.max_mmapped_mem = ms->max_mmapped_mem;
/* add version-dependent code here */ /* add version-dependent code here */
if (ms->version >= 1) { if (ms->version >= 1)
{
/* Check whether it is safe to enable malloc checking, or whether /* Check whether it is safe to enable malloc checking, or whether
it is necessary to disable it. */ it is necessary to disable it. */
if (ms->using_malloc_checking && !using_malloc_checking && if (ms->using_malloc_checking && !using_malloc_checking &&
!disallow_malloc_check) !disallow_malloc_check)
__malloc_check_init (); __malloc_check_init ();
else if (!ms->using_malloc_checking && using_malloc_checking) { else if (!ms->using_malloc_checking && using_malloc_checking)
{
__malloc_hook = NULL; __malloc_hook = NULL;
__free_hook = NULL; __free_hook = NULL;
__realloc_hook = NULL; __realloc_hook = NULL;
@ -574,14 +633,15 @@ __malloc_set_state(void* msptr)
using_malloc_checking = 0; using_malloc_checking = 0;
} }
} }
if (ms->version >= 4) { if (ms->version >= 4)
{
mp_.arena_test = ms->arena_test; mp_.arena_test = ms->arena_test;
mp_.arena_max = ms->arena_max; mp_.arena_max = ms->arena_max;
narenas = ms->narenas; narenas = ms->narenas;
} }
check_malloc_state(&main_arena); check_malloc_state (&main_arena);
(void)mutex_unlock(&main_arena.mutex); (void) mutex_unlock (&main_arena.mutex);
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@ extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
extern void *calloc (size_t __nmemb, size_t __size) extern void *calloc (size_t __nmemb, size_t __size)
__THROW __attribute_malloc__ __wur; __THROW __attribute_malloc__ __wur;
/* Re-allocate the previously allocated block in __ptr, making the new /* Re-allocate the previously allocated block in __ptr, making the new
block SIZE bytes long. */ block SIZE bytes long. */
@ -47,7 +47,7 @@ extern void *calloc (size_t __nmemb, size_t __size)
the same pointer that was passed to it, aliasing needs to be allowed the same pointer that was passed to it, aliasing needs to be allowed
between objects pointed by the old and new pointers. */ between objects pointed by the old and new pointers. */
extern void *realloc (void *__ptr, size_t __size) extern void *realloc (void *__ptr, size_t __size)
__THROW __attribute_warn_unused_result__; __THROW __attribute_warn_unused_result__;
/* Free a block allocated by `malloc', `realloc' or `calloc'. */ /* Free a block allocated by `malloc', `realloc' or `calloc'. */
extern void free (void *__ptr) __THROW; extern void free (void *__ptr) __THROW;
@ -57,14 +57,14 @@ extern void cfree (void *__ptr) __THROW;
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
extern void *memalign (size_t __alignment, size_t __size) extern void *memalign (size_t __alignment, size_t __size)
__THROW __attribute_malloc__ __wur; __THROW __attribute_malloc__ __wur;
/* Allocate SIZE bytes on a page boundary. */ /* Allocate SIZE bytes on a page boundary. */
extern void *valloc (size_t __size) __THROW __attribute_malloc__ __wur; extern void *valloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
__size to nearest pagesize. */ __size to nearest pagesize. */
extern void * pvalloc (size_t __size) __THROW __attribute_malloc__ __wur; extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ __wur;
/* Underlying allocation function; successive calls should return /* Underlying allocation function; successive calls should return
contiguous pieces of memory. */ contiguous pieces of memory. */
@ -72,7 +72,7 @@ extern void *(*__morecore) (ptrdiff_t __size);
/* Default value of `__morecore'. */ /* Default value of `__morecore'. */
extern void *__default_morecore (ptrdiff_t __size) extern void *__default_morecore (ptrdiff_t __size)
__THROW __attribute_malloc__; __THROW __attribute_malloc__;
/* SVID2/XPG mallinfo structure */ /* SVID2/XPG mallinfo structure */
@ -145,22 +145,22 @@ extern int malloc_set_state (void *__ptr) __THROW;
the application provides the preferred way to set up the hook the application provides the preferred way to set up the hook
pointers. */ pointers. */
extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) extern void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void)
__MALLOC_DEPRECATED; __MALLOC_DEPRECATED;
/* Hooks for debugging and user-defined versions. */ /* Hooks for debugging and user-defined versions. */
extern void (*__MALLOC_HOOK_VOLATILE __free_hook) (void *__ptr, extern void (*__MALLOC_HOOK_VOLATILE __free_hook) (void *__ptr,
const void *) const void *)
__MALLOC_DEPRECATED; __MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook) (size_t __size, extern void *(*__MALLOC_HOOK_VOLATILE __malloc_hook)(size_t __size,
const void *) const void *)
__MALLOC_DEPRECATED; __MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook) (void *__ptr, extern void *(*__MALLOC_HOOK_VOLATILE __realloc_hook)(void *__ptr,
size_t __size, size_t __size,
const void *) const void *)
__MALLOC_DEPRECATED; __MALLOC_DEPRECATED;
extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook) (size_t __alignment, extern void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t __alignment,
size_t __size, size_t __size,
const void *) const void *)
__MALLOC_DEPRECATED; __MALLOC_DEPRECATED;
extern void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void); extern void (*__MALLOC_HOOK_VOLATILE __after_morecore_hook) (void);
/* Activate a standard set of debugging hooks. */ /* Activate a standard set of debugging hooks. */
@ -168,5 +168,4 @@ extern void __malloc_check_init (void) __THROW __MALLOC_DEPRECATED;
__END_DECLS __END_DECLS
#endif /* malloc.h */ #endif /* malloc.h */

View File

@ -28,7 +28,7 @@
#endif #endif
/* Old hook values. */ /* Old hook values. */
static void (*old_free_hook) (__ptr_t ptr, const __ptr_t); static void (*old_free_hook)(__ptr_t ptr, const __ptr_t);
static __ptr_t (*old_malloc_hook) (size_t size, const __ptr_t); static __ptr_t (*old_malloc_hook) (size_t size, const __ptr_t);
static __ptr_t (*old_memalign_hook) (size_t alignment, size_t size, static __ptr_t (*old_memalign_hook) (size_t alignment, size_t size,
const __ptr_t); const __ptr_t);
@ -46,14 +46,14 @@ static void (*abortfunc) (enum mcheck_status);
#define FREEFLOOD ((char) 0x95) #define FREEFLOOD ((char) 0x95)
struct hdr struct hdr
{ {
size_t size; /* Exact size requested by user. */ size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */ unsigned long int magic; /* Magic number to check header integrity. */
struct hdr *prev; struct hdr *prev;
struct hdr *next; struct hdr *next;
__ptr_t block; /* Real block allocated, for memalign. */ __ptr_t block; /* Real block allocated, for memalign. */
unsigned long int magic2; /* Extra, keeps us doubleword aligned. */ unsigned long int magic2; /* Extra, keeps us doubleword aligned. */
}; };
/* This is the beginning of the list of all memory blocks allocated. /* This is the beginning of the list of all memory blocks allocated.
It is only constructed if the pedantic testing is requested. */ It is only constructed if the pedantic testing is requested. */
@ -69,11 +69,10 @@ static int pedantic;
# define flood memset # define flood memset
#else #else
static void flood (__ptr_t, int, size_t); static void flood (__ptr_t, int, size_t);
static void static void flood (ptr, val, size)
flood (ptr, val, size) __ptr_t ptr;
__ptr_t ptr; int val;
int val; size_t size;
size_t size;
{ {
char *cp = ptr; char *cp = ptr;
while (size--) while (size--)
@ -194,7 +193,7 @@ freehook (__ptr_t ptr, const __ptr_t caller)
} }
__free_hook = old_free_hook; __free_hook = old_free_hook;
if (old_free_hook != NULL) if (old_free_hook != NULL)
(*old_free_hook) (ptr, caller); (*old_free_hook)(ptr, caller);
else else
free (ptr); free (ptr);
__free_hook = freehook; __free_hook = freehook;
@ -216,7 +215,7 @@ mallochook (size_t size, const __ptr_t caller)
__malloc_hook = old_malloc_hook; __malloc_hook = old_malloc_hook;
if (old_malloc_hook != NULL) if (old_malloc_hook != NULL)
hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1, hdr = (struct hdr *) (*old_malloc_hook)(sizeof (struct hdr) + size + 1,
caller); caller);
else else
hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
@ -244,7 +243,7 @@ memalignhook (size_t alignment, size_t size,
if (pedantic) if (pedantic)
mcheck_check_all (); mcheck_check_all ();
slop = (sizeof *hdr + alignment - 1) & -alignment; slop = (sizeof *hdr + alignment - 1) & - alignment;
if (size > ~((size_t) 0) - (slop + 1)) if (size > ~((size_t) 0) - (slop + 1))
{ {
@ -254,7 +253,7 @@ memalignhook (size_t alignment, size_t size,
__memalign_hook = old_memalign_hook; __memalign_hook = old_memalign_hook;
if (old_memalign_hook != NULL) if (old_memalign_hook != NULL)
block = (*old_memalign_hook) (alignment, slop + size + 1, caller); block = (*old_memalign_hook)(alignment, slop + size + 1, caller);
else else
block = memalign (alignment, slop + size + 1); block = memalign (alignment, slop + size + 1);
__memalign_hook = memalignhook; __memalign_hook = memalignhook;
@ -313,7 +312,7 @@ reallochook (__ptr_t ptr, size_t size, const __ptr_t caller)
__memalign_hook = old_memalign_hook; __memalign_hook = old_memalign_hook;
__realloc_hook = old_realloc_hook; __realloc_hook = old_realloc_hook;
if (old_realloc_hook != NULL) if (old_realloc_hook != NULL)
hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr, hdr = (struct hdr *) (*old_realloc_hook)((__ptr_t) hdr,
sizeof (struct hdr) + size + 1, sizeof (struct hdr) + size + 1,
caller); caller);
else else
@ -344,19 +343,19 @@ mabort (enum mcheck_status status)
switch (status) switch (status)
{ {
case MCHECK_OK: case MCHECK_OK:
msg = _("memory is consistent, library is buggy\n"); msg = _ ("memory is consistent, library is buggy\n");
break; break;
case MCHECK_HEAD: case MCHECK_HEAD:
msg = _("memory clobbered before allocated block\n"); msg = _ ("memory clobbered before allocated block\n");
break; break;
case MCHECK_TAIL: case MCHECK_TAIL:
msg = _("memory clobbered past end of allocated block\n"); msg = _ ("memory clobbered past end of allocated block\n");
break; break;
case MCHECK_FREE: case MCHECK_FREE:
msg = _("block freed twice\n"); msg = _ ("block freed twice\n");
break; break;
default: default:
msg = _("bogus mcheck_status, library is buggy\n"); msg = _ ("bogus mcheck_status, library is buggy\n");
break; break;
} }
#ifdef _LIBC #ifdef _LIBC
@ -370,11 +369,10 @@ mabort (enum mcheck_status status)
/* Memory barrier so that GCC does not optimize out the argument. */ /* Memory barrier so that GCC does not optimize out the argument. */
#define malloc_opt_barrier(x) \ #define malloc_opt_barrier(x) \
({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; }) ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
int int mcheck (func)
mcheck (func) void (*func)(enum mcheck_status);
void (*func) (enum mcheck_status);
{ {
abortfunc = (func != NULL) ? func : &mabort; abortfunc = (func != NULL) ? func : &mabort;
@ -404,9 +402,8 @@ mcheck (func)
libc_hidden_def (mcheck) libc_hidden_def (mcheck)
#endif #endif
int int mcheck_pedantic (func)
mcheck_pedantic (func) void (*func)(enum mcheck_status);
void (*func) (enum mcheck_status);
{ {
int res = mcheck (func); int res = mcheck (func);
if (res == 0) if (res == 0)

View File

@ -25,24 +25,24 @@ __BEGIN_DECLS
/* Return values for `mprobe': these are the kinds of inconsistencies that /* Return values for `mprobe': these are the kinds of inconsistencies that
`mcheck' enables detection of. */ `mcheck' enables detection of. */
enum mcheck_status enum mcheck_status
{ {
MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
MCHECK_OK, /* Block is fine. */ MCHECK_OK, /* Block is fine. */
MCHECK_FREE, /* Block freed twice. */ MCHECK_FREE, /* Block freed twice. */
MCHECK_HEAD, /* Memory before the block was clobbered. */ MCHECK_HEAD, /* Memory before the block was clobbered. */
MCHECK_TAIL /* Memory after the block was clobbered. */ MCHECK_TAIL /* Memory after the block was clobbered. */
}; };
/* Activate a standard collection of debugging hooks. This must be called /* Activate a standard collection of debugging hooks. This must be called
before `malloc' is ever called. ABORTFUNC is called with an error code before `malloc' is ever called. ABORTFUNC is called with an error code
(see enum above) when an inconsistency is detected. If ABORTFUNC is (see enum above) when an inconsistency is detected. If ABORTFUNC is
null, the standard function prints on stderr and then calls `abort'. */ null, the standard function prints on stderr and then calls `abort'. */
extern int mcheck (void (*__abortfunc) (enum mcheck_status)) __THROW; extern int mcheck (void (*__abortfunc)(enum mcheck_status)) __THROW;
/* Similar to `mcheck' but performs checks for all block whenever one of /* Similar to `mcheck' but performs checks for all block whenever one of
the memory handling functions is called. This can be very slow. */ the memory handling functions is called. This can be very slow. */
extern int mcheck_pedantic (void (*__abortfunc) (enum mcheck_status)) __THROW; extern int mcheck_pedantic (void (*__abortfunc)(enum mcheck_status)) __THROW;
/* Force check of all blocks now. */ /* Force check of all blocks now. */
extern void mcheck_check_all (void); extern void mcheck_check_all (void);
@ -57,5 +57,4 @@ extern void mtrace (void) __THROW;
extern void muntrace (void) __THROW; extern void muntrace (void) __THROW;
__END_DECLS __END_DECLS
#endif /* mcheck.h */ #endif /* mcheck.h */

View File

@ -38,7 +38,7 @@
/* Pointer to the real functions. These are determined used `dlsym' /* Pointer to the real functions. These are determined used `dlsym'
when really needed. */ when really needed. */
static void *(*mallocp) (size_t); static void *(*mallocp)(size_t);
static void *(*reallocp) (void *, size_t); static void *(*reallocp) (void *, size_t);
static void *(*callocp) (size_t, size_t); static void *(*callocp) (size_t, size_t);
static void (*freep) (void *); static void (*freep) (void *);
@ -221,19 +221,19 @@ me (void)
size_t prog_len = strlen (__progname); size_t prog_len = strlen (__progname);
initialized = -1; initialized = -1;
mallocp = (void *(*) (size_t)) dlsym (RTLD_NEXT, "malloc"); mallocp = (void *(*)(size_t))dlsym (RTLD_NEXT, "malloc");
reallocp = (void *(*) (void *, size_t)) dlsym (RTLD_NEXT, "realloc"); reallocp = (void *(*)(void *, size_t))dlsym (RTLD_NEXT, "realloc");
callocp = (void *(*) (size_t, size_t)) dlsym (RTLD_NEXT, "calloc"); callocp = (void *(*)(size_t, size_t))dlsym (RTLD_NEXT, "calloc");
freep = (void (*) (void *)) dlsym (RTLD_NEXT, "free"); freep = (void (*)(void *))dlsym (RTLD_NEXT, "free");
mmapp = (void *(*) (void *, size_t, int, int, int, off_t)) dlsym (RTLD_NEXT, mmapp = (void *(*)(void *, size_t, int, int, int, off_t))dlsym (RTLD_NEXT,
"mmap"); "mmap");
mmap64p = mmap64p =
(void *(*) (void *, size_t, int, int, int, off64_t)) dlsym (RTLD_NEXT, (void *(*)(void *, size_t, int, int, int, off64_t))dlsym (RTLD_NEXT,
"mmap64"); "mmap64");
mremapp = (void *(*) (void *, size_t, size_t, int, void *)) dlsym (RTLD_NEXT, mremapp = (void *(*)(void *, size_t, size_t, int, void *))dlsym (RTLD_NEXT,
"mremap"); "mremap");
munmapp = (int (*) (void *, size_t)) dlsym (RTLD_NEXT, "munmap"); munmapp = (int (*)(void *, size_t))dlsym (RTLD_NEXT, "munmap");
initialized = 1; initialized = 1;
if (env != NULL) if (env != NULL)
@ -317,7 +317,7 @@ __attribute__ ((constructor))
init (void) init (void)
{ {
start_sp = GETSP (); start_sp = GETSP ();
if (! initialized) if (!initialized)
me (); me ();
} }
@ -334,12 +334,13 @@ malloc (size_t len)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
if (not_me) if (not_me)
return (*mallocp) (len); return (*mallocp)(len);
/* Keep track of number of calls. */ /* Keep track of number of calls. */
catomic_increment (&calls[idx_malloc]); catomic_increment (&calls[idx_malloc]);
@ -356,7 +357,7 @@ malloc (size_t len)
catomic_increment (&calls_total); catomic_increment (&calls_total);
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*mallocp) (len + sizeof (struct header)); result = (struct header *) (*mallocp)(len + sizeof (struct header));
if (result == NULL) if (result == NULL)
{ {
catomic_increment (&failed[idx_malloc]); catomic_increment (&failed[idx_malloc]);
@ -385,12 +386,13 @@ realloc (void *old, size_t len)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
if (not_me) if (not_me)
return (*reallocp) (old, len); return (*reallocp)(old, len);
if (old == NULL) if (old == NULL)
{ {
@ -403,7 +405,8 @@ realloc (void *old, size_t len)
real = ((struct header *) old) - 1; real = ((struct header *) old) - 1;
if (real->magic != MAGIC) if (real->magic != MAGIC)
/* This is no memory allocated here. */ /* This is no memory allocated here. */
return (*reallocp) (old, len); return (*reallocp)(old, len);
old_len = real->length; old_len = real->length;
} }
@ -442,7 +445,7 @@ realloc (void *old, size_t len)
catomic_increment (&calls_total); catomic_increment (&calls_total);
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*reallocp) (real, len + sizeof (struct header)); result = (struct header *) (*reallocp)(real, len + sizeof (struct header));
if (result == NULL) if (result == NULL)
{ {
catomic_increment (&failed[idx_realloc]); catomic_increment (&failed[idx_realloc]);
@ -477,12 +480,13 @@ calloc (size_t n, size_t len)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* If this is not the correct program just use the normal function. */ /* If this is not the correct program just use the normal function. */
if (not_me) if (not_me)
return (*callocp) (n, len); return (*callocp)(n, len);
/* Keep track of number of calls. */ /* Keep track of number of calls. */
catomic_increment (&calls[idx_calloc]); catomic_increment (&calls[idx_calloc]);
@ -499,7 +503,7 @@ calloc (size_t n, size_t len)
++calls_total; ++calls_total;
/* Do the real work. */ /* Do the real work. */
result = (struct header *) (*mallocp) (size + sizeof (struct header)); result = (struct header *) (*mallocp)(size + sizeof (struct header));
if (result == NULL) if (result == NULL)
{ {
catomic_increment (&failed[idx_calloc]); catomic_increment (&failed[idx_calloc]);
@ -526,6 +530,7 @@ free (void *ptr)
{ {
if (initialized == -1) if (initialized == -1)
return; return;
me (); me ();
} }
@ -577,11 +582,12 @@ mmap (void *start, size_t len, int prot, int flags, int fd, off_t offset)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* Always get a block. We don't need extra memory. */ /* Always get a block. We don't need extra memory. */
result = (*mmapp) (start, len, prot, flags, fd, offset); result = (*mmapp)(start, len, prot, flags, fd, offset);
if (!not_me && trace_mmap) if (!not_me && trace_mmap)
{ {
@ -629,11 +635,12 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* Always get a block. We don't need extra memory. */ /* Always get a block. We don't need extra memory. */
result = (*mmap64p) (start, len, prot, flags, fd, offset); result = (*mmap64p)(start, len, prot, flags, fd, offset);
if (!not_me && trace_mmap) if (!not_me && trace_mmap)
{ {
@ -686,11 +693,12 @@ mremap (void *start, size_t old_len, size_t len, int flags, ...)
{ {
if (initialized == -1) if (initialized == -1)
return NULL; return NULL;
me (); me ();
} }
/* Always get a block. We don't need extra memory. */ /* Always get a block. We don't need extra memory. */
result = (*mremapp) (start, old_len, len, flags, newaddr); result = (*mremapp)(start, old_len, len, flags, newaddr);
if (!not_me && trace_mmap) if (!not_me && trace_mmap)
{ {
@ -746,11 +754,12 @@ munmap (void *start, size_t len)
{ {
if (initialized == -1) if (initialized == -1)
return -1; return -1;
me (); me ();
} }
/* Do the real work. */ /* Do the real work. */
result = (*munmapp) (start, len); result = (*munmapp)(start, len);
if (!not_me && trace_mmap) if (!not_me && trace_mmap)
{ {
@ -785,6 +794,7 @@ dest (void)
/* If we haven't done anything here just return. */ /* If we haven't done anything here just return. */
if (not_me) if (not_me)
return; return;
/* If we should call any of the memory functions don't do any profiling. */ /* If we should call any of the memory functions don't do any profiling. */
not_me = true; not_me = true;

View File

@ -53,24 +53,24 @@
/* Definitions of arguments for argp functions. */ /* Definitions of arguments for argp functions. */
static const struct argp_option options[] = static const struct argp_option options[] =
{ {
{ "output", 'o', N_("FILE"), 0, N_("Name output file") }, { "output", 'o', N_ ("FILE"), 0, N_ ("Name output file") },
{ "string", 's', N_("STRING"), 0, N_("Title string used in output graphic") }, { "string", 's', N_ ("STRING"), 0, N_ ("Title string used in output graphic") },
{ "time", 't', NULL, 0, N_("\ { "time", 't', NULL, 0, N_ (" \
Generate output linear to time (default is linear to number of function calls)\ Generate output linear to time (default is linear to number of function calls)\
") }, ") },
{ "total", 'T', NULL, 0, { "total", 'T', NULL, 0,
N_("Also draw graph for total memory consumption") }, N_ ("Also draw graph for total memory consumption") },
{ "x-size", 'x', N_("VALUE"), 0, { "x-size", 'x', N_ ("VALUE"), 0,
N_("Make output graphic VALUE pixels wide") }, N_ ("Make output graphic VALUE pixels wide") },
{ "y-size", 'y', "VALUE", 0, N_("Make output graphic VALUE pixels high") }, { "y-size", 'y', "VALUE", 0, N_ ("Make output graphic VALUE pixels high") },
{ NULL, 0, NULL, 0, NULL } { NULL, 0, NULL, 0, NULL }
}; };
/* Short description of program. */ /* Short description of program. */
static const char doc[] = N_("Generate graphic from memory profiling data"); static const char doc[] = N_ ("Generate graphic from memory profiling data");
/* Strings for arguments in help texts. */ /* Strings for arguments in help texts. */
static const char args_doc[] = N_("DATAFILE [OUTFILE]"); static const char args_doc[] = N_ ("DATAFILE [OUTFILE]");
/* Prototype for option handler. */ /* Prototype for option handler. */
static error_t parse_opt (int key, char *arg, struct argp_state *state); static error_t parse_opt (int key, char *arg, struct argp_state *state);
@ -439,7 +439,7 @@ main (int argc, char *argv[])
gdImageString (im_out, gdFontSmall, 40 + (xsize - 39 * 6 - 80) / 2, gdImageString (im_out, gdFontSmall, 40 + (xsize - 39 * 6 - 80) / 2,
ysize - 12, ysize - 12,
(unsigned char *) "\ (unsigned char *) " \
# memory handling function calls / time", blue); # memory handling function calls / time", blue);
for (cnt = 0; cnt < 20; cnt += 2) for (cnt = 0; cnt < 20; cnt += 2)
@ -564,7 +564,9 @@ more_help (int key, const char *text, void *input)
For bug reporting instructions, please see:\n\ For bug reporting instructions, please see:\n\
%s.\n"), REPORT_BUGS_TO) < 0) %s.\n"), REPORT_BUGS_TO) < 0)
return NULL; return NULL;
return tp; return tp;
default: default:
break; break;
} }

View File

@ -16,26 +16,26 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_INTERNAL #ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL # define _MALLOC_INTERNAL
#include <malloc.h> # include <malloc.h>
#endif #endif
#ifndef __GNU_LIBRARY__ #ifndef __GNU_LIBRARY__
#define __sbrk sbrk # define __sbrk sbrk
#endif #endif
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
/* It is best not to declare this and cast its result on foreign operating /* It is best not to declare this and cast its result on foreign operating
systems with potentially hostile include files. */ systems with potentially hostile include files. */
#include <stddef.h> # include <stddef.h>
#include <stdlib.h> # include <stdlib.h>
extern void *__sbrk (ptrdiff_t increment) __THROW; extern void *__sbrk (ptrdiff_t increment) __THROW;
libc_hidden_proto (__sbrk) libc_hidden_proto (__sbrk)
#endif #endif
#ifndef NULL #ifndef NULL
#define NULL 0 # define NULL 0
#endif #endif
/* Allocate INCREMENT more bytes of data space, /* Allocate INCREMENT more bytes of data space,
@ -47,6 +47,7 @@ __default_morecore (ptrdiff_t increment)
void *result = (void *) __sbrk (increment); void *result = (void *) __sbrk (increment);
if (result == (void *) -1) if (result == (void *) -1)
return NULL; return NULL;
return result; return result;
} }
libc_hidden_def (__default_morecore) libc_hidden_def (__default_morecore)

View File

@ -19,10 +19,10 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_INTERNAL #ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL # define _MALLOC_INTERNAL
#include <malloc.h> # include <malloc.h>
#include <mcheck.h> # include <mcheck.h>
#include <bits/libc-lock.h> # include <bits/libc-lock.h>
#endif #endif
#include <dlfcn.h> #include <dlfcn.h>
@ -48,7 +48,7 @@
#define TRACE_BUFFER_SIZE 512 #define TRACE_BUFFER_SIZE 512
static FILE *mallstream; static FILE *mallstream;
static const char mallenv[]= "MALLOC_TRACE"; static const char mallenv[] = "MALLOC_TRACE";
static char *malloc_trace_buffer; static char *malloc_trace_buffer;
__libc_lock_define_initialized (static, lock); __libc_lock_define_initialized (static, lock);
@ -79,10 +79,9 @@ libc_hidden_def (tr_break)
static void tr_where (const __ptr_t, Dl_info *) __THROW internal_function; static void tr_where (const __ptr_t, Dl_info *) __THROW internal_function;
static void static void
internal_function internal_function tr_where (caller, info)
tr_where (caller, info) const __ptr_t caller;
const __ptr_t caller; Dl_info *info;
Dl_info *info;
{ {
if (caller != NULL) if (caller != NULL)
{ {
@ -107,7 +106,7 @@ tr_where (caller, info)
} }
fprintf (mallstream, "@ %s%s%s[%p] ", fprintf (mallstream, "@ %s%s%s[%p] ",
info->dli_fname ?: "", info->dli_fname ? ":" : "", info->dli_fname ? : "", info->dli_fname ? ":" : "",
buf, caller); buf, caller);
} }
else else
@ -131,10 +130,9 @@ lock_and_info (const __ptr_t caller, Dl_info *mem)
static void tr_freehook (__ptr_t, const __ptr_t) __THROW; static void tr_freehook (__ptr_t, const __ptr_t) __THROW;
static void static void tr_freehook (ptr, caller)
tr_freehook (ptr, caller) __ptr_t ptr;
__ptr_t ptr; const __ptr_t caller;
const __ptr_t caller;
{ {
if (ptr == NULL) if (ptr == NULL)
return; return;
@ -152,7 +150,7 @@ tr_freehook (ptr, caller)
} }
__free_hook = tr_old_free_hook; __free_hook = tr_old_free_hook;
if (tr_old_free_hook != NULL) if (tr_old_free_hook != NULL)
(*tr_old_free_hook) (ptr, caller); (*tr_old_free_hook)(ptr, caller);
else else
free (ptr); free (ptr);
__free_hook = tr_freehook; __free_hook = tr_freehook;
@ -160,10 +158,9 @@ tr_freehook (ptr, caller)
} }
static __ptr_t tr_mallochook (size_t, const __ptr_t) __THROW; static __ptr_t tr_mallochook (size_t, const __ptr_t) __THROW;
static __ptr_t static __ptr_t tr_mallochook (size, caller)
tr_mallochook (size, caller) size_t size;
size_t size; const __ptr_t caller;
const __ptr_t caller;
{ {
__ptr_t hdr; __ptr_t hdr;
@ -172,7 +169,7 @@ tr_mallochook (size, caller)
__malloc_hook = tr_old_malloc_hook; __malloc_hook = tr_old_malloc_hook;
if (tr_old_malloc_hook != NULL) if (tr_old_malloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller); hdr = (__ptr_t) (*tr_old_malloc_hook)(size, caller);
else else
hdr = (__ptr_t) malloc (size); hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook; __malloc_hook = tr_mallochook;
@ -190,12 +187,11 @@ tr_mallochook (size, caller)
} }
static __ptr_t tr_reallochook (__ptr_t, size_t, const __ptr_t) static __ptr_t tr_reallochook (__ptr_t, size_t, const __ptr_t)
__THROW; __THROW;
static __ptr_t static __ptr_t tr_reallochook (ptr, size, caller)
tr_reallochook (ptr, size, caller) __ptr_t ptr;
__ptr_t ptr; size_t size;
size_t size; const __ptr_t caller;
const __ptr_t caller;
{ {
__ptr_t hdr; __ptr_t hdr;
@ -209,7 +205,7 @@ tr_reallochook (ptr, size, caller)
__malloc_hook = tr_old_malloc_hook; __malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook; __realloc_hook = tr_old_realloc_hook;
if (tr_old_realloc_hook != NULL) if (tr_old_realloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller); hdr = (__ptr_t) (*tr_old_realloc_hook)(ptr, size, caller);
else else
hdr = (__ptr_t) realloc (ptr, size); hdr = (__ptr_t) realloc (ptr, size);
__free_hook = tr_freehook; __free_hook = tr_freehook;
@ -244,10 +240,9 @@ tr_reallochook (ptr, size, caller)
static __ptr_t tr_memalignhook (size_t, size_t, static __ptr_t tr_memalignhook (size_t, size_t,
const __ptr_t) __THROW; const __ptr_t) __THROW;
static __ptr_t static __ptr_t tr_memalignhook (alignment, size, caller)
tr_memalignhook (alignment, size, caller) size_t alignment, size;
size_t alignment, size; const __ptr_t caller;
const __ptr_t caller;
{ {
__ptr_t hdr; __ptr_t hdr;
@ -257,7 +252,7 @@ tr_memalignhook (alignment, size, caller)
__memalign_hook = tr_old_memalign_hook; __memalign_hook = tr_old_memalign_hook;
__malloc_hook = tr_old_malloc_hook; __malloc_hook = tr_old_malloc_hook;
if (tr_old_memalign_hook != NULL) if (tr_old_memalign_hook != NULL)
hdr = (__ptr_t) (*tr_old_memalign_hook) (alignment, size, caller); hdr = (__ptr_t) (*tr_old_memalign_hook)(alignment, size, caller);
else else
hdr = (__ptr_t) memalign (alignment, size); hdr = (__ptr_t) memalign (alignment, size);
__memalign_hook = tr_memalignhook; __memalign_hook = tr_memalignhook;
@ -352,7 +347,7 @@ mtrace (void)
{ {
extern void *__dso_handle __attribute__ ((__weak__)); extern void *__dso_handle __attribute__ ((__weak__));
added_atexit_handler = 1; added_atexit_handler = 1;
__cxa_atexit ((void (*) (void *)) release_libc_mem, NULL, __cxa_atexit ((void (*)(void *))release_libc_mem, NULL,
&__dso_handle ? __dso_handle : NULL); &__dso_handle ? __dso_handle : NULL);
} }
#endif #endif

View File

@ -78,10 +78,10 @@ struct fooalign
But in fact it might be less smart and round addresses to as much as But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */ DEFAULT_ROUNDING. So we prepare for it to do that. */
enum enum
{ {
DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
DEFAULT_ROUNDING = sizeof (union fooround) DEFAULT_ROUNDING = sizeof (union fooround)
}; };
/* When we copy a long block of data, this is the unit to do it with. /* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work; On some machines, copying successive ints does not work;
@ -127,19 +127,19 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
do not allow (expr) ? void : void. */ do not allow (expr) ? void : void. */
# define CALL_CHUNKFUN(h, size) \ # define CALL_CHUNKFUN(h, size) \
(((h) -> use_extra_arg) \ (((h)->use_extra_arg) \
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ ? (*(h)->chunkfun)((h)->extra_arg, (size)) \
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) : (*(struct _obstack_chunk *(*)(long))(h)->chunkfun)((size)))
# define CALL_FREEFUN(h, old_chunk) \ # define CALL_FREEFUN(h, old_chunk) \
do { \ do { \
if ((h) -> use_extra_arg) \ if ((h)->use_extra_arg) \
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ (*(h)->freefun)((h)->extra_arg, (old_chunk)); \
else \ else \
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ (*(void (*)(void *))(h)->freefun)((old_chunk)); \
} while (0) } while (0)
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default). Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks, CHUNKFUN is the function to use to allocate chunks,
@ -151,8 +151,8 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
int int
_obstack_begin (struct obstack *h, _obstack_begin (struct obstack *h,
int size, int alignment, int size, int alignment,
void *(*chunkfun) (long), void *(*chunkfun)(long),
void (*freefun) (void *)) void (*freefun)(void *))
{ {
struct _obstack_chunk *chunk; /* points to new chunk */ struct _obstack_chunk *chunk; /* points to new chunk */
@ -175,15 +175,15 @@ _obstack_begin (struct obstack *h,
size = 4096 - extra; size = 4096 - extra;
} }
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
h->chunk_size = size; h->chunk_size = size;
h->alignment_mask = alignment - 1; h->alignment_mask = alignment - 1;
h->use_extra_arg = 0; h->use_extra_arg = 0;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk) if (!chunk)
(*obstack_alloc_failed_handler) (); (*obstack_alloc_failed_handler)();
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1); alignment - 1);
h->chunk_limit = chunk->limit h->chunk_limit = chunk->limit
@ -197,8 +197,8 @@ _obstack_begin (struct obstack *h,
int int
_obstack_begin_1 (struct obstack *h, int size, int alignment, _obstack_begin_1 (struct obstack *h, int size, int alignment,
void *(*chunkfun) (void *, long), void *(*chunkfun)(void *, long),
void (*freefun) (void *, void *), void (*freefun)(void *, void *),
void *arg) void *arg)
{ {
struct _obstack_chunk *chunk; /* points to new chunk */ struct _obstack_chunk *chunk; /* points to new chunk */
@ -222,16 +222,16 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
size = 4096 - extra; size = 4096 - extra;
} }
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
h->chunk_size = size; h->chunk_size = size;
h->alignment_mask = alignment - 1; h->alignment_mask = alignment - 1;
h->extra_arg = arg; h->extra_arg = arg;
h->use_extra_arg = 1; h->use_extra_arg = 1;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk) if (!chunk)
(*obstack_alloc_failed_handler) (); (*obstack_alloc_failed_handler)();
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1); alignment - 1);
h->chunk_limit = chunk->limit h->chunk_limit = chunk->limit
@ -268,7 +268,7 @@ _obstack_newchunk (struct obstack *h, int length)
/* Allocate and initialize the new chunk. */ /* Allocate and initialize the new chunk. */
new_chunk = CALL_CHUNKFUN (h, new_size); new_chunk = CALL_CHUNKFUN (h, new_size);
if (!new_chunk) if (!new_chunk)
(*obstack_alloc_failed_handler) (); (*obstack_alloc_failed_handler)();
h->chunk = new_chunk; h->chunk = new_chunk;
new_chunk->prev = old_chunk; new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
@ -284,8 +284,8 @@ _obstack_newchunk (struct obstack *h, int length)
{ {
for (i = obj_size / sizeof (COPYING_UNIT) - 1; for (i = obj_size / sizeof (COPYING_UNIT) - 1;
i >= 0; i--) i >= 0; i--)
((COPYING_UNIT *)object_base)[i] ((COPYING_UNIT *) object_base)[i]
= ((COPYING_UNIT *)h->object_base)[i]; = ((COPYING_UNIT *) h->object_base)[i];
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */ which does not do strict alignment for COPYING_UNITS. */
@ -300,7 +300,7 @@ _obstack_newchunk (struct obstack *h, int length)
/* If the object just copied was the only data in OLD_CHUNK, /* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain. free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */ But not if that chunk might contain an empty object. */
if (! h->maybe_empty_object if (!h->maybe_empty_object
&& (h->object_base && (h->object_base
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask))) h->alignment_mask)))
@ -343,7 +343,7 @@ _obstack_allocated_p (struct obstack *h, void *obj)
} }
return lp != 0; return lp != 0;
} }
/* Free objects in obstack H, including OBJ and everything allocate /* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */ more recently than OBJ. If OBJ is zero, free everything in H. */
@ -384,11 +384,11 @@ obstack_free (struct obstack *h, void *obj)
called by non-GCC compilers. */ called by non-GCC compilers. */
strong_alias (obstack_free, _obstack_free) strong_alias (obstack_free, _obstack_free)
# endif # endif
int int
_obstack_memory_used (struct obstack *h) _obstack_memory_used (struct obstack *h)
{ {
struct _obstack_chunk* lp; struct _obstack_chunk *lp;
int nbytes = 0; int nbytes = 0;
for (lp = h->chunk; lp != 0; lp = lp->prev) for (lp = h->chunk; lp != 0; lp = lp->prev)
@ -397,7 +397,7 @@ _obstack_memory_used (struct obstack *h)
} }
return nbytes; return nbytes;
} }
/* Define the error handler. */ /* Define the error handler. */
# ifdef _LIBC # ifdef _LIBC
# include <libintl.h> # include <libintl.h>
@ -429,11 +429,10 @@ print_and_abort (void)
like this and the translation should be reused instead of creating like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */ a very similar string which requires a separate translation. */
# ifdef _LIBC # ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted")); (void) __fxprintf (NULL, "%s\n", _ ("memory exhausted"));
# else # else
fprintf (stderr, "%s\n", _("memory exhausted")); fprintf (stderr, "%s\n", _ ("memory exhausted"));
# endif # endif
exit (obstack_exit_failure); exit (obstack_exit_failure);
} }
#endif /* !ELIDE_CODE */ #endif /* !ELIDE_CODE */

View File

@ -18,73 +18,73 @@
/* Summary: /* Summary:
All the apparent functions defined here are macros. The idea All the apparent functions defined here are macros. The idea
is that you would use these pre-tested macros to solve a is that you would use these pre-tested macros to solve a
very specific set of problems, and they would run fast. very specific set of problems, and they would run fast.
Caution: no side-effects in arguments please!! They may be Caution: no side-effects in arguments please!! They may be
evaluated MANY times!! evaluated MANY times!!
These macros operate a stack of objects. Each object starts life These macros operate a stack of objects. Each object starts life
small, and may grow to maturity. (Consider building a word syllable small, and may grow to maturity. (Consider building a word syllable
by syllable.) An object can move while it is growing. Once it has by syllable.) An object can move while it is growing. Once it has
been "finished" it never changes address again. So the "top of the been "finished" it never changes address again. So the "top of the
stack" is typically an immature growing object, while the rest of the stack" is typically an immature growing object, while the rest of the
stack is of mature, fixed size and fixed address objects. stack is of mature, fixed size and fixed address objects.
These routines grab large chunks of memory, using a function you These routines grab large chunks of memory, using a function you
supply, called `obstack_chunk_alloc'. On occasion, they free chunks, supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
by calling `obstack_chunk_free'. You must define them and declare by calling `obstack_chunk_free'. You must define them and declare
them before using any obstack macros. them before using any obstack macros.
Each independent stack is represented by a `struct obstack'. Each independent stack is represented by a `struct obstack'.
Each of the obstack macros expects a pointer to such a structure Each of the obstack macros expects a pointer to such a structure
as the first argument. as the first argument.
One motivation for this package is the problem of growing char strings One motivation for this package is the problem of growing char strings
in symbol tables. Unless you are "fascist pig with a read-only mind" in symbol tables. Unless you are "fascist pig with a read-only mind"
--Gosper's immortal quote from HAKMEM item 154, out of context--you --Gosper's immortal quote from HAKMEM item 154, out of context--you
would not like to put any arbitrary upper limit on the length of your would not like to put any arbitrary upper limit on the length of your
symbols. symbols.
In practice this often means you will build many short symbols and a In practice this often means you will build many short symbols and a
few long symbols. At the time you are reading a symbol you don't know few long symbols. At the time you are reading a symbol you don't know
how long it is. One traditional method is to read a symbol into a how long it is. One traditional method is to read a symbol into a
buffer, realloc()ating the buffer every time you try to read a symbol buffer, realloc()ating the buffer every time you try to read a symbol
that is longer than the buffer. This is beaut, but you still will that is longer than the buffer. This is beaut, but you still will
want to copy the symbol from the buffer to a more permanent want to copy the symbol from the buffer to a more permanent
symbol-table entry say about half the time. symbol-table entry say about half the time.
With obstacks, you can work differently. Use one obstack for all symbol With obstacks, you can work differently. Use one obstack for all symbol
names. As you read a symbol, grow the name in the obstack gradually. names. As you read a symbol, grow the name in the obstack gradually.
When the name is complete, finalize it. Then, if the symbol exists already, When the name is complete, finalize it. Then, if the symbol exists already,
free the newly read name. free the newly read name.
The way we do this is to take a large chunk, allocating memory from The way we do this is to take a large chunk, allocating memory from
low addresses. When you want to build a symbol in the chunk you just low addresses. When you want to build a symbol in the chunk you just
add chars above the current "high water mark" in the chunk. When you add chars above the current "high water mark" in the chunk. When you
have finished adding chars, because you got to the end of the symbol, have finished adding chars, because you got to the end of the symbol,
you know how long the chars are, and you can create a new object. you know how long the chars are, and you can create a new object.
Mostly the chars will not burst over the highest address of the chunk, Mostly the chars will not burst over the highest address of the chunk,
because you would typically expect a chunk to be (say) 100 times as because you would typically expect a chunk to be (say) 100 times as
long as an average object. long as an average object.
In case that isn't clear, when we have enough chars to make up In case that isn't clear, when we have enough chars to make up
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
so we just point to it where it lies. No moving of chars is so we just point to it where it lies. No moving of chars is
needed and this is the second win: potentially long strings need needed and this is the second win: potentially long strings need
never be explicitly shuffled. Once an object is formed, it does not never be explicitly shuffled. Once an object is formed, it does not
change its address during its lifetime. change its address during its lifetime.
When the chars burst over a chunk boundary, we allocate a larger When the chars burst over a chunk boundary, we allocate a larger
chunk, and then copy the partly formed object from the end of the old chunk, and then copy the partly formed object from the end of the old
chunk to the beginning of the new larger chunk. We then carry on chunk to the beginning of the new larger chunk. We then carry on
accreting characters to the end of the object as we normally would. accreting characters to the end of the object as we normally would.
A special macro is provided to add a single char at a time to a A special macro is provided to add a single char at a time to a
growing object. This allows the use of register variables, which growing object. This allows the use of register variables, which
break the ordinary 'growth' macro. break the ordinary 'growth' macro.
Summary: Summary:
We allocate large chunks. We allocate large chunks.
We carve out one object at a time from the current chunk. We carve out one object at a time from the current chunk.
Once carved, an object never moves. Once carved, an object never moves.
@ -96,7 +96,7 @@ Summary:
Because of the way we do it, you can `unwind' an obstack Because of the way we do it, you can `unwind' an obstack
back to a previous state. (You may remove objects much back to a previous state. (You may remove objects much
as you would with a stack.) as you would with a stack.)
*/ */
/* Don't do the contents of this file more than once. */ /* Don't do the contents of this file more than once. */
@ -107,7 +107,7 @@ Summary:
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is /* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
defined, as with GNU C, use that; that way we don't pollute the defined, as with GNU C, use that; that way we don't pollute the
namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h> namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
@ -124,7 +124,7 @@ extern "C" {
aligning P to the next multiple of A + 1. B and P must be of type aligning P to the next multiple of A + 1. B and P must be of type
char *. A + 1 must be a power of 2. */ char *. A + 1 must be a power of 2. */
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) #define __BPTR_ALIGN(B, P, A) ((B) + (((P) -(B) + (A)) & ~(A)))
/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case /* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
where pointers can be converted to integers, aligned as integers, where pointers can be converted to integers, aligned as integers,
@ -165,12 +165,12 @@ struct obstack /* control current object in current chunk */
struct _obstack_chunk *(*chunkfun) (void *, long); struct _obstack_chunk *(*chunkfun) (void *, long);
void (*freefun) (void *, struct _obstack_chunk *); void (*freefun) (void *, struct _obstack_chunk *);
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object:1;/* There is a possibility that the current unsigned maybe_empty_object : 1; /* There is a possibility that the current
chunk contains a zero-length object. This chunk contains a zero-length object. This
prevents freeing the chunk if we allocate prevents freeing the chunk if we allocate
a bigger chunk to replace it. */ a bigger chunk to replace it. */
unsigned alloc_failed:1; /* No longer used, as we now call the failed unsigned alloc_failed : 1; /* No longer used, as we now call the failed
handler on error, but retained for binary handler on error, but retained for binary
compatibility. */ compatibility. */
}; };
@ -179,15 +179,15 @@ struct obstack /* control current object in current chunk */
extern void _obstack_newchunk (struct obstack *, int); extern void _obstack_newchunk (struct obstack *, int);
extern int _obstack_begin (struct obstack *, int, int, extern int _obstack_begin (struct obstack *, int, int,
void *(*) (long), void (*) (void *)); void *(*)(long), void (*)(void *));
extern int _obstack_begin_1 (struct obstack *, int, int, extern int _obstack_begin_1 (struct obstack *, int, int,
void *(*) (void *, long), void *(*)(void *, long),
void (*) (void *, void *), void *); void (*)(void *, void *), void *);
extern int _obstack_memory_used (struct obstack *); extern int _obstack_memory_used (struct obstack *);
void obstack_free (struct obstack *__obstack, void *__glibc_block); void obstack_free (struct obstack *__obstack, void *__glibc_block);
/* Error handler called when `obstack_chunk_alloc' failed to allocate /* Error handler called when `obstack_chunk_alloc' failed to allocate
more memory. This can be set to a user defined function which more memory. This can be set to a user defined function which
should either abort gracefully or use longjump - but shouldn't should either abort gracefully or use longjump - but shouldn't
@ -196,7 +196,7 @@ extern void (*obstack_alloc_failed_handler) (void);
/* Exit value used when `print_and_abort' is used. */ /* Exit value used when `print_and_abort' is used. */
extern int obstack_exit_failure; extern int obstack_exit_failure;
/* Pointer to beginning of object being allocated or to be allocated next. /* Pointer to beginning of object being allocated or to be allocated next.
Note that this might not be the final address of the object Note that this might not be the final address of the object
because a new chunk might be needed to hold the final size. */ because a new chunk might be needed to hold the final size. */
@ -218,36 +218,36 @@ extern int obstack_exit_failure;
/* To prevent prototype warnings provide complete argument list. */ /* To prevent prototype warnings provide complete argument list. */
#define obstack_init(h) \ #define obstack_init(h) \
_obstack_begin ((h), 0, 0, \ _obstack_begin ((h), 0, 0, \
(void *(*) (long)) obstack_chunk_alloc, \ (void *(*)(long))obstack_chunk_alloc, \
(void (*) (void *)) obstack_chunk_free) (void (*)(void *))obstack_chunk_free)
#define obstack_begin(h, size) \ #define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \ _obstack_begin ((h), (size), 0, \
(void *(*) (long)) obstack_chunk_alloc, \ (void *(*)(long))obstack_chunk_alloc, \
(void (*) (void *)) obstack_chunk_free) (void (*)(void *))obstack_chunk_free)
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \ _obstack_begin ((h), (size), (alignment), \
(void *(*) (long)) (chunkfun), \ (void *(*)(long))(chunkfun), \
(void (*) (void *)) (freefun)) (void (*)(void *))(freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \ _obstack_begin_1 ((h), (size), (alignment), \
(void *(*) (void *, long)) (chunkfun), \ (void *(*)(void *, long))(chunkfun), \
(void (*) (void *, void *)) (freefun), (arg)) (void (*)(void *, void *))(freefun), (arg))
#define obstack_chunkfun(h, newchunkfun) \ #define obstack_chunkfun(h, newchunkfun) \
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) ((h)->chunkfun = (struct _obstack_chunk *(*)(void *, long))(newchunkfun))
#define obstack_freefun(h, newfreefun) \ #define obstack_freefun(h, newfreefun) \
((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) ((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) #define obstack_1grow_fast(h, achar) (*((h)->next_free)++ = (achar))
#define obstack_blank_fast(h,n) ((h)->next_free += (n)) #define obstack_blank_fast(h, n) ((h)->next_free += (n))
#define obstack_memory_used(h) _obstack_memory_used (h) #define obstack_memory_used(h) _obstack_memory_used (h)
#if defined __GNUC__ #if defined __GNUC__
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
does not implement __extension__. But that compiler doesn't define does not implement __extension__. But that compiler doesn't define
@ -271,9 +271,9 @@ extern int obstack_exit_failure;
({ struct obstack const *__o = (OBSTACK); \ ({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); }) (unsigned) (__o->chunk_limit - __o->next_free); })
# define obstack_make_room(OBSTACK,length) \ # define obstack_make_room(OBSTACK, length) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
int __len = (length); \ int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \ if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \ _obstack_newchunk (__o, __len); \
@ -287,9 +287,9 @@ __extension__ \
__o->chunk->contents, \ __o->chunk->contents, \
__o->alignment_mask)); }) __o->alignment_mask)); })
# define obstack_grow(OBSTACK,where,length) \ # define obstack_grow(OBSTACK, where, length) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
int __len = (length); \ int __len = (length); \
if (__o->next_free + __len > __o->chunk_limit) \ if (__o->next_free + __len > __o->chunk_limit) \
_obstack_newchunk (__o, __len); \ _obstack_newchunk (__o, __len); \
@ -297,9 +297,9 @@ __extension__ \
__o->next_free += __len; \ __o->next_free += __len; \
(void) 0; }) (void) 0; })
# define obstack_grow0(OBSTACK,where,length) \ # define obstack_grow0(OBSTACK, where, length) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
int __len = (length); \ int __len = (length); \
if (__o->next_free + __len + 1 > __o->chunk_limit) \ if (__o->next_free + __len + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, __len + 1); \ _obstack_newchunk (__o, __len + 1); \
@ -308,9 +308,9 @@ __extension__ \
*(__o->next_free)++ = 0; \ *(__o->next_free)++ = 0; \
(void) 0; }) (void) 0; })
# define obstack_1grow(OBSTACK,datum) \ # define obstack_1grow(OBSTACK, datum) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + 1 > __o->chunk_limit) \ if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \ _obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); \ obstack_1grow_fast (__o, datum); \
@ -320,86 +320,86 @@ __extension__ \
or ints, and that the data added so far to the current object or ints, and that the data added so far to the current object
shares that much alignment. */ shares that much alignment. */
# define obstack_ptr_grow(OBSTACK,datum) \ # define obstack_ptr_grow(OBSTACK, datum) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \ _obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); }) \ obstack_ptr_grow_fast (__o, datum); }) \
# define obstack_int_grow(OBSTACK,datum) \ # define obstack_int_grow(OBSTACK, datum) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \ _obstack_newchunk (__o, sizeof (int)); \
obstack_int_grow_fast (__o, datum); }) obstack_int_grow_fast (__o, datum); })
# define obstack_ptr_grow_fast(OBSTACK,aptr) \ # define obstack_ptr_grow_fast(OBSTACK, aptr) \
__extension__ \ __extension__ \
({ struct obstack *__o1 = (OBSTACK); \ ({ struct obstack *__o1 = (OBSTACK); \
*(const void **) __o1->next_free = (aptr); \ *(const void **) __o1->next_free = (aptr); \
__o1->next_free += sizeof (const void *); \ __o1->next_free += sizeof (const void *); \
(void) 0; }) (void) 0; })
# define obstack_int_grow_fast(OBSTACK,aint) \ # define obstack_int_grow_fast(OBSTACK, aint) \
__extension__ \ __extension__ \
({ struct obstack *__o1 = (OBSTACK); \ ({ struct obstack *__o1 = (OBSTACK); \
*(int *) __o1->next_free = (aint); \ *(int *) __o1->next_free = (aint); \
__o1->next_free += sizeof (int); \ __o1->next_free += sizeof (int); \
(void) 0; }) (void) 0; })
# define obstack_blank(OBSTACK,length) \ # define obstack_blank(OBSTACK, length) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
int __len = (length); \ int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \ if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \ _obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); \ obstack_blank_fast (__o, __len); \
(void) 0; }) (void) 0; })
# define obstack_alloc(OBSTACK,length) \ # define obstack_alloc(OBSTACK, length) \
__extension__ \ __extension__ \
({ struct obstack *__h = (OBSTACK); \ ({ struct obstack *__h = (OBSTACK); \
obstack_blank (__h, (length)); \ obstack_blank (__h, (length)); \
obstack_finish (__h); }) obstack_finish (__h); })
# define obstack_copy(OBSTACK,where,length) \ # define obstack_copy(OBSTACK, where, length) \
__extension__ \ __extension__ \
({ struct obstack *__h = (OBSTACK); \ ({ struct obstack *__h = (OBSTACK); \
obstack_grow (__h, (where), (length)); \ obstack_grow (__h, (where), (length)); \
obstack_finish (__h); }) obstack_finish (__h); })
# define obstack_copy0(OBSTACK,where,length) \ # define obstack_copy0(OBSTACK, where, length) \
__extension__ \ __extension__ \
({ struct obstack *__h = (OBSTACK); \ ({ struct obstack *__h = (OBSTACK); \
obstack_grow0 (__h, (where), (length)); \ obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); }) obstack_finish (__h); })
/* The local variable is named __o1 to avoid a name conflict /* The local variable is named __o1 to avoid a name conflict
when obstack_blank is called. */ when obstack_blank is called. */
# define obstack_finish(OBSTACK) \ # define obstack_finish(OBSTACK) \
__extension__ \ __extension__ \
({ struct obstack *__o1 = (OBSTACK); \ ({ struct obstack *__o1 = (OBSTACK); \
void *__value = (void *) __o1->object_base; \ void *__value = (void *) __o1->object_base; \
if (__o1->next_free == __value) \ if (__o1->next_free == __value) \
__o1->maybe_empty_object = 1; \ __o1->maybe_empty_object = 1; \
__o1->next_free \ __o1->next_free \
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \ = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
__o1->alignment_mask); \ __o1->alignment_mask); \
if (__o1->next_free - (char *)__o1->chunk \ if (__o1->next_free - (char *) __o1->chunk \
> __o1->chunk_limit - (char *)__o1->chunk) \ > __o1->chunk_limit - (char *) __o1->chunk) \
__o1->next_free = __o1->chunk_limit; \ __o1->next_free = __o1->chunk_limit; \
__o1->object_base = __o1->next_free; \ __o1->object_base = __o1->next_free; \
__value; }) __value; })
# define obstack_free(OBSTACK, OBJ) \ # define obstack_free(OBSTACK, OBJ) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
void *__obj = (OBJ); \ void *__obj = (OBJ); \
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
__o->next_free = __o->object_base = (char *)__obj; \ __o->next_free = __o->object_base = (char *) __obj; \
else (obstack_free) (__o, __obj); }) else (obstack_free) (__o, __obj); })
#else /* not __GNUC__ */ #else /* not __GNUC__ */
# define obstack_object_size(h) \ # define obstack_object_size(h) \
@ -420,64 +420,64 @@ __extension__ \
Casting the third operand to void was tried before, Casting the third operand to void was tried before,
but some compilers won't accept it. */ but some compilers won't accept it. */
# define obstack_make_room(h,length) \ # define obstack_make_room(h, length) \
( (h)->temp.tempint = (length), \ ((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
# define obstack_grow(h,where,length) \ # define obstack_grow(h, where, length) \
( (h)->temp.tempint = (length), \ ((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \ memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint) (h)->next_free += (h)->temp.tempint)
# define obstack_grow0(h,where,length) \ # define obstack_grow0(h, where, length) \
( (h)->temp.tempint = (length), \ ((h)->temp.tempint = (length), \
(((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.tempint), \ memcpy ((h)->next_free, where, (h)->temp.tempint), \
(h)->next_free += (h)->temp.tempint, \ (h)->next_free += (h)->temp.tempint, \
*((h)->next_free)++ = 0) *((h)->next_free)++ = 0)
# define obstack_1grow(h,datum) \ # define obstack_1grow(h, datum) \
( (((h)->next_free + 1 > (h)->chunk_limit) \ ((((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \ ? (_obstack_newchunk ((h), 1), 0) : 0), \
obstack_1grow_fast (h, datum)) obstack_1grow_fast (h, datum))
# define obstack_ptr_grow(h,datum) \ # define obstack_ptr_grow(h, datum) \
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ ((((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
obstack_ptr_grow_fast (h, datum)) obstack_ptr_grow_fast (h, datum))
# define obstack_int_grow(h,datum) \ # define obstack_int_grow(h, datum) \
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ ((((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
obstack_int_grow_fast (h, datum)) obstack_int_grow_fast (h, datum))
# define obstack_ptr_grow_fast(h,aptr) \ # define obstack_ptr_grow_fast(h, aptr) \
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
# define obstack_int_grow_fast(h,aint) \ # define obstack_int_grow_fast(h, aint) \
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
# define obstack_blank(h,length) \ # define obstack_blank(h, length) \
( (h)->temp.tempint = (length), \ ((h)->temp.tempint = (length), \
(((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
obstack_blank_fast (h, (h)->temp.tempint)) obstack_blank_fast (h, (h)->temp.tempint))
# define obstack_alloc(h,length) \ # define obstack_alloc(h, length) \
(obstack_blank ((h), (length)), obstack_finish ((h))) (obstack_blank ((h), (length)), obstack_finish ((h)))
# define obstack_copy(h,where,length) \ # define obstack_copy(h, where, length) \
(obstack_grow ((h), (where), (length)), obstack_finish ((h))) (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
# define obstack_copy0(h,where,length) \ # define obstack_copy0(h, where, length) \
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
# define obstack_finish(h) \ # define obstack_finish(h) \
( ((h)->next_free == (h)->object_base \ (((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \ ? (((h)->maybe_empty_object = 1), 0) \
: 0), \ : 0), \
(h)->temp.tempptr = (h)->object_base, \ (h)->temp.tempptr = (h)->object_base, \
@ -490,18 +490,16 @@ __extension__ \
(h)->object_base = (h)->next_free, \ (h)->object_base = (h)->next_free, \
(h)->temp.tempptr) (h)->temp.tempptr)
# define obstack_free(h,obj) \ # define obstack_free(h, obj) \
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ ((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \ ((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
? (((h)->next_free = (h)->object_base \ ? (((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk), 0) \ = (h)->temp.tempint + (char *) (h)->chunk), 0) \
: ((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0))) : ((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0)))
#endif /* not __GNUC__ */ #endif /* not __GNUC__ */
#ifdef __cplusplus #ifdef __cplusplus
} /* C++ */ } /* C++ */
#endif #endif
#endif /* obstack.h */ #endif /* obstack.h */

View File

@ -33,16 +33,16 @@ __libc_freeres (void)
protect for multiple executions since these are fatal. */ protect for multiple executions since these are fatal. */
static long int already_called; static long int already_called;
if (! atomic_compare_and_exchange_bool_acq (&already_called, 1, 0)) if (!atomic_compare_and_exchange_bool_acq (&already_called, 1, 0))
{ {
void * const *p; void *const *p;
_IO_cleanup (); _IO_cleanup ();
RUN_HOOK (__libc_subfreeres, ()); RUN_HOOK (__libc_subfreeres, ());
for (p = symbol_set_first_element (__libc_freeres_ptrs); for (p = symbol_set_first_element (__libc_freeres_ptrs);
! symbol_set_end_p (__libc_freeres_ptrs, p); ++p) !symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
free (*p); free (*p);
} }
} }

View File

@ -48,7 +48,7 @@ main (void)
free (malloc (10)); free (malloc (10));
for (i=0; i<100; ++i) for (i = 0; i < 100; ++i)
{ {
save_state = malloc_get_state (); save_state = malloc_get_state ();
if (save_state == NULL) if (save_state == NULL)
@ -58,7 +58,7 @@ main (void)
} }
/*free (malloc (10)); This could change the top chunk! */ /*free (malloc (10)); This could change the top chunk! */
malloc_set_state (save_state); malloc_set_state (save_state);
p1 = realloc (p1, i*4 + 4); p1 = realloc (p1, i * 4 + 4);
if (p1 == NULL) if (p1 == NULL)
merror ("realloc (i*4) failed."); merror ("realloc (i*4) failed.");
free (save_state); free (save_state);

View File

@ -65,7 +65,7 @@ main (void)
abort (); abort ();
p = (char **) tsearch (copy, &root, p = (char **) tsearch (copy, &root,
(int (*) (const void *, const void *)) strcmp); (int (*)(const void *, const void *))strcmp);
if (*p != copy) if (*p != copy)
/* This line wasn't added. */ /* This line wasn't added. */
free (copy); free (copy);