1*86d7f5d3SJohn Marino /* Memory allocation routines.
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino Copyright 1991, 1993, 1994, 2000, 2001, 2002 Free Software Foundation, Inc.
4*86d7f5d3SJohn Marino
5*86d7f5d3SJohn Marino This file is part of the GNU MP Library.
6*86d7f5d3SJohn Marino
7*86d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
8*86d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
9*86d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
10*86d7f5d3SJohn Marino option) any later version.
11*86d7f5d3SJohn Marino
12*86d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
13*86d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*86d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15*86d7f5d3SJohn Marino License for more details.
16*86d7f5d3SJohn Marino
17*86d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
18*86d7f5d3SJohn Marino along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
19*86d7f5d3SJohn Marino
20*86d7f5d3SJohn Marino #include <stdio.h>
21*86d7f5d3SJohn Marino #include <stdlib.h> /* for malloc, realloc, free */
22*86d7f5d3SJohn Marino
23*86d7f5d3SJohn Marino #include "gmp.h"
24*86d7f5d3SJohn Marino #include "gmp-impl.h"
25*86d7f5d3SJohn Marino
26*86d7f5d3SJohn Marino
27*86d7f5d3SJohn Marino void * (*__gmp_allocate_func) __GMP_PROTO ((size_t)) = __gmp_default_allocate;
28*86d7f5d3SJohn Marino void * (*__gmp_reallocate_func) __GMP_PROTO ((void *, size_t, size_t))
29*86d7f5d3SJohn Marino = __gmp_default_reallocate;
30*86d7f5d3SJohn Marino void (*__gmp_free_func) __GMP_PROTO ((void *, size_t)) = __gmp_default_free;
31*86d7f5d3SJohn Marino
32*86d7f5d3SJohn Marino
33*86d7f5d3SJohn Marino /* Default allocation functions. In case of failure to allocate/reallocate
34*86d7f5d3SJohn Marino an error message is written to stderr and the program aborts. */
35*86d7f5d3SJohn Marino
36*86d7f5d3SJohn Marino void *
__gmp_default_allocate(size_t size)37*86d7f5d3SJohn Marino __gmp_default_allocate (size_t size)
38*86d7f5d3SJohn Marino {
39*86d7f5d3SJohn Marino void *ret;
40*86d7f5d3SJohn Marino #ifdef DEBUG
41*86d7f5d3SJohn Marino size_t req_size = size;
42*86d7f5d3SJohn Marino size += 2 * BYTES_PER_MP_LIMB;
43*86d7f5d3SJohn Marino #endif
44*86d7f5d3SJohn Marino ret = malloc (size);
45*86d7f5d3SJohn Marino if (ret == 0)
46*86d7f5d3SJohn Marino {
47*86d7f5d3SJohn Marino fprintf (stderr, "GNU MP: Cannot allocate memory (size=%lu)\n", (long) size);
48*86d7f5d3SJohn Marino abort ();
49*86d7f5d3SJohn Marino }
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino #ifdef DEBUG
52*86d7f5d3SJohn Marino {
53*86d7f5d3SJohn Marino mp_ptr p = ret;
54*86d7f5d3SJohn Marino p++;
55*86d7f5d3SJohn Marino p[-1] = (0xdeadbeef << 31) + 0xdeafdeed;
56*86d7f5d3SJohn Marino if (req_size % BYTES_PER_MP_LIMB == 0)
57*86d7f5d3SJohn Marino p[req_size / BYTES_PER_MP_LIMB] = ~((0xdeadbeef << 31) + 0xdeafdeed);
58*86d7f5d3SJohn Marino ret = p;
59*86d7f5d3SJohn Marino }
60*86d7f5d3SJohn Marino #endif
61*86d7f5d3SJohn Marino return ret;
62*86d7f5d3SJohn Marino }
63*86d7f5d3SJohn Marino
64*86d7f5d3SJohn Marino void *
__gmp_default_reallocate(void * oldptr,size_t old_size,size_t new_size)65*86d7f5d3SJohn Marino __gmp_default_reallocate (void *oldptr, size_t old_size, size_t new_size)
66*86d7f5d3SJohn Marino {
67*86d7f5d3SJohn Marino void *ret;
68*86d7f5d3SJohn Marino
69*86d7f5d3SJohn Marino #ifdef DEBUG
70*86d7f5d3SJohn Marino size_t req_size = new_size;
71*86d7f5d3SJohn Marino
72*86d7f5d3SJohn Marino if (old_size != 0)
73*86d7f5d3SJohn Marino {
74*86d7f5d3SJohn Marino mp_ptr p = oldptr;
75*86d7f5d3SJohn Marino if (p[-1] != (0xdeadbeef << 31) + 0xdeafdeed)
76*86d7f5d3SJohn Marino {
77*86d7f5d3SJohn Marino fprintf (stderr, "gmp: (realloc) data clobbered before allocation block\n");
78*86d7f5d3SJohn Marino abort ();
79*86d7f5d3SJohn Marino }
80*86d7f5d3SJohn Marino if (old_size % BYTES_PER_MP_LIMB == 0)
81*86d7f5d3SJohn Marino if (p[old_size / BYTES_PER_MP_LIMB] != ~((0xdeadbeef << 31) + 0xdeafdeed))
82*86d7f5d3SJohn Marino {
83*86d7f5d3SJohn Marino fprintf (stderr, "gmp: (realloc) data clobbered after allocation block\n");
84*86d7f5d3SJohn Marino abort ();
85*86d7f5d3SJohn Marino }
86*86d7f5d3SJohn Marino oldptr = p - 1;
87*86d7f5d3SJohn Marino }
88*86d7f5d3SJohn Marino
89*86d7f5d3SJohn Marino new_size += 2 * BYTES_PER_MP_LIMB;
90*86d7f5d3SJohn Marino #endif
91*86d7f5d3SJohn Marino
92*86d7f5d3SJohn Marino ret = realloc (oldptr, new_size);
93*86d7f5d3SJohn Marino if (ret == 0)
94*86d7f5d3SJohn Marino {
95*86d7f5d3SJohn Marino fprintf (stderr, "GNU MP: Cannot reallocate memory (old_size=%lu new_size=%lu)\n", (long) old_size, (long) new_size);
96*86d7f5d3SJohn Marino abort ();
97*86d7f5d3SJohn Marino }
98*86d7f5d3SJohn Marino
99*86d7f5d3SJohn Marino #ifdef DEBUG
100*86d7f5d3SJohn Marino {
101*86d7f5d3SJohn Marino mp_ptr p = ret;
102*86d7f5d3SJohn Marino p++;
103*86d7f5d3SJohn Marino p[-1] = (0xdeadbeef << 31) + 0xdeafdeed;
104*86d7f5d3SJohn Marino if (req_size % BYTES_PER_MP_LIMB == 0)
105*86d7f5d3SJohn Marino p[req_size / BYTES_PER_MP_LIMB] = ~((0xdeadbeef << 31) + 0xdeafdeed);
106*86d7f5d3SJohn Marino ret = p;
107*86d7f5d3SJohn Marino }
108*86d7f5d3SJohn Marino #endif
109*86d7f5d3SJohn Marino return ret;
110*86d7f5d3SJohn Marino }
111*86d7f5d3SJohn Marino
112*86d7f5d3SJohn Marino void
__gmp_default_free(void * blk_ptr,size_t blk_size)113*86d7f5d3SJohn Marino __gmp_default_free (void *blk_ptr, size_t blk_size)
114*86d7f5d3SJohn Marino {
115*86d7f5d3SJohn Marino #ifdef DEBUG
116*86d7f5d3SJohn Marino {
117*86d7f5d3SJohn Marino mp_ptr p = blk_ptr;
118*86d7f5d3SJohn Marino if (blk_size != 0)
119*86d7f5d3SJohn Marino {
120*86d7f5d3SJohn Marino if (p[-1] != (0xdeadbeef << 31) + 0xdeafdeed)
121*86d7f5d3SJohn Marino {
122*86d7f5d3SJohn Marino fprintf (stderr, "gmp: (free) data clobbered before allocation block\n");
123*86d7f5d3SJohn Marino abort ();
124*86d7f5d3SJohn Marino }
125*86d7f5d3SJohn Marino if (blk_size % BYTES_PER_MP_LIMB == 0)
126*86d7f5d3SJohn Marino if (p[blk_size / BYTES_PER_MP_LIMB] != ~((0xdeadbeef << 31) + 0xdeafdeed))
127*86d7f5d3SJohn Marino {
128*86d7f5d3SJohn Marino fprintf (stderr, "gmp: (free) data clobbered after allocation block\n");
129*86d7f5d3SJohn Marino abort ();
130*86d7f5d3SJohn Marino }
131*86d7f5d3SJohn Marino }
132*86d7f5d3SJohn Marino blk_ptr = p - 1;
133*86d7f5d3SJohn Marino }
134*86d7f5d3SJohn Marino #endif
135*86d7f5d3SJohn Marino free (blk_ptr);
136*86d7f5d3SJohn Marino }
137