diff --git a/envvar.c b/envvar.c index 77518d2..e3769a8 100644 --- a/envvar.c +++ b/envvar.c @@ -93,6 +93,26 @@ typedef struct umem_env_item { static arg_process_t umem_backend_process; #endif +#ifdef __GLIBC__ +/* replace getenv() with a specialized version that doesn't + * need to allocate memory. We can't use strlen or strcmp + * here. */ +#include +static char *safe_getenv(const char *name) +{ + int i, l; + for (l = 0; name[l]; l++) + ; + for (i = 0; __environ[i]; i++) { + if (!memcmp(__environ[i], name, l) && __environ[i][l] == '=') { + return &__environ[i][l+1]; + } + } + return NULL; +} +#define getenv(x) safe_getenv(x) +#endif + static arg_process_t umem_log_process; const char *____umem_environ_msg_options = "-- UMEM_OPTIONS --"; @@ -553,6 +573,7 @@ umem_setup_envvars(int invalid) static volatile enum { STATE_START, STATE_GETENV, + STATE_DLOPEN, STATE_DLSYM, STATE_FUNC, STATE_DONE @@ -577,6 +598,10 @@ umem_setup_envvars(int invalid) where = "during getenv(3C) calls -- " "getenv(3C) results ignored."; break; + case STATE_DLOPEN: + where = "during dlopen(3C) call -- " + "_umem_*() results ignored."; + break; case STATE_DLSYM: where = "during dlsym(3C) call -- " "_umem_*() results ignored."; @@ -623,6 +648,7 @@ umem_setup_envvars(int invalid) # define dlclose(a) 0 # define dlerror() 0 #endif + state = STATE_DLOPEN; /* get a handle to the "a.out" object */ if ((h = dlopen(0, RTLD_FIRST | RTLD_LAZY)) != NULL) { for (cur_env = umem_envvars; cur_env->env_name != NULL; diff --git a/malloc.c b/malloc.c index 45fae6e..7eec207 100644 --- a/malloc.c +++ b/malloc.c @@ -41,6 +41,10 @@ #include "misc.h" +#ifdef __GLIBC__ +# include +#endif + /* * malloc_data_t is an 8-byte structure which is located "before" the pointer * returned from {m,c,re}alloc and memalign. The first four bytes give @@ -58,8 +62,12 @@ typedef struct malloc_data { uint32_t malloc_stat; /* = UMEM_MALLOC_ENCODE(state, malloc_size) */ } malloc_data_t; +#ifdef __GLIBC__ +static void *umem_malloc_hook(size_t size_arg, const void *caller) +#else void * malloc(size_t size_arg) +#endif { #ifdef _LP64 uint32_t high_size = 0; @@ -120,6 +128,7 @@ malloc(size_t size_arg) return ((void *)ret); } +#ifndef __GLIBC__ void * calloc(size_t nelem, size_t elsize) { @@ -138,6 +147,7 @@ calloc(size_t nelem, size_t elsize) (void) memset(retval, 0, size); return (retval); } +#endif /* * memalign uses vmem_xalloc to do its work. @@ -146,8 +156,12 @@ calloc(size_t nelem, size_t elsize) * code. */ +#ifdef __GLIBC__ +static void *umem_memalign_hook(size_t size_arg, size_t align, const void *caller) +#else void * memalign(size_t align, size_t size_arg) +#endif { size_t size; uintptr_t phase; @@ -226,11 +240,13 @@ memalign(size_t align, size_t size_arg) return ((void *)ret); } +#ifndef __GLIBC__ void * valloc(size_t size) { return (memalign(pagesize, size)); } +#endif /* * process_free: @@ -376,8 +392,12 @@ process_memalign: return (1); } +#ifdef __GLIBC__ +static void umem_free_hook(void *buf, const void *caller) +#else void free(void *buf) +#endif { if (buf == NULL) return; @@ -388,8 +408,12 @@ free(void *buf) (void) process_free(buf, 1, NULL); } +#ifdef __GLIBC__ +static void *umem_realloc_hook(void *buf_arg, size_t newsize, const void *caller) +#else void * realloc(void *buf_arg, size_t newsize) +#endif { size_t oldsize; void *buf; @@ -417,8 +441,25 @@ realloc(void *buf_arg, size_t newsize) return (buf); } +#ifdef __GLIBC__ +static void __attribute__((constructor)) umem_malloc_init_hook(void) +{ + if (__malloc_hook != umem_malloc_hook) { + umem_startup(NULL, 0, 0, NULL, NULL); + __malloc_hook = umem_malloc_hook; + __free_hook = umem_free_hook; + __realloc_hook = umem_realloc_hook; + __memalign_hook = umem_memalign_hook; + } +} + +void (*__malloc_initialize_hook)(void) = umem_malloc_init_hook; + +#else void __attribute__((constructor)) __malloc_umem_init (void) { - umem_startup(NULL, 0, 0, NULL, NULL); + umem_startup(NULL, 0, 0, NULL, NULL); } +#endif +