xref: /netbsd-src/external/gpl3/binutils.old/dist/libiberty/obstack.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
116dce513Schristos /* obstack.c - subroutines used implicitly by object stack macros
2*e992f068Schristos    Copyright (C) 1988-2022 Free Software Foundation, Inc.
316dce513Schristos    This file is part of the GNU C Library.
416dce513Schristos 
516dce513Schristos    The GNU C Library is free software; you can redistribute it and/or
616dce513Schristos    modify it under the terms of the GNU Lesser General Public
716dce513Schristos    License as published by the Free Software Foundation; either
816dce513Schristos    version 2.1 of the License, or (at your option) any later version.
916dce513Schristos 
1016dce513Schristos    The GNU C Library is distributed in the hope that it will be useful,
1116dce513Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1216dce513Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1316dce513Schristos    Lesser General Public License for more details.
1416dce513Schristos 
1516dce513Schristos    You should have received a copy of the GNU Lesser General Public
1616dce513Schristos    License along with the GNU C Library; if not, see
1716dce513Schristos    <http://www.gnu.org/licenses/>.  */
1816dce513Schristos 
1916dce513Schristos 
2016dce513Schristos #ifdef _LIBC
2116dce513Schristos # include <obstack.h>
2216dce513Schristos #else
2316dce513Schristos # include <config.h>
2416dce513Schristos # include "obstack.h"
2516dce513Schristos #endif
2616dce513Schristos 
2716dce513Schristos /* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in
2816dce513Schristos    obstack.h must be incremented whenever callers compiled using an old
2916dce513Schristos    obstack.h can no longer properly call the functions in this file.  */
3016dce513Schristos 
3116dce513Schristos /* Comment out all this code if we are using the GNU C Library, and are not
3216dce513Schristos    actually compiling the library itself, and the installed library
3316dce513Schristos    supports the same library interface we do.  This code is part of the GNU
3416dce513Schristos    C Library, but also included in many other GNU distributions.  Compiling
3516dce513Schristos    and linking in this code is a waste when using the GNU C library
3616dce513Schristos    (especially if it is a shared library).  Rather than having every GNU
3716dce513Schristos    program understand 'configure --with-gnu-libc' and omit the object
3816dce513Schristos    files, it is simpler to just do this in the source for each such file.  */
3916dce513Schristos #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
4016dce513Schristos # include <gnu-versions.h>
4116dce513Schristos # if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION	      \
4216dce513Schristos       || (_GNU_OBSTACK_INTERFACE_VERSION == 1				      \
4316dce513Schristos           && _OBSTACK_INTERFACE_VERSION == 2				      \
4416dce513Schristos           && defined SIZEOF_INT && defined SIZEOF_SIZE_T		      \
4516dce513Schristos           && SIZEOF_INT == SIZEOF_SIZE_T))
4616dce513Schristos #  define _OBSTACK_ELIDE_CODE
4716dce513Schristos # endif
4816dce513Schristos #endif
4916dce513Schristos 
5016dce513Schristos #ifndef _OBSTACK_ELIDE_CODE
5116dce513Schristos /* If GCC, or if an oddball (testing?) host that #defines __alignof__,
5216dce513Schristos    use the already-supplied __alignof__.  Otherwise, this must be Gnulib
5316dce513Schristos    (as glibc assumes GCC); defer to Gnulib's alignof_type.  */
5416dce513Schristos # if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__
5516dce513Schristos #  if defined __cplusplus
5616dce513Schristos template <class type> struct alignof_helper { char __slot1; type __slot2; };
5716dce513Schristos #   define __alignof__(type) offsetof (alignof_helper<type>, __slot2)
5816dce513Schristos #  else
5916dce513Schristos #   define __alignof__(type)						      \
6016dce513Schristos   offsetof (struct { char __slot1; type __slot2; }, __slot2)
6116dce513Schristos #  endif
6216dce513Schristos # endif
6316dce513Schristos # include <stdlib.h>
6416dce513Schristos # include <stdint.h>
6516dce513Schristos 
6616dce513Schristos # ifndef MAX
6716dce513Schristos #  define MAX(a,b) ((a) > (b) ? (a) : (b))
6816dce513Schristos # endif
6916dce513Schristos 
7016dce513Schristos /* Determine default alignment.  */
7116dce513Schristos 
7216dce513Schristos /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
7316dce513Schristos    But in fact it might be less smart and round addresses to as much as
7416dce513Schristos    DEFAULT_ROUNDING.  So we prepare for it to do that.
7516dce513Schristos 
7616dce513Schristos    DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h.  */
7716dce513Schristos #define DEFAULT_ALIGNMENT MAX (__alignof__ (long double),		      \
7816dce513Schristos                                MAX (__alignof__ (uintmax_t),		      \
7916dce513Schristos                                     __alignof__ (void *)))
8016dce513Schristos #define DEFAULT_ROUNDING MAX (sizeof (long double),			      \
8116dce513Schristos                                MAX (sizeof (uintmax_t),			      \
8216dce513Schristos                                     sizeof (void *)))
8316dce513Schristos 
8416dce513Schristos /* Call functions with either the traditional malloc/free calling
8516dce513Schristos    interface, or the mmalloc/mfree interface (that adds an extra first
8616dce513Schristos    argument), based on the value of use_extra_arg.  */
8716dce513Schristos 
8816dce513Schristos static void *
call_chunkfun(struct obstack * h,size_t size)8916dce513Schristos call_chunkfun (struct obstack *h, size_t size)
9016dce513Schristos {
9116dce513Schristos   if (h->use_extra_arg)
9216dce513Schristos     return h->chunkfun.extra (h->extra_arg, size);
9316dce513Schristos   else
9416dce513Schristos     return h->chunkfun.plain (size);
9516dce513Schristos }
9616dce513Schristos 
9716dce513Schristos static void
call_freefun(struct obstack * h,void * old_chunk)9816dce513Schristos call_freefun (struct obstack *h, void *old_chunk)
9916dce513Schristos {
10016dce513Schristos   if (h->use_extra_arg)
10116dce513Schristos     h->freefun.extra (h->extra_arg, old_chunk);
10216dce513Schristos   else
10316dce513Schristos     h->freefun.plain (old_chunk);
10416dce513Schristos }
10516dce513Schristos 
10616dce513Schristos 
10716dce513Schristos /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
10816dce513Schristos    Objects start on multiples of ALIGNMENT (0 means use default).
10916dce513Schristos 
11016dce513Schristos    Return nonzero if successful, calls obstack_alloc_failed_handler if
11116dce513Schristos    allocation fails.  */
11216dce513Schristos 
11316dce513Schristos static int
_obstack_begin_worker(struct obstack * h,_OBSTACK_SIZE_T size,_OBSTACK_SIZE_T alignment)11416dce513Schristos _obstack_begin_worker (struct obstack *h,
11516dce513Schristos                        _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
11616dce513Schristos {
11716dce513Schristos   struct _obstack_chunk *chunk; /* points to new chunk */
11816dce513Schristos 
11916dce513Schristos   if (alignment == 0)
12016dce513Schristos     alignment = DEFAULT_ALIGNMENT;
12116dce513Schristos   if (size == 0)
12216dce513Schristos     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
12316dce513Schristos     {
12416dce513Schristos       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
12516dce513Schristos          Use the values for range checking, because if range checking is off,
12616dce513Schristos          the extra bytes won't be missed terribly, but if range checking is on
12716dce513Schristos          and we used a larger request, a whole extra 4096 bytes would be
12816dce513Schristos          allocated.
12916dce513Schristos 
13016dce513Schristos          These number are irrelevant to the new GNU malloc.  I suspect it is
13116dce513Schristos          less sensitive to the size of the request.  */
13216dce513Schristos       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
13316dce513Schristos                     + 4 + DEFAULT_ROUNDING - 1)
13416dce513Schristos                    & ~(DEFAULT_ROUNDING - 1));
13516dce513Schristos       size = 4096 - extra;
13616dce513Schristos     }
13716dce513Schristos 
13816dce513Schristos   h->chunk_size = size;
13916dce513Schristos   h->alignment_mask = alignment - 1;
14016dce513Schristos 
14116dce513Schristos   chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size);
14216dce513Schristos   if (!chunk)
14316dce513Schristos     (*obstack_alloc_failed_handler) ();
14416dce513Schristos   h->chunk = chunk;
14516dce513Schristos   h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
14616dce513Schristos                                                alignment - 1);
14716dce513Schristos   h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
14816dce513Schristos   chunk->prev = 0;
14916dce513Schristos   /* The initial chunk now contains no empty object.  */
15016dce513Schristos   h->maybe_empty_object = 0;
15116dce513Schristos   h->alloc_failed = 0;
15216dce513Schristos   return 1;
15316dce513Schristos }
15416dce513Schristos 
15516dce513Schristos int
_obstack_begin(struct obstack * h,_OBSTACK_SIZE_T size,_OBSTACK_SIZE_T alignment,void * (* chunkfun)(size_t),void (* freefun)(void *))15616dce513Schristos _obstack_begin (struct obstack *h,
15716dce513Schristos                 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
15816dce513Schristos                 void *(*chunkfun) (size_t),
15916dce513Schristos                 void (*freefun) (void *))
16016dce513Schristos {
16116dce513Schristos   h->chunkfun.plain = chunkfun;
16216dce513Schristos   h->freefun.plain = freefun;
16316dce513Schristos   h->use_extra_arg = 0;
16416dce513Schristos   return _obstack_begin_worker (h, size, alignment);
16516dce513Schristos }
16616dce513Schristos 
16716dce513Schristos int
_obstack_begin_1(struct obstack * h,_OBSTACK_SIZE_T size,_OBSTACK_SIZE_T alignment,void * (* chunkfun)(void *,size_t),void (* freefun)(void *,void *),void * arg)16816dce513Schristos _obstack_begin_1 (struct obstack *h,
16916dce513Schristos                   _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
17016dce513Schristos                   void *(*chunkfun) (void *, size_t),
17116dce513Schristos                   void (*freefun) (void *, void *),
17216dce513Schristos                   void *arg)
17316dce513Schristos {
17416dce513Schristos   h->chunkfun.extra = chunkfun;
17516dce513Schristos   h->freefun.extra = freefun;
17616dce513Schristos   h->extra_arg = arg;
17716dce513Schristos   h->use_extra_arg = 1;
17816dce513Schristos   return _obstack_begin_worker (h, size, alignment);
17916dce513Schristos }
18016dce513Schristos 
18116dce513Schristos /* Allocate a new current chunk for the obstack *H
18216dce513Schristos    on the assumption that LENGTH bytes need to be added
18316dce513Schristos    to the current object, or a new object of length LENGTH allocated.
18416dce513Schristos    Copies any partial object from the end of the old chunk
18516dce513Schristos    to the beginning of the new one.  */
18616dce513Schristos 
18716dce513Schristos void
_obstack_newchunk(struct obstack * h,_OBSTACK_SIZE_T length)18816dce513Schristos _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
18916dce513Schristos {
19016dce513Schristos   struct _obstack_chunk *old_chunk = h->chunk;
19116dce513Schristos   struct _obstack_chunk *new_chunk = 0;
19216dce513Schristos   size_t obj_size = h->next_free - h->object_base;
19316dce513Schristos   char *object_base;
19416dce513Schristos 
19516dce513Schristos   /* Compute size for new chunk.  */
19616dce513Schristos   size_t sum1 = obj_size + length;
19716dce513Schristos   size_t sum2 = sum1 + h->alignment_mask;
19816dce513Schristos   size_t new_size = sum2 + (obj_size >> 3) + 100;
19916dce513Schristos   if (new_size < sum2)
20016dce513Schristos     new_size = sum2;
20116dce513Schristos   if (new_size < h->chunk_size)
20216dce513Schristos     new_size = h->chunk_size;
20316dce513Schristos 
20416dce513Schristos   /* Allocate and initialize the new chunk.  */
20516dce513Schristos   if (obj_size <= sum1 && sum1 <= sum2)
20616dce513Schristos     new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size);
20716dce513Schristos   if (!new_chunk)
20816dce513Schristos     (*obstack_alloc_failed_handler)();
20916dce513Schristos   h->chunk = new_chunk;
21016dce513Schristos   new_chunk->prev = old_chunk;
21116dce513Schristos   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
21216dce513Schristos 
21316dce513Schristos   /* Compute an aligned object_base in the new chunk */
21416dce513Schristos   object_base =
21516dce513Schristos     __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
21616dce513Schristos 
21716dce513Schristos   /* Move the existing object to the new chunk.  */
21816dce513Schristos   memcpy (object_base, h->object_base, obj_size);
21916dce513Schristos 
22016dce513Schristos   /* If the object just copied was the only data in OLD_CHUNK,
22116dce513Schristos      free that chunk and remove it from the chain.
22216dce513Schristos      But not if that chunk might contain an empty object.  */
22316dce513Schristos   if (!h->maybe_empty_object
22416dce513Schristos       && (h->object_base
22516dce513Schristos           == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
22616dce513Schristos                           h->alignment_mask)))
22716dce513Schristos     {
22816dce513Schristos       new_chunk->prev = old_chunk->prev;
22916dce513Schristos       call_freefun (h, old_chunk);
23016dce513Schristos     }
23116dce513Schristos 
23216dce513Schristos   h->object_base = object_base;
23316dce513Schristos   h->next_free = h->object_base + obj_size;
23416dce513Schristos   /* The new chunk certainly contains no empty object yet.  */
23516dce513Schristos   h->maybe_empty_object = 0;
23616dce513Schristos }
23716dce513Schristos 
23816dce513Schristos /* Return nonzero if object OBJ has been allocated from obstack H.
23916dce513Schristos    This is here for debugging.
24016dce513Schristos    If you use it in a program, you are probably losing.  */
24116dce513Schristos 
24216dce513Schristos /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
24316dce513Schristos    obstack.h because it is just for debugging.  */
24416dce513Schristos int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
24516dce513Schristos 
24616dce513Schristos int
_obstack_allocated_p(struct obstack * h,void * obj)24716dce513Schristos _obstack_allocated_p (struct obstack *h, void *obj)
24816dce513Schristos {
24916dce513Schristos   struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
25016dce513Schristos   struct _obstack_chunk *plp;   /* point to previous chunk if any */
25116dce513Schristos 
25216dce513Schristos   lp = (h)->chunk;
25316dce513Schristos   /* We use >= rather than > since the object cannot be exactly at
25416dce513Schristos      the beginning of the chunk but might be an empty object exactly
25516dce513Schristos      at the end of an adjacent chunk.  */
25616dce513Schristos   while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
25716dce513Schristos     {
25816dce513Schristos       plp = lp->prev;
25916dce513Schristos       lp = plp;
26016dce513Schristos     }
26116dce513Schristos   return lp != 0;
26216dce513Schristos }
26316dce513Schristos 
26416dce513Schristos /* Free objects in obstack H, including OBJ and everything allocate
26516dce513Schristos    more recently than OBJ.  If OBJ is zero, free everything in H.  */
26616dce513Schristos 
26716dce513Schristos void
_obstack_free(struct obstack * h,void * obj)26816dce513Schristos _obstack_free (struct obstack *h, void *obj)
26916dce513Schristos {
27016dce513Schristos   struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
27116dce513Schristos   struct _obstack_chunk *plp;   /* point to previous chunk if any */
27216dce513Schristos 
27316dce513Schristos   lp = h->chunk;
27416dce513Schristos   /* We use >= because there cannot be an object at the beginning of a chunk.
27516dce513Schristos      But there can be an empty object at that address
27616dce513Schristos      at the end of another chunk.  */
27716dce513Schristos   while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
27816dce513Schristos     {
27916dce513Schristos       plp = lp->prev;
28016dce513Schristos       call_freefun (h, lp);
28116dce513Schristos       lp = plp;
28216dce513Schristos       /* If we switch chunks, we can't tell whether the new current
28316dce513Schristos          chunk contains an empty object, so assume that it may.  */
28416dce513Schristos       h->maybe_empty_object = 1;
28516dce513Schristos     }
28616dce513Schristos   if (lp)
28716dce513Schristos     {
28816dce513Schristos       h->object_base = h->next_free = (char *) (obj);
28916dce513Schristos       h->chunk_limit = lp->limit;
29016dce513Schristos       h->chunk = lp;
29116dce513Schristos     }
29216dce513Schristos   else if (obj != 0)
29316dce513Schristos     /* obj is not in any of the chunks! */
29416dce513Schristos     abort ();
29516dce513Schristos }
29616dce513Schristos 
29716dce513Schristos _OBSTACK_SIZE_T
_obstack_memory_used(struct obstack * h)29816dce513Schristos _obstack_memory_used (struct obstack *h)
29916dce513Schristos {
30016dce513Schristos   struct _obstack_chunk *lp;
30116dce513Schristos   _OBSTACK_SIZE_T nbytes = 0;
30216dce513Schristos 
30316dce513Schristos   for (lp = h->chunk; lp != 0; lp = lp->prev)
30416dce513Schristos     {
30516dce513Schristos       nbytes += lp->limit - (char *) lp;
30616dce513Schristos     }
30716dce513Schristos   return nbytes;
30816dce513Schristos }
30916dce513Schristos 
31016dce513Schristos # ifndef _OBSTACK_NO_ERROR_HANDLER
31116dce513Schristos /* Define the error handler.  */
31216dce513Schristos #  include <stdio.h>
31316dce513Schristos 
31416dce513Schristos /* Exit value used when 'print_and_abort' is used.  */
31516dce513Schristos #  ifdef _LIBC
31616dce513Schristos int obstack_exit_failure = EXIT_FAILURE;
31716dce513Schristos #  else
31816dce513Schristos #   ifndef EXIT_FAILURE
31916dce513Schristos #    define EXIT_FAILURE 1
32016dce513Schristos #   endif
32116dce513Schristos #   define obstack_exit_failure EXIT_FAILURE
32216dce513Schristos #  endif
32316dce513Schristos 
32416dce513Schristos #  if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
32516dce513Schristos #   include <libintl.h>
32616dce513Schristos #   ifndef _
32716dce513Schristos #    define _(msgid) gettext (msgid)
32816dce513Schristos #   endif
32916dce513Schristos #  else
33016dce513Schristos #   ifndef _
33116dce513Schristos #    define _(msgid) (msgid)
33216dce513Schristos #   endif
33316dce513Schristos #  endif
33416dce513Schristos 
33516dce513Schristos #  if !(defined _Noreturn						      \
33616dce513Schristos         || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112))
33716dce513Schristos #   if ((defined __GNUC__						      \
33816dce513Schristos 	 && (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)))	      \
33916dce513Schristos 	|| (defined __SUNPRO_C && __SUNPRO_C >= 0x5110))
34016dce513Schristos #    define _Noreturn __attribute__ ((__noreturn__))
34116dce513Schristos #   elif defined _MSC_VER && _MSC_VER >= 1200
34216dce513Schristos #    define _Noreturn __declspec (noreturn)
34316dce513Schristos #   else
34416dce513Schristos #    define _Noreturn
34516dce513Schristos #   endif
34616dce513Schristos #  endif
34716dce513Schristos 
34816dce513Schristos #  ifdef _LIBC
34916dce513Schristos #   include <libio/iolibio.h>
35016dce513Schristos #  endif
35116dce513Schristos 
35216dce513Schristos static _Noreturn void
print_and_abort(void)35316dce513Schristos print_and_abort (void)
35416dce513Schristos {
35516dce513Schristos   /* Don't change any of these strings.  Yes, it would be possible to add
35616dce513Schristos      the newline to the string and use fputs or so.  But this must not
35716dce513Schristos      happen because the "memory exhausted" message appears in other places
35816dce513Schristos      like this and the translation should be reused instead of creating
35916dce513Schristos      a very similar string which requires a separate translation.  */
36016dce513Schristos #  ifdef _LIBC
36116dce513Schristos   (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
36216dce513Schristos #  else
36316dce513Schristos   fprintf (stderr, "%s\n", _("memory exhausted"));
36416dce513Schristos #  endif
36516dce513Schristos   exit (obstack_exit_failure);
36616dce513Schristos }
36716dce513Schristos 
36816dce513Schristos /* The functions allocating more room by calling 'obstack_chunk_alloc'
36916dce513Schristos    jump to the handler pointed to by 'obstack_alloc_failed_handler'.
37016dce513Schristos    This can be set to a user defined function which should either
37116dce513Schristos    abort gracefully or use longjump - but shouldn't return.  This
37216dce513Schristos    variable by default points to the internal function
37316dce513Schristos    'print_and_abort'.  */
37416dce513Schristos void (*obstack_alloc_failed_handler) (void) = print_and_abort;
37516dce513Schristos # endif /* !_OBSTACK_NO_ERROR_HANDLER */
37616dce513Schristos #endif /* !_OBSTACK_ELIDE_CODE */
377