|
@ -8,7 +8,7 @@ |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#if defined(LIBC_SCCS) && !defined(lint) |
|
|
#if defined(LIBC_SCCS) && !defined(lint) |
|
|
static char rcsid[] = "$OpenBSD: malloc.c,v 1.60 2003/09/27 21:09:15 tedu Exp $"; |
|
|
|
|
|
|
|
|
static char rcsid[] = "$OpenBSD: malloc.c,v 1.61 2003/09/30 00:22:03 tedu Exp $"; |
|
|
#endif /* LIBC_SCCS and not lint */ |
|
|
#endif /* LIBC_SCCS and not lint */ |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
@ -149,7 +149,7 @@ static int fdzero; |
|
|
#define MMAP_FD fdzero |
|
|
#define MMAP_FD fdzero |
|
|
#define INIT_MMAP() \ |
|
|
#define INIT_MMAP() \ |
|
|
{ if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \ |
|
|
{ if ((fdzero=open("/dev/zero", O_RDWR, 0000)) == -1) \ |
|
|
wrterror("open of /dev/zero.\n"); } |
|
|
|
|
|
|
|
|
wrterror("open of /dev/zero\n"); } |
|
|
#else |
|
|
#else |
|
|
#define MMAP_FD (-1) |
|
|
#define MMAP_FD (-1) |
|
|
#define INIT_MMAP() |
|
|
#define INIT_MMAP() |
|
@ -289,7 +289,7 @@ malloc_dump(FILE *fd) |
|
|
fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n", |
|
|
fprintf(fd, "Free: @%p [%p...%p[ %ld ->%p <-%p\n", |
|
|
pf, pf->page, pf->end, pf->size, pf->prev, pf->next); |
|
|
pf, pf->page, pf->end, pf->size, pf->prev, pf->next); |
|
|
if (pf == pf->next) { |
|
|
if (pf == pf->next) { |
|
|
fprintf(fd, "Free_list loops.\n"); |
|
|
|
|
|
|
|
|
fprintf(fd, "Free_list loops\n"); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -359,7 +359,7 @@ static void |
|
|
malloc_exit(void) |
|
|
malloc_exit(void) |
|
|
{ |
|
|
{ |
|
|
FILE *fd = fopen("malloc.out", "a"); |
|
|
FILE *fd = fopen("malloc.out", "a"); |
|
|
char *q = "malloc() warning: Couldn't dump stats.\n"; |
|
|
|
|
|
|
|
|
char *q = "malloc() warning: Couldn't dump stats\n"; |
|
|
if (fd != NULL) { |
|
|
if (fd != NULL) { |
|
|
malloc_dump(fd); |
|
|
malloc_dump(fd); |
|
|
fclose(fd); |
|
|
fclose(fd); |
|
@ -381,7 +381,7 @@ map_pages(size_t pages) |
|
|
pages <<= malloc_pageshift; |
|
|
pages <<= malloc_pageshift; |
|
|
if (pages > SIZE_T_MAX - (size_t)result) { |
|
|
if (pages > SIZE_T_MAX - (size_t)result) { |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
wrtwarning("(ES): overflow in map_pages fails.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("(ES): overflow in map_pages fails\n"); |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
errno = ENOMEM; |
|
|
errno = ENOMEM; |
|
|
return (NULL); |
|
|
return (NULL); |
|
@ -390,7 +390,7 @@ map_pages(size_t pages) |
|
|
|
|
|
|
|
|
if (brk(tail) == (char *)-1) { |
|
|
if (brk(tail) == (char *)-1) { |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
wrtwarning("(ES): map_pages fails.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("(ES): map_pages fails\n"); |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
@ -521,7 +521,7 @@ malloc_init(void) |
|
|
default: |
|
|
default: |
|
|
j = malloc_abort; |
|
|
j = malloc_abort; |
|
|
malloc_abort = 0; |
|
|
malloc_abort = 0; |
|
|
wrtwarning("unknown char in MALLOC_OPTIONS.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("unknown char in MALLOC_OPTIONS\n"); |
|
|
malloc_abort = j; |
|
|
malloc_abort = j; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
@ -539,14 +539,14 @@ malloc_init(void) |
|
|
|
|
|
|
|
|
#ifdef MALLOC_STATS |
|
|
#ifdef MALLOC_STATS |
|
|
if (malloc_stats && (atexit(malloc_exit) == -1)) |
|
|
if (malloc_stats && (atexit(malloc_exit) == -1)) |
|
|
wrtwarning("atexit(2) failed. Will not be able to dump malloc stats on exit.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("atexit(2) failed. Will not be able to dump malloc stats on exit\n"); |
|
|
#endif /* MALLOC_STATS */ |
|
|
#endif /* MALLOC_STATS */ |
|
|
|
|
|
|
|
|
/* Allocate one page for the page directory */ |
|
|
/* Allocate one page for the page directory */ |
|
|
page_dir = (struct pginfo **) MMAP(malloc_pagesize); |
|
|
page_dir = (struct pginfo **) MMAP(malloc_pagesize); |
|
|
|
|
|
|
|
|
if (page_dir == MAP_FAILED) |
|
|
if (page_dir == MAP_FAILED) |
|
|
wrterror("mmap(2) failed, check limits.\n"); |
|
|
|
|
|
|
|
|
wrterror("mmap(2) failed, check limits\n"); |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* We need a maximum of malloc_pageshift buckets, steal these from the |
|
|
* We need a maximum of malloc_pageshift buckets, steal these from the |
|
@ -594,19 +594,19 @@ malloc_pages(size_t size) |
|
|
|
|
|
|
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
if (pf->size & malloc_pagemask) |
|
|
if (pf->size & malloc_pagemask) |
|
|
wrterror("(ES): junk length entry on free_list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): junk length entry on free_list\n"); |
|
|
if (!pf->size) |
|
|
if (!pf->size) |
|
|
wrterror("(ES): zero length entry on free_list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): zero length entry on free_list\n"); |
|
|
if (pf->page == pf->end) |
|
|
if (pf->page == pf->end) |
|
|
wrterror("(ES): zero entry on free_list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): zero entry on free_list\n"); |
|
|
if (pf->page > pf->end) |
|
|
if (pf->page > pf->end) |
|
|
wrterror("(ES): sick entry on free_list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): sick entry on free_list\n"); |
|
|
if ((void*)pf->page >= (void*)sbrk(0)) |
|
|
if ((void*)pf->page >= (void*)sbrk(0)) |
|
|
wrterror("(ES): entry on free_list past brk.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): entry on free_list past brk\n"); |
|
|
if (page_dir[ptr2index(pf->page)] != MALLOC_FREE) |
|
|
if (page_dir[ptr2index(pf->page)] != MALLOC_FREE) |
|
|
wrterror("(ES): non-free first page on free-list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): non-free first page on free-list\n"); |
|
|
if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE) |
|
|
if (page_dir[ptr2index(pf->end)-1] != MALLOC_FREE) |
|
|
wrterror("(ES): non-free last page on free-list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): non-free last page on free-list\n"); |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
|
|
|
|
|
|
if (pf->size < size) |
|
|
if (pf->size < size) |
|
@ -629,7 +629,7 @@ malloc_pages(size_t size) |
|
|
|
|
|
|
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE) |
|
|
if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE) |
|
|
wrterror("(ES): allocated non-free page on free-list.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): allocated non-free page on free-list\n"); |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
|
|
|
|
|
|
size >>= malloc_pageshift; |
|
|
size >>= malloc_pageshift; |
|
@ -840,7 +840,7 @@ imalloc(size_t size) |
|
|
result = malloc_pages(size); |
|
|
result = malloc_pages(size); |
|
|
|
|
|
|
|
|
if (malloc_abort && result == NULL) |
|
|
if (malloc_abort && result == NULL) |
|
|
wrterror("allocation failed.\n"); |
|
|
|
|
|
|
|
|
wrterror("allocation failed\n"); |
|
|
|
|
|
|
|
|
if (malloc_zero && result != NULL) |
|
|
if (malloc_zero && result != NULL) |
|
|
memset(result, 0, size); |
|
|
memset(result, 0, size); |
|
@ -863,19 +863,19 @@ irealloc(void *ptr, size_t size) |
|
|
abort(); |
|
|
abort(); |
|
|
|
|
|
|
|
|
if (!malloc_started) { |
|
|
if (!malloc_started) { |
|
|
wrtwarning("malloc() has never been called.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("malloc() has never been called\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
index = ptr2index(ptr); |
|
|
index = ptr2index(ptr); |
|
|
|
|
|
|
|
|
if (index < malloc_pageshift) { |
|
|
if (index < malloc_pageshift) { |
|
|
wrtwarning("junk pointer, too low to make sense.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("junk pointer, too low to make sense\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (index > last_index) { |
|
|
if (index > last_index) { |
|
|
wrtwarning("junk pointer, too high to make sense.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("junk pointer, too high to make sense\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -885,7 +885,7 @@ irealloc(void *ptr, size_t size) |
|
|
|
|
|
|
|
|
/* Check the pointer */ |
|
|
/* Check the pointer */ |
|
|
if ((u_long)ptr & malloc_pagemask) { |
|
|
if ((u_long)ptr & malloc_pagemask) { |
|
|
wrtwarning("modified (page-) pointer.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("modified (page-) pointer\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -905,7 +905,7 @@ irealloc(void *ptr, size_t size) |
|
|
|
|
|
|
|
|
/* Check the pointer for sane values */ |
|
|
/* Check the pointer for sane values */ |
|
|
if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) { |
|
|
if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) { |
|
|
wrtwarning("modified (chunk-) pointer.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("modified (chunk-) pointer\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -914,7 +914,7 @@ irealloc(void *ptr, size_t size) |
|
|
|
|
|
|
|
|
/* Verify that it isn't a free chunk already */ |
|
|
/* Verify that it isn't a free chunk already */ |
|
|
if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) { |
|
|
if ((*mp)->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) { |
|
|
wrtwarning("chunk is already free.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("chunk is already free\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -930,7 +930,7 @@ irealloc(void *ptr, size_t size) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
wrtwarning("pointer to wrong page.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("pointer to wrong page\n"); |
|
|
return (NULL); |
|
|
return (NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -963,17 +963,17 @@ free_pages(void *ptr, int index, struct pginfo *info) |
|
|
void *tail; |
|
|
void *tail; |
|
|
|
|
|
|
|
|
if (info == MALLOC_FREE) { |
|
|
if (info == MALLOC_FREE) { |
|
|
wrtwarning("page is already free.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("page is already free\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (info != MALLOC_FIRST) { |
|
|
if (info != MALLOC_FIRST) { |
|
|
wrtwarning("pointer to wrong page.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("pointer to wrong page\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((u_long)ptr & malloc_pagemask) { |
|
|
if ((u_long)ptr & malloc_pagemask) { |
|
|
wrtwarning("modified (page-) pointer.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("modified (page-) pointer\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1051,7 +1051,7 @@ free_pages(void *ptr, int index, struct pginfo *info) |
|
|
pf = px; |
|
|
pf = px; |
|
|
px = NULL; |
|
|
px = NULL; |
|
|
} else { |
|
|
} else { |
|
|
wrterror("freelist is destroyed.\n"); |
|
|
|
|
|
|
|
|
wrterror("freelist is destroyed\n"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1100,12 +1100,12 @@ free_bytes(void *ptr, int index, struct pginfo *info) |
|
|
i = ((u_long)ptr & malloc_pagemask) >> info->shift; |
|
|
i = ((u_long)ptr & malloc_pagemask) >> info->shift; |
|
|
|
|
|
|
|
|
if ((u_long)ptr & ((1UL<<(info->shift))-1)) { |
|
|
if ((u_long)ptr & ((1UL<<(info->shift))-1)) { |
|
|
wrtwarning("modified (chunk-) pointer.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("modified (chunk-) pointer\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) { |
|
|
if (info->bits[i/MALLOC_BITS] & (1UL<<(i%MALLOC_BITS))) { |
|
|
wrtwarning("chunk is already free.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("chunk is already free\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1140,7 +1140,7 @@ free_bytes(void *ptr, int index, struct pginfo *info) |
|
|
mp = &((*mp)->next); |
|
|
mp = &((*mp)->next); |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
#ifdef MALLOC_EXTRA_SANITY |
|
|
if (!*mp) |
|
|
if (!*mp) |
|
|
wrterror("(ES): Not on queue.\n"); |
|
|
|
|
|
|
|
|
wrterror("(ES): Not on queue\n"); |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
#endif /* MALLOC_EXTRA_SANITY */ |
|
|
} |
|
|
} |
|
|
*mp = info->next; |
|
|
*mp = info->next; |
|
@ -1171,7 +1171,7 @@ ifree(void *ptr) |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
if (!malloc_started) { |
|
|
if (!malloc_started) { |
|
|
wrtwarning("malloc() has never been called.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("malloc() has never been called\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1182,12 +1182,12 @@ ifree(void *ptr) |
|
|
index = ptr2index(ptr); |
|
|
index = ptr2index(ptr); |
|
|
|
|
|
|
|
|
if (index < malloc_pageshift) { |
|
|
if (index < malloc_pageshift) { |
|
|
wrtwarning("junk pointer, too low to make sense.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("junk pointer, too low to make sense\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (index > last_index) { |
|
|
if (index > last_index) { |
|
|
wrtwarning("junk pointer, too high to make sense.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("junk pointer, too high to make sense\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1214,7 +1214,7 @@ malloc(size_t size) |
|
|
malloc_func = " in malloc():"; |
|
|
malloc_func = " in malloc():"; |
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
if (malloc_active++) { |
|
|
if (malloc_active++) { |
|
|
wrtwarning("recursive call.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("recursive call\n"); |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
return (NULL); |
|
|
return (NULL); |
|
@ -1224,7 +1224,7 @@ malloc(size_t size) |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (malloc_xmalloc && r == NULL) |
|
|
if (malloc_xmalloc && r == NULL) |
|
|
wrterror("out of memory.\n"); |
|
|
|
|
|
|
|
|
wrterror("out of memory\n"); |
|
|
return (r); |
|
|
return (r); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1234,7 +1234,7 @@ free(void *ptr) |
|
|
malloc_func = " in free():"; |
|
|
malloc_func = " in free():"; |
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
if (malloc_active++) { |
|
|
if (malloc_active++) { |
|
|
wrtwarning("recursive call.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("recursive call\n"); |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
return; |
|
|
return; |
|
@ -1254,7 +1254,7 @@ realloc(void *ptr, size_t size) |
|
|
malloc_func = " in realloc():"; |
|
|
malloc_func = " in realloc():"; |
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
if (malloc_active++) { |
|
|
if (malloc_active++) { |
|
|
wrtwarning("recursive call.\n"); |
|
|
|
|
|
|
|
|
wrtwarning("recursive call\n"); |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
return (NULL); |
|
|
return (NULL); |
|
@ -1268,6 +1268,6 @@ realloc(void *ptr, size_t size) |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (malloc_xmalloc && r == NULL) |
|
|
if (malloc_xmalloc && r == NULL) |
|
|
wrterror("out of memory.\n"); |
|
|
|
|
|
|
|
|
wrterror("out of memory\n"); |
|
|
return (r); |
|
|
return (r); |
|
|
} |
|
|
} |