3 extern void abort (void);
5 extern int inside_main
;
6 void *chk_fail_buf
[256] __attribute__((aligned (16)));
7 volatile int chk_fail_allowed
, chk_calls
;
8 volatile int memcpy_disallowed
, mempcpy_disallowed
, memmove_disallowed
;
9 volatile int memset_disallowed
, strcpy_disallowed
, stpcpy_disallowed
;
10 volatile int strncpy_disallowed
, strcat_disallowed
, strncat_disallowed
;
11 volatile int sprintf_disallowed
, vsprintf_disallowed
;
12 volatile int snprintf_disallowed
, vsnprintf_disallowed
;
13 extern __SIZE_TYPE__
strlen (const char *);
14 extern int vsprintf (char *, const char *, va_list);
16 void __attribute__((noreturn
))
20 __builtin_longjmp (chk_fail_buf
, 1);
25 memcpy (void *dst
, const void *src
, __SIZE_TYPE__ n
)
31 if (memcpy_disallowed
&& inside_main
)
44 __memcpy_chk (void *dst
, const void *src
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
46 /* If size is -1, GCC should always optimize the call into memcpy. */
47 if (size
== (__SIZE_TYPE__
) -1)
52 return memcpy (dst
, src
, n
);
56 mempcpy (void *dst
, const void *src
, __SIZE_TYPE__ n
)
62 if (mempcpy_disallowed
&& inside_main
)
75 __mempcpy_chk (void *dst
, const void *src
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
77 /* If size is -1, GCC should always optimize the call into mempcpy. */
78 if (size
== (__SIZE_TYPE__
) -1)
83 return mempcpy (dst
, src
, n
);
87 memmove (void *dst
, const void *src
, __SIZE_TYPE__ n
)
93 if (memmove_disallowed
&& inside_main
)
110 __memmove_chk (void *dst
, const void *src
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
112 /* If size is -1, GCC should always optimize the call into memmove. */
113 if (size
== (__SIZE_TYPE__
) -1)
118 return memmove (dst
, src
, n
);
122 memset (void *dst
, int c
, __SIZE_TYPE__ n
)
124 /* Single-byte memsets should be done inline when optimisation
127 if (memset_disallowed
&& inside_main
&& n
< 2)
138 __memset_chk (void *dst
, int c
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
140 /* If size is -1, GCC should always optimize the call into memset. */
141 if (size
== (__SIZE_TYPE__
) -1)
146 return memset (dst
, c
, n
);
150 strcpy (char *d
, const char *s
)
154 if (strcpy_disallowed
&& inside_main
)
157 while ((*d
++ = *s
++));
162 __strcpy_chk (char *d
, const char *s
, __SIZE_TYPE__ size
)
164 /* If size is -1, GCC should always optimize the call into strcpy. */
165 if (size
== (__SIZE_TYPE__
) -1)
168 if (strlen (s
) >= size
)
170 return strcpy (d
, s
);
174 stpcpy (char *dst
, const char *src
)
177 if (stpcpy_disallowed
&& inside_main
)
189 __stpcpy_chk (char *d
, const char *s
, __SIZE_TYPE__ size
)
191 /* If size is -1, GCC should always optimize the call into stpcpy. */
192 if (size
== (__SIZE_TYPE__
) -1)
195 if (strlen (s
) >= size
)
197 return stpcpy (d
, s
);
201 strncpy (char *s1
, const char *s2
, __SIZE_TYPE__ n
)
205 if (strncpy_disallowed
&& inside_main
)
208 for (; *s2
&& n
; n
--)
216 __strncpy_chk (char *s1
, const char *s2
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
218 /* If size is -1, GCC should always optimize the call into strncpy. */
219 if (size
== (__SIZE_TYPE__
) -1)
224 return strncpy (s1
, s2
, n
);
228 strcat (char *dst
, const char *src
)
233 if (strcat_disallowed
&& inside_main
)
239 while ((*p
++ = *src
++))
245 __strcat_chk (char *d
, const char *s
, __SIZE_TYPE__ size
)
247 /* If size is -1, GCC should always optimize the call into strcat. */
248 if (size
== (__SIZE_TYPE__
) -1)
251 if (strlen (d
) + strlen (s
) >= size
)
253 return strcat (d
, s
);
257 strncat (char *s1
, const char *s2
, __SIZE_TYPE__ n
)
262 if (strncat_disallowed
&& inside_main
)
281 __strncat_chk (char *d
, const char *s
, __SIZE_TYPE__ n
, __SIZE_TYPE__ size
)
283 __SIZE_TYPE__ len
= strlen (d
), n1
= n
;
286 /* If size is -1, GCC should always optimize the call into strncat. */
287 if (size
== (__SIZE_TYPE__
) -1)
290 while (len
< size
&& n1
> 0)
300 return strncat (d
, s
, n
);
303 /* No chk test in GCC testsuite needs more bytes than this.
304 As we can't expect vsnprintf to be available on the target,
305 assume 4096 bytes is enough. */
306 static char chk_sprintf_buf
[4096];
309 __sprintf_chk (char *str
, int flag
, __SIZE_TYPE__ size
, const char *fmt
, ...)
314 /* If size is -1 and flag 0, GCC should always optimize the call into
316 if (size
== (__SIZE_TYPE__
) -1 && flag
== 0)
320 if (sprintf_disallowed
&& inside_main
)
324 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
330 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
336 __vsprintf_chk (char *str
, int flag
, __SIZE_TYPE__ size
, const char *fmt
,
341 /* If size is -1 and flag 0, GCC should always optimize the call into
343 if (size
== (__SIZE_TYPE__
) -1 && flag
== 0)
347 if (vsprintf_disallowed
&& inside_main
)
350 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
355 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
361 __snprintf_chk (char *str
, __SIZE_TYPE__ len
, int flag
, __SIZE_TYPE__ size
,
362 const char *fmt
, ...)
367 /* If size is -1 and flag 0, GCC should always optimize the call into
369 if (size
== (__SIZE_TYPE__
) -1 && flag
== 0)
375 if (snprintf_disallowed
&& inside_main
)
379 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
384 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
387 memcpy (str
, chk_sprintf_buf
, len
- 1);
395 __vsnprintf_chk (char *str
, __SIZE_TYPE__ len
, int flag
, __SIZE_TYPE__ size
,
396 const char *fmt
, va_list ap
)
400 /* If size is -1 and flag 0, GCC should always optimize the call into
402 if (size
== (__SIZE_TYPE__
) -1 && flag
== 0)
408 if (vsnprintf_disallowed
&& inside_main
)
411 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
415 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
418 memcpy (str
, chk_sprintf_buf
, len
- 1);
426 snprintf (char *str
, __SIZE_TYPE__ len
, const char *fmt
, ...)
432 if (snprintf_disallowed
&& inside_main
)
436 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
441 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
444 memcpy (str
, chk_sprintf_buf
, len
- 1);
452 vsnprintf (char *str
, __SIZE_TYPE__ len
, const char *fmt
, va_list ap
)
457 if (vsnprintf_disallowed
&& inside_main
)
460 ret
= vsprintf (chk_sprintf_buf
, fmt
, ap
);
464 memcpy (str
, chk_sprintf_buf
, ret
+ 1);
467 memcpy (str
, chk_sprintf_buf
, len
- 1);