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