1*fae548d3Szrj /* memory allocation routines with error checking.
2*fae548d3Szrj    Copyright (C) 1989-2020 Free Software Foundation, Inc.
3*fae548d3Szrj 
4*fae548d3Szrj This file is part of the libiberty library.
5*fae548d3Szrj Libiberty is free software; you can redistribute it and/or
6*fae548d3Szrj modify it under the terms of the GNU Library General Public
7*fae548d3Szrj License as published by the Free Software Foundation; either
8*fae548d3Szrj version 2 of the License, or (at your option) any later version.
9*fae548d3Szrj 
10*fae548d3Szrj Libiberty is distributed in the hope that it will be useful,
11*fae548d3Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
12*fae548d3Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*fae548d3Szrj Library General Public License for more details.
14*fae548d3Szrj 
15*fae548d3Szrj You should have received a copy of the GNU Library General Public
16*fae548d3Szrj License along with libiberty; see the file COPYING.LIB.  If
17*fae548d3Szrj not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
18*fae548d3Szrj Boston, MA 02110-1301, USA.  */
19*fae548d3Szrj 
20*fae548d3Szrj /*
21*fae548d3Szrj 
22*fae548d3Szrj @deftypefn Replacement void* xmalloc (size_t)
23*fae548d3Szrj 
24*fae548d3Szrj Allocate memory without fail.  If @code{malloc} fails, this will print
25*fae548d3Szrj a message to @code{stderr} (using the name set by
26*fae548d3Szrj @code{xmalloc_set_program_name},
27*fae548d3Szrj if any) and then call @code{xexit}.  Note that it is therefore safe for
28*fae548d3Szrj a program to contain @code{#define malloc xmalloc} in its source.
29*fae548d3Szrj 
30*fae548d3Szrj @end deftypefn
31*fae548d3Szrj 
32*fae548d3Szrj @deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
33*fae548d3Szrj Reallocate memory without fail.  This routine functions like @code{realloc},
34*fae548d3Szrj but will behave the same as @code{xmalloc} if memory cannot be found.
35*fae548d3Szrj 
36*fae548d3Szrj @end deftypefn
37*fae548d3Szrj 
38*fae548d3Szrj @deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
39*fae548d3Szrj 
40*fae548d3Szrj Allocate memory without fail, and set it to zero.  This routine functions
41*fae548d3Szrj like @code{calloc}, but will behave the same as @code{xmalloc} if memory
42*fae548d3Szrj cannot be found.
43*fae548d3Szrj 
44*fae548d3Szrj @end deftypefn
45*fae548d3Szrj 
46*fae548d3Szrj @deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
47*fae548d3Szrj 
48*fae548d3Szrj You can use this to set the name of the program used by
49*fae548d3Szrj @code{xmalloc_failed} when printing a failure message.
50*fae548d3Szrj 
51*fae548d3Szrj @end deftypefn
52*fae548d3Szrj 
53*fae548d3Szrj @deftypefn Replacement void xmalloc_failed (size_t)
54*fae548d3Szrj 
55*fae548d3Szrj This function is not meant to be called by client code, and is listed
56*fae548d3Szrj here for completeness only.  If any of the allocation routines fail, this
57*fae548d3Szrj function will be called to print an error message and terminate execution.
58*fae548d3Szrj 
59*fae548d3Szrj @end deftypefn
60*fae548d3Szrj 
61*fae548d3Szrj */
62*fae548d3Szrj 
63*fae548d3Szrj #ifdef HAVE_CONFIG_H
64*fae548d3Szrj #include "config.h"
65*fae548d3Szrj #endif
66*fae548d3Szrj #include "ansidecl.h"
67*fae548d3Szrj #include "libiberty.h"
68*fae548d3Szrj #include "environ.h"
69*fae548d3Szrj 
70*fae548d3Szrj #include <stdio.h>
71*fae548d3Szrj 
72*fae548d3Szrj #include <stddef.h>
73*fae548d3Szrj 
74*fae548d3Szrj #if VMS
75*fae548d3Szrj #include <stdlib.h>
76*fae548d3Szrj #include <unixlib.h>
77*fae548d3Szrj #else
78*fae548d3Szrj /* For systems with larger pointers than ints, these must be declared.  */
79*fae548d3Szrj #  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
80*fae548d3Szrj       && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
81*fae548d3Szrj #    include <stdlib.h>
82*fae548d3Szrj #    include <unistd.h>
83*fae548d3Szrj #  else
84*fae548d3Szrj #    ifdef __cplusplus
85*fae548d3Szrj extern "C" {
86*fae548d3Szrj #    endif /* __cplusplus */
87*fae548d3Szrj void *malloc (size_t);
88*fae548d3Szrj void *realloc (void *, size_t);
89*fae548d3Szrj void *calloc (size_t, size_t);
90*fae548d3Szrj void *sbrk (ptrdiff_t);
91*fae548d3Szrj #    ifdef __cplusplus
92*fae548d3Szrj }
93*fae548d3Szrj #    endif /* __cplusplus */
94*fae548d3Szrj #  endif /* HAVE_STDLIB_H ...  */
95*fae548d3Szrj #endif /* VMS */
96*fae548d3Szrj 
97*fae548d3Szrj /* The program name if set.  */
98*fae548d3Szrj static const char *name = "";
99*fae548d3Szrj 
100*fae548d3Szrj #ifdef HAVE_SBRK
101*fae548d3Szrj /* The initial sbrk, set when the program name is set. Not used for win32
102*fae548d3Szrj    ports other than cygwin32.  */
103*fae548d3Szrj static char *first_break = NULL;
104*fae548d3Szrj #endif /* HAVE_SBRK */
105*fae548d3Szrj 
106*fae548d3Szrj void
xmalloc_set_program_name(const char * s)107*fae548d3Szrj xmalloc_set_program_name (const char *s)
108*fae548d3Szrj {
109*fae548d3Szrj   name = s;
110*fae548d3Szrj #ifdef HAVE_SBRK
111*fae548d3Szrj   /* Win32 ports other than cygwin32 don't have brk() */
112*fae548d3Szrj   if (first_break == NULL)
113*fae548d3Szrj     first_break = (char *) sbrk (0);
114*fae548d3Szrj #endif /* HAVE_SBRK */
115*fae548d3Szrj }
116*fae548d3Szrj 
117*fae548d3Szrj void
xmalloc_failed(size_t size)118*fae548d3Szrj xmalloc_failed (size_t size)
119*fae548d3Szrj {
120*fae548d3Szrj #ifdef HAVE_SBRK
121*fae548d3Szrj   size_t allocated;
122*fae548d3Szrj 
123*fae548d3Szrj   if (first_break != NULL)
124*fae548d3Szrj     allocated = (char *) sbrk (0) - first_break;
125*fae548d3Szrj   else
126*fae548d3Szrj     allocated = (char *) sbrk (0) - (char *) &environ;
127*fae548d3Szrj   fprintf (stderr,
128*fae548d3Szrj 	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
129*fae548d3Szrj 	   name, *name ? ": " : "",
130*fae548d3Szrj 	   (unsigned long) size, (unsigned long) allocated);
131*fae548d3Szrj #else /* HAVE_SBRK */
132*fae548d3Szrj   fprintf (stderr,
133*fae548d3Szrj 	   "\n%s%sout of memory allocating %lu bytes\n",
134*fae548d3Szrj 	   name, *name ? ": " : "",
135*fae548d3Szrj 	   (unsigned long) size);
136*fae548d3Szrj #endif /* HAVE_SBRK */
137*fae548d3Szrj   xexit (1);
138*fae548d3Szrj }
139*fae548d3Szrj 
140*fae548d3Szrj PTR
xmalloc(size_t size)141*fae548d3Szrj xmalloc (size_t size)
142*fae548d3Szrj {
143*fae548d3Szrj   PTR newmem;
144*fae548d3Szrj 
145*fae548d3Szrj   if (size == 0)
146*fae548d3Szrj     size = 1;
147*fae548d3Szrj   newmem = malloc (size);
148*fae548d3Szrj   if (!newmem)
149*fae548d3Szrj     xmalloc_failed (size);
150*fae548d3Szrj 
151*fae548d3Szrj   return (newmem);
152*fae548d3Szrj }
153*fae548d3Szrj 
154*fae548d3Szrj PTR
xcalloc(size_t nelem,size_t elsize)155*fae548d3Szrj xcalloc (size_t nelem, size_t elsize)
156*fae548d3Szrj {
157*fae548d3Szrj   PTR newmem;
158*fae548d3Szrj 
159*fae548d3Szrj   if (nelem == 0 || elsize == 0)
160*fae548d3Szrj     nelem = elsize = 1;
161*fae548d3Szrj 
162*fae548d3Szrj   newmem = calloc (nelem, elsize);
163*fae548d3Szrj   if (!newmem)
164*fae548d3Szrj     xmalloc_failed (nelem * elsize);
165*fae548d3Szrj 
166*fae548d3Szrj   return (newmem);
167*fae548d3Szrj }
168*fae548d3Szrj 
169*fae548d3Szrj PTR
xrealloc(PTR oldmem,size_t size)170*fae548d3Szrj xrealloc (PTR oldmem, size_t size)
171*fae548d3Szrj {
172*fae548d3Szrj   PTR newmem;
173*fae548d3Szrj 
174*fae548d3Szrj   if (size == 0)
175*fae548d3Szrj     size = 1;
176*fae548d3Szrj   if (!oldmem)
177*fae548d3Szrj     newmem = malloc (size);
178*fae548d3Szrj   else
179*fae548d3Szrj     newmem = realloc (oldmem, size);
180*fae548d3Szrj   if (!newmem)
181*fae548d3Szrj     xmalloc_failed (size);
182*fae548d3Szrj 
183*fae548d3Szrj   return (newmem);
184*fae548d3Szrj }
185