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

     1  /*
     2  
     3  Copyright 2013-2015, 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 "testutils.h"
    21  
    22  /* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
    23     works. */
    24  #include "../mini-gmp.c"
    25  
    26  static size_t total_alloc = 0;
    27  
    28  /* Custom memory allocation to track memory usage, and add a small red
    29     zone.
    30  
    31     About alignment: In general, getting a block from malloc, and
    32     incrementing it by sizeof(size_t), like we do here, might give a
    33     pointer which is not properly aligned for all types. But the
    34     largest type we allocate space for is unsigned long (mp_limb_t),
    35     which shouldn't have stricter alignment requirements than
    36     size_t. */
    37  
    38  static unsigned char block_end[8] =
    39    { 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 };
    40  
    41  static void *
    42  block_init (size_t *block, size_t size)
    43  {
    44    char *p;
    45    *block++ = size;
    46  
    47    p = (char *) block;
    48    memcpy (p + size, block_end, sizeof(block_end));
    49  
    50    total_alloc += size;
    51    return p;
    52  }
    53  
    54  /* Check small redzone, return pointer to malloced block. */
    55  static size_t *
    56  block_check  (void *p)
    57  {
    58    size_t *block = (size_t *) p - 1;
    59    size_t size = block[0];
    60  
    61    if (memcmp ((char *)p + size, block_end, sizeof(block_end)) != 0)
    62      {
    63        fprintf (stderr, "red zone overwritten.\n");
    64        abort ();
    65      }
    66    total_alloc -= size;
    67    return block;
    68  }
    69  
    70  static void *
    71  tu_alloc (size_t size)
    72  {
    73    size_t *block = (size_t *) malloc (sizeof(size_t) + size + sizeof(block_end));
    74    if (!block)
    75      {
    76        fprintf (stderr, "Virtual memory exhausted.\n");
    77        abort ();
    78      }
    79  
    80    return block_init (block, size);
    81  }
    82  
    83  static void *
    84  tu_realloc (void *p, size_t old_size, size_t new_size)
    85  {
    86    size_t *block = block_check (p);
    87    block = (size_t *) realloc (block, sizeof(size_t) + new_size + sizeof(block_end));
    88    if (!block)
    89      {
    90        fprintf (stderr, "Virtual memory exhausted.\n");
    91        abort ();
    92      }
    93  
    94    return block_init (block, new_size);
    95  }
    96  
    97  static void
    98  tu_free (void *p, size_t old_size)
    99  {
   100    free (block_check (p));
   101  }
   102  
   103  /* Free memory allocated via mini-gmp allocation function. */
   104  void
   105  testfree (void *p)
   106  {
   107    void (*freefunc) (void *, size_t);
   108    mp_get_memory_functions (NULL, NULL, &freefunc);
   109  
   110    freefunc (p, 0);
   111  }
   112  
   113  int
   114  main (int argc, char **argv)
   115  {
   116    hex_random_init ();
   117  
   118    mp_set_memory_functions (tu_alloc, tu_realloc, tu_free);
   119  
   120    /* Currently, t-comb seems to be the only program accepting any
   121       arguments. It might make sense to parse common arguments here. */
   122    testmain (argc, argv);
   123  
   124    if (total_alloc != 0)
   125      {
   126        fprintf (stderr, "Memory leaked: %lu bytes.\n",
   127  	       (unsigned long) total_alloc);
   128        abort ();
   129      }
   130    return 0;
   131  }
   132  
   133  void
   134  testhalves (int count, void (*tested_fun) (int))
   135  {
   136    void (*freefunc) (void *, size_t);
   137    void *(*reallocfunc) (void *, size_t, size_t);
   138    void *(*allocfunc) (size_t);
   139    size_t initial_alloc;
   140  
   141    mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc);
   142    initial_alloc = total_alloc;
   143    (*tested_fun) (count / 2);
   144    if (initial_alloc != total_alloc)
   145      {
   146        fprintf (stderr, "First half, memory leaked: %lu bytes.\n",
   147  	       (unsigned long) total_alloc - initial_alloc);
   148        abort ();
   149      }
   150    mp_set_memory_functions (NULL, NULL, NULL);
   151    (*tested_fun) (count / 2);
   152    mp_set_memory_functions (allocfunc, reallocfunc, freefunc);
   153  }
   154  
   155  void
   156  dump (const char *label, const mpz_t x)
   157  {
   158    char *buf = mpz_get_str (NULL, 16, x);
   159    fprintf (stderr, "%s: %s\n", label, buf);
   160    testfree (buf);
   161  }
   162  
   163  void
   164  mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
   165  {
   166    if (mpz_set_str (z, str, base) != 0)
   167      {
   168        fprintf (stderr, "ERROR: mpz_set_str failed\n");
   169        fprintf (stderr, "   str  = \"%s\"\n", str);
   170        fprintf (stderr, "   base = %d\n", base);
   171        abort();
   172      }
   173  }