(root)/
glibc-2.38/
support/
tst-support_blob_repeat.c
       1  /* Tests for <support/blob_repeat.h>
       2     Copyright (C) 2018-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 <stdio.h>
      20  #include <string.h>
      21  #include <support/blob_repeat.h>
      22  #include <support/check.h>
      23  
      24  static int
      25  do_test (void)
      26  {
      27    struct support_blob_repeat repeat
      28      = support_blob_repeat_allocate ("5", 1, 5);
      29    TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5);
      30    support_blob_repeat_free (&repeat);
      31  
      32    repeat = support_blob_repeat_allocate ("ABC", 3, 3);
      33    TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9);
      34    support_blob_repeat_free (&repeat);
      35  
      36    repeat = support_blob_repeat_allocate ("abc", 4, 3);
      37    TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12);
      38    support_blob_repeat_free (&repeat);
      39  
      40    size_t gigabyte = 1U << 30;
      41    repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1);
      42    if (repeat.start == NULL)
      43      puts ("warning: not enough memory for 1 GiB mapping");
      44    else
      45      {
      46        TEST_COMPARE (repeat.size, gigabyte + 1);
      47        {
      48          unsigned char *p = repeat.start;
      49          for (size_t i = 0; i < gigabyte + 1; ++i)
      50            if (p[i] != 'X')
      51              FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
      52  
      53          /* Check that there is no sharing across the mapping.  */
      54          p[0] = 'Y';
      55          p[1U << 24] = 'Z';
      56          for (size_t i = 0; i < gigabyte + 1; ++i)
      57            if (i == 0)
      58              TEST_COMPARE (p[i], 'Y');
      59            else if (i == 1U << 24)
      60              TEST_COMPARE (p[i], 'Z');
      61            else if (p[i] != 'X')
      62              FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
      63        }
      64      }
      65    support_blob_repeat_free (&repeat);
      66  
      67    for (int do_shared = 0; do_shared < 2; ++do_shared)
      68      {
      69        if (do_shared)
      70          repeat = support_blob_repeat_allocate_shared ("012345678", 9,
      71                                                        10 * 1000 * 1000);
      72        else
      73          repeat = support_blob_repeat_allocate ("012345678", 9,
      74                                                 10 * 1000 * 1000);
      75        if (repeat.start == NULL)
      76          puts ("warning: not enough memory for large mapping");
      77        else
      78          {
      79            unsigned char *p = repeat.start;
      80            for (int i = 0; i < 10 * 1000 * 1000; ++i)
      81              for (int j = 0; j <= 8; ++j)
      82                if (p[i * 9 + j] != '0' + j)
      83                  {
      84                    printf ("error: element %d index %d\n", i, j);
      85                    TEST_COMPARE (p[i * 9 + j], '0' + j);
      86                  }
      87  
      88            enum { total_size = 9 * 10 * 1000 * 1000 };
      89            p[total_size - 1] = '\0';
      90            asm ("" ::: "memory");
      91            if (do_shared)
      92              /* The write is repeated in multiple places earlier in the
      93                 string due to page sharing.  */
      94              TEST_VERIFY (strlen (repeat.start) < total_size - 1);
      95            else
      96              TEST_COMPARE (strlen (repeat.start), total_size - 1);
      97          }
      98        support_blob_repeat_free (&repeat);
      99      }
     100  
     101    return 0;
     102  }
     103  
     104  #include <support/test-driver.c>