1 /* Minimal tests to verify libc_malloc_debug.so functionality.
2    Copyright (C) 2021-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <malloc.h>
22 #include <shlib-compat.h>
23 #include <libc-diag.h>
24 
25 #include <support/check.h>
26 #include <support/support.h>
27 
28 extern void (*volatile __free_hook) (void *, const void *);
29 extern void *(*volatile __malloc_hook)(size_t, const void *);
30 extern void *(*volatile __realloc_hook)(void *, size_t, const void *);
31 extern void *(*volatile __memalign_hook)(size_t, size_t, const void *);
32 
33 int hook_count, call_count;
34 
35 DIAG_PUSH_NEEDS_COMMENT;
36 DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
37 
38 void
free_called(void * mem,const void * address)39 free_called (void *mem, const void *address)
40 {
41   hook_count++;
42   __free_hook = NULL;
43   free (mem);
44   __free_hook = free_called;
45 }
46 
47 void *
malloc_called(size_t bytes,const void * address)48 malloc_called (size_t bytes, const void *address)
49 {
50   hook_count++;
51   __malloc_hook = NULL;
52   void *mem = malloc (bytes);
53   __malloc_hook = malloc_called;
54   return mem;
55 }
56 
57 void *
realloc_called(void * oldptr,size_t bytes,const void * address)58 realloc_called (void *oldptr, size_t bytes, const void *address)
59 {
60   hook_count++;
61   __realloc_hook = NULL;
62   void *mem = realloc (oldptr, bytes);
63   __realloc_hook = realloc_called;
64   return mem;
65 }
66 
67 void *
calloc_called(size_t n,size_t size,const void * address)68 calloc_called (size_t n, size_t size, const void *address)
69 {
70   hook_count++;
71   __malloc_hook = NULL;
72   void *mem = calloc (n, size);
73   __malloc_hook = malloc_called;
74   return mem;
75 }
76 
77 void *
memalign_called(size_t align,size_t size,const void * address)78 memalign_called (size_t align, size_t size, const void *address)
79 {
80   hook_count++;
81   __memalign_hook = NULL;
82   void *mem = memalign (align, size);
83   __memalign_hook = memalign_called;
84   return mem;
85 }
86 
initialize_hooks(void)87 static void initialize_hooks (void)
88 {
89   __free_hook = free_called;
90   __malloc_hook = malloc_called;
91   __realloc_hook = realloc_called;
92   __memalign_hook = memalign_called;
93 }
94 void (*__malloc_initialize_hook) (void) = initialize_hooks;
95 compat_symbol_reference (libc, __malloc_initialize_hook,
96 			 __malloc_initialize_hook, GLIBC_2_0);
97 compat_symbol_reference (libc, __free_hook,
98 			 __free_hook, GLIBC_2_0);
99 compat_symbol_reference (libc, __malloc_hook,
100 			 __malloc_hook, GLIBC_2_0);
101 compat_symbol_reference (libc, __realloc_hook,
102 			 __realloc_hook, GLIBC_2_0);
103 compat_symbol_reference (libc, __memalign_hook,
104 			 __memalign_hook, GLIBC_2_0);
105 
106 DIAG_POP_NEEDS_COMMENT;
107 
108 static int
do_test(void)109 do_test (void)
110 {
111   void *p;
112   p = malloc (0);
113   TEST_VERIFY_EXIT (p != NULL);
114   call_count++;
115 
116   p = realloc (p, 0);
117   TEST_VERIFY_EXIT (p == NULL);
118   call_count++;
119 
120   p = calloc (512, 1);
121   TEST_VERIFY_EXIT (p != NULL);
122   call_count++;
123 
124   free (p);
125   call_count++;
126 
127   p = memalign (0x100, 0x100);
128   TEST_VERIFY_EXIT (p != NULL);
129   call_count++;
130 
131   free (p);
132   call_count++;
133 
134   printf ("call_count: %d, hook_count: %d\n", call_count, hook_count);
135 
136 #ifdef HOOKS_ENABLED
137   TEST_VERIFY_EXIT (call_count == hook_count);
138 #else
139   TEST_VERIFY_EXIT (hook_count == 0);
140 #endif
141 
142   exit (0);
143 }
144 
145 #include <support/test-driver.c>
146