(root)/
glibc-2.38/
malloc/
alloc_buffer_alloc_array.c
       1  /* Array allocation from a fixed-size buffer.
       2     Copyright (C) 2017-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  #include <alloc_buffer.h>
      20  #include <libc-pointer-arith.h>
      21  
      22  void *
      23  __libc_alloc_buffer_alloc_array (struct alloc_buffer *buf, size_t element_size,
      24                                   size_t align, size_t count)
      25  {
      26    uintptr_t current = buf->__alloc_buffer_current;
      27    /* The caller asserts that align is a power of two.  */
      28    uintptr_t aligned = ALIGN_UP (current, align);
      29    size_t size;
      30    bool overflow = __builtin_mul_overflow (element_size, count, &size);
      31    uintptr_t new_current = aligned + size;
      32    if (!overflow                /* Multiplication did not overflow.  */
      33        && aligned >= current    /* No overflow in align step.  */
      34        && new_current >= size   /* No overflow in size computation.  */
      35        && new_current <= buf->__alloc_buffer_end) /* Room in buffer.  */
      36      {
      37        buf->__alloc_buffer_current = new_current;
      38        return (void *) aligned;
      39      }
      40    else
      41      {
      42        alloc_buffer_mark_failed (buf);
      43        return NULL;
      44      }
      45  }
      46  libc_hidden_def (__libc_alloc_buffer_alloc_array)