modernc.org/cc@v1.0.1/testdata/gcc-6.3.0/gcc/testsuite/gcc.c-torture/execute/builtins/lib/chk.c (about)

     1  #include <stdarg.h>
     2  #ifdef __unix__
     3  #include <sys/types.h>
     4  #endif
     5  
     6  extern void abort (void);
     7  
     8  extern int inside_main;
     9  void *chk_fail_buf[256] __attribute__((aligned (16)));
    10  volatile int chk_fail_allowed, chk_calls;
    11  volatile int memcpy_disallowed, mempcpy_disallowed, memmove_disallowed;
    12  volatile int memset_disallowed, strcpy_disallowed, stpcpy_disallowed;
    13  volatile int strncpy_disallowed, stpncpy_disallowed, strcat_disallowed;
    14  volatile int strncat_disallowed, sprintf_disallowed, vsprintf_disallowed;
    15  volatile int snprintf_disallowed, vsnprintf_disallowed;
    16  extern __SIZE_TYPE__ strlen (const char *);
    17  extern int vsprintf (char *, const char *, va_list);
    18  
    19  void __attribute__((noreturn))
    20  __chk_fail (void)
    21  {
    22    if (chk_fail_allowed)
    23      __builtin_longjmp (chk_fail_buf, 1);
    24    abort ();
    25  }
    26  
    27  void *
    28  memcpy (void *dst, const void *src, __SIZE_TYPE__ n)
    29  {
    30    const char *srcp;
    31    char *dstp;
    32  
    33  #ifdef __OPTIMIZE__
    34    if (memcpy_disallowed && inside_main)
    35      abort ();
    36  #endif
    37  
    38    srcp = src;
    39    dstp = dst;
    40    while (n-- != 0)
    41      *dstp++ = *srcp++;
    42  
    43    return dst;
    44  }
    45  
    46  void *
    47  __memcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
    48  {
    49    /* If size is -1, GCC should always optimize the call into memcpy.  */
    50    if (size == (__SIZE_TYPE__) -1)
    51      abort ();
    52    ++chk_calls;
    53    if (n > size)
    54      __chk_fail ();
    55    return memcpy (dst, src, n);
    56  }
    57  
    58  void *
    59  mempcpy (void *dst, const void *src, __SIZE_TYPE__ n)
    60  {
    61    const char *srcp;
    62    char *dstp;
    63  
    64  #ifdef __OPTIMIZE__
    65    if (mempcpy_disallowed && inside_main)
    66      abort ();
    67  #endif
    68  
    69    srcp = src;
    70    dstp = dst;
    71    while (n-- != 0)
    72      *dstp++ = *srcp++;
    73  
    74    return dstp;
    75  }
    76  
    77  void *
    78  __mempcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
    79  {
    80    /* If size is -1, GCC should always optimize the call into mempcpy.  */
    81    if (size == (__SIZE_TYPE__) -1)
    82      abort ();
    83    ++chk_calls;
    84    if (n > size)
    85      __chk_fail ();
    86    return mempcpy (dst, src, n);
    87  }
    88  
    89  void *
    90  memmove (void *dst, const void *src, __SIZE_TYPE__ n)
    91  {
    92    const char *srcp;
    93    char *dstp;
    94  
    95  #ifdef __OPTIMIZE__
    96    if (memmove_disallowed && inside_main)
    97      abort ();
    98  #endif
    99  
   100    srcp = src;
   101    dstp = dst;
   102    if (srcp < dstp)
   103      while (n-- != 0)
   104        dstp[n] = srcp[n];
   105    else
   106      while (n-- != 0)
   107        *dstp++ = *srcp++;
   108  
   109    return dst;
   110  }
   111  
   112  void *
   113  __memmove_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
   114  {
   115    /* If size is -1, GCC should always optimize the call into memmove.  */
   116    if (size == (__SIZE_TYPE__) -1)
   117      abort ();
   118    ++chk_calls;
   119    if (n > size)
   120      __chk_fail ();
   121    return memmove (dst, src, n);
   122  }
   123  
   124  void *
   125  memset (void *dst, int c, __SIZE_TYPE__ n)
   126  {
   127    while (n-- != 0)
   128      n[(char *) dst] = c;
   129  
   130    /* Single-byte memsets should be done inline when optimisation
   131       is enabled.  Do this after the copy in case we're being called to
   132       initialize bss.  */
   133  #ifdef __OPTIMIZE__
   134    if (memset_disallowed && inside_main && n < 2)
   135      abort ();
   136  #endif
   137  
   138    return dst;
   139  }
   140  
   141  void *
   142  __memset_chk (void *dst, int c, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
   143  {
   144    /* If size is -1, GCC should always optimize the call into memset.  */
   145    if (size == (__SIZE_TYPE__) -1)
   146      abort ();
   147    ++chk_calls;
   148    if (n > size)
   149      __chk_fail ();
   150    return memset (dst, c, n);
   151  }
   152  
   153  char *
   154  strcpy (char *d, const char *s)
   155  {
   156    char *r = d;
   157  #ifdef __OPTIMIZE__
   158    if (strcpy_disallowed && inside_main)
   159      abort ();
   160  #endif
   161    while ((*d++ = *s++));
   162    return r;
   163  }
   164  
   165  char *
   166  __strcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
   167  {
   168    /* If size is -1, GCC should always optimize the call into strcpy.  */
   169    if (size == (__SIZE_TYPE__) -1)
   170      abort ();
   171    ++chk_calls;
   172    if (strlen (s) >= size)
   173      __chk_fail ();
   174    return strcpy (d, s);
   175  }
   176  
   177  char *
   178  stpcpy (char *dst, const char *src)
   179  {
   180  #ifdef __OPTIMIZE__
   181    if (stpcpy_disallowed && inside_main)
   182      abort ();
   183  #endif
   184  
   185    while (*src != 0)
   186      *dst++ = *src++;
   187  
   188    *dst = 0;
   189    return dst;
   190  }
   191  
   192  char *
   193  __stpcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
   194  {
   195    /* If size is -1, GCC should always optimize the call into stpcpy.  */
   196    if (size == (__SIZE_TYPE__) -1)
   197      abort ();
   198    ++chk_calls;
   199    if (strlen (s) >= size)
   200      __chk_fail ();
   201    return stpcpy (d, s);
   202  }
   203  
   204  char *
   205  stpncpy (char *dst, const char *src, __SIZE_TYPE__ n)
   206  {
   207  #ifdef __OPTIMIZE__
   208    if (stpncpy_disallowed && inside_main)
   209      abort ();
   210  #endif
   211  
   212    for (; *src && n; n--)
   213      *dst++ = *src++;
   214  
   215    char *ret = dst;
   216  
   217    while (n--)
   218      *dst++ = 0;
   219  
   220    return ret;
   221  }
   222  
   223  
   224  char *
   225  __stpncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
   226  {
   227    /* If size is -1, GCC should always optimize the call into stpncpy.  */
   228    if (size == (__SIZE_TYPE__) -1)
   229      abort ();
   230    ++chk_calls;
   231    if (n > size)
   232      __chk_fail ();
   233    return stpncpy (s1, s2, n);
   234  }
   235  
   236  char *
   237  strncpy (char *s1, const char *s2, __SIZE_TYPE__ n)
   238  {
   239    char *dest = s1;
   240  #ifdef __OPTIMIZE__
   241    if (strncpy_disallowed && inside_main)
   242      abort();
   243  #endif
   244    for (; *s2 && n; n--)
   245      *s1++ = *s2++;
   246    while (n--)
   247      *s1++ = 0;
   248    return dest;
   249  }
   250  
   251  char *
   252  __strncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
   253  {
   254    /* If size is -1, GCC should always optimize the call into strncpy.  */
   255    if (size == (__SIZE_TYPE__) -1)
   256      abort ();
   257    ++chk_calls;
   258    if (n > size)
   259      __chk_fail ();
   260    return strncpy (s1, s2, n);
   261  }
   262  
   263  char *
   264  strcat (char *dst, const char *src)
   265  {
   266    char *p = dst;
   267    
   268  #ifdef __OPTIMIZE__
   269    if (strcat_disallowed && inside_main)
   270      abort ();
   271  #endif
   272  
   273    while (*p)
   274      p++;
   275    while ((*p++ = *src++))
   276      ;
   277    return dst;
   278  }
   279  
   280  char *
   281  __strcat_chk (char *d, const char *s, __SIZE_TYPE__ size)
   282  {
   283    /* If size is -1, GCC should always optimize the call into strcat.  */
   284    if (size == (__SIZE_TYPE__) -1)
   285      abort ();
   286    ++chk_calls;
   287    if (strlen (d) + strlen (s) >= size)
   288      __chk_fail ();
   289    return strcat (d, s);
   290  }
   291  
   292  char *
   293  strncat (char *s1, const char *s2, __SIZE_TYPE__ n)
   294  {
   295    char *dest = s1;
   296    char c;
   297  #ifdef __OPTIMIZE__
   298    if (strncat_disallowed && inside_main)
   299      abort();
   300  #endif
   301    while (*s1) s1++;
   302    c = '\0';
   303    while (n > 0)
   304      {
   305        c = *s2++;
   306        *s1++ = c;
   307        if (c == '\0')
   308  	return dest;
   309        n--;
   310      }
   311    if (c != '\0')
   312      *s1 = '\0';
   313    return dest;
   314  }
   315  
   316  char *
   317  __strncat_chk (char *d, const char *s, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
   318  {
   319    __SIZE_TYPE__ len = strlen (d), n1 = n;
   320    const char *s1 = s;
   321  
   322    /* If size is -1, GCC should always optimize the call into strncat.  */
   323    if (size == (__SIZE_TYPE__) -1)
   324      abort ();
   325    ++chk_calls;
   326    while (len < size && n1 > 0)
   327      {
   328        if (*s1++ == '\0')
   329  	break;
   330        ++len;
   331        --n1;
   332      }
   333  
   334    if (len >= size)
   335      __chk_fail ();
   336    return strncat (d, s, n);
   337  }
   338  
   339  /* No chk test in GCC testsuite needs more bytes than this.
   340     As we can't expect vsnprintf to be available on the target,
   341     assume 4096 bytes is enough.  */
   342  static char chk_sprintf_buf[4096];
   343  
   344  int
   345  __sprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt, ...)
   346  {
   347    int ret;
   348    va_list ap;
   349  
   350    /* If size is -1 and flag 0, GCC should always optimize the call into
   351       sprintf.  */
   352    if (size == (__SIZE_TYPE__) -1 && flag == 0)
   353      abort ();
   354    ++chk_calls;
   355  #ifdef __OPTIMIZE__
   356    if (sprintf_disallowed && inside_main)
   357      abort();
   358  #endif
   359    va_start (ap, fmt);
   360    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   361    va_end (ap);
   362    if (ret >= 0)
   363      {
   364        if (ret >= size)
   365  	__chk_fail ();
   366        memcpy (str, chk_sprintf_buf, ret + 1);
   367      }
   368    return ret;
   369  }
   370  
   371  int
   372  __vsprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt,
   373  		va_list ap)
   374  {
   375    int ret;
   376  
   377    /* If size is -1 and flag 0, GCC should always optimize the call into
   378       vsprintf.  */
   379    if (size == (__SIZE_TYPE__) -1 && flag == 0)
   380      abort ();
   381    ++chk_calls;
   382  #ifdef __OPTIMIZE__
   383    if (vsprintf_disallowed && inside_main)
   384      abort();
   385  #endif
   386    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   387    if (ret >= 0)
   388      {
   389        if (ret >= size)
   390  	__chk_fail ();
   391        memcpy (str, chk_sprintf_buf, ret + 1);
   392      }
   393    return ret;
   394  }
   395  
   396  int
   397  __snprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
   398  		const char *fmt, ...)
   399  {
   400    int ret;
   401    va_list ap;
   402  
   403    /* If size is -1 and flag 0, GCC should always optimize the call into
   404       snprintf.  */
   405    if (size == (__SIZE_TYPE__) -1 && flag == 0)
   406      abort ();
   407    ++chk_calls;
   408    if (size < len)
   409      __chk_fail ();
   410  #ifdef __OPTIMIZE__
   411    if (snprintf_disallowed && inside_main)
   412      abort();
   413  #endif
   414    va_start (ap, fmt);
   415    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   416    va_end (ap);
   417    if (ret >= 0)
   418      {
   419        if (ret < len)
   420  	memcpy (str, chk_sprintf_buf, ret + 1);
   421        else
   422  	{
   423  	  memcpy (str, chk_sprintf_buf, len - 1);
   424  	  str[len - 1] = '\0';
   425  	}
   426      }
   427    return ret;
   428  }
   429  
   430  int
   431  __vsnprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
   432  		 const char *fmt, va_list ap)
   433  {
   434    int ret;
   435  
   436    /* If size is -1 and flag 0, GCC should always optimize the call into
   437       vsnprintf.  */
   438    if (size == (__SIZE_TYPE__) -1 && flag == 0)
   439      abort ();
   440    ++chk_calls;
   441    if (size < len)
   442      __chk_fail ();
   443  #ifdef __OPTIMIZE__
   444    if (vsnprintf_disallowed && inside_main)
   445      abort();
   446  #endif
   447    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   448    if (ret >= 0)
   449      {
   450        if (ret < len)
   451  	memcpy (str, chk_sprintf_buf, ret + 1);
   452        else
   453  	{
   454  	  memcpy (str, chk_sprintf_buf, len - 1);
   455  	  str[len - 1] = '\0';
   456  	}
   457      }
   458    return ret;
   459  }
   460  
   461  int
   462  snprintf (char *str, __SIZE_TYPE__ len, const char *fmt, ...)
   463  {
   464    int ret;
   465    va_list ap;
   466  
   467  #ifdef __OPTIMIZE__
   468    if (snprintf_disallowed && inside_main)
   469      abort();
   470  #endif
   471    va_start (ap, fmt);
   472    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   473    va_end (ap);
   474    if (ret >= 0)
   475      {
   476        if (ret < len)
   477  	memcpy (str, chk_sprintf_buf, ret + 1);
   478        else if (len)
   479  	{
   480  	  memcpy (str, chk_sprintf_buf, len - 1);
   481  	  str[len - 1] = '\0';
   482  	}
   483      }
   484    return ret;
   485  }
   486  
   487  /* uClibc's vsprintf calls vsnprintf.  */
   488  #ifndef __UCLIBC__
   489  int
   490  vsnprintf (char *str, __SIZE_TYPE__ len, const char *fmt, va_list ap)
   491  {
   492    int ret;
   493  
   494  #ifdef __OPTIMIZE__
   495    if (vsnprintf_disallowed && inside_main)
   496      abort();
   497  #endif
   498    ret = vsprintf (chk_sprintf_buf, fmt, ap);
   499    if (ret >= 0)
   500      {
   501        if (ret < len)
   502  	memcpy (str, chk_sprintf_buf, ret + 1);
   503        else if (len)
   504  	{
   505  	  memcpy (str, chk_sprintf_buf, len - 1);
   506  	  str[len - 1] = '\0';
   507  	}
   508      }
   509    return ret;
   510  }
   511  #endif