github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/memory.c (about) 1 /* Memory allocation used during tests. 2 3 Copyright 2001, 2002, 2007, 2013 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> /* for abort */ 22 #include <string.h> /* for memcpy, memcmp */ 23 #include "gmp.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 #if GMP_LIMB_BITS == 64 28 #define PATTERN1 CNST_LIMB(0xcafebabedeadbeef) 29 #define PATTERN2 CNST_LIMB(0xabacadabaedeedab) 30 #else 31 #define PATTERN1 CNST_LIMB(0xcafebabe) 32 #define PATTERN2 CNST_LIMB(0xdeadbeef) 33 #endif 34 35 #if HAVE_INTPTR_T 36 #define PTRLIMB(p) ((mp_limb_t) (intptr_t) p) 37 #else 38 #define PTRLIMB(p) ((mp_limb_t) (size_t) p) 39 #endif 40 41 /* Each block allocated is a separate malloc, for the benefit of a redzoning 42 malloc debugger during development or when bug hunting. 43 44 Sizes passed when reallocating or freeing are checked (the default 45 routines don't care about these). 46 47 Memory leaks are checked by requiring that all blocks have been freed 48 when tests_memory_end() is called. Test programs must be sure to have 49 "clear"s for all temporary variables used. */ 50 51 52 struct header { 53 void *ptr; 54 size_t size; 55 struct header *next; 56 }; 57 58 struct header *tests_memory_list = NULL; 59 60 /* Return a pointer to a pointer to the found block (so it can be updated 61 when unlinking). */ 62 struct header ** 63 tests_memory_find (void *ptr) 64 { 65 struct header **hp; 66 67 for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next)) 68 if ((*hp)->ptr == ptr) 69 return hp; 70 71 return NULL; 72 } 73 74 int 75 tests_memory_valid (void *ptr) 76 { 77 return (tests_memory_find (ptr) != NULL); 78 } 79 80 void * 81 tests_allocate (size_t size) 82 { 83 struct header *h; 84 void *rptr, *ptr; 85 mp_limb_t PATTERN2_var; 86 87 if (size == 0) 88 { 89 fprintf (stderr, "tests_allocate(): attempt to allocate 0 bytes\n"); 90 abort (); 91 } 92 93 h = (struct header *) __gmp_default_allocate (sizeof (*h)); 94 h->next = tests_memory_list; 95 tests_memory_list = h; 96 97 rptr = __gmp_default_allocate (size + 2 * sizeof (mp_limb_t)); 98 ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t)); 99 100 *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t))) 101 = PATTERN1 - PTRLIMB (ptr); 102 PATTERN2_var = PATTERN2 - PTRLIMB (ptr); 103 memcpy ((void *) ((gmp_intptr_t) ptr + size), &PATTERN2_var, sizeof (mp_limb_t)); 104 105 h->size = size; 106 h->ptr = ptr; 107 return h->ptr; 108 } 109 110 void * 111 tests_reallocate (void *ptr, size_t old_size, size_t new_size) 112 { 113 struct header **hp, *h; 114 void *rptr; 115 mp_limb_t PATTERN2_var; 116 117 if (new_size == 0) 118 { 119 fprintf (stderr, "tests_reallocate(): attempt to reallocate %p to 0 bytes\n", 120 ptr); 121 abort (); 122 } 123 124 hp = tests_memory_find (ptr); 125 if (hp == NULL) 126 { 127 fprintf (stderr, "tests_reallocate(): attempt to reallocate bad pointer %p\n", 128 ptr); 129 abort (); 130 } 131 h = *hp; 132 133 if (h->size != old_size) 134 { 135 fprintf (stderr, "tests_reallocate(): bad old size %lu, should be %lu\n", 136 (unsigned long) old_size, (unsigned long) h->size); 137 abort (); 138 } 139 140 if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t))) 141 != PATTERN1 - PTRLIMB (ptr)) 142 { 143 fprintf (stderr, "in realloc: redzone clobbered before block\n"); 144 abort (); 145 } 146 PATTERN2_var = PATTERN2 - PTRLIMB (ptr); 147 if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t))) 148 { 149 fprintf (stderr, "in realloc: redzone clobbered after block\n"); 150 abort (); 151 } 152 153 rptr = __gmp_default_reallocate ((void *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)), 154 old_size + 2 * sizeof (mp_limb_t), 155 new_size + 2 * sizeof (mp_limb_t)); 156 ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t)); 157 158 *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t))) 159 = PATTERN1 - PTRLIMB (ptr); 160 PATTERN2_var = PATTERN2 - PTRLIMB (ptr); 161 memcpy ((void *) ((gmp_intptr_t) ptr + new_size), &PATTERN2_var, sizeof (mp_limb_t)); 162 163 h->size = new_size; 164 h->ptr = ptr; 165 return h->ptr; 166 } 167 168 struct header ** 169 tests_free_find (void *ptr) 170 { 171 struct header **hp = tests_memory_find (ptr); 172 if (hp == NULL) 173 { 174 fprintf (stderr, "tests_free(): attempt to free bad pointer %p\n", 175 ptr); 176 abort (); 177 } 178 return hp; 179 } 180 181 void 182 tests_free_nosize (void *ptr) 183 { 184 struct header **hp = tests_free_find (ptr); 185 struct header *h = *hp; 186 mp_limb_t PATTERN2_var; 187 188 *hp = h->next; /* unlink */ 189 190 if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t))) 191 != PATTERN1 - PTRLIMB (ptr)) 192 { 193 fprintf (stderr, "in free: redzone clobbered before block\n"); 194 abort (); 195 } 196 PATTERN2_var = PATTERN2 - PTRLIMB (ptr); 197 if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t))) 198 { 199 fprintf (stderr, "in free: redzone clobbered after block\n"); 200 abort (); 201 } 202 203 __gmp_default_free ((void *) ((gmp_intptr_t) ptr - sizeof(mp_limb_t)), 204 h->size + 2 * sizeof (mp_limb_t)); 205 __gmp_default_free (h, sizeof (*h)); 206 } 207 208 void 209 tests_free (void *ptr, size_t size) 210 { 211 struct header **hp = tests_free_find (ptr); 212 struct header *h = *hp; 213 214 if (h->size != size) 215 { 216 fprintf (stderr, "tests_free(): bad size %lu, should be %lu\n", 217 (unsigned long) size, (unsigned long) h->size); 218 abort (); 219 } 220 221 tests_free_nosize (ptr); 222 } 223 224 void 225 tests_memory_start (void) 226 { 227 mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free); 228 } 229 230 void 231 tests_memory_end (void) 232 { 233 if (tests_memory_list != NULL) 234 { 235 struct header *h; 236 unsigned count; 237 238 fprintf (stderr, "tests_memory_end(): not all memory freed\n"); 239 240 count = 0; 241 for (h = tests_memory_list; h != NULL; h = h->next) 242 count++; 243 244 fprintf (stderr, " %u blocks remaining\n", count); 245 abort (); 246 } 247 }