github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/testutils.c (about) 1 /* 2 3 Copyright 2013-2015, 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 "testutils.h" 21 22 /* Include it here, so we we could tweak, e.g., how MPZ_REALLOC 23 works. */ 24 #include "../mini-gmp.c" 25 26 static size_t total_alloc = 0; 27 28 /* Custom memory allocation to track memory usage, and add a small red 29 zone. 30 31 About alignment: In general, getting a block from malloc, and 32 incrementing it by sizeof(size_t), like we do here, might give a 33 pointer which is not properly aligned for all types. But the 34 largest type we allocate space for is unsigned long (mp_limb_t), 35 which shouldn't have stricter alignment requirements than 36 size_t. */ 37 38 static unsigned char block_end[8] = 39 { 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 }; 40 41 static void * 42 block_init (size_t *block, size_t size) 43 { 44 char *p; 45 *block++ = size; 46 47 p = (char *) block; 48 memcpy (p + size, block_end, sizeof(block_end)); 49 50 total_alloc += size; 51 return p; 52 } 53 54 /* Check small redzone, return pointer to malloced block. */ 55 static size_t * 56 block_check (void *p) 57 { 58 size_t *block = (size_t *) p - 1; 59 size_t size = block[0]; 60 61 if (memcmp ((char *)p + size, block_end, sizeof(block_end)) != 0) 62 { 63 fprintf (stderr, "red zone overwritten.\n"); 64 abort (); 65 } 66 total_alloc -= size; 67 return block; 68 } 69 70 static void * 71 tu_alloc (size_t size) 72 { 73 size_t *block = (size_t *) malloc (sizeof(size_t) + size + sizeof(block_end)); 74 if (!block) 75 { 76 fprintf (stderr, "Virtual memory exhausted.\n"); 77 abort (); 78 } 79 80 return block_init (block, size); 81 } 82 83 static void * 84 tu_realloc (void *p, size_t old_size, size_t new_size) 85 { 86 size_t *block = block_check (p); 87 block = (size_t *) realloc (block, sizeof(size_t) + new_size + sizeof(block_end)); 88 if (!block) 89 { 90 fprintf (stderr, "Virtual memory exhausted.\n"); 91 abort (); 92 } 93 94 return block_init (block, new_size); 95 } 96 97 static void 98 tu_free (void *p, size_t old_size) 99 { 100 free (block_check (p)); 101 } 102 103 /* Free memory allocated via mini-gmp allocation function. */ 104 void 105 testfree (void *p) 106 { 107 void (*freefunc) (void *, size_t); 108 mp_get_memory_functions (NULL, NULL, &freefunc); 109 110 freefunc (p, 0); 111 } 112 113 int 114 main (int argc, char **argv) 115 { 116 hex_random_init (); 117 118 mp_set_memory_functions (tu_alloc, tu_realloc, tu_free); 119 120 /* Currently, t-comb seems to be the only program accepting any 121 arguments. It might make sense to parse common arguments here. */ 122 testmain (argc, argv); 123 124 if (total_alloc != 0) 125 { 126 fprintf (stderr, "Memory leaked: %lu bytes.\n", 127 (unsigned long) total_alloc); 128 abort (); 129 } 130 return 0; 131 } 132 133 void 134 testhalves (int count, void (*tested_fun) (int)) 135 { 136 void (*freefunc) (void *, size_t); 137 void *(*reallocfunc) (void *, size_t, size_t); 138 void *(*allocfunc) (size_t); 139 size_t initial_alloc; 140 141 mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc); 142 initial_alloc = total_alloc; 143 (*tested_fun) (count / 2); 144 if (initial_alloc != total_alloc) 145 { 146 fprintf (stderr, "First half, memory leaked: %lu bytes.\n", 147 (unsigned long) total_alloc - initial_alloc); 148 abort (); 149 } 150 mp_set_memory_functions (NULL, NULL, NULL); 151 (*tested_fun) (count / 2); 152 mp_set_memory_functions (allocfunc, reallocfunc, freefunc); 153 } 154 155 void 156 dump (const char *label, const mpz_t x) 157 { 158 char *buf = mpz_get_str (NULL, 16, x); 159 fprintf (stderr, "%s: %s\n", label, buf); 160 testfree (buf); 161 } 162 163 void 164 mpz_set_str_or_abort (mpz_ptr z, const char *str, int base) 165 { 166 if (mpz_set_str (z, str, base) != 0) 167 { 168 fprintf (stderr, "ERROR: mpz_set_str failed\n"); 169 fprintf (stderr, " str = \"%s\"\n", str); 170 fprintf (stderr, " base = %d\n", base); 171 abort(); 172 } 173 }