(root)/
glibc-2.38/
benchtests/
bench-strcpy_chk.c
       1  /* Measure __strcpy_chk functions.
       2     Copyright (C) 2013-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  #ifndef STRCPY_RESULT
      20  # define STRCPY_RESULT(dst, len) dst
      21  # define TEST_MAIN
      22  # define TEST_NAME "strcpy_chk"
      23  # include "bench-string.h"
      24  
      25  /* This test case implicitly tests the availability of the __chk_fail
      26     symbol, which is part of the public ABI and may be used
      27     externally. */
      28  extern void __attribute__ ((noreturn)) __chk_fail (void);
      29  extern char *normal_strcpy (char *, const char *, size_t)
      30    __asm ("strcpy");
      31  extern char *__strcpy_chk (char *, const char *, size_t);
      32  
      33  IMPL (normal_strcpy, 1)
      34  IMPL (__strcpy_chk, 2)
      35  
      36  #endif
      37  
      38  #include <fcntl.h>
      39  #include <paths.h>
      40  #include <setjmp.h>
      41  #include <signal.h>
      42  
      43  #include <support/support.h>
      44  
      45  volatile int chk_fail_ok;
      46  jmp_buf chk_fail_buf;
      47  
      48  static void
      49  handler (int sig)
      50  {
      51    if (chk_fail_ok)
      52      {
      53        chk_fail_ok = 0;
      54        longjmp (chk_fail_buf, 1);
      55      }
      56    else
      57      _exit (127);
      58  }
      59  
      60  typedef char *(*proto_t) (char *, const char *, size_t);
      61  
      62  static void
      63  do_one_test (impl_t *impl, char *dst, const char *src,
      64  	     size_t len, size_t dlen)
      65  {
      66    char *res;
      67    size_t i, iters = INNER_LOOP_ITERS_LARGE;
      68    timing_t start, stop, cur;
      69  
      70    if (dlen <= len)
      71      {
      72        if (impl->test == 1)
      73  	return;
      74  
      75        chk_fail_ok = 1;
      76        if (setjmp (chk_fail_buf) == 0)
      77  	{
      78  	  res = CALL (impl, dst, src, dlen);
      79  	  printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
      80  		  impl->name, len, dlen);
      81  	  chk_fail_ok = 0;
      82  	  ret = 1;
      83  	}
      84        return;
      85      }
      86    else
      87      res = CALL (impl, dst, src, dlen);
      88  
      89    if (res != STRCPY_RESULT (dst, len))
      90      {
      91        printf ("Wrong result in function %s %p %p\n", impl->name,
      92  	      res, STRCPY_RESULT (dst, len));
      93        ret = 1;
      94        return;
      95      }
      96  
      97    if (strcmp (dst, src) != 0)
      98      {
      99        printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
     100  	      impl->name, dst, src);
     101        ret = 1;
     102        return;
     103      }
     104  
     105    TIMING_NOW (start);
     106    for (i = 0; i < iters; ++i)
     107      {
     108        CALL (impl, dst, src, dlen);
     109      }
     110    TIMING_NOW (stop);
     111  
     112    TIMING_DIFF (cur, start, stop);
     113  
     114    TIMING_PRINT_MEAN ((double) cur, (double) iters);
     115  }
     116  
     117  static void
     118  do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
     119  {
     120    size_t i;
     121    char *s1, *s2;
     122  
     123    align1 &= 7;
     124    if (align1 + len >= page_size)
     125      return;
     126  
     127    align2 &= 7;
     128    if (align2 + len >= page_size)
     129      return;
     130  
     131    s1 = (char *) buf1 + align1;
     132    s2 = (char *) buf2 + align2;
     133  
     134    for (i = 0; i < len; i++)
     135      s1[i] = 32 + 23 * i % (max_char - 32);
     136    s1[len] = 0;
     137  
     138    if (dlen > len)
     139      printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
     140  
     141    FOR_EACH_IMPL (impl, 0)
     142      do_one_test (impl, s2, s1, len, dlen);
     143  
     144    if (dlen > len)
     145      putchar ('\n');
     146  }
     147  
     148  static int
     149  test_main (void)
     150  {
     151    size_t i;
     152  
     153    set_fortify_handler (handler);
     154  
     155    test_init ();
     156  
     157    printf ("%23s", "");
     158    FOR_EACH_IMPL (impl, 0)
     159      printf ("\t%s", impl->name);
     160    putchar ('\n');
     161  
     162    for (i = 0; i < 16; ++i)
     163      {
     164        do_test (0, 0, i, i + 1, 127);
     165        do_test (0, 0, i, i + 1, 255);
     166        do_test (0, i, i, i + 1, 127);
     167        do_test (i, 0, i, i + 1, 255);
     168      }
     169  
     170    for (i = 1; i < 8; ++i)
     171      {
     172        do_test (0, 0, 8 << i, (8 << i) + 1, 127);
     173        do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
     174      }
     175  
     176    for (i = 1; i < 8; ++i)
     177      {
     178        do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
     179        do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
     180        do_test (i, i, (8 << i), (8 << i) + 1, 127);
     181        do_test (i, i, (8 << i), (8 << i) + 1, 255);
     182      }
     183  
     184    for (i = 0; i < 16; ++i)
     185      {
     186        do_test (0, 0, i, i + 256, 127);
     187        do_test (0, 0, i, i + 256, 255);
     188        do_test (0, i, i, i + 256, 127);
     189        do_test (i, 0, i, i + 256, 255);
     190      }
     191  
     192    for (i = 1; i < 8; ++i)
     193      {
     194        do_test (0, 0, 8 << i, (8 << i) + 256, 127);
     195        do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
     196      }
     197  
     198    for (i = 1; i < 8; ++i)
     199      {
     200        do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
     201        do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
     202        do_test (i, i, (8 << i), (8 << i) + 256, 127);
     203        do_test (i, i, (8 << i), (8 << i) + 256, 255);
     204      }
     205  
     206    for (i = 0; i < 16; ++i)
     207      {
     208        do_test (0, 0, i, i, 127);
     209        do_test (0, 0, i, i + 2, 255);
     210        do_test (0, i, i, i + 3, 127);
     211        do_test (i, 0, i, i + 4, 255);
     212      }
     213  
     214    for (i = 1; i < 8; ++i)
     215      {
     216        do_test (0, 0, 8 << i, (8 << i) - 15, 127);
     217        do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
     218      }
     219  
     220    for (i = 1; i < 8; ++i)
     221      {
     222        do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
     223        do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
     224        do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
     225        do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
     226      }
     227  
     228    return 0;
     229  }
     230  
     231  #include <support/test-driver.c>