mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
update from main archive 961220
Sat Dec 21 04:14:16 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/common/pause.c: Add missing second argument in call to __sigpause. Reported by a sun <asun@zoology.washington.edu>. * locale/weight.h: Correct handling of collation elements. Reported by Keld Simonsen <keld@dkuug.dk>. * manual/time.texi: Document ^ flag and %P format. * new-malloc/malloc.c: Update from Wolfram Gloger. * nss/nss.h: Reformat copyright. * posix/sched.h: Likewise. * sysdeps/i386/fpu_control.h: Likewise. * sysdeps/unix/sysv/linux/fcntlbits.h: Likewise. * sysdeps/unix/sysv/linux/ioctls.h: Likewise. * sysdeps/unix/sysv/linux/sigcontext.h: Likewise. * sysdeps/unix/sysv/linux/utsnamelen.h: Likewise. * sysdeps/unix/sysv/linux/sys/acct.h: Likewise. * sysvips/sys/msg.h: Likewise. * stdio-common/Makefile (routines): Remove fcloseall. * stdio-common/fcloseall.c: Removed. * stdlib/Makefile (distribute): Add abort-instr.h. * sysdeps/generic/abort-instr.h: New file. * sysdeps/i386/abort-instr.h: New file. * sysdeps/generic/abort.c: Use lock and stage counter to prevent any form of loop. * sysdeps/unix/sysv/linux/timebits.h: Define CLK_TCK as 100. * sysdeps/unix/sysv/linux/alpha/timebits.h: Define CLOCKS_PER_SEC as 1000000. Define CLK_TCK as 1024. * time/time.c (CLK_TCK): Define only if not already set. * time/strftime.c: Don't use `isdigit' when computing field width from string since the locale might have more than one digit block. Fri Dec 20 12:38:14 1996 Darrel Hankerson <hankedr@mail.auburn.edu> * posix/getopt.c (in -W option handling): Return when optind == argc. Thu Dec 19 14:24:50 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * nis/nss_nis/nis-alias.c (_nss_nis_parse_aliasent): Add const to type of KEY. * nis/nss_compat/compat-grp.c: Include the declaration of the file parser. * nis/nss_compat/compat-pwd.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise. * nis/nss_nis/nis-ethers.c: Likewise. * nis/nss_nis/nis-grp.c: Likewise. * nis/nss_nis/nis-network.c: Likewise. * nis/nss_nis/nis-proto.c: Likewise. * nis/nss_nis/nis-pwd.c: Likewise. * nis/nss_nis/nis-rpc.c: Likewise. * nis/nss_nis/nis-spwd.c: Likewise. * nis/nss_compat/compat-grp.c (getgrent_next_nis, getgrent_next_file): Pass the correct type for the buffer to the parser function. * nis/nss_compat/compat-pwd.c (getpwent_next_netgr, getpwent_next_nis, getpwent_next_file): Likewise. * nis/nss_compat/compat-spwd.c (getspent_next_netgr, getspent_next_nis, getspent_next_file): Likewise. * nis/nss_nis/nis-ethers.c (internal_nis_getetherent_r, _nss_nis_getethernam_r, _nss_nis_getetherbyaddr_r): Likewise. * nis/nss_nis/nis-grp.c (internal_nis_getgrent_r, _nss_nis_getgrnam_r, _nss_nis_getgrgid_r): Likewise. * nis/nss_nis/nis-network.c (internal_nis_getnetent_r, _nss_nis_getnetbyname_r, _nss_nis_getnetbyaddr_r): Likewise. * nis/nss_nis/nis-proto.c (internal_nis_getprotoent_r, _nss_nis_getprotobyname_r, _nss_nis_getprotobynumber_r): Likewise. * nis/nss_nis/nis-pwd.c (internal_nis_getpwent_r, _nss_nis_getpwnam_r, _nss_nis_getpwuid_r): Likewise. * nis/nss_nis/nis-rpc.c (internal_nis_getrpcent_r, _nss_nis_getrpcbynumber_r): Likewise. * nis/nss_nis/nis-spwd.c (internal_nis_getspent_r, _nss_nis_getspnam_r): Likewise. Thu Dec 19 13:37:16 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/m68k/setjmp.c: New file.
This commit is contained in:
266
malloc/malloc.c
266
malloc/malloc.c
@ -179,7 +179,7 @@
|
||||
Define to enable debugging. Adds fairly extensive assertion-based
|
||||
checking to help track down memory errors, but noticeably slows down
|
||||
execution.
|
||||
MALLOC_HOOKS (default: NOT defined)
|
||||
MALLOC_HOOKS (default: NOT defined)
|
||||
Define to enable support run-time replacement of the allocation
|
||||
functions through user-defined `hooks'.
|
||||
REALLOC_ZERO_BYTES_FREES (default: NOT defined)
|
||||
@ -298,7 +298,7 @@
|
||||
#if __STD_C
|
||||
# include <stddef.h> /* for size_t */
|
||||
# if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
# include <stdlib.h> /* for getenv() */
|
||||
# include <stdlib.h> /* for getenv(), abort() */
|
||||
# endif
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
@ -315,13 +315,6 @@ extern "C" {
|
||||
|
||||
#include <stdio.h> /* needed for malloc_stats */
|
||||
|
||||
/* We must not pollute the name space in the GNU libc. */
|
||||
#ifdef _LIBC
|
||||
#define malloc_stats __malloc_stats
|
||||
#define malloc_usable_size __malloc_usable_size
|
||||
#define malloc_trim __malloc_trim
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Compile-time options
|
||||
@ -878,6 +871,9 @@ extern Void_t* sbrk();
|
||||
#define pvALLOc __libc_pvalloc
|
||||
#define mALLINFo __libc_mallinfo
|
||||
#define mALLOPt __libc_mallopt
|
||||
#define mALLOC_STATs __malloc_stats
|
||||
#define mALLOC_USABLE_SIZe __malloc_usable_size
|
||||
#define mALLOC_TRIm __malloc_trim
|
||||
|
||||
#else
|
||||
|
||||
@ -890,6 +886,9 @@ extern Void_t* sbrk();
|
||||
#define pvALLOc pvalloc
|
||||
#define mALLINFo mallinfo
|
||||
#define mALLOPt mallopt
|
||||
#define mALLOC_STATs malloc_stats
|
||||
#define mALLOC_USABLE_SIZe malloc_usable_size
|
||||
#define mALLOC_TRIm malloc_trim
|
||||
|
||||
#endif
|
||||
|
||||
@ -908,12 +907,9 @@ Void_t* vALLOc(size_t);
|
||||
Void_t* pvALLOc(size_t);
|
||||
Void_t* cALLOc(size_t, size_t);
|
||||
void cfree(Void_t*);
|
||||
int __malloc_trim(size_t);
|
||||
int malloc_trim(size_t);
|
||||
size_t __malloc_usable_size(Void_t*);
|
||||
size_t malloc_usable_size(Void_t*);
|
||||
void __malloc_stats(void);
|
||||
void malloc_stats(void);
|
||||
int mALLOC_TRIm(size_t);
|
||||
size_t mALLOC_USABLE_SIZe(Void_t*);
|
||||
void mALLOC_STATs(void);
|
||||
int mALLOPt(int, int);
|
||||
struct mallinfo mALLINFo(void);
|
||||
#else
|
||||
@ -928,12 +924,9 @@ Void_t* vALLOc();
|
||||
Void_t* pvALLOc();
|
||||
Void_t* cALLOc();
|
||||
void cfree();
|
||||
int __malloc_trim();
|
||||
int malloc_trim();
|
||||
size_t _malloc_usable_size();
|
||||
size_t malloc_usable_size();
|
||||
void __malloc_stats();
|
||||
void malloc_stats();
|
||||
int mALLOC_TRIm();
|
||||
size_t mALLOC_USABLE_SIZe();
|
||||
void mALLOC_STATs();
|
||||
int mALLOPt();
|
||||
struct mallinfo mALLINFo();
|
||||
#endif
|
||||
@ -1166,9 +1159,9 @@ typedef struct _heap_info {
|
||||
static void chunk_free(arena *ar_ptr, mchunkptr p);
|
||||
static mchunkptr chunk_alloc(arena *ar_ptr, INTERNAL_SIZE_T size);
|
||||
static mchunkptr chunk_realloc(arena *ar_ptr, mchunkptr oldp,
|
||||
INTERNAL_SIZE_T oldsize, INTERNAL_SIZE_T nb);
|
||||
INTERNAL_SIZE_T oldsize, INTERNAL_SIZE_T nb);
|
||||
static mchunkptr chunk_align(arena *ar_ptr, INTERNAL_SIZE_T nb,
|
||||
size_t alignment);
|
||||
size_t alignment);
|
||||
static int main_trim(size_t pad);
|
||||
#ifndef NO_THREADS
|
||||
static int heap_trim(heap_info *heap, size_t pad);
|
||||
@ -1178,6 +1171,8 @@ static Void_t* malloc_check(size_t sz);
|
||||
static void free_check(Void_t* mem);
|
||||
static Void_t* realloc_check(Void_t* oldmem, size_t bytes);
|
||||
static Void_t* memalign_check(size_t alignment, size_t bytes);
|
||||
static Void_t* malloc_starter(size_t sz);
|
||||
static void free_starter(Void_t* mem);
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -1195,6 +1190,8 @@ static Void_t* malloc_check();
|
||||
static void free_check();
|
||||
static Void_t* realloc_check();
|
||||
static Void_t* memalign_check();
|
||||
static Void_t* malloc_starter();
|
||||
static void free_starter();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1434,7 +1431,7 @@ static arena main_arena = {
|
||||
IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
|
||||
IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
|
||||
},
|
||||
NULL, /* next */
|
||||
&main_arena, /* next */
|
||||
0, /* size */
|
||||
#if THREAD_STATS
|
||||
0, 0, 0, /* stat_lock_direct, stat_lock_loop, stat_lock_wait */
|
||||
@ -1489,8 +1486,9 @@ static unsigned long max_mmapped_mem = 0;
|
||||
|
||||
|
||||
|
||||
/* Already initialized? */
|
||||
int __malloc_initialized;
|
||||
|
||||
/* Already initialized? */
|
||||
int __malloc_initialized = 0;
|
||||
|
||||
|
||||
/* Initialization routine. */
|
||||
@ -1507,11 +1505,22 @@ ptmalloc_init __MALLOC_P((void))
|
||||
#endif
|
||||
{
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
__malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size));
|
||||
void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
|
||||
const char* s;
|
||||
#endif
|
||||
|
||||
if(__malloc_initialized) return;
|
||||
__malloc_initialized = 1;
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
/* With some threads implementations, creating thread-specific data
|
||||
or initializing a mutex may call malloc() itself. Provide a
|
||||
simple starter version (realloc() won't work). */
|
||||
save_malloc_hook = __malloc_hook;
|
||||
save_free_hook = __free_hook;
|
||||
__malloc_hook = malloc_starter;
|
||||
__free_hook = free_starter;
|
||||
#endif
|
||||
#if defined(_LIBC)
|
||||
/* Initialize the pthreads interface. */
|
||||
if (__pthread_initialize != NULL)
|
||||
@ -1525,6 +1534,8 @@ ptmalloc_init __MALLOC_P((void))
|
||||
#endif
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
s = getenv("MALLOC_CHECK_");
|
||||
__malloc_hook = save_malloc_hook;
|
||||
__free_hook = save_free_hook;
|
||||
if(s) {
|
||||
if(s[0]) mallopt(M_CHECK_ACTION, (int)(s[0] - '0'));
|
||||
malloc_check_init();
|
||||
@ -1598,7 +1609,8 @@ malloc_check_init()
|
||||
__free_hook = free_check;
|
||||
__realloc_hook = realloc_check;
|
||||
__memalign_hook = memalign_check;
|
||||
fprintf(stderr, "Using debugging hooks\n");
|
||||
if(check_action == 1)
|
||||
fprintf(stderr, "malloc: using debugging hooks\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1821,17 +1833,16 @@ grow_heap(h, diff) heap_info *h; long diff;
|
||||
/* arena_get() acquires an arena and locks the corresponding mutex.
|
||||
First, try the one last locked successfully by this thread. (This
|
||||
is the common case and handled with a macro for speed.) Then, loop
|
||||
over the singly linked list of arenas. If no arena is readily
|
||||
available, create a new one. */
|
||||
once over the circularly linked list of arenas. If no arena is
|
||||
readily available, create a new one. */
|
||||
|
||||
#define arena_get(ptr, size) do { \
|
||||
Void_t *vptr = NULL; \
|
||||
ptr = (arena *)tsd_getspecific(arena_key, vptr); \
|
||||
if(ptr && !mutex_trylock(&ptr->mutex)) { \
|
||||
THREAD_STAT(++(ptr->stat_lock_direct)); \
|
||||
} else { \
|
||||
} else \
|
||||
ptr = arena_get2(ptr, (size)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static arena *
|
||||
@ -1847,17 +1858,27 @@ arena_get2(a_tsd, size) arena *a_tsd; size_t size;
|
||||
int i;
|
||||
unsigned long misalign;
|
||||
|
||||
/* Check the singly-linked list for unlocked arenas. */
|
||||
if(a_tsd) {
|
||||
for(a = a_tsd->next; a; a = a->next) {
|
||||
if(!mutex_trylock(&a->mutex))
|
||||
goto done;
|
||||
if(!a_tsd)
|
||||
a = a_tsd = &main_arena;
|
||||
else {
|
||||
a = a_tsd->next;
|
||||
if(!a) {
|
||||
/* This can only happen while initializing the new arena. */
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
THREAD_STAT(++(main_arena.stat_lock_wait));
|
||||
return &main_arena;
|
||||
}
|
||||
}
|
||||
for(a = &main_arena; a != a_tsd; a = a->next) {
|
||||
if(!mutex_trylock(&a->mutex))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check the global, circularly linked list for available arenas. */
|
||||
do {
|
||||
if(!mutex_trylock(&a->mutex)) {
|
||||
THREAD_STAT(++(a->stat_lock_loop));
|
||||
tsd_setspecific(arena_key, (Void_t *)a);
|
||||
return a;
|
||||
}
|
||||
a = a->next;
|
||||
} while(a != a_tsd);
|
||||
|
||||
/* Nothing immediately available, so generate a new arena. */
|
||||
h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT));
|
||||
@ -1866,7 +1887,9 @@ arena_get2(a_tsd, size) arena *a_tsd; size_t size;
|
||||
a = h->ar_ptr = (arena *)(h+1);
|
||||
for(i=0; i<NAV; i++)
|
||||
init_bin(a, i);
|
||||
a->next = NULL;
|
||||
a->size = h->size;
|
||||
tsd_setspecific(arena_key, (Void_t *)a);
|
||||
mutex_init(&a->mutex);
|
||||
i = mutex_lock(&a->mutex); /* remember result */
|
||||
|
||||
@ -1887,9 +1910,7 @@ arena_get2(a_tsd, size) arena *a_tsd; size_t size;
|
||||
if(i) /* locking failed; keep arena for further attempts later */
|
||||
return 0;
|
||||
|
||||
done:
|
||||
THREAD_STAT(++(a->stat_lock_loop));
|
||||
tsd_setspecific(arena_key, (Void_t *)a);
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -2890,7 +2911,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
||||
static mchunkptr
|
||||
#if __STD_C
|
||||
chunk_realloc(arena* ar_ptr, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
|
||||
INTERNAL_SIZE_T nb)
|
||||
INTERNAL_SIZE_T nb)
|
||||
#else
|
||||
chunk_realloc(ar_ptr, oldp, oldsize, nb)
|
||||
arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
|
||||
@ -3339,9 +3360,9 @@ void cfree(mem) Void_t *mem;
|
||||
*/
|
||||
|
||||
#if __STD_C
|
||||
int malloc_trim(size_t pad)
|
||||
int mALLOC_TRIm(size_t pad)
|
||||
#else
|
||||
int malloc_trim(pad) size_t pad;
|
||||
int mALLOC_TRIm(pad) size_t pad;
|
||||
#endif
|
||||
{
|
||||
int res;
|
||||
@ -3475,9 +3496,9 @@ heap_trim(heap, pad) heap_info *heap; size_t pad;
|
||||
*/
|
||||
|
||||
#if __STD_C
|
||||
size_t malloc_usable_size(Void_t* mem)
|
||||
size_t mALLOC_USABLE_SIZe(Void_t* mem)
|
||||
#else
|
||||
size_t malloc_usable_size(mem) Void_t* mem;
|
||||
size_t mALLOC_USABLE_SIZe(mem) Void_t* mem;
|
||||
#endif
|
||||
{
|
||||
mchunkptr p;
|
||||
@ -3603,7 +3624,7 @@ dump_heap(heap) heap_info *heap;
|
||||
|
||||
*/
|
||||
|
||||
void malloc_stats()
|
||||
void mALLOC_STATs()
|
||||
{
|
||||
int i;
|
||||
arena *ar_ptr;
|
||||
@ -3613,7 +3634,7 @@ void malloc_stats()
|
||||
long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0;
|
||||
#endif
|
||||
|
||||
for(i=0, ar_ptr = &main_arena; ar_ptr; ar_ptr = ar_ptr->next, i++) {
|
||||
for(i=0, ar_ptr = &main_arena;; i++) {
|
||||
malloc_update_mallinfo(ar_ptr, &mi);
|
||||
fprintf(stderr, "Arena %d:\n", i);
|
||||
fprintf(stderr, "system bytes = %10u\n", (unsigned int)mi.arena);
|
||||
@ -3627,10 +3648,14 @@ void malloc_stats()
|
||||
#endif
|
||||
#if !defined(NO_THREADS) && MALLOC_DEBUG > 1
|
||||
if(ar_ptr != &main_arena) {
|
||||
(void)mutex_lock(&ar_ptr->mutex);
|
||||
heap_info *heap = heap_for_ptr(top(ar_ptr));
|
||||
while(heap) { dump_heap(heap); heap = heap->prev; }
|
||||
(void)mutex_unlock(&ar_ptr->mutex);
|
||||
}
|
||||
#endif
|
||||
ar_ptr = ar_ptr->next;
|
||||
if(ar_ptr == &main_arena) break;
|
||||
}
|
||||
fprintf(stderr, "Total (incl. mmap):\n");
|
||||
fprintf(stderr, "system bytes = %10u\n", system_b);
|
||||
@ -3713,26 +3738,7 @@ int mALLOPt(param_number, value) int param_number; int value;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
weak_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
|
||||
weak_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree)
|
||||
weak_alias (__libc_free, __free) weak_alias (__libc_free, free)
|
||||
weak_alias (__libc_malloc, __malloc) weak_alias (__libc_malloc, malloc)
|
||||
weak_alias (__libc_memalign, __memalign) weak_alias (__libc_memalign, memalign)
|
||||
weak_alias (__libc_realloc, __realloc) weak_alias (__libc_realloc, realloc)
|
||||
weak_alias (__libc_valloc, __valloc) weak_alias (__libc_valloc, valloc)
|
||||
weak_alias (__libc_pvalloc, __pvalloc) weak_alias (__libc_pvalloc, pvalloc)
|
||||
weak_alias (__libc_mallinfo, __mallinfo) weak_alias (__libc_mallinfo, mallinfo)
|
||||
weak_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
|
||||
|
||||
#undef malloc_stats
|
||||
weak_alias (__malloc_stats, malloc_stats)
|
||||
#undef malloc_usable_size
|
||||
weak_alias (__malloc_usable_size, malloc_usable_size)
|
||||
#undef malloc_trim
|
||||
weak_alias (__malloc_trim, malloc_trim)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_LIBC) || defined(MALLOC_HOOKS)
|
||||
@ -3741,7 +3747,7 @@ weak_alias (__malloc_trim, malloc_trim)
|
||||
byte per chunk; still this will catch most cases of double frees or
|
||||
overruns. */
|
||||
|
||||
#define MAGICBYTE ((char)0xd7)
|
||||
#define MAGICBYTE(p) ( ( ((unsigned)p >> 3) ^ ((unsigned)p >> 11)) & 0xFF )
|
||||
|
||||
/* Convert a pointer to be free()d or realloc()ed to a valid chunk
|
||||
pointer. If the provided pointer is not valid, return NULL. The
|
||||
@ -3760,29 +3766,35 @@ mem2chunk_check(mem) Void_t* mem;
|
||||
p = mem2chunk(mem);
|
||||
if(!aligned_OK(p)) return NULL;
|
||||
if( (char*)p>=sbrk_base && (char*)p<(sbrk_base+sbrked_mem) ) {
|
||||
/* Must be a chunk in conventional memory. */
|
||||
/* Must be a chunk in conventional heap memory. */
|
||||
if(chunk_is_mmapped(p) ||
|
||||
( (sz = chunksize(p)), ((char*)p + sz)>=(sbrk_base+sbrked_mem) ) ||
|
||||
sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ) return NULL;
|
||||
if(*((char*)p + sz + (SIZE_SZ-1)) != MAGICBYTE) return NULL;
|
||||
*((char*)p + sz + (SIZE_SZ-1)) = 0;
|
||||
sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||
|
||||
( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||
|
||||
(long)prev_chunk(p)<(long)sbrk_base ||
|
||||
next_chunk(prev_chunk(p))!=p) ))
|
||||
return NULL;
|
||||
if(*((unsigned char*)p + sz + (SIZE_SZ-1)) != MAGICBYTE(p))
|
||||
return NULL;
|
||||
*((unsigned char*)p + sz + (SIZE_SZ-1)) ^= 0xFF;
|
||||
} else {
|
||||
unsigned long offset, page_mask = malloc_getpagesize-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
|
||||
first. */
|
||||
offset = (unsigned long)mem & page_mask;
|
||||
if((offset!=MALLOC_ALIGNMENT && offset!=0 && offset!=0x10 &&
|
||||
offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 &&
|
||||
offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 &&
|
||||
offset<0x2000) ||
|
||||
offset!=0x20 && offset!=0x40 && offset!=0x80 && offset!=0x100 &&
|
||||
offset!=0x200 && offset!=0x400 && offset!=0x800 && offset!=0x1000 &&
|
||||
offset<0x2000) ||
|
||||
!chunk_is_mmapped(p) || (p->size & PREV_INUSE) ||
|
||||
( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) ||
|
||||
( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) )
|
||||
return NULL;
|
||||
if(*((char*)p + sz - 1) != MAGICBYTE) return NULL;
|
||||
*((char*)p + sz - 1) = 0;
|
||||
if(*((unsigned char*)p + sz - 1) != MAGICBYTE(p))
|
||||
return NULL;
|
||||
*((unsigned char*)p + sz - 1) ^= 0xFF;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@ -3806,7 +3818,7 @@ malloc_check(sz) size_t sz;
|
||||
--nb;
|
||||
else
|
||||
nb += SIZE_SZ - 1;
|
||||
*((char*)victim + nb) = MAGICBYTE;
|
||||
*((unsigned char*)victim + nb) = MAGICBYTE(victim);
|
||||
return chunk2mem(victim);
|
||||
}
|
||||
|
||||
@ -3820,8 +3832,10 @@ free_check(mem) Void_t* mem;
|
||||
mchunkptr p;
|
||||
|
||||
if(!mem) return;
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
p = mem2chunk_check(mem);
|
||||
if(!p) {
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
switch(check_action) {
|
||||
case 1:
|
||||
fprintf(stderr, "free(): invalid pointer %lx!\n", (long)(mem));
|
||||
@ -3833,11 +3847,14 @@ free_check(mem) Void_t* mem;
|
||||
}
|
||||
#if HAVE_MMAP
|
||||
if (chunk_is_mmapped(p)) {
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
munmap_chunk(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
#if 0 /* Erase freed memory. */
|
||||
memset(mem, 0, chunksize(p) - (SIZE_SZ+1));
|
||||
#endif
|
||||
chunk_free(&main_arena, p);
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
}
|
||||
@ -3853,8 +3870,10 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
||||
INTERNAL_SIZE_T nb, oldsize;
|
||||
|
||||
if (oldmem == 0) return malloc_check(bytes);
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
oldp = mem2chunk_check(oldmem);
|
||||
if(!oldp) {
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
switch(check_action) {
|
||||
case 1:
|
||||
fprintf(stderr, "realloc(): invalid pointer %lx!\n", (long)(oldmem));
|
||||
@ -3868,7 +3887,6 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
||||
|
||||
nb = request2size(bytes+1);
|
||||
|
||||
(void)mutex_lock(&main_arena.mutex);
|
||||
#if HAVE_MMAP
|
||||
if (chunk_is_mmapped(oldp)) {
|
||||
#if HAVE_MREMAP
|
||||
@ -3878,19 +3896,31 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
||||
/* Note the extra SIZE_SZ overhead. */
|
||||
if(oldsize - SIZE_SZ >= nb) newp = oldp; /* do nothing */
|
||||
else {
|
||||
/* Must alloc, copy, free. */
|
||||
newp = chunk_alloc(&main_arena, nb);
|
||||
if (newp) {
|
||||
MALLOC_COPY(chunk2mem(newp), oldmem, oldsize - 2*SIZE_SZ);
|
||||
munmap_chunk(oldp);
|
||||
}
|
||||
/* Must alloc, copy, free. */
|
||||
newp = chunk_alloc(&main_arena, nb);
|
||||
if (newp) {
|
||||
MALLOC_COPY(chunk2mem(newp), oldmem, oldsize - 2*SIZE_SZ);
|
||||
munmap_chunk(oldp);
|
||||
}
|
||||
}
|
||||
#if HAVE_MREMAP
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
} else {
|
||||
#endif /* HAVE_MMAP */
|
||||
newp = chunk_realloc(&main_arena, oldp, oldsize, nb);
|
||||
#if 0 /* Erase freed memory. */
|
||||
nb = chunksize(newp);
|
||||
if(oldp<newp || oldp>=chunk_at_offset(newp, nb)) {
|
||||
memset((char*)oldmem + 2*sizeof(mbinptr), 0,
|
||||
oldsize - (2*sizeof(mbinptr)+2*SIZE_SZ+1));
|
||||
} else if(nb > oldsize+SIZE_SZ) {
|
||||
memset((char*)chunk2mem(newp) + oldsize, 0, nb - (oldsize+SIZE_SZ));
|
||||
}
|
||||
#endif
|
||||
#if HAVE_MMAP
|
||||
}
|
||||
#endif
|
||||
(void)mutex_unlock(&main_arena.mutex);
|
||||
|
||||
if(!newp) return NULL;
|
||||
@ -3899,7 +3929,7 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
|
||||
--nb;
|
||||
else
|
||||
nb += SIZE_SZ - 1;
|
||||
*((char*)newp + nb) = MAGICBYTE;
|
||||
*((unsigned char*)newp + nb) = MAGICBYTE(newp);
|
||||
return chunk2mem(newp);
|
||||
}
|
||||
|
||||
@ -3926,12 +3956,66 @@ memalign_check(alignment, bytes) size_t alignment; size_t bytes;
|
||||
--nb;
|
||||
else
|
||||
nb += SIZE_SZ - 1;
|
||||
*((char*)p + nb) = MAGICBYTE;
|
||||
*((unsigned char*)p + nb) = MAGICBYTE(p);
|
||||
return chunk2mem(p);
|
||||
}
|
||||
|
||||
/* The following hooks are used when the global initialization in
|
||||
ptmalloc_init() hasn't completed yet. */
|
||||
|
||||
static Void_t*
|
||||
#if __STD_C
|
||||
malloc_starter(size_t sz)
|
||||
#else
|
||||
malloc_starter(sz) size_t sz;
|
||||
#endif
|
||||
{
|
||||
mchunkptr victim = chunk_alloc(&main_arena, request2size(sz));
|
||||
|
||||
return victim ? chunk2mem(victim) : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
#if __STD_C
|
||||
free_starter(Void_t* mem)
|
||||
#else
|
||||
free_starter(mem) Void_t* mem;
|
||||
#endif
|
||||
{
|
||||
mchunkptr p;
|
||||
|
||||
if(!mem) return;
|
||||
p = mem2chunk(mem);
|
||||
#if HAVE_MMAP
|
||||
if (chunk_is_mmapped(p)) {
|
||||
munmap_chunk(p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
chunk_free(&main_arena, p);
|
||||
}
|
||||
|
||||
#endif /* defined(_LIBC) || defined(MALLOC_HOOKS) */
|
||||
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
weak_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
|
||||
weak_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree)
|
||||
weak_alias (__libc_free, __free) weak_alias (__libc_free, free)
|
||||
weak_alias (__libc_malloc, __malloc) weak_alias (__libc_malloc, malloc)
|
||||
weak_alias (__libc_memalign, __memalign) weak_alias (__libc_memalign, memalign)
|
||||
weak_alias (__libc_realloc, __realloc) weak_alias (__libc_realloc, realloc)
|
||||
weak_alias (__libc_valloc, __valloc) weak_alias (__libc_valloc, valloc)
|
||||
weak_alias (__libc_pvalloc, __pvalloc) weak_alias (__libc_pvalloc, pvalloc)
|
||||
weak_alias (__libc_mallinfo, __mallinfo) weak_alias (__libc_mallinfo, mallinfo)
|
||||
weak_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
|
||||
|
||||
weak_alias (__malloc_stats, malloc_stats)
|
||||
weak_alias (__malloc_usable_size, malloc_usable_size)
|
||||
weak_alias (__malloc_trim, malloc_trim)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
History:
|
||||
|
Reference in New Issue
Block a user