1 /* 2 american fuzzy lop++ - compiler instrumentation wrapper 3 ------------------------------------------------------- 4 5 Written by Michal Zalewski, Laszlo Szekeres and Marc Heuse 6 7 Copyright 2015, 2016 Google Inc. All rights reserved. 8 Copyright 2019-2020 AFLplusplus Project. All rights reserved. 9 10 Licensed under the Apache License, Version 2.0 (the "License"); 11 you may not use this file except in compliance with the License. 12 You may obtain a copy of the License at: 13 14 http://www.apache.org/licenses/LICENSE-2.0 15 16 */ 17 18 #define AFL_MAIN 19 20 #include "common.h" 21 #include "config.h" 22 #include "types.h" 23 #include "debug.h" 24 #include "alloc-inl.h" 25 #include "llvm-alternative-coverage.h" 26 27 #include <stdio.h> 28 #include <unistd.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <limits.h> 33 #include <assert.h> 34 35 #if (LLVM_MAJOR - 0 == 0) run_sample()36 #undef LLVM_MAJOR 37 #endif 38 #if !defined(LLVM_MAJOR) 39 #define LLVM_MAJOR 0 40 #endif 41 #if (LLVM_MINOR - 0 == 0) 42 #undef LLVM_MINOR 43 #endif 44 #if !defined(LLVM_MINOR) 45 #define LLVM_MINOR 0 46 #endif 47 48 static u8 * obj_path; /* Path to runtime libraries */ 49 static u8 **cc_params; /* Parameters passed to the real CC */ 50 static u32 cc_par_cnt = 1; /* Param count, including argv0 */ 51 static u8 clang_mode; /* Invoked as afl-clang*? */ 52 static u8 llvm_fullpath[PATH_MAX]; 53 static u8 instrument_mode, instrument_opt_mode, ngram_size, ctx_k, lto_mode; 54 static u8 compiler_mode, plusplus_mode, have_instr_env = 0; 55 static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0; 56 static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull; 57 static u8 debug; 58 static u8 cwd[4096]; 59 static u8 cmplog_mode; 60 u8 use_stdin; /* dummy */ 61 // static u8 *march_opt = CFLAGS_OPT; 62 63 enum { 64 65 INSTRUMENT_DEFAULT = 0, 66 INSTRUMENT_CLASSIC = 1, 67 INSTRUMENT_AFL = 1, 68 INSTRUMENT_PCGUARD = 2, 69 INSTRUMENT_CFG = 3, 70 INSTRUMENT_LTO = 4, 71 INSTRUMENT_LLVMNATIVE = 5, 72 INSTRUMENT_GCC = 6, 73 INSTRUMENT_CLANG = 7, 74 INSTRUMENT_OPT_CTX = 8, 75 INSTRUMENT_OPT_NGRAM = 16, 76 INSTRUMENT_OPT_CALLER = 32, 77 INSTRUMENT_OPT_CTX_K = 64, 78 79 }; 80 81 char instrument_mode_string[18][18] = { 82 83 "DEFAULT", 84 "CLASSIC", 85 "PCGUARD", 86 "CFG", 87 "LTO", 88 "PCGUARD-NATIVE", 89 "GCC", 90 "CLANG", 91 "CTX", 92 "CALLER", 93 "", 94 "", 95 "", 96 "", 97 "", 98 "", 99 "NGRAM", 100 "" 101 102 }; 103 104 enum { 105 106 UNSET = 0, 107 LTO = 1, 108 LLVM = 2, 109 GCC_PLUGIN = 3, 110 GCC = 4, 111 CLANG = 5 112 113 }; 114 115 char compiler_mode_string[7][12] = { 116 117 "AUTOSELECT", "LLVM-LTO", "LLVM", "GCC_PLUGIN", 118 "GCC", "CLANG", "" 119 120 }; 121 122 u8 *getthecwd() { 123 124 if (getcwd(cwd, sizeof(cwd)) == NULL) { 125 126 static u8 fail[] = ""; 127 return fail; 128 129 } 130 131 return cwd; 132 133 } 134 135 /* Try to find a specific runtime we need, returns NULL on fail. */ 136 137 /* 138 in find_object() we look here: 139 140 1. if obj_path is already set we look there first 141 2. then we check the $AFL_PATH environment variable location if set 142 3. next we check argv[0] if it has path information and use it 143 a) we also check ../lib/afl 144 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and 145 FreeBSD with procfs) 146 a) and check here in ../lib/afl too 147 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) 148 6. we finally try the current directory 149 150 if all these attempts fail - we return NULL and the caller has to decide 151 what to do. 152 */ 153 154 static u8 *find_object(u8 *obj, u8 *argv0) { 155 156 u8 *afl_path = getenv("AFL_PATH"); 157 u8 *slash = NULL, *tmp; 158 159 if (afl_path) { 160 161 tmp = alloc_printf("%s/%s", afl_path, obj); 162 163 if (debug) DEBUGF("Trying %s\n", tmp); 164 165 if (!access(tmp, R_OK)) { 166 167 obj_path = afl_path; 168 return tmp; 169 170 } 171 172 ck_free(tmp); 173 174 } 175 176 if (argv0) { 177 178 slash = strrchr(argv0, '/'); 179 180 if (slash) { 181 182 u8 *dir = ck_strdup(argv0); 183 184 slash = strrchr(dir, '/'); 185 *slash = 0; 186 187 tmp = alloc_printf("%s/%s", dir, obj); 188 189 if (debug) DEBUGF("Trying %s\n", tmp); 190 191 if (!access(tmp, R_OK)) { 192 193 obj_path = dir; 194 return tmp; 195 196 } 197 198 ck_free(tmp); 199 tmp = alloc_printf("%s/../lib/afl/%s", dir, obj); 200 201 if (debug) DEBUGF("Trying %s\n", tmp); 202 203 if (!access(tmp, R_OK)) { 204 205 u8 *dir2 = alloc_printf("%s/../lib/afl", dir); 206 obj_path = dir2; 207 ck_free(dir); 208 return tmp; 209 210 } 211 212 ck_free(tmp); 213 ck_free(dir); 214 215 } 216 217 #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__) || \ 218 defined(__ANDROID__) || defined(__NetBSD__) 219 #define HAS_PROC_FS 1 220 #endif 221 #ifdef HAS_PROC_FS 222 else { 223 224 char *procname = NULL; 225 #if defined(__FreeBSD__) || defined(__DragonFly__) 226 procname = "/proc/curproc/file"; 227 #elif defined(__linux__) || defined(__ANDROID__) 228 procname = "/proc/self/exe"; 229 #elif defined(__NetBSD__) 230 procname = "/proc/curproc/exe"; 231 #endif 232 if (procname) { 233 234 char exepath[PATH_MAX]; 235 ssize_t exepath_len = readlink(procname, exepath, sizeof(exepath)); 236 if (exepath_len > 0 && exepath_len < PATH_MAX) { 237 238 exepath[exepath_len] = 0; 239 slash = strrchr(exepath, '/'); 240 241 if (slash) { 242 243 *slash = 0; 244 tmp = alloc_printf("%s/%s", exepath, obj); 245 246 if (!access(tmp, R_OK)) { 247 248 u8 *dir = alloc_printf("%s", exepath); 249 obj_path = dir; 250 return tmp; 251 252 } 253 254 ck_free(tmp); 255 tmp = alloc_printf("%s/../lib/afl/%s", exepath, obj); 256 257 if (debug) DEBUGF("Trying %s\n", tmp); 258 259 if (!access(tmp, R_OK)) { 260 261 u8 *dir = alloc_printf("%s/../lib/afl/", exepath); 262 obj_path = dir; 263 return tmp; 264 265 } 266 267 } 268 269 } 270 271 } 272 273 } 274 275 #endif 276 #undef HAS_PROC_FS 277 278 } 279 280 tmp = alloc_printf("%s/%s", AFL_PATH, obj); 281 282 if (debug) DEBUGF("Trying %s\n", tmp); 283 284 if (!access(tmp, R_OK)) { 285 286 obj_path = AFL_PATH; 287 return tmp; 288 289 } 290 291 ck_free(tmp); 292 293 tmp = alloc_printf("./%s", obj); 294 295 if (debug) DEBUGF("Trying %s\n", tmp); 296 297 if (!access(tmp, R_OK)) { 298 299 obj_path = "."; 300 return tmp; 301 302 } 303 304 ck_free(tmp); 305 306 if (debug) DEBUGF("Trying ... giving up\n"); 307 308 return NULL; 309 310 } 311 312 /* Copy argv to cc_params, making the necessary edits. */ 313 314 static void edit_params(u32 argc, char **argv, char **envp) { 315 316 u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0, 317 preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0, 318 have_c = 0, partial_linking = 0; 319 320 cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); 321 322 if (lto_mode) { 323 324 if (lto_flag[0] != '-') 325 FATAL( 326 "Using afl-clang-lto is not possible because Makefile magic did not " 327 "identify the correct -flto flag"); 328 else 329 compiler_mode = LTO; 330 331 } 332 333 if (plusplus_mode) { 334 335 u8 *alt_cxx = getenv("AFL_CXX"); 336 337 if (!alt_cxx) { 338 339 if (compiler_mode >= GCC_PLUGIN) { 340 341 if (compiler_mode == GCC) { 342 343 alt_cxx = clang_mode ? "clang++" : "g++"; 344 345 } else if (compiler_mode == CLANG) { 346 347 alt_cxx = "clang++"; 348 349 } else { 350 351 alt_cxx = "g++"; 352 353 } 354 355 } else { 356 357 if (USE_BINDIR) 358 snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++", 359 LLVM_BINDIR); 360 else 361 snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANGPP_BIN); 362 alt_cxx = llvm_fullpath; 363 364 } 365 366 } 367 368 cc_params[0] = alt_cxx; 369 370 } else { 371 372 u8 *alt_cc = getenv("AFL_CC"); 373 374 if (!alt_cc) { 375 376 if (compiler_mode >= GCC_PLUGIN) { 377 378 if (compiler_mode == GCC) { 379 380 alt_cc = clang_mode ? "clang" : "gcc"; 381 382 } else if (compiler_mode == CLANG) { 383 384 alt_cc = "clang"; 385 386 } else { 387 388 alt_cc = "gcc"; 389 390 } 391 392 } else { 393 394 if (USE_BINDIR) 395 snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang", 396 LLVM_BINDIR); 397 else 398 snprintf(llvm_fullpath, sizeof(llvm_fullpath), CLANG_BIN); 399 alt_cc = llvm_fullpath; 400 401 } 402 403 } 404 405 cc_params[0] = alt_cc; 406 407 } 408 409 if (compiler_mode == GCC || compiler_mode == CLANG) { 410 411 cc_params[cc_par_cnt++] = "-B"; 412 cc_params[cc_par_cnt++] = obj_path; 413 414 if (clang_mode || compiler_mode == CLANG) { 415 416 cc_params[cc_par_cnt++] = "-no-integrated-as"; 417 418 } 419 420 } 421 422 if (compiler_mode == GCC_PLUGIN) { 423 424 char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); 425 cc_params[cc_par_cnt++] = fplugin_arg; 426 427 } 428 429 if (compiler_mode == LLVM || compiler_mode == LTO) { 430 431 cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; 432 433 if (lto_mode && have_instr_env) { 434 435 cc_params[cc_par_cnt++] = "-Xclang"; 436 cc_params[cc_par_cnt++] = "-load"; 437 cc_params[cc_par_cnt++] = "-Xclang"; 438 cc_params[cc_par_cnt++] = 439 alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); 440 441 } 442 443 if (getenv("AFL_LLVM_DICT2FILE")) { 444 445 cc_params[cc_par_cnt++] = "-Xclang"; 446 cc_params[cc_par_cnt++] = "-load"; 447 cc_params[cc_par_cnt++] = "-Xclang"; 448 cc_params[cc_par_cnt++] = 449 alloc_printf("%s/afl-llvm-dict2file.so", obj_path); 450 451 } 452 453 // laf 454 if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { 455 456 if (lto_mode && !have_c) { 457 458 cc_params[cc_par_cnt++] = alloc_printf( 459 "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); 460 461 } else { 462 463 cc_params[cc_par_cnt++] = "-Xclang"; 464 cc_params[cc_par_cnt++] = "-load"; 465 cc_params[cc_par_cnt++] = "-Xclang"; 466 cc_params[cc_par_cnt++] = 467 alloc_printf("%s/split-switches-pass.so", obj_path); 468 469 } 470 471 } 472 473 if (getenv("LAF_TRANSFORM_COMPARES") || 474 getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { 475 476 if (lto_mode && !have_c) { 477 478 cc_params[cc_par_cnt++] = alloc_printf( 479 "-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path); 480 481 } else { 482 483 cc_params[cc_par_cnt++] = "-Xclang"; 484 cc_params[cc_par_cnt++] = "-load"; 485 cc_params[cc_par_cnt++] = "-Xclang"; 486 cc_params[cc_par_cnt++] = 487 alloc_printf("%s/compare-transform-pass.so", obj_path); 488 489 } 490 491 } 492 493 if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || 494 getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { 495 496 if (lto_mode && !have_c) { 497 498 cc_params[cc_par_cnt++] = alloc_printf( 499 "-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path); 500 501 } else { 502 503 cc_params[cc_par_cnt++] = "-Xclang"; 504 cc_params[cc_par_cnt++] = "-load"; 505 cc_params[cc_par_cnt++] = "-Xclang"; 506 cc_params[cc_par_cnt++] = 507 alloc_printf("%s/split-compares-pass.so", obj_path); 508 509 } 510 511 } 512 513 // /laf 514 515 unsetenv("AFL_LD"); 516 unsetenv("AFL_LD_CALLER"); 517 518 if (cmplog_mode) { 519 520 if (lto_mode && !have_c) { 521 522 cc_params[cc_par_cnt++] = alloc_printf( 523 "-Wl,-mllvm=-load=%s/cmplog-switches-pass.so", obj_path); 524 525 cc_params[cc_par_cnt++] = alloc_printf( 526 "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); 527 528 } else { 529 530 cc_params[cc_par_cnt++] = "-Xclang"; 531 cc_params[cc_par_cnt++] = "-load"; 532 cc_params[cc_par_cnt++] = "-Xclang"; 533 cc_params[cc_par_cnt++] = 534 alloc_printf("%s/cmplog-switches-pass.so", obj_path); 535 536 // reuse split switches from laf 537 cc_params[cc_par_cnt++] = "-Xclang"; 538 cc_params[cc_par_cnt++] = "-load"; 539 cc_params[cc_par_cnt++] = "-Xclang"; 540 cc_params[cc_par_cnt++] = 541 alloc_printf("%s/split-switches-pass.so", obj_path); 542 543 } 544 545 cc_params[cc_par_cnt++] = "-fno-inline"; 546 547 } 548 549 #if LLVM_MAJOR >= 13 550 // fuck you llvm 13 551 cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; 552 #endif 553 554 if (lto_mode && !have_c) { 555 556 u8 *ld_path = strdup(AFL_REAL_LD); 557 if (!ld_path || !*ld_path) { ld_path = strdup("ld.lld"); } 558 if (!ld_path) { PFATAL("Could not allocate mem for ld_path"); } 559 #if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12 560 cc_params[cc_par_cnt++] = alloc_printf("--ld-path=%s", ld_path); 561 #else 562 cc_params[cc_par_cnt++] = alloc_printf("-fuse-ld=%s", ld_path); 563 #endif 564 free(ld_path); 565 566 cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; 567 568 if (instrument_mode == INSTRUMENT_CFG || 569 instrument_mode == INSTRUMENT_PCGUARD) 570 cc_params[cc_par_cnt++] = alloc_printf( 571 "-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); 572 else 573 574 cc_params[cc_par_cnt++] = alloc_printf( 575 "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path); 576 cc_params[cc_par_cnt++] = lto_flag; 577 578 } else { 579 580 if (instrument_mode == INSTRUMENT_PCGUARD) { 581 582 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) 583 #if defined __ANDROID__ || ANDROID 584 cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; 585 instrument_mode = INSTRUMENT_LLVMNATIVE; 586 #else 587 if (have_instr_list) { 588 589 if (!be_quiet) 590 SAYF( 591 "Using unoptimized trace-pc-guard, due usage of " 592 "-fsanitize-coverage-allow/denylist, you can use " 593 "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n"); 594 cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; 595 instrument_mode = INSTRUMENT_LLVMNATIVE; 596 597 } else { 598 599 cc_params[cc_par_cnt++] = "-Xclang"; 600 cc_params[cc_par_cnt++] = "-load"; 601 cc_params[cc_par_cnt++] = "-Xclang"; 602 cc_params[cc_par_cnt++] = 603 alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); 604 605 } 606 607 #endif 608 #else 609 #if LLVM_MAJOR >= 4 610 if (!be_quiet) 611 SAYF( 612 "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for " 613 "enhanced version.\n"); 614 cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; 615 instrument_mode = INSTRUMENT_LLVMNATIVE; 616 #else 617 FATAL("pcguard instrumentation requires llvm 4.0.1+"); 618 #endif 619 #endif 620 621 } else if (instrument_mode == INSTRUMENT_LLVMNATIVE) { 622 623 #if LLVM_MAJOR >= 4 624 cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; 625 #else 626 FATAL("pcguard instrumentation requires llvm 4.0.1+"); 627 #endif 628 629 } else { 630 631 cc_params[cc_par_cnt++] = "-Xclang"; 632 cc_params[cc_par_cnt++] = "-load"; 633 cc_params[cc_par_cnt++] = "-Xclang"; 634 cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); 635 636 } 637 638 } 639 640 if (cmplog_mode) { 641 642 if (lto_mode && !have_c) { 643 644 cc_params[cc_par_cnt++] = alloc_printf( 645 "-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path); 646 cc_params[cc_par_cnt++] = alloc_printf( 647 "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path); 648 649 } else { 650 651 cc_params[cc_par_cnt++] = "-Xclang"; 652 cc_params[cc_par_cnt++] = "-load"; 653 cc_params[cc_par_cnt++] = "-Xclang"; 654 cc_params[cc_par_cnt++] = 655 alloc_printf("%s/cmplog-instructions-pass.so", obj_path); 656 657 cc_params[cc_par_cnt++] = "-Xclang"; 658 cc_params[cc_par_cnt++] = "-load"; 659 cc_params[cc_par_cnt++] = "-Xclang"; 660 cc_params[cc_par_cnt++] = 661 alloc_printf("%s/cmplog-routines-pass.so", obj_path); 662 663 } 664 665 } 666 667 // cc_params[cc_par_cnt++] = "-Qunused-arguments"; 668 669 // in case LLVM is installed not via a package manager or "make install" 670 // e.g. compiled download or compiled from github then its ./lib directory 671 // might not be in the search path. Add it if so. 672 u8 *libdir = strdup(LLVM_LIBDIR); 673 if (plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) && 674 strncmp(libdir, "/lib", 4)) { 675 676 cc_params[cc_par_cnt++] = "-rpath"; 677 cc_params[cc_par_cnt++] = libdir; 678 679 } else { 680 681 free(libdir); 682 683 } 684 685 if (lto_mode && argc > 1) { 686 687 u32 idx; 688 for (idx = 1; idx < argc; idx++) { 689 690 if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1; 691 692 } 693 694 if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC"; 695 696 } 697 698 } 699 700 /* Detect stray -v calls from ./configure scripts. */ 701 702 u8 skip_next = 0; 703 while (--argc) { 704 705 u8 *cur = *(++argv); 706 707 if (skip_next) { 708 709 skip_next = 0; 710 continue; 711 712 } 713 714 if (!strncmp(cur, "--afl", 5)) continue; 715 if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue; 716 if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue; 717 if (!strncmp(cur, "-fno-unroll", 11)) continue; 718 if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue; 719 if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") || 720 !strcmp(cur, "--no-undefined")) { 721 722 continue; 723 724 } 725 726 if (!strcmp(cur, "-z")) { 727 728 u8 *param = *(argv + 1); 729 if (!strcmp(param, "defs")) { 730 731 skip_next = 1; 732 continue; 733 734 } 735 736 } 737 738 if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) || 739 !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) && 740 (strncmp(cur, "sanitize-coverage-allow", 741 strlen("sanitize-coverage-allow")) && 742 strncmp(cur, "sanitize-coverage-deny", 743 strlen("sanitize-coverage-deny")) && 744 instrument_mode != INSTRUMENT_LLVMNATIVE)) { 745 746 if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); } 747 continue; 748 749 } 750 751 if (!strcmp(cur, "-fsanitize=fuzzer")) { 752 753 u8 *afllib = find_object("libAFLDriver.a", argv[0]); 754 755 if (!be_quiet) 756 WARNF( 757 "Found erroneous '-fsanitize=fuzzer', trying to replace with " 758 "libAFLDriver.a"); 759 760 if (!afllib) { 761 762 WARNF( 763 "Cannot find 'libAFLDriver.a' to replace a wrong " 764 "'-fsanitize=fuzzer' in the flags - this will fail!"); 765 766 } else { 767 768 cc_params[cc_par_cnt++] = afllib; 769 770 #ifdef __APPLE__ 771 cc_params[cc_par_cnt++] = "-undefined"; 772 cc_params[cc_par_cnt++] = "dynamic_lookup"; 773 #endif 774 775 } 776 777 continue; 778 779 } 780 781 if (!strcmp(cur, "-m32")) bit_mode = 32; 782 if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; 783 if (!strcmp(cur, "-m64")) bit_mode = 64; 784 785 if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) 786 have_instr_list = 1; 787 788 if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) 789 asan_set = 1; 790 791 if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; 792 793 if (!strcmp(cur, "-x")) x_set = 1; 794 if (!strcmp(cur, "-E")) preprocessor_only = 1; 795 if (!strcmp(cur, "-shared")) shared_linking = 1; 796 if (!strcmp(cur, "-Wl,-r")) partial_linking = 1; 797 if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1; 798 if (!strcmp(cur, "-r")) partial_linking = 1; 799 if (!strcmp(cur, "--relocatable")) partial_linking = 1; 800 if (!strcmp(cur, "-c")) have_c = 1; 801 802 if (!strncmp(cur, "-O", 2)) have_o = 1; 803 if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1; 804 805 cc_params[cc_par_cnt++] = cur; 806 807 } 808 809 if (getenv("AFL_HARDEN")) { 810 811 cc_params[cc_par_cnt++] = "-fstack-protector-all"; 812 813 if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; 814 815 } 816 817 if (!asan_set) { 818 819 if (getenv("AFL_USE_ASAN")) { 820 821 if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive"); 822 823 if (getenv("AFL_HARDEN")) 824 FATAL("ASAN and AFL_HARDEN are mutually exclusive"); 825 826 cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; 827 cc_params[cc_par_cnt++] = "-fsanitize=address"; 828 829 } else if (getenv("AFL_USE_MSAN")) { 830 831 if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive"); 832 833 if (getenv("AFL_HARDEN")) 834 FATAL("MSAN and AFL_HARDEN are mutually exclusive"); 835 836 cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; 837 cc_params[cc_par_cnt++] = "-fsanitize=memory"; 838 839 } 840 841 } 842 843 if (getenv("AFL_USE_UBSAN")) { 844 845 cc_params[cc_par_cnt++] = "-fsanitize=undefined"; 846 cc_params[cc_par_cnt++] = "-fsanitize-undefined-trap-on-error"; 847 cc_params[cc_par_cnt++] = "-fno-sanitize-recover=all"; 848 849 } 850 851 if (getenv("AFL_USE_LSAN")) { 852 853 cc_params[cc_par_cnt++] = "-fsanitize=leak"; 854 cc_params[cc_par_cnt++] = "-includesanitizer/lsan_interface.h"; 855 cc_params[cc_par_cnt++] = "-D__AFL_LEAK_CHECK()=__lsan_do_leak_check()"; 856 857 } 858 859 if (getenv("AFL_USE_CFISAN")) { 860 861 if (!lto_mode) { 862 863 uint32_t i = 0, found = 0; 864 while (envp[i] != NULL && !found) 865 if (strncmp("-flto", envp[i++], 5) == 0) found = 1; 866 if (!found) cc_params[cc_par_cnt++] = "-flto"; 867 868 } 869 870 cc_params[cc_par_cnt++] = "-fsanitize=cfi"; 871 cc_params[cc_par_cnt++] = "-fvisibility=hidden"; 872 873 } 874 875 if (!getenv("AFL_DONT_OPTIMIZE")) { 876 877 cc_params[cc_par_cnt++] = "-g"; 878 if (!have_o) cc_params[cc_par_cnt++] = "-O3"; 879 if (!have_unroll) cc_params[cc_par_cnt++] = "-funroll-loops"; 880 // if (strlen(march_opt) > 1 && march_opt[0] == '-') 881 // cc_params[cc_par_cnt++] = march_opt; 882 883 } 884 885 if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || 886 getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || 887 lto_mode) { 888 889 cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; 890 cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; 891 cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; 892 cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; 893 cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; 894 cc_params[cc_par_cnt++] = "-fno-builtin-bcmp"; 895 cc_params[cc_par_cnt++] = "-fno-builtin-strstr"; 896 cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr"; 897 898 } 899 900 #if defined(USEMMAP) && !defined(__HAIKU__) 901 if (!have_c) cc_params[cc_par_cnt++] = "-lrt"; 902 #endif 903 904 cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; 905 cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; 906 cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; 907 908 /* When the user tries to use persistent or deferred forkserver modes by 909 appending a single line to the program, we want to reliably inject a 910 signature into the binary (to be picked up by afl-fuzz) and we want 911 to call a function from the runtime .o file. This is unnecessarily 912 painful for three reasons: 913 914 1) We need to convince the compiler not to optimize out the signature. 915 This is done with __attribute__((used)). 916 917 2) We need to convince the linker, when called with -Wl,--gc-sections, 918 not to do the same. This is done by forcing an assignment to a 919 'volatile' pointer. 920 921 3) We need to declare __afl_persistent_loop() in the global namespace, 922 but doing this within a method in a class is hard - :: and extern "C" 923 are forbidden and __attribute__((alias(...))) doesn't work. Hence the 924 __asm__ aliasing trick. 925 926 */ 927 928 cc_params[cc_par_cnt++] = 929 "-D__AFL_FUZZ_INIT()=" 930 "int __afl_sharedmem_fuzzing = 1;" 931 "extern unsigned int *__afl_fuzz_len;" 932 "extern unsigned char *__afl_fuzz_ptr;" 933 "unsigned char __afl_fuzz_alt[1048576];" 934 "unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;"; 935 936 if (plusplus_mode) { 937 938 cc_params[cc_par_cnt++] = 939 "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" 940 "extern \"C\" void __afl_coverage_discard();" 941 "extern \"C\" void __afl_coverage_skip();" 942 "extern \"C\" void __afl_coverage_on();" 943 "extern \"C\" void __afl_coverage_off();"; 944 945 } else { 946 947 cc_params[cc_par_cnt++] = 948 "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;" 949 "void __afl_coverage_discard();" 950 "void __afl_coverage_skip();" 951 "void __afl_coverage_on();" 952 "void __afl_coverage_off();"; 953 954 } 955 956 cc_params[cc_par_cnt++] = 957 "-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = " 958 "1;"; 959 cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ON()=__afl_coverage_on()"; 960 cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()"; 961 cc_params[cc_par_cnt++] = 962 "-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()"; 963 cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_SKIP()=__afl_coverage_skip()"; 964 cc_params[cc_par_cnt++] = 965 "-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : " 966 "__afl_fuzz_alt_ptr)"; 967 cc_params[cc_par_cnt++] = 968 "-D__AFL_FUZZ_TESTCASE_LEN=(__afl_fuzz_ptr ? *__afl_fuzz_len : " 969 "(*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff " 970 "? 0 : *__afl_fuzz_len)"; 971 972 cc_params[cc_par_cnt++] = 973 "-D__AFL_LOOP(_A)=" 974 "({ static volatile char *_B __attribute__((used)); " 975 " _B = (char*)\"" PERSIST_SIG 976 "\"; " 977 #ifdef __APPLE__ 978 "__attribute__((visibility(\"default\"))) " 979 "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); " 980 #else 981 "__attribute__((visibility(\"default\"))) " 982 "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); " 983 #endif /* ^__APPLE__ */ 984 "_L(_A); })"; 985 986 cc_params[cc_par_cnt++] = 987 "-D__AFL_INIT()=" 988 "do { static volatile char *_A __attribute__((used)); " 989 " _A = (char*)\"" DEFER_SIG 990 "\"; " 991 #ifdef __APPLE__ 992 "__attribute__((visibility(\"default\"))) " 993 "void _I(void) __asm__(\"___afl_manual_init\"); " 994 #else 995 "__attribute__((visibility(\"default\"))) " 996 "void _I(void) __asm__(\"__afl_manual_init\"); " 997 #endif /* ^__APPLE__ */ 998 "_I(); } while (0)"; 999 1000 if (x_set) { 1001 1002 cc_params[cc_par_cnt++] = "-x"; 1003 cc_params[cc_par_cnt++] = "none"; 1004 1005 } 1006 1007 // prevent unnecessary build errors 1008 cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument"; 1009 1010 if (preprocessor_only || have_c) { 1011 1012 /* In the preprocessor_only case (-E), we are not actually compiling at 1013 all but requesting the compiler to output preprocessed sources only. 1014 We must not add the runtime in this case because the compiler will 1015 simply output its binary content back on stdout, breaking any build 1016 systems that rely on a separate source preprocessing step. */ 1017 cc_params[cc_par_cnt] = NULL; 1018 return; 1019 1020 } 1021 1022 #ifndef __ANDROID__ 1023 1024 if (compiler_mode != GCC && compiler_mode != CLANG) { 1025 1026 switch (bit_mode) { 1027 1028 case 0: 1029 if (!shared_linking && !partial_linking) 1030 cc_params[cc_par_cnt++] = 1031 alloc_printf("%s/afl-compiler-rt.o", obj_path); 1032 if (lto_mode) 1033 cc_params[cc_par_cnt++] = 1034 alloc_printf("%s/afl-llvm-rt-lto.o", obj_path); 1035 break; 1036 1037 case 32: 1038 if (!shared_linking && !partial_linking) { 1039 1040 cc_params[cc_par_cnt++] = 1041 alloc_printf("%s/afl-compiler-rt-32.o", obj_path); 1042 if (access(cc_params[cc_par_cnt - 1], R_OK)) 1043 FATAL("-m32 is not supported by your compiler"); 1044 1045 } 1046 1047 if (lto_mode) { 1048 1049 cc_params[cc_par_cnt++] = 1050 alloc_printf("%s/afl-llvm-rt-lto-32.o", obj_path); 1051 if (access(cc_params[cc_par_cnt - 1], R_OK)) 1052 FATAL("-m32 is not supported by your compiler"); 1053 1054 } 1055 1056 break; 1057 1058 case 64: 1059 if (!shared_linking && !partial_linking) { 1060 1061 cc_params[cc_par_cnt++] = 1062 alloc_printf("%s/afl-compiler-rt-64.o", obj_path); 1063 if (access(cc_params[cc_par_cnt - 1], R_OK)) 1064 FATAL("-m64 is not supported by your compiler"); 1065 1066 } 1067 1068 if (lto_mode) { 1069 1070 cc_params[cc_par_cnt++] = 1071 alloc_printf("%s/afl-llvm-rt-lto-64.o", obj_path); 1072 if (access(cc_params[cc_par_cnt - 1], R_OK)) 1073 FATAL("-m64 is not supported by your compiler"); 1074 1075 } 1076 1077 break; 1078 1079 } 1080 1081 #if !defined(__APPLE__) && !defined(__sun) 1082 if (!shared_linking && !partial_linking) 1083 cc_params[cc_par_cnt++] = 1084 alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); 1085 #endif 1086 1087 } 1088 1089 #if defined(USEMMAP) && !defined(__HAIKU__) 1090 cc_params[cc_par_cnt++] = "-lrt"; 1091 #endif 1092 1093 #endif 1094 1095 cc_params[cc_par_cnt] = NULL; 1096 1097 } 1098 1099 /* Main entry point */ 1100 1101 int main(int argc, char **argv, char **envp) { 1102 1103 int i, passthrough = 0; 1104 char *callname = argv[0], *ptr = NULL; 1105 1106 if (getenv("AFL_DEBUG")) { 1107 1108 debug = 1; 1109 if (strcmp(getenv("AFL_DEBUG"), "0") == 0) unsetenv("AFL_DEBUG"); 1110 1111 } else if (getenv("AFL_QUIET")) 1112 1113 be_quiet = 1; 1114 1115 if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") || 1116 getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") || 1117 getenv("AFL_LLVM_BLOCKLIST")) { 1118 1119 have_instr_env = 1; 1120 1121 } 1122 1123 if (getenv("AFL_PASSTHROUGH") || getenv("AFL_NOOPT")) { 1124 1125 passthrough = 1; 1126 if (!debug) { be_quiet = 1; } 1127 1128 } 1129 1130 if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1; 1131 argvnull = (u8 *)argv[0]; 1132 check_environment_vars(envp); 1133 1134 if ((ptr = find_object("as", argv[0])) != NULL) { 1135 1136 have_gcc = 1; 1137 ck_free(ptr); 1138 1139 } 1140 1141 #if (LLVM_MAJOR > 2) 1142 1143 if ((ptr = find_object("SanitizerCoverageLTO.so", argv[0])) != NULL) { 1144 1145 have_lto = 1; 1146 ck_free(ptr); 1147 1148 } 1149 1150 if ((ptr = find_object("cmplog-routines-pass.so", argv[0])) != NULL) { 1151 1152 have_llvm = 1; 1153 ck_free(ptr); 1154 1155 } 1156 1157 #endif 1158 1159 #ifdef __ANDROID__ 1160 have_llvm = 1; 1161 #endif 1162 1163 if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) { 1164 1165 have_gcc_plugin = 1; 1166 ck_free(ptr); 1167 1168 } 1169 1170 #if (LLVM_MAJOR > 2) 1171 1172 if (strncmp(callname, "afl-clang-fast", 14) == 0) { 1173 1174 compiler_mode = LLVM; 1175 1176 } else if (strncmp(callname, "afl-clang-lto", 13) == 0 || 1177 1178 strncmp(callname, "afl-lto", 7) == 0) { 1179 1180 compiler_mode = LTO; 1181 1182 } else 1183 1184 #endif 1185 if (strncmp(callname, "afl-gcc-fast", 12) == 0 || 1186 1187 strncmp(callname, "afl-g++-fast", 12) == 0) { 1188 1189 compiler_mode = GCC_PLUGIN; 1190 1191 } else if (strncmp(callname, "afl-gcc", 7) == 0 || 1192 1193 strncmp(callname, "afl-g++", 7) == 0) { 1194 1195 compiler_mode = GCC; 1196 1197 } else if (strcmp(callname, "afl-clang") == 0 || 1198 1199 strcmp(callname, "afl-clang++") == 0) { 1200 1201 compiler_mode = CLANG; 1202 1203 } 1204 1205 if ((ptr = getenv("AFL_CC_COMPILER"))) { 1206 1207 if (compiler_mode) { 1208 1209 WARNF( 1210 "\"AFL_CC_COMPILER\" is set but a specific compiler was already " 1211 "selected by command line parameter or symlink, ignoring the " 1212 "environment variable!"); 1213 1214 } else { 1215 1216 if (strncasecmp(ptr, "LTO", 3) == 0) { 1217 1218 compiler_mode = LTO; 1219 1220 } else if (strncasecmp(ptr, "LLVM", 4) == 0) { 1221 1222 compiler_mode = LLVM; 1223 1224 } else if (strncasecmp(ptr, "GCC_P", 5) == 0 || 1225 1226 strncasecmp(ptr, "GCC-P", 5) == 0 || 1227 strncasecmp(ptr, "GCCP", 4) == 0) { 1228 1229 compiler_mode = GCC_PLUGIN; 1230 1231 } else if (strcasecmp(ptr, "GCC") == 0) { 1232 1233 compiler_mode = GCC; 1234 1235 } else 1236 1237 FATAL("Unknown AFL_CC_COMPILER mode: %s\n", ptr); 1238 1239 } 1240 1241 } 1242 1243 if (strcmp(callname, "afl-clang") == 0 || 1244 strcmp(callname, "afl-clang++") == 0) { 1245 1246 clang_mode = 1; 1247 compiler_mode = CLANG; 1248 1249 if (strcmp(callname, "afl-clang++") == 0) { plusplus_mode = 1; } 1250 1251 } 1252 1253 for (i = 1; i < argc; i++) { 1254 1255 if (strncmp(argv[i], "--afl", 5) == 0) { 1256 1257 if (!strcmp(argv[i], "--afl_noopt") || !strcmp(argv[i], "--afl-noopt")) { 1258 1259 passthrough = 1; 1260 argv[i] = "-g"; // we have to overwrite it, -g is always good 1261 continue; 1262 1263 } 1264 1265 if (compiler_mode) 1266 WARNF( 1267 "--afl-... compiler mode supersedes the AFL_CC_COMPILER and " 1268 "symlink compiler selection!"); 1269 1270 ptr = argv[i]; 1271 ptr += 5; 1272 while (*ptr == '-') 1273 ptr++; 1274 1275 if (strncasecmp(ptr, "LTO", 3) == 0) { 1276 1277 compiler_mode = LTO; 1278 1279 } else if (strncasecmp(ptr, "LLVM", 4) == 0) { 1280 1281 compiler_mode = LLVM; 1282 1283 } else if (strncasecmp(ptr, "PCGUARD", 7) == 0 || 1284 1285 strncasecmp(ptr, "PC-GUARD", 8) == 0) { 1286 1287 compiler_mode = LLVM; 1288 instrument_mode = INSTRUMENT_PCGUARD; 1289 1290 } else if (strcasecmp(ptr, "INSTRIM") == 0 || 1291 1292 strcasecmp(ptr, "CFG") == 0) { 1293 1294 FATAL( 1295 "InsTrim instrumentation was removed. Use a modern LLVM and " 1296 "PCGUARD (default in afl-cc).\n"); 1297 1298 } else if (strcasecmp(ptr, "AFL") == 0 || 1299 1300 strcasecmp(ptr, "CLASSIC") == 0) { 1301 1302 compiler_mode = LLVM; 1303 instrument_mode = INSTRUMENT_CLASSIC; 1304 1305 } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 || 1306 1307 strcasecmp(ptr, "NATIVE") == 0 || 1308 strcasecmp(ptr, "LLVM-NATIVE") == 0) { 1309 1310 compiler_mode = LLVM; 1311 instrument_mode = INSTRUMENT_LLVMNATIVE; 1312 1313 } else if (strncasecmp(ptr, "GCC_P", 5) == 0 || 1314 1315 strncasecmp(ptr, "GCC-P", 5) == 0 || 1316 strncasecmp(ptr, "GCCP", 4) == 0) { 1317 1318 compiler_mode = GCC_PLUGIN; 1319 1320 } else if (strcasecmp(ptr, "GCC") == 0) { 1321 1322 compiler_mode = GCC; 1323 1324 } else if (strncasecmp(ptr, "CLANG", 5) == 0) { 1325 1326 compiler_mode = CLANG; 1327 1328 } else 1329 1330 FATAL("Unknown --afl-... compiler mode: %s\n", argv[i]); 1331 1332 } 1333 1334 } 1335 1336 if (strlen(callname) > 2 && 1337 (strncmp(callname + strlen(callname) - 2, "++", 2) == 0 || 1338 strstr(callname, "-g++") != NULL)) 1339 plusplus_mode = 1; 1340 1341 if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") || 1342 getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) { 1343 1344 if (instrument_mode == 0) 1345 instrument_mode = INSTRUMENT_PCGUARD; 1346 else if (instrument_mode != INSTRUMENT_PCGUARD) 1347 FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); 1348 1349 } 1350 1351 if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) { 1352 1353 WARNF( 1354 "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined " 1355 "for file matching, only function matching!"); 1356 1357 } 1358 1359 if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || 1360 getenv("INSTRIM_LIB")) { 1361 1362 FATAL( 1363 "InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD " 1364 "(default in afl-cc).\n"); 1365 1366 } 1367 1368 if (getenv("AFL_LLVM_CTX")) instrument_opt_mode |= INSTRUMENT_OPT_CTX; 1369 if (getenv("AFL_LLVM_CALLER")) instrument_opt_mode |= INSTRUMENT_OPT_CALLER; 1370 1371 if (getenv("AFL_LLVM_NGRAM_SIZE")) { 1372 1373 instrument_opt_mode |= INSTRUMENT_OPT_NGRAM; 1374 ngram_size = atoi(getenv("AFL_LLVM_NGRAM_SIZE")); 1375 if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) 1376 FATAL( 1377 "NGRAM instrumentation mode must be between 2 and NGRAM_SIZE_MAX " 1378 "(%u)", 1379 NGRAM_SIZE_MAX); 1380 1381 } 1382 1383 if (getenv("AFL_LLVM_CTX_K")) { 1384 1385 ctx_k = atoi(getenv("AFL_LLVM_CTX_K")); 1386 if (ctx_k < 1 || ctx_k > CTX_MAX_K) 1387 FATAL("K-CTX instrumentation mode must be between 1 and CTX_MAX_K (%u)", 1388 CTX_MAX_K); 1389 if (ctx_k == 1) { 1390 1391 setenv("AFL_LLVM_CALLER", "1", 1); 1392 unsetenv("AFL_LLVM_CTX_K"); 1393 instrument_opt_mode |= INSTRUMENT_OPT_CALLER; 1394 1395 } else { 1396 1397 instrument_opt_mode |= INSTRUMENT_OPT_CTX_K; 1398 1399 } 1400 1401 } 1402 1403 if (getenv("AFL_LLVM_INSTRUMENT")) { 1404 1405 u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;"); 1406 1407 while (ptr2) { 1408 1409 if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 || 1410 strncasecmp(ptr2, "classic", strlen("classic")) == 0) { 1411 1412 if (instrument_mode == INSTRUMENT_LTO) { 1413 1414 instrument_mode = INSTRUMENT_CLASSIC; 1415 lto_mode = 1; 1416 1417 } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) 1418 1419 instrument_mode = INSTRUMENT_AFL; 1420 else 1421 FATAL("main instrumentation mode already set with %s", 1422 instrument_mode_string[instrument_mode]); 1423 1424 } 1425 1426 if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 || 1427 strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) { 1428 1429 if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD) 1430 instrument_mode = INSTRUMENT_PCGUARD; 1431 else 1432 FATAL("main instrumentation mode already set with %s", 1433 instrument_mode_string[instrument_mode]); 1434 1435 } 1436 1437 if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 || 1438 strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) { 1439 1440 if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) 1441 instrument_mode = INSTRUMENT_LLVMNATIVE; 1442 else 1443 FATAL("main instrumentation mode already set with %s", 1444 instrument_mode_string[instrument_mode]); 1445 1446 } 1447 1448 if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 || 1449 strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) { 1450 1451 FATAL( 1452 "InsTrim instrumentation was removed. Use a modern LLVM and " 1453 "PCGUARD (default in afl-cc).\n"); 1454 1455 } 1456 1457 if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) { 1458 1459 lto_mode = 1; 1460 if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) 1461 instrument_mode = INSTRUMENT_LTO; 1462 else 1463 FATAL("main instrumentation mode already set with %s", 1464 instrument_mode_string[instrument_mode]); 1465 1466 } 1467 1468 if (strcasecmp(ptr2, "gcc") == 0) { 1469 1470 if (!instrument_mode || instrument_mode == INSTRUMENT_GCC) 1471 instrument_mode = INSTRUMENT_GCC; 1472 else if (instrument_mode != INSTRUMENT_GCC) 1473 FATAL("main instrumentation mode already set with %s", 1474 instrument_mode_string[instrument_mode]); 1475 compiler_mode = GCC; 1476 1477 } 1478 1479 if (strcasecmp(ptr2, "clang") == 0) { 1480 1481 if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG) 1482 instrument_mode = INSTRUMENT_CLANG; 1483 else if (instrument_mode != INSTRUMENT_CLANG) 1484 FATAL("main instrumentation mode already set with %s", 1485 instrument_mode_string[instrument_mode]); 1486 compiler_mode = CLANG; 1487 1488 } 1489 1490 if (strncasecmp(ptr2, "ctx-", strlen("ctx-")) == 0 || 1491 strncasecmp(ptr2, "kctx-", strlen("c-ctx-")) == 0 || 1492 strncasecmp(ptr2, "k-ctx-", strlen("k-ctx-")) == 0) { 1493 1494 u8 *ptr3 = ptr2; 1495 while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9')) 1496 ptr3++; 1497 1498 if (!*ptr3) { 1499 1500 if ((ptr3 = getenv("AFL_LLVM_CTX_K")) == NULL) 1501 FATAL( 1502 "you must set the K-CTX K with (e.g. for value 2) " 1503 "AFL_LLVM_INSTRUMENT=ctx-2"); 1504 1505 } 1506 1507 ctx_k = atoi(ptr3); 1508 if (ctx_k < 1 || ctx_k > CTX_MAX_K) 1509 FATAL( 1510 "K-CTX instrumentation option must be between 1 and CTX_MAX_K " 1511 "(%u)", 1512 CTX_MAX_K); 1513 1514 if (ctx_k == 1) { 1515 1516 instrument_opt_mode |= INSTRUMENT_OPT_CALLER; 1517 setenv("AFL_LLVM_CALLER", "1", 1); 1518 unsetenv("AFL_LLVM_CTX_K"); 1519 1520 } else { 1521 1522 instrument_opt_mode |= (INSTRUMENT_OPT_CTX_K); 1523 u8 *ptr4 = alloc_printf("%u", ctx_k); 1524 setenv("AFL_LLVM_CTX_K", ptr4, 1); 1525 1526 } 1527 1528 } 1529 1530 if (strcasecmp(ptr2, "ctx") == 0) { 1531 1532 instrument_opt_mode |= INSTRUMENT_OPT_CTX; 1533 setenv("AFL_LLVM_CTX", "1", 1); 1534 1535 } 1536 1537 if (strncasecmp(ptr2, "caller", strlen("caller")) == 0) { 1538 1539 instrument_opt_mode |= INSTRUMENT_OPT_CALLER; 1540 setenv("AFL_LLVM_CALLER", "1", 1); 1541 1542 } 1543 1544 if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) { 1545 1546 u8 *ptr3 = ptr2 + strlen("ngram"); 1547 while (*ptr3 && (*ptr3 < '0' || *ptr3 > '9')) 1548 ptr3++; 1549 1550 if (!*ptr3) { 1551 1552 if ((ptr3 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL) 1553 FATAL( 1554 "you must set the NGRAM size with (e.g. for value 2) " 1555 "AFL_LLVM_INSTRUMENT=ngram-2"); 1556 1557 } 1558 1559 ngram_size = atoi(ptr3); 1560 if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX) 1561 FATAL( 1562 "NGRAM instrumentation option must be between 2 and " 1563 "NGRAM_SIZE_MAX (%u)", 1564 NGRAM_SIZE_MAX); 1565 instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM); 1566 u8 *ptr4 = alloc_printf("%u", ngram_size); 1567 setenv("AFL_LLVM_NGRAM_SIZE", ptr4, 1); 1568 1569 } 1570 1571 ptr2 = strtok(NULL, ":,;"); 1572 1573 } 1574 1575 } 1576 1577 if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && 1578 (instrument_opt_mode & INSTRUMENT_OPT_CALLER)) { 1579 1580 FATAL("you cannot set CTX and CALLER together"); 1581 1582 } 1583 1584 if ((instrument_opt_mode & INSTRUMENT_OPT_CTX) && 1585 (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) { 1586 1587 FATAL("you cannot set CTX and K-CTX together"); 1588 1589 } 1590 1591 if ((instrument_opt_mode & INSTRUMENT_OPT_CALLER) && 1592 (instrument_opt_mode & INSTRUMENT_OPT_CTX_K)) { 1593 1594 FATAL("you cannot set CALLER and K-CTX together"); 1595 1596 } 1597 1598 if (instrument_opt_mode && instrument_mode == INSTRUMENT_DEFAULT && 1599 (compiler_mode == LLVM || compiler_mode == UNSET)) { 1600 1601 instrument_mode = INSTRUMENT_CLASSIC; 1602 compiler_mode = LLVM; 1603 1604 } 1605 1606 if (!compiler_mode) { 1607 1608 // lto is not a default because outside of afl-cc RANLIB and AR have to 1609 // be set to llvm versions so this would work 1610 if (have_llvm) 1611 compiler_mode = LLVM; 1612 else if (have_gcc_plugin) 1613 compiler_mode = GCC_PLUGIN; 1614 else if (have_gcc) 1615 #ifdef __APPLE__ 1616 // on OSX clang masquerades as GCC 1617 compiler_mode = CLANG; 1618 #else 1619 compiler_mode = GCC; 1620 #endif 1621 else if (have_lto) 1622 compiler_mode = LTO; 1623 else 1624 FATAL("no compiler mode available"); 1625 1626 } 1627 1628 if (compiler_mode == GCC) { 1629 1630 if (clang_mode) { 1631 1632 instrument_mode = INSTRUMENT_CLANG; 1633 1634 } else { 1635 1636 instrument_mode = INSTRUMENT_GCC; 1637 1638 } 1639 1640 } 1641 1642 if (compiler_mode == CLANG) { 1643 1644 instrument_mode = INSTRUMENT_CLANG; 1645 setenv(CLANG_ENV_VAR, "1", 1); // used by afl-as 1646 1647 } 1648 1649 if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) { 1650 1651 printf("afl-cc" VERSION 1652 " by Michal Zalewski, Laszlo Szekeres, Marc Heuse\n"); 1653 1654 SAYF( 1655 "\n" 1656 "afl-cc/afl-c++ [options]\n" 1657 "\n" 1658 "This is a helper application for afl-fuzz. It serves as a drop-in " 1659 "replacement\n" 1660 "for gcc and clang, letting you recompile third-party code with the " 1661 "required\n" 1662 "runtime instrumentation. A common use pattern would be one of the " 1663 "following:\n\n" 1664 1665 " CC=afl-cc CXX=afl-c++ ./configure --disable-shared\n" 1666 " cmake -DCMAKE_C_COMPILERC=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ .\n" 1667 " CC=afl-cc CXX=afl-c++ meson\n\n"); 1668 1669 SAYF( 1670 " |------------- FEATURES " 1671 "-------------|\n" 1672 "MODES: NCC PERSIST DICT LAF " 1673 "CMPLOG SELECT\n" 1674 " [LTO] llvm LTO: %s%s\n" 1675 " PCGUARD DEFAULT yes yes yes yes yes " 1676 " yes\n" 1677 " CLASSIC yes yes yes yes yes " 1678 " yes\n" 1679 " [LLVM] llvm: %s%s\n" 1680 " PCGUARD %s yes yes module yes yes " 1681 "yes\n" 1682 " CLASSIC %s no yes module yes yes " 1683 "yes\n" 1684 " - NORMAL\n" 1685 " - CALLER\n" 1686 " - CTX\n" 1687 " - NGRAM-{2-16}\n" 1688 " [GCC_PLUGIN] gcc plugin: %s%s\n" 1689 " CLASSIC DEFAULT no yes no no no " 1690 "yes\n" 1691 " [GCC/CLANG] simple gcc/clang: %s%s\n" 1692 " CLASSIC DEFAULT no no no no no " 1693 "no\n\n", 1694 have_lto ? "AVAILABLE" : "unavailable!", 1695 compiler_mode == LTO ? " [SELECTED]" : "", 1696 have_llvm ? "AVAILABLE" : "unavailable!", 1697 compiler_mode == LLVM ? " [SELECTED]" : "", 1698 LLVM_MAJOR > 6 ? "DEFAULT" : " ", 1699 LLVM_MAJOR > 6 ? " " : "DEFAULT", 1700 have_gcc_plugin ? "AVAILABLE" : "unavailable!", 1701 compiler_mode == GCC_PLUGIN ? " [SELECTED]" : "", 1702 have_gcc ? "AVAILABLE" : "unavailable!", 1703 (compiler_mode == GCC || compiler_mode == CLANG) ? " [SELECTED]" : ""); 1704 1705 SAYF( 1706 "Modes:\n" 1707 " To select the compiler mode use a symlink version (e.g. " 1708 "afl-clang-fast), set\n" 1709 " the environment variable AFL_CC_COMPILER to a mode (e.g. LLVM) or " 1710 "use the\n" 1711 " command line parameter --afl-MODE (e.g. --afl-llvm). If none is " 1712 "selected,\n" 1713 " afl-cc will select the best available (LLVM -> GCC_PLUGIN -> GCC).\n" 1714 " The best is LTO but it often needs RANLIB and AR settings outside " 1715 "of afl-cc.\n\n"); 1716 1717 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) 1718 #define NATIVE_MSG \ 1719 " LLVM-NATIVE: use llvm's native PCGUARD instrumentation (less " \ 1720 "performant)\n" 1721 #else 1722 #define NATIVE_MSG "" 1723 #endif 1724 1725 SAYF( 1726 "Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best " 1727 "available)\n" 1728 " PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n" 1729 1730 NATIVE_MSG 1731 1732 " CLASSIC: decision target instrumentation (README.llvm.md)\n" 1733 " CALLER: CLASSIC + single callee context " 1734 "(instrumentation/README.ctx.md)\n" 1735 " CTX: CLASSIC + full callee context " 1736 "(instrumentation/README.ctx.md)\n" 1737 " NGRAM-x: CLASSIC + previous path " 1738 "((instrumentation/README.ngram.md)\n\n"); 1739 1740 #undef NATIVE_MSG 1741 1742 SAYF( 1743 "Features: (see documentation links)\n" 1744 " NCC: non-colliding coverage [automatic] (that is an amazing " 1745 "thing!)\n" 1746 " (instrumentation/README.lto.md)\n" 1747 " PERSIST: persistent mode support [code] (huge speed increase!)\n" 1748 " (instrumentation/README.persistent_mode.md)\n" 1749 " DICT: dictionary in the target [yes=automatic or llvm module " 1750 "pass]\n" 1751 " (instrumentation/README.lto.md + " 1752 "instrumentation/README.llvm.md)\n" 1753 " LAF: comparison splitting [env] " 1754 "(instrumentation/README.laf-intel.md)\n" 1755 " CMPLOG: input2state exploration [env] " 1756 "(instrumentation/README.cmplog.md)\n" 1757 " SELECT: selective instrumentation (allow/deny) on filename or " 1758 "function [env]\n" 1759 " (instrumentation/README.instrument_list.md)\n\n"); 1760 1761 if (argc < 2 || strncmp(argv[1], "-hh", 3)) { 1762 1763 SAYF( 1764 "To see all environment variables for the configuration of afl-cc " 1765 "use \"-hh\".\n"); 1766 1767 } else { 1768 1769 SAYF( 1770 "Environment variables used:\n" 1771 " AFL_CC: path to the C compiler to use\n" 1772 " AFL_CXX: path to the C++ compiler to use\n" 1773 " AFL_DEBUG: enable developer debugging output\n" 1774 " AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" 1775 " AFL_NO_BUILTIN: no builtins for string compare functions (for " 1776 "libtokencap.so)\n" 1777 " AFL_NOOP: behave like a normal compiler (to pass configure " 1778 "tests)\n" 1779 " AFL_PATH: path to instrumenting pass and runtime " 1780 "(afl-compiler-rt.*o)\n" 1781 " AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" 1782 " AFL_INST_RATIO: percentage of branches to instrument\n" 1783 " AFL_QUIET: suppress verbose output\n" 1784 " AFL_HARDEN: adds code hardening to catch memory bugs\n" 1785 " AFL_USE_ASAN: activate address sanitizer\n" 1786 " AFL_USE_CFISAN: activate control flow sanitizer\n" 1787 " AFL_USE_MSAN: activate memory sanitizer\n" 1788 " AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" 1789 " AFL_USE_LSAN: activate leak-checker sanitizer\n"); 1790 1791 if (have_gcc_plugin) 1792 SAYF( 1793 "\nGCC Plugin-specific environment variables:\n" 1794 " AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n" 1795 " AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n" 1796 " AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by " 1797 "filename\n"); 1798 1799 #if LLVM_MAJOR < 9 1800 #define COUNTER_BEHAVIOUR \ 1801 " AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" 1802 #else 1803 #define COUNTER_BEHAVIOUR \ 1804 " AFL_LLVM_SKIP_NEVERZERO: do not skip zero on trace counters\n" 1805 #endif 1806 if (have_llvm) 1807 SAYF( 1808 "\nLLVM/LTO/afl-clang-fast/afl-clang-lto specific environment " 1809 "variables:\n" 1810 " AFL_LLVM_THREADSAFE_INST: instrument with thread safe counters, " 1811 "disables neverzero\n" 1812 1813 COUNTER_BEHAVIOUR 1814 1815 " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " 1816 "comparisons\n" 1817 " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" 1818 " AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" 1819 " AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" 1820 " AFL_LLVM_LAF_SPLIT_SWITCHES: cascaded comparisons on switches\n" 1821 " AFL_LLVM_LAF_SPLIT_FLOATS: cascaded comparisons on floats\n" 1822 " AFL_LLVM_LAF_TRANSFORM_COMPARES: cascade comparisons for string " 1823 "functions\n" 1824 " AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST: enable " 1825 "instrument allow/\n" 1826 " deny listing (selective instrumentation)\n"); 1827 1828 if (have_llvm) 1829 SAYF( 1830 " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " 1831 "mutator)\n" 1832 " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" 1833 " CLASSIC, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, NGRAM-2 " 1834 "..-16\n" 1835 " You can also use the old environment variables instead:\n" 1836 " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" 1837 " AFL_LLVM_CALLER: use single context sensitive coverage (for " 1838 "CLASSIC)\n" 1839 " AFL_LLVM_CTX: use full context sensitive coverage (for " 1840 "CLASSIC)\n" 1841 " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " 1842 "CLASSIC)\n"); 1843 1844 #ifdef AFL_CLANG_FLTO 1845 if (have_lto) 1846 SAYF( 1847 "\nLTO/afl-clang-lto specific environment variables:\n" 1848 " AFL_LLVM_MAP_ADDR: use a fixed coverage map address (speed), " 1849 "e.g. " 1850 "0x10000\n" 1851 " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " 1852 "functions\n" 1853 " into this file\n" 1854 " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " 1855 "global var\n" 1856 " AFL_LLVM_LTO_STARTID: from which ID to start counting from for " 1857 "a " 1858 "bb\n" 1859 " AFL_REAL_LD: use this lld linker instead of the compiled in " 1860 "path\n" 1861 "If anything fails - be sure to read README.lto.md!\n"); 1862 #endif 1863 1864 SAYF( 1865 "\nYou can supply --afl-noopt to not instrument, like AFL_NOOPT. " 1866 "(this is helpful\n" 1867 "in some build systems if you do not want to instrument " 1868 "everything.\n"); 1869 1870 } 1871 1872 SAYF( 1873 "\nFor any information on the available instrumentations and options " 1874 "please \n" 1875 "consult the README.md, especially section 3.1 about instrumenting " 1876 "targets.\n\n"); 1877 1878 #if (LLVM_MAJOR > 2) 1879 if (have_lto) 1880 SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO); 1881 if (have_llvm) 1882 SAYF("afl-cc LLVM version %d using the binary path \"%s\".\n", LLVM_MAJOR, 1883 LLVM_BINDIR); 1884 #endif 1885 1886 #ifdef USEMMAP 1887 #if !defined(__HAIKU__) 1888 SAYF("Compiled with shm_open support.\n"); 1889 #else 1890 SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); 1891 #endif 1892 #else 1893 SAYF("Compiled with shmat support.\n"); 1894 #endif 1895 SAYF("\n"); 1896 1897 SAYF( 1898 "Do not be overwhelmed :) afl-cc uses good defaults if no options are " 1899 "selected.\n" 1900 "Read the documentation for FEATURES though, all are good but few are " 1901 "defaults.\n" 1902 "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast " 1903 "with\n" 1904 "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n"); 1905 1906 exit(1); 1907 1908 } 1909 1910 if (compiler_mode == LTO) { 1911 1912 if (instrument_mode == 0 || instrument_mode == INSTRUMENT_LTO || 1913 instrument_mode == INSTRUMENT_CFG || 1914 instrument_mode == INSTRUMENT_PCGUARD) { 1915 1916 lto_mode = 1; 1917 // force CFG 1918 // if (!instrument_mode) { 1919 1920 instrument_mode = INSTRUMENT_PCGUARD; 1921 // ptr = instrument_mode_string[instrument_mode]; 1922 // } 1923 1924 } else if (instrument_mode == INSTRUMENT_LTO || 1925 1926 instrument_mode == INSTRUMENT_CLASSIC) { 1927 1928 lto_mode = 1; 1929 1930 } else { 1931 1932 if (!be_quiet) 1933 WARNF("afl-clang-lto called with mode %s, using that mode instead", 1934 instrument_mode_string[instrument_mode]); 1935 1936 } 1937 1938 } 1939 1940 if (instrument_mode == 0 && compiler_mode < GCC_PLUGIN) { 1941 1942 #if LLVM_MAJOR <= 6 1943 instrument_mode = INSTRUMENT_AFL; 1944 #else 1945 #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) 1946 if (have_instr_env) { 1947 1948 instrument_mode = INSTRUMENT_AFL; 1949 if (!be_quiet) 1950 WARNF( 1951 "Switching to classic instrumentation because " 1952 "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1."); 1953 1954 } else 1955 1956 #endif 1957 instrument_mode = INSTRUMENT_PCGUARD; 1958 1959 #endif 1960 1961 } 1962 1963 if (instrument_opt_mode && compiler_mode != LLVM) 1964 FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode"); 1965 1966 if (!instrument_opt_mode) { 1967 1968 if (lto_mode && instrument_mode == INSTRUMENT_CFG) 1969 instrument_mode = INSTRUMENT_PCGUARD; 1970 ptr = instrument_mode_string[instrument_mode]; 1971 1972 } else { 1973 1974 char *ptr2 = alloc_printf(" + NGRAM-%u", ngram_size); 1975 char *ptr3 = alloc_printf(" + K-CTX-%u", ctx_k); 1976 1977 ptr = alloc_printf( 1978 "%s%s%s%s%s", instrument_mode_string[instrument_mode], 1979 (instrument_opt_mode & INSTRUMENT_OPT_CTX) ? " + CTX" : "", 1980 (instrument_opt_mode & INSTRUMENT_OPT_CALLER) ? " + CALLER" : "", 1981 (instrument_opt_mode & INSTRUMENT_OPT_NGRAM) ? ptr2 : "", 1982 (instrument_opt_mode & INSTRUMENT_OPT_CTX_K) ? ptr3 : ""); 1983 1984 ck_free(ptr2); 1985 ck_free(ptr3); 1986 1987 } 1988 1989 #ifndef AFL_CLANG_FLTO 1990 if (lto_mode) 1991 FATAL( 1992 "instrumentation mode LTO specified but LLVM support not available " 1993 "(requires LLVM 11 or higher)"); 1994 #endif 1995 1996 if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) 1997 FATAL( 1998 "CALLER, CTX and NGRAM instrumentation options can only be used with " 1999 "the LLVM CLASSIC instrumentation mode."); 2000 2001 if (getenv("AFL_LLVM_SKIP_NEVERZERO") && getenv("AFL_LLVM_NOT_ZERO")) 2002 FATAL( 2003 "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set " 2004 "together"); 2005 2006 #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1) 2007 if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) { 2008 2009 FATAL( 2010 "Instrumentation type PCGUARD does not support " 2011 "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead."); 2012 2013 } 2014 2015 #endif 2016 2017 u8 *ptr2; 2018 2019 if ((ptr2 = getenv("AFL_LLVM_DICT2FILE")) != NULL && *ptr2 != '/') 2020 FATAL("AFL_LLVM_DICT2FILE must be set to an absolute file path"); 2021 2022 if ((isatty(2) && !be_quiet) || debug) { 2023 2024 SAYF(cCYA 2025 "afl-cc " VERSION cRST 2026 " by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: %s-%s\n", 2027 compiler_mode_string[compiler_mode], ptr); 2028 2029 } 2030 2031 if (!be_quiet && (compiler_mode == GCC || compiler_mode == CLANG)) { 2032 2033 WARNF( 2034 "You are using outdated instrumentation, install LLVM and/or " 2035 "gcc-plugin and use afl-clang-fast/afl-clang-lto/afl-gcc-fast " 2036 "instead!"); 2037 2038 } 2039 2040 if (debug) { 2041 2042 DEBUGF("cd '%s';", getthecwd()); 2043 for (i = 0; i < argc; i++) 2044 SAYF(" '%s'", argv[i]); 2045 SAYF("\n"); 2046 fflush(stdout); 2047 fflush(stderr); 2048 2049 } 2050 2051 if (getenv("AFL_LLVM_LAF_ALL")) { 2052 2053 setenv("AFL_LLVM_LAF_SPLIT_SWITCHES", "1", 1); 2054 setenv("AFL_LLVM_LAF_SPLIT_COMPARES", "1", 1); 2055 setenv("AFL_LLVM_LAF_SPLIT_FLOATS", "1", 1); 2056 setenv("AFL_LLVM_LAF_TRANSFORM_COMPARES", "1", 1); 2057 2058 } 2059 2060 cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG"); 2061 if (!be_quiet && cmplog_mode) 2062 printf("CmpLog mode by <andreafioraldi@gmail.com>\n"); 2063 2064 #if !defined(__ANDROID__) && !defined(ANDROID) 2065 ptr = find_object("afl-compiler-rt.o", argv[0]); 2066 2067 if (!ptr) { 2068 2069 FATAL( 2070 "Unable to find 'afl-compiler-rt.o'. Please set the AFL_PATH " 2071 "environment variable."); 2072 2073 } 2074 2075 if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); } 2076 2077 ck_free(ptr); 2078 #endif 2079 2080 edit_params(argc, argv, envp); 2081 2082 if (debug) { 2083 2084 DEBUGF("cd '%s';", getthecwd()); 2085 for (i = 0; i < (s32)cc_par_cnt; i++) 2086 SAYF(" '%s'", cc_params[i]); 2087 SAYF("\n"); 2088 fflush(stdout); 2089 fflush(stderr); 2090 2091 } 2092 2093 if (passthrough) { 2094 2095 argv[0] = cc_params[0]; 2096 execvp(cc_params[0], (char **)argv); 2097 2098 } else { 2099 2100 execvp(cc_params[0], (char **)cc_params); 2101 2102 } 2103 2104 FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); 2105 2106 return 0; 2107 2108 } 2109 2110