xref: /netbsd-src/external/gpl3/gdb/dist/libiberty/xmalloc.c (revision 5173eb0a33e5d83890ba976253e703be4c92557c)
198b9484cSchristos /* memory allocation routines with error checking.
2*5173eb0aSchristos    Copyright (C) 1989-2024 Free Software Foundation, Inc.
398b9484cSchristos 
498b9484cSchristos This file is part of the libiberty library.
598b9484cSchristos Libiberty is free software; you can redistribute it and/or
698b9484cSchristos modify it under the terms of the GNU Library General Public
798b9484cSchristos License as published by the Free Software Foundation; either
898b9484cSchristos version 2 of the License, or (at your option) any later version.
998b9484cSchristos 
1098b9484cSchristos Libiberty is distributed in the hope that it will be useful,
1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1298b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1398b9484cSchristos Library General Public License for more details.
1498b9484cSchristos 
1598b9484cSchristos You should have received a copy of the GNU Library General Public
1698b9484cSchristos License along with libiberty; see the file COPYING.LIB.  If
1798b9484cSchristos not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
1898b9484cSchristos Boston, MA 02110-1301, USA.  */
1998b9484cSchristos 
2098b9484cSchristos /*
2198b9484cSchristos 
2298b9484cSchristos @deftypefn Replacement void* xmalloc (size_t)
2398b9484cSchristos 
2498b9484cSchristos Allocate memory without fail.  If @code{malloc} fails, this will print
2598b9484cSchristos a message to @code{stderr} (using the name set by
2698b9484cSchristos @code{xmalloc_set_program_name},
2798b9484cSchristos if any) and then call @code{xexit}.  Note that it is therefore safe for
2898b9484cSchristos a program to contain @code{#define malloc xmalloc} in its source.
2998b9484cSchristos 
3098b9484cSchristos @end deftypefn
3198b9484cSchristos 
3298b9484cSchristos @deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
3398b9484cSchristos Reallocate memory without fail.  This routine functions like @code{realloc},
3498b9484cSchristos but will behave the same as @code{xmalloc} if memory cannot be found.
3598b9484cSchristos 
3698b9484cSchristos @end deftypefn
3798b9484cSchristos 
3898b9484cSchristos @deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
3998b9484cSchristos 
4098b9484cSchristos Allocate memory without fail, and set it to zero.  This routine functions
4198b9484cSchristos like @code{calloc}, but will behave the same as @code{xmalloc} if memory
4298b9484cSchristos cannot be found.
4398b9484cSchristos 
4498b9484cSchristos @end deftypefn
4598b9484cSchristos 
4698b9484cSchristos @deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
4798b9484cSchristos 
4898b9484cSchristos You can use this to set the name of the program used by
4998b9484cSchristos @code{xmalloc_failed} when printing a failure message.
5098b9484cSchristos 
5198b9484cSchristos @end deftypefn
5298b9484cSchristos 
5398b9484cSchristos @deftypefn Replacement void xmalloc_failed (size_t)
5498b9484cSchristos 
5598b9484cSchristos This function is not meant to be called by client code, and is listed
5698b9484cSchristos here for completeness only.  If any of the allocation routines fail, this
5798b9484cSchristos function will be called to print an error message and terminate execution.
5898b9484cSchristos 
5998b9484cSchristos @end deftypefn
6098b9484cSchristos 
6198b9484cSchristos */
6298b9484cSchristos 
6398b9484cSchristos #ifdef HAVE_CONFIG_H
6498b9484cSchristos #include "config.h"
6598b9484cSchristos #endif
6698b9484cSchristos #include "ansidecl.h"
6798b9484cSchristos #include "libiberty.h"
68ba340e45Schristos #include "environ.h"
6998b9484cSchristos 
7098b9484cSchristos #include <stdio.h>
7198b9484cSchristos 
7298b9484cSchristos #include <stddef.h>
7398b9484cSchristos 
7498b9484cSchristos #if VMS
7598b9484cSchristos #include <stdlib.h>
7698b9484cSchristos #include <unixlib.h>
7798b9484cSchristos #else
7898b9484cSchristos /* For systems with larger pointers than ints, these must be declared.  */
7998b9484cSchristos #  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
8098b9484cSchristos       && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
8198b9484cSchristos #    include <stdlib.h>
8298b9484cSchristos #    include <unistd.h>
8398b9484cSchristos #  else
8498b9484cSchristos #    ifdef __cplusplus
8598b9484cSchristos extern "C" {
8698b9484cSchristos #    endif /* __cplusplus */
8798b9484cSchristos void *malloc (size_t);
8898b9484cSchristos void *realloc (void *, size_t);
8998b9484cSchristos void *calloc (size_t, size_t);
904b169a6bSchristos #ifdef HAVE_SBRK
9198b9484cSchristos void *sbrk (ptrdiff_t);
924b169a6bSchristos #endif
9398b9484cSchristos #    ifdef __cplusplus
9498b9484cSchristos }
9598b9484cSchristos #    endif /* __cplusplus */
9698b9484cSchristos #  endif /* HAVE_STDLIB_H ...  */
9798b9484cSchristos #endif /* VMS */
9898b9484cSchristos 
9998b9484cSchristos /* The program name if set.  */
10098b9484cSchristos static const char *name = "";
10198b9484cSchristos 
10298b9484cSchristos #ifdef HAVE_SBRK
10398b9484cSchristos /* The initial sbrk, set when the program name is set. Not used for win32
10498b9484cSchristos    ports other than cygwin32.  */
10598b9484cSchristos static char *first_break = NULL;
10698b9484cSchristos #endif /* HAVE_SBRK */
10798b9484cSchristos 
10898b9484cSchristos void
10998b9484cSchristos xmalloc_set_program_name (const char *s)
11098b9484cSchristos {
11198b9484cSchristos   name = s;
11298b9484cSchristos #ifdef HAVE_SBRK
11398b9484cSchristos   /* Win32 ports other than cygwin32 don't have brk() */
11498b9484cSchristos   if (first_break == NULL)
11598b9484cSchristos     first_break = (char *) sbrk (0);
11698b9484cSchristos #endif /* HAVE_SBRK */
11798b9484cSchristos }
11898b9484cSchristos 
11998b9484cSchristos void
12098b9484cSchristos xmalloc_failed (size_t size)
12198b9484cSchristos {
12298b9484cSchristos #ifdef HAVE_SBRK
12398b9484cSchristos   size_t allocated;
12498b9484cSchristos 
12598b9484cSchristos   if (first_break != NULL)
12698b9484cSchristos     allocated = (char *) sbrk (0) - first_break;
12798b9484cSchristos   else
12898b9484cSchristos     allocated = (char *) sbrk (0) - (char *) &environ;
12998b9484cSchristos   fprintf (stderr,
13098b9484cSchristos 	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
13198b9484cSchristos 	   name, *name ? ": " : "",
13298b9484cSchristos 	   (unsigned long) size, (unsigned long) allocated);
13398b9484cSchristos #else /* HAVE_SBRK */
13498b9484cSchristos   fprintf (stderr,
13598b9484cSchristos 	   "\n%s%sout of memory allocating %lu bytes\n",
13698b9484cSchristos 	   name, *name ? ": " : "",
13798b9484cSchristos 	   (unsigned long) size);
13898b9484cSchristos #endif /* HAVE_SBRK */
13998b9484cSchristos   xexit (1);
14098b9484cSchristos }
14198b9484cSchristos 
1424b169a6bSchristos void *
14398b9484cSchristos xmalloc (size_t size)
14498b9484cSchristos {
1454b169a6bSchristos   void *newmem;
14698b9484cSchristos 
14798b9484cSchristos   if (size == 0)
14898b9484cSchristos     size = 1;
14998b9484cSchristos   newmem = malloc (size);
15098b9484cSchristos   if (!newmem)
15198b9484cSchristos     xmalloc_failed (size);
15298b9484cSchristos 
15398b9484cSchristos   return (newmem);
15498b9484cSchristos }
15598b9484cSchristos 
1564b169a6bSchristos void *
15798b9484cSchristos xcalloc (size_t nelem, size_t elsize)
15898b9484cSchristos {
1594b169a6bSchristos   void *newmem;
16098b9484cSchristos 
16198b9484cSchristos   if (nelem == 0 || elsize == 0)
16298b9484cSchristos     nelem = elsize = 1;
16398b9484cSchristos 
16498b9484cSchristos   newmem = calloc (nelem, elsize);
16598b9484cSchristos   if (!newmem)
16698b9484cSchristos     xmalloc_failed (nelem * elsize);
16798b9484cSchristos 
16898b9484cSchristos   return (newmem);
16998b9484cSchristos }
17098b9484cSchristos 
1714b169a6bSchristos void *
1724b169a6bSchristos xrealloc (void *oldmem, size_t size)
17398b9484cSchristos {
1744b169a6bSchristos   void *newmem;
17598b9484cSchristos 
17698b9484cSchristos   if (size == 0)
17798b9484cSchristos     size = 1;
17898b9484cSchristos   if (!oldmem)
17998b9484cSchristos     newmem = malloc (size);
18098b9484cSchristos   else
18198b9484cSchristos     newmem = realloc (oldmem, size);
18298b9484cSchristos   if (!newmem)
18398b9484cSchristos     xmalloc_failed (size);
18498b9484cSchristos 
18598b9484cSchristos   return (newmem);
18698b9484cSchristos }
187