github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/memory.c (about)

     1  /* Memory allocation used during tests.
     2  
     3  Copyright 2001, 2002, 2007, 2013 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <stdio.h>
    21  #include <stdlib.h>		/* for abort */
    22  #include <string.h>		/* for memcpy, memcmp */
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  #if GMP_LIMB_BITS == 64
    28  #define PATTERN1 CNST_LIMB(0xcafebabedeadbeef)
    29  #define PATTERN2 CNST_LIMB(0xabacadabaedeedab)
    30  #else
    31  #define PATTERN1 CNST_LIMB(0xcafebabe)
    32  #define PATTERN2 CNST_LIMB(0xdeadbeef)
    33  #endif
    34  
    35  #if HAVE_INTPTR_T
    36  #define PTRLIMB(p)  ((mp_limb_t) (intptr_t) p)
    37  #else
    38  #define PTRLIMB(p)  ((mp_limb_t) (size_t) p)
    39  #endif
    40  
    41  /* Each block allocated is a separate malloc, for the benefit of a redzoning
    42     malloc debugger during development or when bug hunting.
    43  
    44     Sizes passed when reallocating or freeing are checked (the default
    45     routines don't care about these).
    46  
    47     Memory leaks are checked by requiring that all blocks have been freed
    48     when tests_memory_end() is called.  Test programs must be sure to have
    49     "clear"s for all temporary variables used.  */
    50  
    51  
    52  struct header {
    53    void           *ptr;
    54    size_t         size;
    55    struct header  *next;
    56  };
    57  
    58  struct header  *tests_memory_list = NULL;
    59  
    60  /* Return a pointer to a pointer to the found block (so it can be updated
    61     when unlinking). */
    62  struct header **
    63  tests_memory_find (void *ptr)
    64  {
    65    struct header  **hp;
    66  
    67    for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
    68      if ((*hp)->ptr == ptr)
    69        return hp;
    70  
    71    return NULL;
    72  }
    73  
    74  int
    75  tests_memory_valid (void *ptr)
    76  {
    77    return (tests_memory_find (ptr) != NULL);
    78  }
    79  
    80  void *
    81  tests_allocate (size_t size)
    82  {
    83    struct header  *h;
    84    void *rptr, *ptr;
    85    mp_limb_t PATTERN2_var;
    86  
    87    if (size == 0)
    88      {
    89        fprintf (stderr, "tests_allocate(): attempt to allocate 0 bytes\n");
    90        abort ();
    91      }
    92  
    93    h = (struct header *) __gmp_default_allocate (sizeof (*h));
    94    h->next = tests_memory_list;
    95    tests_memory_list = h;
    96  
    97    rptr = __gmp_default_allocate (size + 2 * sizeof (mp_limb_t));
    98    ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
    99  
   100    *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
   101      = PATTERN1 - PTRLIMB (ptr);
   102    PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
   103    memcpy ((void *) ((gmp_intptr_t) ptr + size), &PATTERN2_var, sizeof (mp_limb_t));
   104  
   105    h->size = size;
   106    h->ptr = ptr;
   107    return h->ptr;
   108  }
   109  
   110  void *
   111  tests_reallocate (void *ptr, size_t old_size, size_t new_size)
   112  {
   113    struct header  **hp, *h;
   114    void *rptr;
   115    mp_limb_t PATTERN2_var;
   116  
   117    if (new_size == 0)
   118      {
   119        fprintf (stderr, "tests_reallocate(): attempt to reallocate %p to 0 bytes\n",
   120  	       ptr);
   121        abort ();
   122      }
   123  
   124    hp = tests_memory_find (ptr);
   125    if (hp == NULL)
   126      {
   127        fprintf (stderr, "tests_reallocate(): attempt to reallocate bad pointer %p\n",
   128  	       ptr);
   129        abort ();
   130      }
   131    h = *hp;
   132  
   133    if (h->size != old_size)
   134      {
   135        fprintf (stderr, "tests_reallocate(): bad old size %lu, should be %lu\n",
   136  	       (unsigned long) old_size, (unsigned long) h->size);
   137        abort ();
   138      }
   139  
   140    if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
   141        != PATTERN1 - PTRLIMB (ptr))
   142      {
   143        fprintf (stderr, "in realloc: redzone clobbered before block\n");
   144        abort ();
   145      }
   146    PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
   147    if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
   148      {
   149        fprintf (stderr, "in realloc: redzone clobbered after block\n");
   150        abort ();
   151      }
   152  
   153    rptr = __gmp_default_reallocate ((void *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)),
   154  				 old_size + 2 * sizeof (mp_limb_t),
   155  				 new_size + 2 * sizeof (mp_limb_t));
   156    ptr = (void *) ((gmp_intptr_t) rptr + sizeof (mp_limb_t));
   157  
   158    *((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
   159      = PATTERN1 - PTRLIMB (ptr);
   160    PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
   161    memcpy ((void *) ((gmp_intptr_t) ptr + new_size), &PATTERN2_var, sizeof (mp_limb_t));
   162  
   163    h->size = new_size;
   164    h->ptr = ptr;
   165    return h->ptr;
   166  }
   167  
   168  struct header **
   169  tests_free_find (void *ptr)
   170  {
   171    struct header  **hp = tests_memory_find (ptr);
   172    if (hp == NULL)
   173      {
   174        fprintf (stderr, "tests_free(): attempt to free bad pointer %p\n",
   175  	       ptr);
   176        abort ();
   177      }
   178    return hp;
   179  }
   180  
   181  void
   182  tests_free_nosize (void *ptr)
   183  {
   184    struct header  **hp = tests_free_find (ptr);
   185    struct header  *h = *hp;
   186    mp_limb_t PATTERN2_var;
   187  
   188    *hp = h->next;  /* unlink */
   189  
   190    if (*((mp_limb_t *) ((gmp_intptr_t) ptr - sizeof (mp_limb_t)))
   191        != PATTERN1 - PTRLIMB (ptr))
   192      {
   193        fprintf (stderr, "in free: redzone clobbered before block\n");
   194        abort ();
   195      }
   196    PATTERN2_var = PATTERN2 - PTRLIMB (ptr);
   197    if (memcmp ((void *) ((gmp_intptr_t) ptr + h->size), &PATTERN2_var, sizeof (mp_limb_t)))
   198      {
   199        fprintf (stderr, "in free: redzone clobbered after block\n");
   200        abort ();
   201      }
   202  
   203    __gmp_default_free ((void *) ((gmp_intptr_t) ptr - sizeof(mp_limb_t)),
   204  		      h->size + 2 * sizeof (mp_limb_t));
   205    __gmp_default_free (h, sizeof (*h));
   206  }
   207  
   208  void
   209  tests_free (void *ptr, size_t size)
   210  {
   211    struct header  **hp = tests_free_find (ptr);
   212    struct header  *h = *hp;
   213  
   214    if (h->size != size)
   215      {
   216        fprintf (stderr, "tests_free(): bad size %lu, should be %lu\n",
   217  	       (unsigned long) size, (unsigned long) h->size);
   218        abort ();
   219      }
   220  
   221    tests_free_nosize (ptr);
   222  }
   223  
   224  void
   225  tests_memory_start (void)
   226  {
   227    mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
   228  }
   229  
   230  void
   231  tests_memory_end (void)
   232  {
   233    if (tests_memory_list != NULL)
   234      {
   235        struct header  *h;
   236        unsigned  count;
   237  
   238        fprintf (stderr, "tests_memory_end(): not all memory freed\n");
   239  
   240        count = 0;
   241        for (h = tests_memory_list; h != NULL; h = h->next)
   242  	count++;
   243  
   244        fprintf (stderr, "    %u blocks remaining\n", count);
   245        abort ();
   246      }
   247  }