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