diff --git a/shamalloc.c b/shamalloc.c index d93585fd7fbe6be0324f304ba8454df7240889f9..d001a0357fd15c048f8aee8769d4330adb214065 100644 --- a/shamalloc.c +++ b/shamalloc.c @@ -48,8 +48,23 @@ calloc(size_t nmemb, size_t size) { COUNTDOWN_OR_BREAK static void *(*fptr)(size_t, size_t) = NULL; - fptr = fptr ? fptr - : ((void *(*)(size_t, size_t)) dlsym(RTLD_NEXT, "calloc")); + if (fptr == NULL) { + // To bootstrap calloc we need to allow dlsym to allocate some memmory. + static uint8_t calloc_is_recusive_call = 0; + if (calloc_is_recusive_call++) { + static uint8_t bootstrap_memory[BUFFER_SIZE]; + static uint8_t * bootstrap_pointer = bootstrap_memory; + // Check that we don't bootstrap too much memmory we try to allocate too + // much memory + if (size + (bootstrap_memory - bootstrap_pointer) > BUFFER_SIZE) + abort(); + void * ret = bootstrap_pointer; + bootstrap_pointer += size + (size % 8 && 8 - size % 8); + return ret; + } + fptr = ((void *(*)(size_t, size_t)) dlsym(RTLD_NEXT, "calloc")); + calloc_is_recusive_call = 0; + } if (fptr == NULL) abort(); return (*fptr)(nmemb, size);