(root)/
glibc-2.38/
malloc/
obstack.c
       1  /* obstack.c - subroutines used implicitly by object stack macros
       2     Copyright (C) 1988-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  
      20  #ifdef _LIBC
      21  # include <obstack.h>
      22  # include <shlib-compat.h>
      23  #else
      24  # include <config.h>
      25  # include "obstack.h"
      26  #endif
      27  
      28  /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
      29     incremented whenever callers compiled using an old obstack.h can no
      30     longer properly call the functions in this obstack.c.  */
      31  #define OBSTACK_INTERFACE_VERSION 1
      32  
      33  /* Comment out all this code if we are using the GNU C Library, and are not
      34     actually compiling the library itself, and the installed library
      35     supports the same library interface we do.  This code is part of the GNU
      36     C Library, but also included in many other GNU distributions.  Compiling
      37     and linking in this code is a waste when using the GNU C library
      38     (especially if it is a shared library).  Rather than having every GNU
      39     program understand 'configure --with-gnu-libc' and omit the object
      40     files, it is simpler to just do this in the source for each such file.  */
      41  
      42  #include <stdio.h>              /* Random thing to get __GNU_LIBRARY__.  */
      43  #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
      44  # include <gnu-versions.h>
      45  # if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
      46  #  define ELIDE_CODE
      47  # endif
      48  #endif
      49  
      50  #include <stddef.h>
      51  
      52  #ifndef ELIDE_CODE
      53  
      54  
      55  # include <stdint.h>
      56  
      57  /* Determine default alignment.  */
      58  union fooround
      59  {
      60    uintmax_t i;
      61    long double d;
      62    void *p;
      63  };
      64  struct fooalign
      65  {
      66    char c;
      67    union fooround u;
      68  };
      69  /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
      70     But in fact it might be less smart and round addresses to as much as
      71     DEFAULT_ROUNDING.  So we prepare for it to do that.  */
      72  enum
      73  {
      74    DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
      75    DEFAULT_ROUNDING = sizeof (union fooround)
      76  };
      77  
      78  /* When we copy a long block of data, this is the unit to do it with.
      79     On some machines, copying successive ints does not work;
      80     in such a case, redefine COPYING_UNIT to 'long' (if that works)
      81     or 'char' as a last resort.  */
      82  # ifndef COPYING_UNIT
      83  #  define COPYING_UNIT int
      84  # endif
      85  
      86  
      87  /* The functions allocating more room by calling 'obstack_chunk_alloc'
      88     jump to the handler pointed to by 'obstack_alloc_failed_handler'.
      89     This can be set to a user defined function which should either
      90     abort gracefully or use longjump - but shouldn't return.  This
      91     variable by default points to the internal function
      92     'print_and_abort'.  */
      93  static _Noreturn void print_and_abort (void);
      94  void (*obstack_alloc_failed_handler) (void) = print_and_abort;
      95  
      96  /* Exit value used when 'print_and_abort' is used.  */
      97  # include <stdlib.h>
      98  # ifdef _LIBC
      99  int obstack_exit_failure = EXIT_FAILURE;
     100  # else
     101  #  include "exitfail.h"
     102  #  define obstack_exit_failure exit_failure
     103  # endif
     104  
     105  # ifdef _LIBC
     106  #  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
     107  /* A looong time ago (before 1994, anyway; we're not sure) this global variable
     108     was used by non-GNU-C macros to avoid multiple evaluation.  The GNU C
     109     library still exports it because somebody might use it.  */
     110  struct obstack *_obstack_compat = 0;
     111  compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
     112  #  endif
     113  # endif
     114  
     115  /* Define a macro that either calls functions with the traditional malloc/free
     116     calling interface, or calls functions with the mmalloc/mfree interface
     117     (that adds an extra first argument), based on the state of use_extra_arg.
     118     For free, do not use ?:, since some compilers, like the MIPS compilers,
     119     do not allow (expr) ? void : void.  */
     120  
     121  # define CALL_CHUNKFUN(h, size) \
     122    (((h)->use_extra_arg)							      \
     123     ? (*(h)->chunkfun)((h)->extra_arg, (size))				      \
     124     : (*(struct _obstack_chunk *(*)(long))(h)->chunkfun)((size)))
     125  
     126  # define CALL_FREEFUN(h, old_chunk) \
     127    do { \
     128        if ((h)->use_extra_arg)						      \
     129  	(*(h)->freefun)((h)->extra_arg, (old_chunk));			      \
     130        else								      \
     131  	(*(void (*)(void *))(h)->freefun)((old_chunk));			      \
     132      } while (0)
     133  
     134  
     135  /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
     136     Objects start on multiples of ALIGNMENT (0 means use default).
     137     CHUNKFUN is the function to use to allocate chunks,
     138     and FREEFUN the function to free them.
     139  
     140     Return nonzero if successful, calls obstack_alloc_failed_handler if
     141     allocation fails.  */
     142  
     143  int
     144  _obstack_begin (struct obstack *h,
     145  		int size, int alignment,
     146  		void *(*chunkfun) (long),
     147  		void (*freefun) (void *))
     148  {
     149    struct _obstack_chunk *chunk; /* points to new chunk */
     150  
     151    if (alignment == 0)
     152      alignment = DEFAULT_ALIGNMENT;
     153    if (size == 0)
     154      /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     155      {
     156        /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
     157  	 Use the values for range checking, because if range checking is off,
     158  	 the extra bytes won't be missed terribly, but if range checking is on
     159  	 and we used a larger request, a whole extra 4096 bytes would be
     160  	 allocated.
     161  
     162  	 These number are irrelevant to the new GNU malloc.  I suspect it is
     163  	 less sensitive to the size of the request.  */
     164        int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
     165  		    + 4 + DEFAULT_ROUNDING - 1)
     166  		   & ~(DEFAULT_ROUNDING - 1));
     167        size = 4096 - extra;
     168      }
     169  
     170    h->chunkfun = (struct _obstack_chunk * (*) (void *, long)) chunkfun;
     171    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
     172    h->chunk_size = size;
     173    h->alignment_mask = alignment - 1;
     174    h->use_extra_arg = 0;
     175  
     176    chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
     177    if (!chunk)
     178      (*obstack_alloc_failed_handler) ();
     179    h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
     180  					       alignment - 1);
     181    h->chunk_limit = chunk->limit
     182      = (char *) chunk + h->chunk_size;
     183    chunk->prev = 0;
     184    /* The initial chunk now contains no empty object.  */
     185    h->maybe_empty_object = 0;
     186    h->alloc_failed = 0;
     187    return 1;
     188  }
     189  
     190  int
     191  _obstack_begin_1 (struct obstack *h, int size, int alignment,
     192  		  void *(*chunkfun) (void *, long),
     193  		  void (*freefun) (void *, void *),
     194  		  void *arg)
     195  {
     196    struct _obstack_chunk *chunk; /* points to new chunk */
     197  
     198    if (alignment == 0)
     199      alignment = DEFAULT_ALIGNMENT;
     200    if (size == 0)
     201      /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     202      {
     203        /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
     204  	 Use the values for range checking, because if range checking is off,
     205  	 the extra bytes won't be missed terribly, but if range checking is on
     206  	 and we used a larger request, a whole extra 4096 bytes would be
     207  	 allocated.
     208  
     209  	 These number are irrelevant to the new GNU malloc.  I suspect it is
     210  	 less sensitive to the size of the request.  */
     211        int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
     212  		    + 4 + DEFAULT_ROUNDING - 1)
     213  		   & ~(DEFAULT_ROUNDING - 1));
     214        size = 4096 - extra;
     215      }
     216  
     217    h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
     218    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
     219    h->chunk_size = size;
     220    h->alignment_mask = alignment - 1;
     221    h->extra_arg = arg;
     222    h->use_extra_arg = 1;
     223  
     224    chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
     225    if (!chunk)
     226      (*obstack_alloc_failed_handler) ();
     227    h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
     228  					       alignment - 1);
     229    h->chunk_limit = chunk->limit
     230      = (char *) chunk + h->chunk_size;
     231    chunk->prev = 0;
     232    /* The initial chunk now contains no empty object.  */
     233    h->maybe_empty_object = 0;
     234    h->alloc_failed = 0;
     235    return 1;
     236  }
     237  
     238  /* Allocate a new current chunk for the obstack *H
     239     on the assumption that LENGTH bytes need to be added
     240     to the current object, or a new object of length LENGTH allocated.
     241     Copies any partial object from the end of the old chunk
     242     to the beginning of the new one.  */
     243  
     244  void
     245  _obstack_newchunk (struct obstack *h, int length)
     246  {
     247    struct _obstack_chunk *old_chunk = h->chunk;
     248    struct _obstack_chunk *new_chunk;
     249    long new_size;
     250    long obj_size = h->next_free - h->object_base;
     251    long i;
     252    long already;
     253    char *object_base;
     254  
     255    /* Compute size for new chunk.  */
     256    new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
     257    if (new_size < h->chunk_size)
     258      new_size = h->chunk_size;
     259  
     260    /* Allocate and initialize the new chunk.  */
     261    new_chunk = CALL_CHUNKFUN (h, new_size);
     262    if (!new_chunk)
     263      (*obstack_alloc_failed_handler)();
     264    h->chunk = new_chunk;
     265    new_chunk->prev = old_chunk;
     266    new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
     267  
     268    /* Compute an aligned object_base in the new chunk */
     269    object_base =
     270      __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
     271  
     272    /* Move the existing object to the new chunk.
     273       Word at a time is fast and is safe if the object
     274       is sufficiently aligned.  */
     275    if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
     276      {
     277        for (i = obj_size / sizeof (COPYING_UNIT) - 1;
     278  	   i >= 0; i--)
     279  	((COPYING_UNIT *) object_base)[i]
     280  	  = ((COPYING_UNIT *) h->object_base)[i];
     281        /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
     282  	 but that can cross a page boundary on a machine
     283  	 which does not do strict alignment for COPYING_UNITS.  */
     284        already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
     285      }
     286    else
     287      already = 0;
     288    /* Copy remaining bytes one by one.  */
     289    for (i = already; i < obj_size; i++)
     290      object_base[i] = h->object_base[i];
     291  
     292    /* If the object just copied was the only data in OLD_CHUNK,
     293       free that chunk and remove it from the chain.
     294       But not if that chunk might contain an empty object.  */
     295    if (!h->maybe_empty_object
     296        && (h->object_base
     297  	  == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
     298  			  h->alignment_mask)))
     299      {
     300        new_chunk->prev = old_chunk->prev;
     301        CALL_FREEFUN (h, old_chunk);
     302      }
     303  
     304    h->object_base = object_base;
     305    h->next_free = h->object_base + obj_size;
     306    /* The new chunk certainly contains no empty object yet.  */
     307    h->maybe_empty_object = 0;
     308  }
     309  # ifdef _LIBC
     310  libc_hidden_def (_obstack_newchunk)
     311  # endif
     312  
     313  /* Return nonzero if object OBJ has been allocated from obstack H.
     314     This is here for debugging.
     315     If you use it in a program, you are probably losing.  */
     316  
     317  /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
     318     obstack.h because it is just for debugging.  */
     319  int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
     320  
     321  int
     322  _obstack_allocated_p (struct obstack *h, void *obj)
     323  {
     324    struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
     325    struct _obstack_chunk *plp;   /* point to previous chunk if any */
     326  
     327    lp = (h)->chunk;
     328    /* We use >= rather than > since the object cannot be exactly at
     329       the beginning of the chunk but might be an empty object exactly
     330       at the end of an adjacent chunk.  */
     331    while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
     332      {
     333        plp = lp->prev;
     334        lp = plp;
     335      }
     336    return lp != 0;
     337  }
     338  
     339  /* Free objects in obstack H, including OBJ and everything allocate
     340     more recently than OBJ.  If OBJ is zero, free everything in H.  */
     341  
     342  # undef obstack_free
     343  
     344  void
     345  __obstack_free (struct obstack *h, void *obj)
     346  {
     347    struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
     348    struct _obstack_chunk *plp;   /* point to previous chunk if any */
     349  
     350    lp = h->chunk;
     351    /* We use >= because there cannot be an object at the beginning of a chunk.
     352       But there can be an empty object at that address
     353       at the end of another chunk.  */
     354    while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
     355      {
     356        plp = lp->prev;
     357        CALL_FREEFUN (h, lp);
     358        lp = plp;
     359        /* If we switch chunks, we can't tell whether the new current
     360  	 chunk contains an empty object, so assume that it may.  */
     361        h->maybe_empty_object = 1;
     362      }
     363    if (lp)
     364      {
     365        h->object_base = h->next_free = (char *) (obj);
     366        h->chunk_limit = lp->limit;
     367        h->chunk = lp;
     368      }
     369    else if (obj != 0)
     370      /* obj is not in any of the chunks! */
     371      abort ();
     372  }
     373  
     374  # ifdef _LIBC
     375  /* Older versions of libc used a function _obstack_free intended to be
     376     called by non-GCC compilers.  */
     377  strong_alias (obstack_free, _obstack_free)
     378  # endif
     379  
     380  int
     381  _obstack_memory_used (struct obstack *h)
     382  {
     383    struct _obstack_chunk *lp;
     384    int nbytes = 0;
     385  
     386    for (lp = h->chunk; lp != 0; lp = lp->prev)
     387      {
     388        nbytes += lp->limit - (char *) lp;
     389      }
     390    return nbytes;
     391  }
     392  
     393  /* Define the error handler.  */
     394  # ifdef _LIBC
     395  #  include <libintl.h>
     396  # else
     397  #  include "gettext.h"
     398  # endif
     399  # ifndef _
     400  #  define _(msgid) gettext (msgid)
     401  # endif
     402  
     403  # ifdef _LIBC
     404  #  include <libio/iolibio.h>
     405  # endif
     406  
     407  static _Noreturn void
     408  print_and_abort (void)
     409  {
     410    /* Don't change any of these strings.  Yes, it would be possible to add
     411       the newline to the string and use fputs or so.  But this must not
     412       happen because the "memory exhausted" message appears in other places
     413       like this and the translation should be reused instead of creating
     414       a very similar string which requires a separate translation.  */
     415  # ifdef _LIBC
     416    (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
     417  # else
     418    fprintf (stderr, "%s\n", _("memory exhausted"));
     419  # endif
     420    exit (obstack_exit_failure);
     421  }
     422  
     423  #endif  /* !ELIDE_CODE */