@@ -18,8 +18,10 @@
#include <stdio.h>
#include <stdlib.h>
-#include <malloc.h>
#include <dlfcn.h>
+#include <stdbool.h>
+#include <stdalign.h>
+#include <sys/mman.h>
#define DSO "moddummy1.so"
#define FUNC "dummy1"
@@ -81,29 +83,13 @@ call_func (const char *dso_name, const char *func_name)
}
-/* Empty hook that does nothing. */
-void *
-custom_malloc_hook (size_t size, const void *caller)
-{
- void *result;
- /* Restore old hooks. */
- __malloc_hook = old_malloc_hook;
- /* First call a function in another library via dlopen. */
- call_func (DSO1, FUNC1);
- /* Called recursively. */
- result = malloc (size);
- /* Restore new hooks. */
- __malloc_hook = custom_malloc_hook;
- return result;
-}
+/* If true, call another function from malloc. */
+static bool call_function;
static int
do_test (void)
{
- /* Save old hook. */
- old_malloc_hook = __malloc_hook;
- /* Install new hook. */
- __malloc_hook = custom_malloc_hook;
+ call_function = true;
/* Bug 17702 fixes two things:
* A recursive dlopen unmapping the ld.so.cache.
@@ -116,8 +102,7 @@ do_test (void)
will abort because of the assert described in detail below. */
call_func (DSO, FUNC);
- /* Restore old hook. */
- __malloc_hook = old_malloc_hook;
+ call_function = false;
/* The function dummy2() is called by the malloc hook. Check to
see that it was called. This ensures the second recursive
@@ -141,3 +126,89 @@ do_test (void)
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+
+/* The rest of this file contains a minimal malloc implementation. */
+
+/* Chunk header for our minimal malloc implementation. */
+struct __attribute__ ((aligned (__alignof__ (max_align_t)))) chunk_header
+{
+ size_t chunk_size;
+};
+
+static void *
+malloc_internal (size_t size)
+{
+ size_t total_size = size + sizeof (struct chunk_header);
+ if (total_size < size)
+ return NULL;
+ void *result = mmap (NULL, total_size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (result == MAP_FAILED)
+ return NULL;
+ return result + sizeof (struct chunk_header);
+}
+
+void *
+malloc (size_t size)
+{
+ /* First call a function in another library via dlopen. */
+ if (call_function)
+ {
+ call_function = false;
+ call_func (DSO1, FUNC1);
+ call_function = true;
+ }
+ return malloc_internal (size);
+}
+
+void
+free (void *ptr)
+{
+ /* Do nothing. */
+}
+
+size_t
+malloc_usable_size (void *ptr)
+{
+ struct chunk_header *chunk = ptr - sizeof (struct chunk_header);
+ return chunk->chunk_size;
+}
+
+void *
+realloc (void *ptr, size_t size)
+{
+ size_t old_size = malloc_usable_size (ptr);
+ size_t to_copy;
+ if (old_size < size)
+ to_copy = old_size;
+ else
+ to_copy = size;
+ void *newptr = malloc_internal (size);
+ if (newptr == NULL)
+ return NULL;
+ memcpy (newptr, ptr, to_copy);
+ return newptr;
+}
+
+void *
+memalign (size_t alignment, size_t size)
+{
+ if (alignment > __alignof__ (struct chunk_header))
+ {
+ if (size < size + __alignof__ (struct chunk_header))
+ return NULL;
+ void *result = malloc_internal
+ (size + __alignof__ (struct chunk_header));
+ if (result == NULL)
+ return NULL;
+ uintptr_t bits = (uintptr_t) result;
+ /* Round up to the next multiple of he alignment. */
+ bits += __alignof__ (struct chunk_header) - 1;
+ bits &= ~(__alignof__ (struct chunk_header) - 1);
+ result = (void *) bits;
+ struct chunk_header *chunk = result - sizeof (struct chunk_header);
+ chunk->chunk_size = size;
+ return result;
+ }
+ return malloc_internal (size);
+}