1 /* Memory allocation used during tests.
3 Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 #include <stdlib.h> /* for abort */
22 #include <string.h> /* for memcpy, memcmp */
26 #if GMP_LIMB_BITS == 64
27 #define PATTERN1 CNST_LIMB(0xcafebabedeadbeef)
28 #define PATTERN2 CNST_LIMB(0xabacadabaedeedab)
30 #define PATTERN1 CNST_LIMB(0xcafebabe)
31 #define PATTERN2 CNST_LIMB(0xdeadbeef)
34 /* Each block allocated is a separate malloc, for the benefit of a redzoning
35 malloc debugger during development or when bug hunting.
37 Sizes passed when reallocating or freeing are checked (the default
38 routines don't care about these).
40 Memory leaks are checked by requiring that all blocks have been freed
41 when tests_memory_end() is called. Test programs must be sure to have
42 "clear"s for all temporary variables used. */
51 struct header *tests_memory_list = NULL;
53 /* Return a pointer to a pointer to the found block (so it can be updated
56 tests_memory_find (void *ptr)
60 for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
61 if ((*hp)->ptr == ptr)
68 tests_memory_valid (void *ptr)
70 return (tests_memory_find (ptr) != NULL);
74 tests_allocate (size_t size)
78 mp_limb_t PATTERN2_var;
82 fprintf (stderr, "tests_allocate(): attempt to allocate 0 bytes\n");
86 h = (struct header *) __gmp_default_allocate (sizeof (*h));
87 h->next = tests_memory_list;
88 tests_memory_list = h;
90 rptr = __gmp_default_allocate (size + 2 * sizeof (mp_limb_t));
91 ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
93 *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
94 = PATTERN1 - ((mp_limb_t) ptr);
95 PATTERN2_var = PATTERN2 - ((mp_limb_t) ptr);
96 memcpy ((void *) ((gmp_intptr_t) ptr + size), &PATTERN2_var, sizeof (mp_limb_t));
104 tests_reallocate (void *ptr, size_t old_size, size_t new_size)
106 struct header **hp, *h;
108 mp_limb_t PATTERN2_var;
112 fprintf (stderr, "tests_reallocate(): attempt to reallocate %p to 0 bytes\n",
117 hp = tests_memory_find (ptr);
120 fprintf (stderr, "tests_reallocate(): attempt to reallocate bad pointer %p\n",
126 if (h->size != old_size)
128 fprintf (stderr, "tests_reallocate(): bad old size %lu, should be %lu\n",
129 (unsigned long) old_size, (unsigned long) h->size);
133 if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
134 != PATTERN1 - ((mp_limb_t) ptr))
136 fprintf (stderr, "in realloc: redzone clobbered before block\n");
139 PATTERN2_var = PATTERN2 - ((mp_limb_t) ptr);
140 if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
142 fprintf (stderr, "in realloc: redzone clobbered after block\n");
146 rptr = __gmp_default_reallocate ((void *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)),
147 old_size + 2 * sizeof (mp_limb_t),
148 new_size + 2 * sizeof (mp_limb_t));
149 ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
151 *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
152 = PATTERN1 - ((mp_limb_t) ptr);
153 PATTERN2_var = PATTERN2 - ((mp_limb_t) ptr);
154 memcpy ((void *) ((gmp_intptr_t) ptr + new_size), &PATTERN2_var, sizeof (mp_limb_t));
162 tests_free_find (void *ptr)
164 struct header **hp = tests_memory_find (ptr);
167 fprintf (stderr, "tests_free(): attempt to free bad pointer %p\n",
175 tests_free_nosize (void *ptr)
177 struct header **hp = tests_free_find (ptr);
178 struct header *h = *hp;
179 mp_limb_t PATTERN2_var;
181 *hp = h->next; /* unlink */
183 if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
184 != PATTERN1 - ((mp_limb_t) ptr))
186 fprintf (stderr, "in free: redzone clobbered before block\n");
189 PATTERN2_var = PATTERN2 - ((mp_limb_t) ptr);
190 if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
192 fprintf (stderr, "in free: redzone clobbered after block\n");
196 __gmp_default_free ((void *) ((gmp_intptr_t) ptr - sizeof(mp_limb_t)),
197 h->size + 2 * sizeof (mp_limb_t));
198 __gmp_default_free (h, sizeof (*h));
202 tests_free (void *ptr, size_t size)
204 struct header **hp = tests_free_find (ptr);
205 struct header *h = *hp;
209 fprintf (stderr, "tests_free(): bad size %lu, should be %lu\n",
210 (unsigned long) size, (unsigned long) h->size);
214 tests_free_nosize (ptr);
218 tests_memory_start (void)
220 mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
224 tests_memory_end (void)
226 if (tests_memory_list != NULL)
231 fprintf (stderr, "tests_memory_end(): not all memory freed\n");
234 for (h = tests_memory_list; h != NULL; h = h->next)
237 fprintf (stderr, " %u blocks remaining\n", count);