Browse Source

reduce obvious dependency on global g_pool by moving to local aliases

ok otto
OPENBSD_5_6
tedu 10 years ago
parent
commit
705f1bf46e
1 changed files with 48 additions and 42 deletions
  1. +48
    -42
      src/lib/libc/stdlib/malloc.c

+ 48
- 42
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.169 2014/06/27 18:17:03 deraadt Exp $ */
/* $OpenBSD: malloc.c,v 1.170 2014/07/09 19:11:00 tedu Exp $ */
/* /*
* Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net>
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@ -167,7 +167,7 @@ struct chunk_info {
}; };
struct malloc_readonly { struct malloc_readonly {
struct dir_info *g_pool; /* Main bookkeeping information */
struct dir_info *malloc_pool; /* Main bookkeeping information */
int malloc_abort; /* abort() on error */ int malloc_abort; /* abort() on error */
int malloc_freenow; /* Free quickly - disable chunk rnd */ int malloc_freenow; /* Free quickly - disable chunk rnd */
int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ int malloc_freeunmap; /* mprotect free pages PROT_NONE? */
@ -181,7 +181,7 @@ struct malloc_readonly {
#ifdef MALLOC_STATS #ifdef MALLOC_STATS
int malloc_stats; /* dump statistics at end */ int malloc_stats; /* dump statistics at end */
#endif #endif
u_int32_t malloc_canary; /* Matched against ones in g_pool */
u_int32_t malloc_canary; /* Matched against ones in malloc_pool */
}; };
/* This object is mapped PROT_READ after initialisation to prevent tampering */ /* This object is mapped PROT_READ after initialisation to prevent tampering */
@ -190,7 +190,7 @@ static union {
u_char _pad[MALLOC_PAGESIZE]; u_char _pad[MALLOC_PAGESIZE];
} malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE))); } malloc_readonly __attribute__((aligned(MALLOC_PAGESIZE)));
#define mopts malloc_readonly.mopts #define mopts malloc_readonly.mopts
#define g_pool mopts.g_pool
#define getpool() mopts.malloc_pool
char *malloc_options; /* compile-time options */ char *malloc_options; /* compile-time options */
static char *malloc_func; /* current function */ static char *malloc_func; /* current function */
@ -794,7 +794,7 @@ delete(struct dir_info *d, struct region_info *ri)
if (d->regions_total & (d->regions_total - 1)) if (d->regions_total & (d->regions_total - 1))
wrterror("regions_total not 2^x", NULL); wrterror("regions_total not 2^x", NULL);
d->regions_free++; d->regions_free++;
STATS_INC(g_pool->deletes);
STATS_INC(getpool()->deletes);
i = ri - d->r; i = ri - d->r;
for (;;) { for (;;) {
@ -810,7 +810,7 @@ delete(struct dir_info *d, struct region_info *ri)
(j < i && i <= r)) (j < i && i <= r))
continue; continue;
d->r[j] = d->r[i]; d->r[j] = d->r[i];
STATS_INC(g_pool->delete_moves);
STATS_INC(getpool()->delete_moves);
break; break;
} }
@ -1046,6 +1046,7 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
static void * static void *
omalloc(size_t sz, int zero_fill, void *f) omalloc(size_t sz, int zero_fill, void *f)
{ {
struct dir_info *pool = getpool();
void *p; void *p;
size_t psz; size_t psz;
@ -1056,13 +1057,13 @@ omalloc(size_t sz, int zero_fill, void *f)
} }
sz += mopts.malloc_guard; sz += mopts.malloc_guard;
psz = PAGEROUND(sz); psz = PAGEROUND(sz);
p = map(g_pool, psz, zero_fill);
p = map(pool, psz, zero_fill);
if (p == MAP_FAILED) { if (p == MAP_FAILED) {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
if (insert(g_pool, p, sz, f)) {
unmap(g_pool, p, psz);
if (insert(pool, p, sz, f)) {
unmap(pool, p, psz);
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
@ -1070,7 +1071,7 @@ omalloc(size_t sz, int zero_fill, void *f)
if (mprotect((char *)p + psz - mopts.malloc_guard, if (mprotect((char *)p + psz - mopts.malloc_guard,
mopts.malloc_guard, PROT_NONE)) mopts.malloc_guard, PROT_NONE))
wrterror("mprotect", NULL); wrterror("mprotect", NULL);
STATS_ADD(g_pool->malloc_guarded, mopts.malloc_guard);
STATS_ADD(pool->malloc_guarded, mopts.malloc_guard);
} }
if (mopts.malloc_move && if (mopts.malloc_move &&
@ -1098,7 +1099,7 @@ omalloc(size_t sz, int zero_fill, void *f)
} else { } else {
/* takes care of SOME_JUNK */ /* takes care of SOME_JUNK */
p = malloc_bytes(g_pool, sz, f);
p = malloc_bytes(pool, sz, f);
if (zero_fill && p != NULL && sz > 0) if (zero_fill && p != NULL && sz > 0)
memset(p, 0, sz); memset(p, 0, sz);
} }
@ -1128,7 +1129,7 @@ malloc_recurse(void)
static int static int
malloc_init(void) malloc_init(void)
{ {
if (omalloc_init(&g_pool)) {
if (omalloc_init(&mopts.malloc_pool)) {
_MALLOC_UNLOCK(); _MALLOC_UNLOCK();
if (mopts.malloc_xmalloc) if (mopts.malloc_xmalloc)
wrterror("out of memory", NULL); wrterror("out of memory", NULL);
@ -1146,10 +1147,11 @@ malloc(size_t size)
_MALLOC_LOCK(); _MALLOC_LOCK();
malloc_func = "malloc():"; malloc_func = "malloc():";
if (g_pool == NULL) {
if (getpool() == NULL) {
if (malloc_init() != 0) if (malloc_init() != 0)
return NULL; return NULL;
} }
if (malloc_active++) { if (malloc_active++) {
malloc_recurse(); malloc_recurse();
return NULL; return NULL;
@ -1169,10 +1171,11 @@ malloc(size_t size)
static void static void
ofree(void *p) ofree(void *p)
{ {
struct dir_info *pool = getpool();
struct region_info *r; struct region_info *r;
size_t sz; size_t sz;
r = find(g_pool, p);
r = find(pool, p);
if (r == NULL) { if (r == NULL) {
wrterror("bogus pointer (double free?)", p); wrterror("bogus pointer (double free?)", p);
return; return;
@ -1204,15 +1207,15 @@ ofree(void *p)
PROT_READ | PROT_WRITE)) PROT_READ | PROT_WRITE))
wrterror("mprotect", NULL); wrterror("mprotect", NULL);
} }
STATS_SUB(g_pool->malloc_guarded, mopts.malloc_guard);
STATS_SUB(pool->malloc_guarded, mopts.malloc_guard);
} }
if (mopts.malloc_junk && !mopts.malloc_freeunmap) { if (mopts.malloc_junk && !mopts.malloc_freeunmap) {
size_t amt = mopts.malloc_junk == 1 ? MALLOC_MAXCHUNK : size_t amt = mopts.malloc_junk == 1 ? MALLOC_MAXCHUNK :
PAGEROUND(sz) - mopts.malloc_guard; PAGEROUND(sz) - mopts.malloc_guard;
memset(p, SOME_FREEJUNK, amt); memset(p, SOME_FREEJUNK, amt);
} }
unmap(g_pool, p, PAGEROUND(sz));
delete(g_pool, r);
unmap(pool, p, PAGEROUND(sz));
delete(pool, r);
} else { } else {
void *tmp; void *tmp;
int i; int i;
@ -1220,24 +1223,24 @@ ofree(void *p)
if (mopts.malloc_junk && sz > 0) if (mopts.malloc_junk && sz > 0)
memset(p, SOME_FREEJUNK, sz); memset(p, SOME_FREEJUNK, sz);
if (!mopts.malloc_freenow) { if (!mopts.malloc_freenow) {
if (find_chunknum(g_pool, r, p) == -1)
if (find_chunknum(pool, r, p) == -1)
return; return;
i = getrbyte(g_pool) & MALLOC_DELAYED_CHUNK_MASK;
i = getrbyte(pool) & MALLOC_DELAYED_CHUNK_MASK;
tmp = p; tmp = p;
p = g_pool->delayed_chunks[i];
p = pool->delayed_chunks[i];
if (tmp == p) { if (tmp == p) {
wrterror("double free", p); wrterror("double free", p);
return; return;
} }
g_pool->delayed_chunks[i] = tmp;
pool->delayed_chunks[i] = tmp;
} }
if (p != NULL) { if (p != NULL) {
r = find(g_pool, p);
r = find(pool, p);
if (r == NULL) { if (r == NULL) {
wrterror("bogus pointer (double free?)", p); wrterror("bogus pointer (double free?)", p);
return; return;
} }
free_bytes(g_pool, r, p);
free_bytes(pool, r, p);
} }
} }
} }
@ -1253,7 +1256,7 @@ free(void *ptr)
_MALLOC_LOCK(); _MALLOC_LOCK();
malloc_func = "free():"; malloc_func = "free():";
if (g_pool == NULL) {
if (getpool() == NULL) {
_MALLOC_UNLOCK(); _MALLOC_UNLOCK();
wrterror("free() called before allocation", NULL); wrterror("free() called before allocation", NULL);
return; return;
@ -1272,6 +1275,7 @@ free(void *ptr)
static void * static void *
orealloc(void *p, size_t newsz, void *f) orealloc(void *p, size_t newsz, void *f)
{ {
struct dir_info *pool = getpool();
struct region_info *r; struct region_info *r;
size_t oldsz, goldsz, gnewsz; size_t oldsz, goldsz, gnewsz;
void *q; void *q;
@ -1279,7 +1283,7 @@ orealloc(void *p, size_t newsz, void *f)
if (p == NULL) if (p == NULL)
return omalloc(newsz, 0, f); return omalloc(newsz, 0, f);
r = find(g_pool, p);
r = find(pool, p);
if (r == NULL) { if (r == NULL) {
wrterror("bogus pointer (double free?)", p); wrterror("bogus pointer (double free?)", p);
return NULL; return NULL;
@ -1311,20 +1315,20 @@ orealloc(void *p, size_t newsz, void *f)
void *hint = (char *)p + roldsz; void *hint = (char *)p + roldsz;
size_t needed = rnewsz - roldsz; size_t needed = rnewsz - roldsz;
STATS_INC(g_pool->cheap_realloc_tries);
zapcacheregion(g_pool, hint, needed);
STATS_INC(pool->cheap_realloc_tries);
zapcacheregion(pool, hint, needed);
q = MQUERY(hint, needed); q = MQUERY(hint, needed);
if (q == hint) if (q == hint)
q = MMAPA(hint, needed); q = MMAPA(hint, needed);
else else
q = MAP_FAILED; q = MAP_FAILED;
if (q == hint) { if (q == hint) {
STATS_ADD(g_pool->malloc_used, needed);
STATS_ADD(pool->malloc_used, needed);
if (mopts.malloc_junk == 2) if (mopts.malloc_junk == 2)
memset(q, SOME_JUNK, needed); memset(q, SOME_JUNK, needed);
r->size = newsz; r->size = newsz;
STATS_SETF(r, f); STATS_SETF(r, f);
STATS_INC(g_pool->cheap_reallocs);
STATS_INC(pool->cheap_reallocs);
return p; return p;
} else if (q != MAP_FAILED) { } else if (q != MAP_FAILED) {
if (munmap(q, needed)) if (munmap(q, needed))
@ -1342,7 +1346,7 @@ orealloc(void *p, size_t newsz, void *f)
PROT_NONE)) PROT_NONE))
wrterror("mprotect", NULL); wrterror("mprotect", NULL);
} }
unmap(g_pool, (char *)p + rnewsz, roldsz - rnewsz);
unmap(pool, (char *)p + rnewsz, roldsz - rnewsz);
r->size = gnewsz; r->size = gnewsz;
STATS_SETF(r, f); STATS_SETF(r, f);
return p; return p;
@ -1382,7 +1386,7 @@ realloc(void *ptr, size_t size)
_MALLOC_LOCK(); _MALLOC_LOCK();
malloc_func = "realloc():"; malloc_func = "realloc():";
if (g_pool == NULL) {
if (getpool() == NULL) {
if (malloc_init() != 0) if (malloc_init() != 0)
return NULL; return NULL;
} }
@ -1418,7 +1422,7 @@ calloc(size_t nmemb, size_t size)
_MALLOC_LOCK(); _MALLOC_LOCK();
malloc_func = "calloc():"; malloc_func = "calloc():";
if (g_pool == NULL) {
if (getpool() == NULL) {
if (malloc_init() != 0) if (malloc_init() != 0)
return NULL; return NULL;
} }
@ -1491,6 +1495,7 @@ mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill)
static void * static void *
omemalign(size_t alignment, size_t sz, int zero_fill, void *f) omemalign(size_t alignment, size_t sz, int zero_fill, void *f)
{ {
struct dir_info *pool = getpool();
size_t psz; size_t psz;
void *p; void *p;
@ -1512,14 +1517,14 @@ omemalign(size_t alignment, size_t sz, int zero_fill, void *f)
sz += mopts.malloc_guard; sz += mopts.malloc_guard;
psz = PAGEROUND(sz); psz = PAGEROUND(sz);
p = mapalign(g_pool, alignment, psz, zero_fill);
p = mapalign(pool, alignment, psz, zero_fill);
if (p == NULL) { if (p == NULL) {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
if (insert(g_pool, p, sz, f)) {
unmap(g_pool, p, psz);
if (insert(pool, p, sz, f)) {
unmap(pool, p, psz);
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
@ -1528,7 +1533,7 @@ omemalign(size_t alignment, size_t sz, int zero_fill, void *f)
if (mprotect((char *)p + psz - mopts.malloc_guard, if (mprotect((char *)p + psz - mopts.malloc_guard,
mopts.malloc_guard, PROT_NONE)) mopts.malloc_guard, PROT_NONE))
wrterror("mprotect", NULL); wrterror("mprotect", NULL);
STATS_ADD(g_pool->malloc_guarded, mopts.malloc_guard);
STATS_ADD(pool->malloc_guarded, mopts.malloc_guard);
} }
if (mopts.malloc_junk == 2) { if (mopts.malloc_junk == 2) {
@ -1554,7 +1559,7 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
_MALLOC_LOCK(); _MALLOC_LOCK();
malloc_func = "posix_memalign():"; malloc_func = "posix_memalign():";
if (g_pool == NULL) {
if (getpool() == NULL) {
if (malloc_init() != 0) if (malloc_init() != 0)
goto err; goto err;
} }
@ -1804,24 +1809,25 @@ malloc_dump1(int fd, struct dir_info *d)
void void
malloc_dump(int fd) malloc_dump(int fd)
{ {
struct dir_info *pool = getpool();
int i; int i;
void *p; void *p;
struct region_info *r; struct region_info *r;
int saved_errno = errno; int saved_errno = errno;
for (i = 0; i < MALLOC_DELAYED_CHUNK_MASK + 1; i++) { for (i = 0; i < MALLOC_DELAYED_CHUNK_MASK + 1; i++) {
p = g_pool->delayed_chunks[i];
p = pool->delayed_chunks[i];
if (p == NULL) if (p == NULL)
continue; continue;
r = find(g_pool, p);
r = find(pool, p);
if (r == NULL) if (r == NULL)
wrterror("bogus pointer in malloc_dump", p); wrterror("bogus pointer in malloc_dump", p);
free_bytes(g_pool, r, p);
g_pool->delayed_chunks[i] = NULL;
free_bytes(pool, r, p);
pool->delayed_chunks[i] = NULL;
} }
/* XXX leak when run multiple times */ /* XXX leak when run multiple times */
RB_INIT(&leakhead); RB_INIT(&leakhead);
malloc_dump1(fd, g_pool);
malloc_dump1(fd, pool);
errno = saved_errno; errno = saved_errno;
} }


Loading…
Cancel
Save