modernc.org/ccgo/v3@v3.16.14/lib/testdata/gcc-9.1.0/gcc/testsuite/gcc.c-torture/execute/builtins/memmove-chk.c (about)

     1  /* Copyright (C) 2004, 2005  Free Software Foundation.
     2  
     3     Ensure builtin __memcpy_chk performs correctly.  */
     4  
     5  extern void abort (void);
     6  typedef __SIZE_TYPE__ size_t;
     7  extern size_t strlen(const char *);
     8  extern void *memcpy (void *, const void *, size_t);
     9  extern void *memmove (void *, const void *, size_t);
    10  extern int memcmp (const void *, const void *, size_t);
    11  
    12  #include "chk.h"
    13  
    14  const char s1[] = "123"; 
    15  char p[32] = "";
    16  volatile char *s2 = "defg"; /* prevent constant propagation to happen when whole program assumptions are made.  */
    17  volatile char *s3 = "FGH"; /* prevent constant propagation to happen when whole program assumptions are made.  */
    18  volatile size_t l1 = 1; /* prevent constant propagation to happen when whole program assumptions are made.  */
    19  
    20  void
    21  __attribute__((noinline))
    22  test1 (void)
    23  {
    24    int i;
    25  
    26  #if defined __i386__ || defined __x86_64__
    27    /* The functions below might not be optimized into direct stores on all
    28       arches.  It depends on how many instructions would be generated and
    29       what limits the architecture chooses in STORE_BY_PIECES_P.  */
    30    memmove_disallowed = 1;
    31    memcpy_disallowed = 1;
    32  #endif
    33  
    34    /* All the memmove calls in this routine except last have fixed length, so
    35       object size checking should be done at compile time if optimizing.  */
    36    chk_calls = 0;
    37  
    38    if (memmove (p, "ABCDE", 6) != p || memcmp (p, "ABCDE", 6))
    39      abort ();
    40    if (memmove (p + 16, "VWX" + 1, 2) != p + 16
    41        || memcmp (p + 16, "WX\0\0", 5))
    42      abort ();
    43    if (memmove (p + 1, "", 1) != p + 1 || memcmp (p, "A\0CDE", 6))
    44      abort ();
    45    if (memmove (p + 3, "FGHI", 4) != p + 3 || memcmp (p, "A\0CFGHI", 8))
    46      abort ();
    47  
    48    i = 8;
    49    memmove (p + 20, "qrstu", 6);
    50    memmove (p + 25, "QRSTU", 6);
    51    if (memmove (p + 25 + 1, s1, 3) != p + 25 + 1
    52        || memcmp (p + 25, "Q123U", 6))
    53      abort ();
    54  
    55    if (memmove (memmove (p, "abcdEFG", 4) + 4, "efg", 4) != p + 4
    56        || memcmp (p, "abcdefg", 8))
    57      abort();
    58  
    59    /* Test at least one instance of the __builtin_ style.  We do this
    60       to ensure that it works and that the prototype is correct.  */
    61    if (__builtin_memmove (p, "ABCDE", 6) != p || memcmp (p, "ABCDE", 6))
    62      abort ();
    63  
    64    memmove (p + 5, s3, 1);
    65    if (memcmp (p, "ABCDEFg", 8))
    66      abort ();
    67  
    68    memmove_disallowed = 0;
    69    memcpy_disallowed = 0;
    70    if (chk_calls)
    71      abort ();
    72    chk_calls = 0;
    73  
    74    memmove (p + 6, s1 + 1, l1);
    75    if (memcmp (p, "ABCDEF2", 8))
    76      abort ();
    77  
    78    /* The above memmove copies into an object with known size, but
    79       unknown length, so it should be a __memmove_chk call.  */
    80    if (chk_calls != 1)
    81      abort ();
    82  }
    83  
    84  long buf1[64];
    85  char *buf2 = (char *) (buf1 + 32);
    86  long buf5[20];
    87  char buf7[20];
    88  
    89  void
    90  __attribute__((noinline))
    91  test2_sub (long *buf3, char *buf4, char *buf6, int n)
    92  {
    93    int i = 0;
    94  
    95    /* All the memmove/__builtin_memmove/__builtin___memmove_chk
    96       calls in this routine are either fixed length, or have
    97       side-effects in __builtin_object_size arguments, or
    98       dst doesn't point into a known object.  */
    99    chk_calls = 0;
   100  
   101    /* These should probably be handled by store_by_pieces on most arches.  */
   102    if (memmove (buf1, "ABCDEFGHI", 9) != (char *) buf1
   103        || memcmp (buf1, "ABCDEFGHI\0", 11))
   104      abort ();
   105  
   106    if (memmove (buf1, "abcdefghijklmnopq", 17) != (char *) buf1
   107        || memcmp (buf1, "abcdefghijklmnopq\0", 19))
   108      abort ();
   109  
   110    if (__builtin_memmove (buf3, "ABCDEF", 6) != (char *) buf1
   111        || memcmp (buf1, "ABCDEFghijklmnopq\0", 19))
   112      abort ();
   113  
   114    if (__builtin_memmove (buf3, "a", 1) != (char *) buf1
   115        || memcmp (buf1, "aBCDEFghijklmnopq\0", 19))
   116      abort ();
   117  
   118    if (memmove ((char *) buf3 + 2, "bcd" + ++i, 2) != (char *) buf1 + 2
   119        || memcmp (buf1, "aBcdEFghijklmnopq\0", 19)
   120        || i != 1)
   121      abort ();
   122  
   123    /* These should probably be handled by move_by_pieces on most arches.  */
   124    if (memmove ((char *) buf3 + 4, buf5, 6) != (char *) buf1 + 4
   125        || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
   126      abort ();
   127  
   128    if (__builtin_memmove ((char *) buf1 + ++i + 8, (char *) buf5 + 1, 1)
   129        != (char *) buf1 + 10
   130        || memcmp (buf1, "aBcdRSTUVWSlmnopq\0", 19)
   131        || i != 2)
   132      abort ();
   133  
   134    if (memmove ((char *) buf3 + 14, buf6, 2) != (char *) buf1 + 14
   135        || memcmp (buf1, "aBcdRSTUVWSlmnrsq\0", 19))
   136      abort ();
   137  
   138    if (memmove (buf3, buf5, 8) != (char *) buf1
   139        || memcmp (buf1, "RSTUVWXYVWSlmnrsq\0", 19))
   140      abort ();
   141  
   142    if (memmove (buf3, buf5, 17) != (char *) buf1
   143        || memcmp (buf1, "RSTUVWXYZ01234567\0", 19))
   144      abort ();
   145  
   146    __builtin_memmove (buf3, "aBcdEFghijklmnopq\0", 19);
   147  
   148    /* These should be handled either by movmemendM or memmove
   149       call.  */
   150  
   151    /* buf3 points to an unknown object, so __memmove_chk should not be done.  */
   152    if (memmove ((char *) buf3 + 4, buf5, n + 6) != (char *) buf1 + 4
   153        || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
   154      abort ();
   155  
   156    /* This call has side-effects in dst, therefore no checking.  */
   157    if (__builtin___memmove_chk ((char *) buf1 + ++i + 8, (char *) buf5 + 1,
   158  			       n + 1, os ((char *) buf1 + ++i + 8))
   159        != (char *) buf1 + 11
   160        || memcmp (buf1, "aBcdRSTUVWkSmnopq\0", 19)
   161        || i != 3)
   162      abort ();
   163  
   164    if (memmove ((char *) buf3 + 14, buf6, n + 2) != (char *) buf1 + 14
   165        || memcmp (buf1, "aBcdRSTUVWkSmnrsq\0", 19))
   166      abort ();
   167  
   168    i = 1;
   169  
   170    /* These might be handled by store_by_pieces.  */
   171    if (memmove (buf2, "ABCDEFGHI", 9) != buf2
   172        || memcmp (buf2, "ABCDEFGHI\0", 11))
   173      abort ();
   174  
   175    if (memmove (buf2, "abcdefghijklmnopq", 17) != buf2
   176        || memcmp (buf2, "abcdefghijklmnopq\0", 19))
   177      abort ();
   178  
   179    if (__builtin_memmove (buf4, "ABCDEF", 6) != buf2
   180        || memcmp (buf2, "ABCDEFghijklmnopq\0", 19))
   181      abort ();
   182  
   183    if (__builtin_memmove (buf4, "a", 1) != buf2
   184        || memcmp (buf2, "aBCDEFghijklmnopq\0", 19))
   185      abort ();
   186  
   187    if (memmove (buf4 + 2, "bcd" + i++, 2) != buf2 + 2
   188        || memcmp (buf2, "aBcdEFghijklmnopq\0", 19)
   189        || i != 2)
   190      abort ();
   191  
   192    /* These might be handled by move_by_pieces.  */
   193    if (memmove (buf4 + 4, buf7, 6) != buf2 + 4
   194        || memcmp (buf2, "aBcdRSTUVWklmnopq\0", 19))
   195      abort ();
   196  
   197    /* Side effect.  */
   198    if (__builtin___memmove_chk (buf2 + i++ + 8, buf7 + 1, 1,
   199  			       os (buf2 + i++ + 8))
   200        != buf2 + 10
   201        || memcmp (buf2, "aBcdRSTUVWSlmnopq\0", 19)
   202        || i != 3)
   203      abort ();
   204  
   205    if (memmove (buf4 + 14, buf6, 2) != buf2 + 14
   206        || memcmp (buf2, "aBcdRSTUVWSlmnrsq\0", 19))
   207      abort ();
   208  
   209    __builtin_memmove (buf4, "aBcdEFghijklmnopq\0", 19);
   210  
   211    /* These should be handled either by movmemendM or memmove
   212       call.  */
   213    if (memmove (buf4 + 4, buf7, n + 6) != buf2 + 4
   214        || memcmp (buf2, "aBcdRSTUVWklmnopq\0", 19))
   215      abort ();
   216  
   217    /* Side effect.  */
   218    if (__builtin___memmove_chk (buf2 + i++ + 8, buf7 + 1, n + 1,
   219  			       os (buf2 + i++ + 8))
   220        != buf2 + 11
   221        || memcmp (buf2, "aBcdRSTUVWkSmnopq\0", 19)
   222        || i != 4)
   223      abort ();
   224  
   225    if (memmove (buf4 + 14, buf6, n + 2) != buf2 + 14
   226        || memcmp (buf2, "aBcdRSTUVWkSmnrsq\0", 19))
   227      abort ();
   228  
   229    if (chk_calls)
   230      abort ();
   231  }
   232  
   233  void
   234  __attribute__((noinline))
   235  test2 (void)
   236  {
   237    long *x;
   238    char *y;
   239    int z;
   240    __builtin_memmove (buf5, "RSTUVWXYZ0123456789", 20);
   241    __builtin_memmove (buf7, "RSTUVWXYZ0123456789", 20);
   242   __asm ("" : "=r" (x) : "0" (buf1));
   243   __asm ("" : "=r" (y) : "0" (buf2));
   244   __asm ("" : "=r" (z) : "0" (0));
   245    test2_sub (x, y, "rstuvwxyz", z);
   246  }
   247  
   248  static const struct foo
   249  {
   250    char *s;
   251    double d;
   252    long l;
   253  } foo[] =
   254  {
   255    { "hello world1", 3.14159, 101L },
   256    { "hello world2", 3.14159, 102L },
   257    { "hello world3", 3.14159, 103L },
   258    { "hello world4", 3.14159, 104L },
   259    { "hello world5", 3.14159, 105L },
   260    { "hello world6", 3.14159, 106L }
   261  };
   262  
   263  static const struct bar
   264  {
   265    char *s;
   266    const struct foo f[3];
   267  } bar[] =
   268  {
   269    {
   270      "hello world10",
   271      {
   272        { "hello1", 3.14159, 201L },
   273        { "hello2", 3.14159, 202L },
   274        { "hello3", 3.14159, 203L },
   275      }
   276    },
   277    {
   278      "hello world11",
   279      {
   280        { "hello4", 3.14159, 204L },
   281        { "hello5", 3.14159, 205L },
   282        { "hello6", 3.14159, 206L },
   283      }
   284    }
   285  };
   286  
   287  static const int baz[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
   288  
   289  void
   290  __attribute__((noinline))
   291  test3 (void)
   292  {
   293    const char *s;
   294    struct foo f1[sizeof foo/sizeof*foo];
   295    struct bar b1[sizeof bar/sizeof*bar];
   296    int bz[sizeof baz/sizeof*baz];
   297  
   298    /* All the memmove/__builtin_memmove calls in this routine have fixed
   299       length.  */
   300    chk_calls = 0;
   301  
   302    /* All the *memmove calls below have src in read-only memory, so all
   303       of them should be optimized into memcpy.  */
   304    memmove_disallowed = 1;
   305    if (memmove (f1, foo, sizeof (foo)) != f1 || memcmp (f1, foo, sizeof (foo)))
   306      abort ();
   307    if (memmove (b1, bar, sizeof (bar)) != b1 || memcmp (b1, bar, sizeof (bar)))
   308      abort ();
   309    memmove (bz, baz, sizeof (baz));
   310    if (memcmp (bz, baz, sizeof (baz)))
   311      abort ();
   312  
   313    if (memmove (p, "abcde", 6) != p || memcmp (p, "abcde", 6))
   314      abort ();
   315    s = s1;
   316    if (memmove (p + 2, ++s, 0) != p + 2 || memcmp (p, "abcde", 6) || s != s1 + 1)
   317      abort ();
   318    if (__builtin_memmove (p + 3, "", 1) != p + 3 || memcmp (p, "abc\0e", 6))
   319      abort ();
   320    memmove (p + 2, "fghijk", 4);
   321    if (memcmp (p, "abfghi", 7))
   322      abort ();
   323    s = s1 + 1;
   324    memmove (p + 1, s++, 0);
   325    if (memcmp (p, "abfghi", 7) || s != s1 + 2)
   326      abort ();
   327    __builtin_memmove (p + 4, "ABCDE", 1);
   328    if (memcmp (p, "abfgAi", 7))
   329      abort ();
   330  
   331    /* memmove with length 1 can be optimized into memcpy if it can be
   332       expanded inline.  */
   333    if (memmove (p + 2, p + 3, 1) != p + 2)
   334      abort ();
   335    if (memcmp (p, "abggAi", 7))
   336      abort ();
   337  
   338    if (chk_calls)
   339      abort ();
   340    memmove_disallowed = 0;
   341  }
   342  
   343  /* Test whether compile time checking is done where it should
   344     and so is runtime object size checking.  */
   345  void
   346  __attribute__((noinline))
   347  test4 (void)
   348  {
   349    struct A { char buf1[10]; char buf2[10]; } a;
   350    char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
   351    char buf3[20];
   352    int i;
   353    size_t l;
   354  
   355    /* The following calls should do runtime checking
   356       - length is not known, but destination is.  */
   357    chk_calls = 0;
   358    memmove (a.buf1 + 2, s3, l1);
   359    memmove (r, s3, l1 + 1);
   360    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   361    memmove (r, s2, l1 + 2);
   362    memmove (r + 2, s3, l1);
   363    r = buf3;
   364    for (i = 0; i < 4; ++i)
   365      {
   366        if (i == l1 - 1)
   367  	r = &a.buf1[1];
   368        else if (i == l1)
   369  	r = &a.buf2[7];
   370        else if (i == l1 + 1)
   371  	r = &buf3[5];
   372        else if (i == l1 + 2)
   373  	r = &a.buf1[9];
   374      }
   375    memmove (r, s2, l1);
   376    if (chk_calls != 5)
   377      abort ();
   378  
   379    /* Following have known destination and known length,
   380       so if optimizing certainly shouldn't result in the checking
   381       variants.  */
   382    chk_calls = 0;
   383    memmove (a.buf1 + 2, s3, 1);
   384    memmove (r, s3, 2);
   385    r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
   386    memmove (r, s2, 3);
   387    r = buf3;
   388    l = 4;
   389    for (i = 0; i < 4; ++i)
   390      {
   391        if (i == l1 - 1)
   392  	r = &a.buf1[1], l = 2;
   393        else if (i == l1)
   394  	r = &a.buf2[7], l = 3;
   395        else if (i == l1 + 1)
   396  	r = &buf3[5], l = 4;
   397        else if (i == l1 + 2)
   398  	r = &a.buf1[9], l = 1;
   399      }
   400    memmove (r, s2, 1);
   401    /* Here, l is known to be at most 4 and __builtin_object_size (&buf3[16], 0)
   402       is 4, so this doesn't need runtime checking.  */
   403    memmove (&buf3[16], s2, l);
   404    if (chk_calls)
   405      abort ();
   406    chk_calls = 0;
   407  }
   408  
   409  /* Test whether runtime and/or compile time checking catches
   410     buffer overflows.  */
   411  void
   412  __attribute__((noinline))
   413  test5 (void)
   414  {
   415    struct A { char buf1[10]; char buf2[10]; } a;
   416    char buf3[20];
   417  
   418    chk_fail_allowed = 1;
   419    /* Runtime checks.  */
   420    if (__builtin_setjmp (chk_fail_buf) == 0)
   421      {
   422        memmove (&a.buf2[9], s2, l1 + 1);
   423        abort ();
   424      }
   425    if (__builtin_setjmp (chk_fail_buf) == 0)
   426      {
   427        memmove (&a.buf2[7], s3, strlen (s3) + 1);
   428        abort ();
   429      }
   430    /* This should be detectable at compile time already.  */
   431    if (__builtin_setjmp (chk_fail_buf) == 0)
   432      {
   433        memmove (&buf3[19], "ab", 2);
   434        abort ();
   435      }
   436    chk_fail_allowed = 0;
   437  }
   438  
   439  #ifndef MAX_OFFSET
   440  #define MAX_OFFSET (sizeof (long long))
   441  #endif
   442  
   443  #ifndef MAX_COPY
   444  #define MAX_COPY (10 * sizeof (long long))
   445  #endif
   446  
   447  #ifndef MAX_EXTRA
   448  #define MAX_EXTRA (sizeof (long long))
   449  #endif
   450  
   451  #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
   452  
   453  /* Use a sequence length that is not divisible by two, to make it more
   454     likely to detect when words are mixed up.  */
   455  #define SEQUENCE_LENGTH 31
   456  
   457  static union {
   458    char buf[MAX_LENGTH];
   459    long long align_int;
   460    long double align_fp;
   461  } u1, u2;
   462  
   463  void
   464  __attribute__((noinline))
   465  test6 (void)
   466  {
   467    int off1, off2, len, i;
   468    char *p, *q, c;
   469  
   470    for (off1 = 0; off1 < MAX_OFFSET; off1++)
   471      for (off2 = 0; off2 < MAX_OFFSET; off2++)
   472        for (len = 1; len < MAX_COPY; len++)
   473  	{
   474  	  for (i = 0, c = 'A'; i < MAX_LENGTH; i++, c++)
   475  	    {
   476  	      u1.buf[i] = 'a';
   477  	      if (c >= 'A' + SEQUENCE_LENGTH)
   478  		c = 'A';
   479  	      u2.buf[i] = c;
   480  	    }
   481  
   482  	  p = memmove (u1.buf + off1, u2.buf + off2, len);
   483  	  if (p != u1.buf + off1)
   484  	    abort ();
   485  
   486  	  q = u1.buf;
   487  	  for (i = 0; i < off1; i++, q++)
   488  	    if (*q != 'a')
   489  	      abort ();
   490  
   491  	  for (i = 0, c = 'A' + off2; i < len; i++, q++, c++)
   492  	    {
   493  	      if (c >= 'A' + SEQUENCE_LENGTH)
   494  		c = 'A';
   495  	      if (*q != c)
   496  		abort ();
   497  	    }
   498  
   499  	  for (i = 0; i < MAX_EXTRA; i++, q++)
   500  	    if (*q != 'a')
   501  	      abort ();
   502  	}
   503  }
   504  
   505  #define TESTSIZE 80
   506  
   507  char srcb[TESTSIZE] __attribute__ ((aligned));
   508  char dstb[TESTSIZE] __attribute__ ((aligned));
   509  
   510  void
   511  __attribute__((noinline))
   512  check (char *test, char *match, int n)
   513  {
   514    if (memcmp (test, match, n))
   515      abort ();
   516  }
   517  
   518  #define TN(n) \
   519  { memset (dstb, 0, n); memmove (dstb, srcb, n); check (dstb, srcb, n); }
   520  #define T(n) \
   521  TN (n) \
   522  TN ((n) + 1) \
   523  TN ((n) + 2) \
   524  TN ((n) + 3)
   525  
   526  void
   527  __attribute__((noinline))
   528  test7 (void)
   529  {
   530    int i;
   531  
   532    chk_calls = 0;
   533  
   534    for (i = 0; i < sizeof (srcb); ++i)
   535        srcb[i] = 'a' + i % 26;
   536  
   537    T (0);
   538    T (4);
   539    T (8);
   540    T (12);
   541    T (16);
   542    T (20);
   543    T (24);
   544    T (28);
   545    T (32);
   546    T (36);
   547    T (40);
   548    T (44);
   549    T (48);
   550    T (52);
   551    T (56);
   552    T (60);
   553    T (64);
   554    T (68);
   555    T (72);
   556    T (76);
   557  
   558    /* All memmove calls in this routine have constant arguments.  */
   559    if (chk_calls)
   560      abort ();
   561  }
   562  
   563  void
   564  main_test (void)
   565  {
   566  #ifndef __OPTIMIZE__
   567    /* Object size checking is only intended for -O[s123].  */
   568    return;
   569  #endif
   570    __asm ("" : "=r" (l1) : "0" (l1));
   571    test1 ();
   572    test2 ();
   573    __builtin_memset (p, '\0', sizeof (p));
   574    test3 ();
   575    test4 ();
   576    test5 ();
   577    test6 ();
   578    test7 ();
   579  }