diff mbox

tst-rec-dlopen: Use custom malloc instead of hooks

Message ID 20160510143805.6AA4141C38D19@oldenburg.str.redhat.com
State New
Headers show

Commit Message

Florian Weimer May 10, 2016, 2:38 p.m. UTC
The hook variables are deprecated.

2016-05-10  Florian Weimer  <fweimer@redhat.com>

	Use custom malloc instead of hooks in tst-rec-dlopen.
	* dlfcn/tst-rec-dlopen.c (call_function): New variable.
	(do_test): Do not change malloc hooks.  Set and clear
	call_function as needed.
	(struct chunk_header): New type.
	(malloc_internal, malloc, free, malloc_usable_size, realloc)
	(memalign): New functions.

Comments

Florian Weimer May 19, 2016, 3:02 p.m. UTC | #1
On 05/10/2016 04:38 PM, Florian Weimer wrote:
> The hook variables are deprecated.
>
> 2016-05-10  Florian Weimer  <fweimer@redhat.com>
>
> 	Use custom malloc instead of hooks in tst-rec-dlopen.
> 	* dlfcn/tst-rec-dlopen.c (call_function): New variable.
> 	(do_test): Do not change malloc hooks.  Set and clear
> 	call_function as needed.
> 	(struct chunk_header): New type.
> 	(malloc_internal, malloc, free, malloc_usable_size, realloc)
> 	(memalign): New functions.

Ping?

   <https://sourceware.org/ml/libc-alpha/2016-05/msg00200.html>

Thanks,
Florian
Adhemerval Zanella Netto May 20, 2016, 6:53 p.m. UTC | #2
LGTM with some comments:

On 10/05/2016 11:38, Florian Weimer wrote:

> +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);
> +}
> 

Since the idea is simulate the hooks for malloc/free, do we still need to add
all this code to be used on this single test?
diff mbox

Patch

diff --git a/dlfcn/tst-rec-dlopen.c b/dlfcn/tst-rec-dlopen.c
index b2a35a7..7acc181 100644
--- a/dlfcn/tst-rec-dlopen.c
+++ b/dlfcn/tst-rec-dlopen.c
@@ -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);
+}