|
@ -1,4 +1,4 @@ |
|
|
/* $OpenBSD: malloc.c,v 1.112 2008/12/29 22:25:50 djm Exp $ */ |
|
|
|
|
|
|
|
|
/* $OpenBSD: malloc.c,v 1.113 2008/12/30 07:44:51 djm Exp $ */ |
|
|
/* |
|
|
/* |
|
|
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> |
|
|
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> |
|
|
* |
|
|
* |
|
@ -88,23 +88,6 @@ |
|
|
#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ |
|
|
#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ |
|
|
MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) |
|
|
MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) |
|
|
|
|
|
|
|
|
/* Protect and unprotect g_pool structure as we enter/exit the allocator */ |
|
|
|
|
|
#define DIR_INFO_RSZ ((sizeof(struct dir_info) + PAGE_MASK) & ~PAGE_MASK) |
|
|
|
|
|
#define PROTECT_G_POOL() \ |
|
|
|
|
|
do { \ |
|
|
|
|
|
if (g_pool != NULL && mopts.malloc_poolprot) { \ |
|
|
|
|
|
mprotect((void *)((uintptr_t)g_pool & ~PAGE_MASK), \ |
|
|
|
|
|
DIR_INFO_RSZ, PROT_NONE); \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} while (0) |
|
|
|
|
|
#define UNPROTECT_G_POOL() \ |
|
|
|
|
|
do { \ |
|
|
|
|
|
if (g_pool != NULL && mopts.malloc_poolprot) { \ |
|
|
|
|
|
mprotect((void *)((uintptr_t)g_pool & ~PAGE_MASK), \ |
|
|
|
|
|
DIR_INFO_RSZ, PROT_READ | PROT_WRITE); \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
|
|
struct region_info { |
|
|
struct region_info { |
|
|
void *p; /* page; low bits used to mark chunks */ |
|
|
void *p; /* page; low bits used to mark chunks */ |
|
|
uintptr_t size; /* size for pages, or chunk_info pointer */ |
|
|
uintptr_t size; /* size for pages, or chunk_info pointer */ |
|
@ -142,7 +125,7 @@ struct dir_info { |
|
|
#endif /* MALLOC_STATS */ |
|
|
#endif /* MALLOC_STATS */ |
|
|
u_int32_t canary2; |
|
|
u_int32_t canary2; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
#define DIR_INFO_RSZ ((sizeof(struct dir_info) + PAGE_MASK) & ~PAGE_MASK) |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* This structure describes a page worth of chunks. |
|
|
* This structure describes a page worth of chunks. |
|
@ -165,7 +148,6 @@ struct chunk_info { |
|
|
struct malloc_readonly { |
|
|
struct malloc_readonly { |
|
|
struct dir_info *g_pool; /* Main bookkeeping information */ |
|
|
struct dir_info *g_pool; /* Main bookkeeping information */ |
|
|
int malloc_abort; /* abort() on error */ |
|
|
int malloc_abort; /* abort() on error */ |
|
|
int malloc_poolprot; /* mprotect heap PROT_NONE? */ |
|
|
|
|
|
int malloc_freeprot; /* mprotect free pages PROT_NONE? */ |
|
|
int malloc_freeprot; /* mprotect free pages PROT_NONE? */ |
|
|
int malloc_hint; /* call madvice on free pages? */ |
|
|
int malloc_hint; /* call madvice on free pages? */ |
|
|
int malloc_junk; /* junk fill? */ |
|
|
int malloc_junk; /* junk fill? */ |
|
@ -653,12 +635,6 @@ omalloc_init(struct dir_info **dp) |
|
|
case 'J': |
|
|
case 'J': |
|
|
mopts.malloc_junk = 1; |
|
|
mopts.malloc_junk = 1; |
|
|
break; |
|
|
break; |
|
|
case 'l': |
|
|
|
|
|
mopts.malloc_poolprot = 0; |
|
|
|
|
|
break; |
|
|
|
|
|
case 'L': |
|
|
|
|
|
mopts.malloc_poolprot = 1; |
|
|
|
|
|
break; |
|
|
|
|
|
case 'n': |
|
|
case 'n': |
|
|
case 'N': |
|
|
case 'N': |
|
|
break; |
|
|
break; |
|
@ -1214,7 +1190,6 @@ malloc_recurse(void) |
|
|
wrterror("recursive call"); |
|
|
wrterror("recursive call"); |
|
|
} |
|
|
} |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
errno = EDEADLK; |
|
|
errno = EDEADLK; |
|
|
} |
|
|
} |
|
@ -1223,7 +1198,6 @@ static void |
|
|
malloc_global_corrupt(void) |
|
|
malloc_global_corrupt(void) |
|
|
{ |
|
|
{ |
|
|
wrterror("global malloc data corrupt"); |
|
|
wrterror("global malloc data corrupt"); |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
errno = EINVAL; |
|
|
errno = EINVAL; |
|
|
} |
|
|
} |
|
@ -1248,7 +1222,6 @@ malloc(size_t size) |
|
|
int saved_errno = errno; |
|
|
int saved_errno = errno; |
|
|
|
|
|
|
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
UNPROTECT_G_POOL(); |
|
|
|
|
|
malloc_func = " in malloc():"; |
|
|
malloc_func = " in malloc():"; |
|
|
if (g_pool == NULL) { |
|
|
if (g_pool == NULL) { |
|
|
if (malloc_init() != 0) |
|
|
if (malloc_init() != 0) |
|
@ -1260,7 +1233,6 @@ malloc(size_t size) |
|
|
} |
|
|
} |
|
|
r = omalloc(size, mopts.malloc_zero); |
|
|
r = omalloc(size, mopts.malloc_zero); |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
wrterror("out of memory"); |
|
|
wrterror("out of memory"); |
|
@ -1349,7 +1321,6 @@ free(void *ptr) |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
UNPROTECT_G_POOL(); |
|
|
|
|
|
malloc_func = " in free():"; |
|
|
malloc_func = " in free():"; |
|
|
if (g_pool == NULL) { |
|
|
if (g_pool == NULL) { |
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
@ -1362,7 +1333,6 @@ free(void *ptr) |
|
|
} |
|
|
} |
|
|
ofree(ptr); |
|
|
ofree(ptr); |
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
errno = saved_errno; |
|
|
errno = saved_errno; |
|
|
} |
|
|
} |
|
@ -1466,7 +1436,6 @@ realloc(void *ptr, size_t size) |
|
|
int saved_errno = errno; |
|
|
int saved_errno = errno; |
|
|
|
|
|
|
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
UNPROTECT_G_POOL(); |
|
|
|
|
|
malloc_func = " in realloc():"; |
|
|
malloc_func = " in realloc():"; |
|
|
if (g_pool == NULL) { |
|
|
if (g_pool == NULL) { |
|
|
if (malloc_init() != 0) |
|
|
if (malloc_init() != 0) |
|
@ -1479,7 +1448,6 @@ realloc(void *ptr, size_t size) |
|
|
r = orealloc(ptr, size); |
|
|
r = orealloc(ptr, size); |
|
|
|
|
|
|
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
wrterror("out of memory"); |
|
|
wrterror("out of memory"); |
|
@ -1500,7 +1468,6 @@ calloc(size_t nmemb, size_t size) |
|
|
int saved_errno = errno; |
|
|
int saved_errno = errno; |
|
|
|
|
|
|
|
|
_MALLOC_LOCK(); |
|
|
_MALLOC_LOCK(); |
|
|
UNPROTECT_G_POOL(); |
|
|
|
|
|
malloc_func = " in calloc():"; |
|
|
malloc_func = " in calloc():"; |
|
|
if (g_pool == NULL) { |
|
|
if (g_pool == NULL) { |
|
|
if (malloc_init() != 0) |
|
|
if (malloc_init() != 0) |
|
@ -1508,7 +1475,6 @@ calloc(size_t nmemb, size_t size) |
|
|
} |
|
|
} |
|
|
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && |
|
|
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && |
|
|
nmemb > 0 && SIZE_MAX / nmemb < size) { |
|
|
nmemb > 0 && SIZE_MAX / nmemb < size) { |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (mopts.malloc_xmalloc) |
|
|
if (mopts.malloc_xmalloc) |
|
|
wrterror("out of memory"); |
|
|
wrterror("out of memory"); |
|
@ -1525,7 +1491,6 @@ calloc(size_t nmemb, size_t size) |
|
|
r = omalloc(size, 1); |
|
|
r = omalloc(size, 1); |
|
|
|
|
|
|
|
|
malloc_active--; |
|
|
malloc_active--; |
|
|
PROTECT_G_POOL(); |
|
|
|
|
|
_MALLOC_UNLOCK(); |
|
|
_MALLOC_UNLOCK(); |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
if (r == NULL && mopts.malloc_xmalloc) { |
|
|
wrterror("out of memory"); |
|
|
wrterror("out of memory"); |
|
|