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