summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwez <wez@1665872d-e22b-0410-9e5d-a57ad4215e6d>2007-03-18 01:37:02 +0000
committerwez <wez@1665872d-e22b-0410-9e5d-a57ad4215e6d>2007-03-18 01:37:02 +0000
commit3112674b98313e57c4ddecdeef1931fc4b926bcb (patch)
tree141dff9e814cb5d930188f2ecc61aed3848fbc9b
parent433cabfe01b15361c8d5446cb1b623e65113ed0b (diff)
downloadportableumem-3112674b98313e57c4ddecdeef1931fc4b926bcb.tar.gz
be more libc friendly when replacing malloc().
Use our own getenv() on glibc platforms, as the glibc implementation calls malloc() internally. This allows the use of env vars to enable debugging modes in the app. git-svn-id: https://labs.omniti.com/portableumem/trunk@36 1665872d-e22b-0410-9e5d-a57ad4215e6d
-rw-r--r--envvar.c26
-rw-r--r--malloc.c43
2 files changed, 68 insertions, 1 deletions
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 <unistd.h>
+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 <malloc.h>
+#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
+