aboutsummaryrefslogtreecommitdiff
path: root/SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c
diff options
context:
space:
mode:
Diffstat (limited to 'SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c')
-rw-r--r--SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c519
1 files changed, 519 insertions, 0 deletions
diff --git a/SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c b/SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c
new file mode 100644
index 00000000..fb14149d
--- /dev/null
+++ b/SingleSource/Regression/C/gcc-c-torture/execute/builtins/lib/chk.c
@@ -0,0 +1,519 @@
+#include <stdarg.h>
+#ifdef __unix__
+#include <sys/types.h>
+#endif
+
+/* If some target has a Max alignment less than 16, please create
+ a #ifdef around the alignment and add your alignment. */
+#ifdef __pdp11__
+#define ALIGNMENT 2
+#else
+#define ALIGNMENT 16
+#endif
+
+extern void abort (void);
+
+extern int inside_main;
+void *chk_fail_buf[256] __attribute__((aligned (ALIGNMENT)));
+volatile int chk_fail_allowed, chk_calls;
+volatile int memcpy_disallowed, mempcpy_disallowed, memmove_disallowed;
+volatile int memset_disallowed, strcpy_disallowed, stpcpy_disallowed;
+volatile int strncpy_disallowed, stpncpy_disallowed, strcat_disallowed;
+volatile int strncat_disallowed, sprintf_disallowed, vsprintf_disallowed;
+volatile int snprintf_disallowed, vsnprintf_disallowed;
+extern __SIZE_TYPE__ strlen (const char *);
+extern int vsprintf (char *, const char *, va_list);
+
+void __attribute__((noreturn))
+__chk_fail (void)
+{
+ if (chk_fail_allowed)
+ __builtin_longjmp (chk_fail_buf, 1);
+ abort ();
+}
+
+void *
+memcpy (void *dst, const void *src, __SIZE_TYPE__ n)
+{
+ const char *srcp;
+ char *dstp;
+
+#ifdef __OPTIMIZE__
+ if (memcpy_disallowed && inside_main)
+ abort ();
+#endif
+
+ srcp = src;
+ dstp = dst;
+ while (n-- != 0)
+ *dstp++ = *srcp++;
+
+ return dst;
+}
+
+void *
+__memcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into memcpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return memcpy (dst, src, n);
+}
+
+void *
+mempcpy (void *dst, const void *src, __SIZE_TYPE__ n)
+{
+ const char *srcp;
+ char *dstp;
+
+#ifdef __OPTIMIZE__
+ if (mempcpy_disallowed && inside_main)
+ abort ();
+#endif
+
+ srcp = src;
+ dstp = dst;
+ while (n-- != 0)
+ *dstp++ = *srcp++;
+
+ return dstp;
+}
+
+void *
+__mempcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into mempcpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return mempcpy (dst, src, n);
+}
+
+void *
+memmove (void *dst, const void *src, __SIZE_TYPE__ n)
+{
+ const char *srcp;
+ char *dstp;
+
+#ifdef __OPTIMIZE__
+ if (memmove_disallowed && inside_main)
+ abort ();
+#endif
+
+ srcp = src;
+ dstp = dst;
+ if (srcp < dstp)
+ while (n-- != 0)
+ dstp[n] = srcp[n];
+ else
+ while (n-- != 0)
+ *dstp++ = *srcp++;
+
+ return dst;
+}
+
+void *
+__memmove_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into memmove. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return memmove (dst, src, n);
+}
+
+void *
+memset (void *dst, int c, __SIZE_TYPE__ n)
+{
+ while (n-- != 0)
+ n[(char *) dst] = c;
+
+ /* Single-byte memsets should be done inline when optimisation
+ is enabled. Do this after the copy in case we're being called to
+ initialize bss. */
+#ifdef __OPTIMIZE__
+ if (memset_disallowed && inside_main && n < 2)
+ abort ();
+#endif
+
+ return dst;
+}
+
+void *
+__memset_chk (void *dst, int c, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into memset. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return memset (dst, c, n);
+}
+
+char *
+strcpy (char *d, const char *s)
+{
+ char *r = d;
+#ifdef __OPTIMIZE__
+ if (strcpy_disallowed && inside_main)
+ abort ();
+#endif
+ while ((*d++ = *s++));
+ return r;
+}
+
+char *
+__strcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into strcpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (strlen (s) >= size)
+ __chk_fail ();
+ return strcpy (d, s);
+}
+
+char *
+stpcpy (char *dst, const char *src)
+{
+#ifdef __OPTIMIZE__
+ if (stpcpy_disallowed && inside_main)
+ abort ();
+#endif
+
+ while (*src != 0)
+ *dst++ = *src++;
+
+ *dst = 0;
+ return dst;
+}
+
+char *
+__stpcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into stpcpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (strlen (s) >= size)
+ __chk_fail ();
+ return stpcpy (d, s);
+}
+
+char *
+stpncpy (char *dst, const char *src, __SIZE_TYPE__ n)
+{
+#ifdef __OPTIMIZE__
+ if (stpncpy_disallowed && inside_main)
+ abort ();
+#endif
+
+ for (; *src && n; n--)
+ *dst++ = *src++;
+
+ char *ret = dst;
+
+ while (n--)
+ *dst++ = 0;
+
+ return ret;
+}
+
+
+char *
+__stpncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into stpncpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return stpncpy (s1, s2, n);
+}
+
+char *
+strncpy (char *s1, const char *s2, __SIZE_TYPE__ n)
+{
+ char *dest = s1;
+#ifdef __OPTIMIZE__
+ if (strncpy_disallowed && inside_main)
+ abort();
+#endif
+ for (; *s2 && n; n--)
+ *s1++ = *s2++;
+ while (n--)
+ *s1++ = 0;
+ return dest;
+}
+
+char *
+__strncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into strncpy. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (n > size)
+ __chk_fail ();
+ return strncpy (s1, s2, n);
+}
+
+char *
+strcat (char *dst, const char *src)
+{
+ char *p = dst;
+
+#ifdef __OPTIMIZE__
+ if (strcat_disallowed && inside_main)
+ abort ();
+#endif
+
+ while (*p)
+ p++;
+ while ((*p++ = *src++))
+ ;
+ return dst;
+}
+
+char *
+__strcat_chk (char *d, const char *s, __SIZE_TYPE__ size)
+{
+ /* If size is -1, GCC should always optimize the call into strcat. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ if (strlen (d) + strlen (s) >= size)
+ __chk_fail ();
+ return strcat (d, s);
+}
+
+char *
+strncat (char *s1, const char *s2, __SIZE_TYPE__ n)
+{
+ char *dest = s1;
+ char c;
+#ifdef __OPTIMIZE__
+ if (strncat_disallowed && inside_main)
+ abort();
+#endif
+ while (*s1) s1++;
+ c = '\0';
+ while (n > 0)
+ {
+ c = *s2++;
+ *s1++ = c;
+ if (c == '\0')
+ return dest;
+ n--;
+ }
+ if (c != '\0')
+ *s1 = '\0';
+ return dest;
+}
+
+char *
+__strncat_chk (char *d, const char *s, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
+{
+ __SIZE_TYPE__ len = strlen (d), n1 = n;
+ const char *s1 = s;
+
+ /* If size is -1, GCC should always optimize the call into strncat. */
+ if (size == (__SIZE_TYPE__) -1)
+ abort ();
+ ++chk_calls;
+ while (len < size && n1 > 0)
+ {
+ if (*s1++ == '\0')
+ break;
+ ++len;
+ --n1;
+ }
+
+ if (len >= size)
+ __chk_fail ();
+ return strncat (d, s, n);
+}
+
+/* No chk test in GCC testsuite needs more bytes than this.
+ As we can't expect vsnprintf to be available on the target,
+ assume 4096 bytes is enough. */
+static char chk_sprintf_buf[4096];
+
+int
+__sprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ /* If size is -1 and flag 0, GCC should always optimize the call into
+ sprintf. */
+ if (size == (__SIZE_TYPE__) -1 && flag == 0)
+ abort ();
+ ++chk_calls;
+#ifdef __OPTIMIZE__
+ if (sprintf_disallowed && inside_main)
+ abort();
+#endif
+ va_start (ap, fmt);
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ va_end (ap);
+ if (ret >= 0)
+ {
+ if (ret >= size)
+ __chk_fail ();
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ }
+ return ret;
+}
+
+int
+__vsprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt,
+ va_list ap)
+{
+ int ret;
+
+ /* If size is -1 and flag 0, GCC should always optimize the call into
+ vsprintf. */
+ if (size == (__SIZE_TYPE__) -1 && flag == 0)
+ abort ();
+ ++chk_calls;
+#ifdef __OPTIMIZE__
+ if (vsprintf_disallowed && inside_main)
+ abort();
+#endif
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ if (ret >= 0)
+ {
+ if (ret >= size)
+ __chk_fail ();
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ }
+ return ret;
+}
+
+int
+__snprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
+ const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ /* If size is -1 and flag 0, GCC should always optimize the call into
+ snprintf. */
+ if (size == (__SIZE_TYPE__) -1 && flag == 0)
+ abort ();
+ ++chk_calls;
+ if (size < len)
+ __chk_fail ();
+#ifdef __OPTIMIZE__
+ if (snprintf_disallowed && inside_main)
+ abort();
+#endif
+ va_start (ap, fmt);
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ va_end (ap);
+ if (ret >= 0)
+ {
+ if (ret < len)
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ else
+ {
+ memcpy (str, chk_sprintf_buf, len - 1);
+ str[len - 1] = '\0';
+ }
+ }
+ return ret;
+}
+
+int
+__vsnprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
+ const char *fmt, va_list ap)
+{
+ int ret;
+
+ /* If size is -1 and flag 0, GCC should always optimize the call into
+ vsnprintf. */
+ if (size == (__SIZE_TYPE__) -1 && flag == 0)
+ abort ();
+ ++chk_calls;
+ if (size < len)
+ __chk_fail ();
+#ifdef __OPTIMIZE__
+ if (vsnprintf_disallowed && inside_main)
+ abort();
+#endif
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ if (ret >= 0)
+ {
+ if (ret < len)
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ else
+ {
+ memcpy (str, chk_sprintf_buf, len - 1);
+ str[len - 1] = '\0';
+ }
+ }
+ return ret;
+}
+
+int
+snprintf (char *str, __SIZE_TYPE__ len, const char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+#ifdef __OPTIMIZE__
+ if (snprintf_disallowed && inside_main)
+ abort();
+#endif
+ va_start (ap, fmt);
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ va_end (ap);
+ if (ret >= 0)
+ {
+ if (ret < len)
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ else if (len)
+ {
+ memcpy (str, chk_sprintf_buf, len - 1);
+ str[len - 1] = '\0';
+ }
+ }
+ return ret;
+}
+
+/* uClibc's vsprintf calls vsnprintf. */
+#ifndef __UCLIBC__
+int
+vsnprintf (char *str, __SIZE_TYPE__ len, const char *fmt, va_list ap)
+{
+ int ret;
+
+#ifdef __OPTIMIZE__
+ if (vsnprintf_disallowed && inside_main)
+ abort();
+#endif
+ ret = vsprintf (chk_sprintf_buf, fmt, ap);
+ if (ret >= 0)
+ {
+ if (ret < len)
+ memcpy (str, chk_sprintf_buf, ret + 1);
+ else if (len)
+ {
+ memcpy (str, chk_sprintf_buf, len - 1);
+ str[len - 1] = '\0';
+ }
+ }
+ return ret;
+}
+#endif