198b9484cSchristos /* obstack.c - subroutines used implicitly by object stack macros 2*5173eb0aSchristos Copyright (C) 1988-2024 Free Software Foundation, Inc. 3ba340e45Schristos This file is part of the GNU C Library. 498b9484cSchristos 5ba340e45Schristos The GNU C Library is free software; you can redistribute it and/or 6ba340e45Schristos modify it under the terms of the GNU Lesser General Public 7ba340e45Schristos License as published by the Free Software Foundation; either 8ba340e45Schristos version 2.1 of the License, or (at your option) any later version. 998b9484cSchristos 10ba340e45Schristos The GNU C Library is distributed in the hope that it will be useful, 1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 12ba340e45Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13ba340e45Schristos Lesser General Public License for more details. 1498b9484cSchristos 15ba340e45Schristos You should have received a copy of the GNU Lesser General Public 16ba340e45Schristos License along with the GNU C Library; if not, see 17ba340e45Schristos <http://www.gnu.org/licenses/>. */ 1898b9484cSchristos 19ba340e45Schristos 20ba340e45Schristos #ifdef _LIBC 21ba340e45Schristos # include <obstack.h> 22ba340e45Schristos #else 2398b9484cSchristos # include <config.h> 24ba340e45Schristos # include "obstack.h" 2598b9484cSchristos #endif 2698b9484cSchristos 27ba340e45Schristos /* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in 28ba340e45Schristos obstack.h must be incremented whenever callers compiled using an old 29ba340e45Schristos obstack.h can no longer properly call the functions in this file. */ 3098b9484cSchristos 3198b9484cSchristos /* Comment out all this code if we are using the GNU C Library, and are not 3298b9484cSchristos actually compiling the library itself, and the installed library 3398b9484cSchristos supports the same library interface we do. This code is part of the GNU 3498b9484cSchristos C Library, but also included in many other GNU distributions. Compiling 3598b9484cSchristos and linking in this code is a waste when using the GNU C library 3698b9484cSchristos (especially if it is a shared library). Rather than having every GNU 37ba340e45Schristos program understand 'configure --with-gnu-libc' and omit the object 3898b9484cSchristos files, it is simpler to just do this in the source for each such file. */ 39ba340e45Schristos #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 4098b9484cSchristos # include <gnu-versions.h> 41ba340e45Schristos # if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \ 42ba340e45Schristos || (_GNU_OBSTACK_INTERFACE_VERSION == 1 \ 43ba340e45Schristos && _OBSTACK_INTERFACE_VERSION == 2 \ 44ba340e45Schristos && defined SIZEOF_INT && defined SIZEOF_SIZE_T \ 45ba340e45Schristos && SIZEOF_INT == SIZEOF_SIZE_T)) 46ba340e45Schristos # define _OBSTACK_ELIDE_CODE 4798b9484cSchristos # endif 4898b9484cSchristos #endif 4998b9484cSchristos 50ba340e45Schristos #ifndef _OBSTACK_ELIDE_CODE 51ba340e45Schristos /* If GCC, or if an oddball (testing?) host that #defines __alignof__, 52ba340e45Schristos use the already-supplied __alignof__. Otherwise, this must be Gnulib 53ba340e45Schristos (as glibc assumes GCC); defer to Gnulib's alignof_type. */ 54ba340e45Schristos # if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__ 55ba340e45Schristos # if defined __cplusplus 56ba340e45Schristos template <class type> struct alignof_helper { char __slot1; type __slot2; }; 57ba340e45Schristos # define __alignof__(type) offsetof (alignof_helper<type>, __slot2) 58ba340e45Schristos # else 59ba340e45Schristos # define __alignof__(type) \ 60ba340e45Schristos offsetof (struct { char __slot1; type __slot2; }, __slot2) 61ba340e45Schristos # endif 62ba340e45Schristos # endif 63ba340e45Schristos # include <stdlib.h> 64ba340e45Schristos # include <stdint.h> 6598b9484cSchristos 66ba340e45Schristos # ifndef MAX 67ba340e45Schristos # define MAX(a,b) ((a) > (b) ? (a) : (b)) 68ba340e45Schristos # endif 6998b9484cSchristos 7098b9484cSchristos /* Determine default alignment. */ 71ba340e45Schristos 7298b9484cSchristos /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. 7398b9484cSchristos But in fact it might be less smart and round addresses to as much as 74ba340e45Schristos DEFAULT_ROUNDING. So we prepare for it to do that. 7598b9484cSchristos 76ba340e45Schristos DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h. */ 77ba340e45Schristos #define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \ 78ba340e45Schristos MAX (__alignof__ (uintmax_t), \ 79ba340e45Schristos __alignof__ (void *))) 80ba340e45Schristos #define DEFAULT_ROUNDING MAX (sizeof (long double), \ 81ba340e45Schristos MAX (sizeof (uintmax_t), \ 82ba340e45Schristos sizeof (void *))) 83ba340e45Schristos 84ba340e45Schristos /* Call functions with either the traditional malloc/free calling 85ba340e45Schristos interface, or the mmalloc/mfree interface (that adds an extra first 86ba340e45Schristos argument), based on the value of use_extra_arg. */ 87ba340e45Schristos 88ba340e45Schristos static void * 89ba340e45Schristos call_chunkfun (struct obstack *h, size_t size) 90ba340e45Schristos { 91ba340e45Schristos if (h->use_extra_arg) 92ba340e45Schristos return h->chunkfun.extra (h->extra_arg, size); 93ba340e45Schristos else 94ba340e45Schristos return h->chunkfun.plain (size); 95ba340e45Schristos } 96ba340e45Schristos 97ba340e45Schristos static void 98ba340e45Schristos call_freefun (struct obstack *h, void *old_chunk) 99ba340e45Schristos { 100ba340e45Schristos if (h->use_extra_arg) 101ba340e45Schristos h->freefun.extra (h->extra_arg, old_chunk); 102ba340e45Schristos else 103ba340e45Schristos h->freefun.plain (old_chunk); 104ba340e45Schristos } 10598b9484cSchristos 10698b9484cSchristos 10798b9484cSchristos /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). 10898b9484cSchristos Objects start on multiples of ALIGNMENT (0 means use default). 10998b9484cSchristos 110ba340e45Schristos Return nonzero if successful, calls obstack_alloc_failed_handler if 111ba340e45Schristos allocation fails. */ 11298b9484cSchristos 113ba340e45Schristos static int 114ba340e45Schristos _obstack_begin_worker (struct obstack *h, 115ba340e45Schristos _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment) 11698b9484cSchristos { 117ba340e45Schristos struct _obstack_chunk *chunk; /* points to new chunk */ 11898b9484cSchristos 11998b9484cSchristos if (alignment == 0) 120ba340e45Schristos alignment = DEFAULT_ALIGNMENT; 12198b9484cSchristos if (size == 0) 12298b9484cSchristos /* Default size is what GNU malloc can fit in a 4096-byte block. */ 12398b9484cSchristos { 12498b9484cSchristos /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. 12598b9484cSchristos Use the values for range checking, because if range checking is off, 12698b9484cSchristos the extra bytes won't be missed terribly, but if range checking is on 12798b9484cSchristos and we used a larger request, a whole extra 4096 bytes would be 12898b9484cSchristos allocated. 12998b9484cSchristos 13098b9484cSchristos These number are irrelevant to the new GNU malloc. I suspect it is 13198b9484cSchristos less sensitive to the size of the request. */ 13298b9484cSchristos int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) 13398b9484cSchristos + 4 + DEFAULT_ROUNDING - 1) 13498b9484cSchristos & ~(DEFAULT_ROUNDING - 1)); 13598b9484cSchristos size = 4096 - extra; 13698b9484cSchristos } 13798b9484cSchristos 13898b9484cSchristos h->chunk_size = size; 13998b9484cSchristos h->alignment_mask = alignment - 1; 14098b9484cSchristos 141ba340e45Schristos chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size); 14298b9484cSchristos if (!chunk) 14398b9484cSchristos (*obstack_alloc_failed_handler) (); 144ba340e45Schristos h->chunk = chunk; 145ba340e45Schristos h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, 146ba340e45Schristos alignment - 1); 147ba340e45Schristos h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; 14898b9484cSchristos chunk->prev = 0; 14998b9484cSchristos /* The initial chunk now contains no empty object. */ 15098b9484cSchristos h->maybe_empty_object = 0; 15198b9484cSchristos h->alloc_failed = 0; 15298b9484cSchristos return 1; 15398b9484cSchristos } 15498b9484cSchristos 15598b9484cSchristos int 156ba340e45Schristos _obstack_begin (struct obstack *h, 157ba340e45Schristos _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, 158ba340e45Schristos void *(*chunkfun) (size_t), 159ba340e45Schristos void (*freefun) (void *)) 16098b9484cSchristos { 161ba340e45Schristos h->chunkfun.plain = chunkfun; 162ba340e45Schristos h->freefun.plain = freefun; 163ba340e45Schristos h->use_extra_arg = 0; 164ba340e45Schristos return _obstack_begin_worker (h, size, alignment); 16598b9484cSchristos } 16698b9484cSchristos 167ba340e45Schristos int 168ba340e45Schristos _obstack_begin_1 (struct obstack *h, 169ba340e45Schristos _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, 170ba340e45Schristos void *(*chunkfun) (void *, size_t), 171ba340e45Schristos void (*freefun) (void *, void *), 172ba340e45Schristos void *arg) 173ba340e45Schristos { 174ba340e45Schristos h->chunkfun.extra = chunkfun; 175ba340e45Schristos h->freefun.extra = freefun; 17698b9484cSchristos h->extra_arg = arg; 17798b9484cSchristos h->use_extra_arg = 1; 178ba340e45Schristos return _obstack_begin_worker (h, size, alignment); 17998b9484cSchristos } 18098b9484cSchristos 18198b9484cSchristos /* Allocate a new current chunk for the obstack *H 18298b9484cSchristos on the assumption that LENGTH bytes need to be added 18398b9484cSchristos to the current object, or a new object of length LENGTH allocated. 18498b9484cSchristos Copies any partial object from the end of the old chunk 18598b9484cSchristos to the beginning of the new one. */ 18698b9484cSchristos 18798b9484cSchristos void 188ba340e45Schristos _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length) 18998b9484cSchristos { 190ba340e45Schristos struct _obstack_chunk *old_chunk = h->chunk; 191ba340e45Schristos struct _obstack_chunk *new_chunk = 0; 192ba340e45Schristos size_t obj_size = h->next_free - h->object_base; 193ba340e45Schristos char *object_base; 19498b9484cSchristos 19598b9484cSchristos /* Compute size for new chunk. */ 196ba340e45Schristos size_t sum1 = obj_size + length; 197ba340e45Schristos size_t sum2 = sum1 + h->alignment_mask; 198ba340e45Schristos size_t new_size = sum2 + (obj_size >> 3) + 100; 199ba340e45Schristos if (new_size < sum2) 200ba340e45Schristos new_size = sum2; 20198b9484cSchristos if (new_size < h->chunk_size) 20298b9484cSchristos new_size = h->chunk_size; 20398b9484cSchristos 20498b9484cSchristos /* Allocate and initialize the new chunk. */ 205ba340e45Schristos if (obj_size <= sum1 && sum1 <= sum2) 206ba340e45Schristos new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size); 20798b9484cSchristos if (!new_chunk) 20898b9484cSchristos (*obstack_alloc_failed_handler)(); 20998b9484cSchristos h->chunk = new_chunk; 21098b9484cSchristos new_chunk->prev = old_chunk; 21198b9484cSchristos new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; 21298b9484cSchristos 213ba340e45Schristos /* Compute an aligned object_base in the new chunk */ 214ba340e45Schristos object_base = 215ba340e45Schristos __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); 216ba340e45Schristos 217ba340e45Schristos /* Move the existing object to the new chunk. */ 218ba340e45Schristos memcpy (object_base, h->object_base, obj_size); 21998b9484cSchristos 22098b9484cSchristos /* If the object just copied was the only data in OLD_CHUNK, 22198b9484cSchristos free that chunk and remove it from the chain. 22298b9484cSchristos But not if that chunk might contain an empty object. */ 223ba340e45Schristos if (!h->maybe_empty_object 224ba340e45Schristos && (h->object_base 225ba340e45Schristos == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, 226ba340e45Schristos h->alignment_mask))) 22798b9484cSchristos { 22898b9484cSchristos new_chunk->prev = old_chunk->prev; 229ba340e45Schristos call_freefun (h, old_chunk); 23098b9484cSchristos } 23198b9484cSchristos 232ba340e45Schristos h->object_base = object_base; 23398b9484cSchristos h->next_free = h->object_base + obj_size; 23498b9484cSchristos /* The new chunk certainly contains no empty object yet. */ 23598b9484cSchristos h->maybe_empty_object = 0; 23698b9484cSchristos } 23798b9484cSchristos 23898b9484cSchristos /* Return nonzero if object OBJ has been allocated from obstack H. 23998b9484cSchristos This is here for debugging. 24098b9484cSchristos If you use it in a program, you are probably losing. */ 24198b9484cSchristos 24298b9484cSchristos /* Suppress -Wmissing-prototypes warning. We don't want to declare this in 24398b9484cSchristos obstack.h because it is just for debugging. */ 244ba340e45Schristos int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__; 24598b9484cSchristos 24698b9484cSchristos int 247ba340e45Schristos _obstack_allocated_p (struct obstack *h, void *obj) 24898b9484cSchristos { 249ba340e45Schristos struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ 250ba340e45Schristos struct _obstack_chunk *plp; /* point to previous chunk if any */ 25198b9484cSchristos 25298b9484cSchristos lp = (h)->chunk; 25398b9484cSchristos /* We use >= rather than > since the object cannot be exactly at 25498b9484cSchristos the beginning of the chunk but might be an empty object exactly 25598b9484cSchristos at the end of an adjacent chunk. */ 256ba340e45Schristos while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) 25798b9484cSchristos { 25898b9484cSchristos plp = lp->prev; 25998b9484cSchristos lp = plp; 26098b9484cSchristos } 26198b9484cSchristos return lp != 0; 26298b9484cSchristos } 263ba340e45Schristos 26498b9484cSchristos /* Free objects in obstack H, including OBJ and everything allocate 26598b9484cSchristos more recently than OBJ. If OBJ is zero, free everything in H. */ 26698b9484cSchristos 26798b9484cSchristos void 268ba340e45Schristos _obstack_free (struct obstack *h, void *obj) 26998b9484cSchristos { 270ba340e45Schristos struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ 271ba340e45Schristos struct _obstack_chunk *plp; /* point to previous chunk if any */ 27298b9484cSchristos 27398b9484cSchristos lp = h->chunk; 27498b9484cSchristos /* We use >= because there cannot be an object at the beginning of a chunk. 27598b9484cSchristos But there can be an empty object at that address 27698b9484cSchristos at the end of another chunk. */ 277ba340e45Schristos while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) 27898b9484cSchristos { 27998b9484cSchristos plp = lp->prev; 280ba340e45Schristos call_freefun (h, lp); 28198b9484cSchristos lp = plp; 28298b9484cSchristos /* If we switch chunks, we can't tell whether the new current 28398b9484cSchristos chunk contains an empty object, so assume that it may. */ 28498b9484cSchristos h->maybe_empty_object = 1; 28598b9484cSchristos } 28698b9484cSchristos if (lp) 28798b9484cSchristos { 28898b9484cSchristos h->object_base = h->next_free = (char *) (obj); 28998b9484cSchristos h->chunk_limit = lp->limit; 29098b9484cSchristos h->chunk = lp; 29198b9484cSchristos } 29298b9484cSchristos else if (obj != 0) 29398b9484cSchristos /* obj is not in any of the chunks! */ 29498b9484cSchristos abort (); 29598b9484cSchristos } 29698b9484cSchristos 297ba340e45Schristos _OBSTACK_SIZE_T 29898b9484cSchristos _obstack_memory_used (struct obstack *h) 29998b9484cSchristos { 300ba340e45Schristos struct _obstack_chunk *lp; 301ba340e45Schristos _OBSTACK_SIZE_T nbytes = 0; 30298b9484cSchristos 30398b9484cSchristos for (lp = h->chunk; lp != 0; lp = lp->prev) 30498b9484cSchristos { 30598b9484cSchristos nbytes += lp->limit - (char *) lp; 30698b9484cSchristos } 30798b9484cSchristos return nbytes; 30898b9484cSchristos } 309ba340e45Schristos 310ba340e45Schristos # ifndef _OBSTACK_NO_ERROR_HANDLER 31198b9484cSchristos /* Define the error handler. */ 312ba340e45Schristos # include <stdio.h> 313ba340e45Schristos 314ba340e45Schristos /* Exit value used when 'print_and_abort' is used. */ 315ba340e45Schristos # ifdef _LIBC 316ba340e45Schristos int obstack_exit_failure = EXIT_FAILURE; 317ba340e45Schristos # else 318ba340e45Schristos # ifndef EXIT_FAILURE 319ba340e45Schristos # define EXIT_FAILURE 1 320ba340e45Schristos # endif 321ba340e45Schristos # define obstack_exit_failure EXIT_FAILURE 322ba340e45Schristos # endif 323ba340e45Schristos 324ba340e45Schristos # if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS) 32598b9484cSchristos # include <libintl.h> 32698b9484cSchristos # ifndef _ 327ba340e45Schristos # define _(msgid) gettext (msgid) 32898b9484cSchristos # endif 32998b9484cSchristos # else 330ba340e45Schristos # ifndef _ 331ba340e45Schristos # define _(msgid) (msgid) 33298b9484cSchristos # endif 33398b9484cSchristos # endif 33498b9484cSchristos 335ba340e45Schristos # if !(defined _Noreturn \ 336ba340e45Schristos || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112)) 337ba340e45Schristos # if ((defined __GNUC__ \ 338ba340e45Schristos && (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))) \ 339ba340e45Schristos || (defined __SUNPRO_C && __SUNPRO_C >= 0x5110)) 340ba340e45Schristos # define _Noreturn __attribute__ ((__noreturn__)) 341ba340e45Schristos # elif defined _MSC_VER && _MSC_VER >= 1200 342ba340e45Schristos # define _Noreturn __declspec (noreturn) 343ba340e45Schristos # else 344ba340e45Schristos # define _Noreturn 345ba340e45Schristos # endif 346ba340e45Schristos # endif 347ba340e45Schristos 348ba340e45Schristos # ifdef _LIBC 349ba340e45Schristos # include <libio/iolibio.h> 350ba340e45Schristos # endif 351ba340e45Schristos 352ba340e45Schristos static _Noreturn void 35398b9484cSchristos print_and_abort (void) 35498b9484cSchristos { 355ba340e45Schristos /* Don't change any of these strings. Yes, it would be possible to add 356ba340e45Schristos the newline to the string and use fputs or so. But this must not 357ba340e45Schristos happen because the "memory exhausted" message appears in other places 358ba340e45Schristos like this and the translation should be reused instead of creating 359ba340e45Schristos a very similar string which requires a separate translation. */ 360ba340e45Schristos # ifdef _LIBC 361ba340e45Schristos (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); 362ba340e45Schristos # else 363ba340e45Schristos fprintf (stderr, "%s\n", _("memory exhausted")); 364ba340e45Schristos # endif 36598b9484cSchristos exit (obstack_exit_failure); 36698b9484cSchristos } 36798b9484cSchristos 368ba340e45Schristos /* The functions allocating more room by calling 'obstack_chunk_alloc' 369ba340e45Schristos jump to the handler pointed to by 'obstack_alloc_failed_handler'. 370ba340e45Schristos This can be set to a user defined function which should either 371ba340e45Schristos abort gracefully or use longjump - but shouldn't return. This 372ba340e45Schristos variable by default points to the internal function 373ba340e45Schristos 'print_and_abort'. */ 374ba340e45Schristos void (*obstack_alloc_failed_handler) (void) = print_and_abort; 375ba340e45Schristos # endif /* !_OBSTACK_NO_ERROR_HANDLER */ 376ba340e45Schristos #endif /* !_OBSTACK_ELIDE_CODE */ 377