diff options
Diffstat (limited to 'src/afl-cc.c')
-rw-r--r-- | src/afl-cc.c | 267 |
1 files changed, 174 insertions, 93 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c index 19dc9a6a..c43ac2c1 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -48,6 +48,7 @@ static u8 * obj_path; /* Path to runtime libraries */ static u8 **cc_params; /* Parameters passed to the real CC */ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ +static u8 clang_mode; /* Invoked as afl-clang*? */ static u8 llvm_fullpath[PATH_MAX]; static u8 instrument_mode, instrument_opt_mode, ngram_size, lto_mode; static u8 compiler_mode, plusplus_mode, have_instr_env = 0; @@ -105,7 +106,24 @@ u8 *getthecwd() { } -/* Try to find the runtime libraries. If that fails, abort. */ +/* Try to find a specific runtime we need, returns NULL on fail. */ + +/* + in find_object() we look here: + + 1. if obj_path is already set we look there first + 2. then we check the $AFL_PATH environment variable location if set + 3. next we check argv[0] if it has path information and use it + a) we also check ../lib/afl + 4. if 3. failed we check /proc (only Linux, Android, NetBSD, DragonFly, and + FreeBSD with procfs) + a) and check here in ../lib/afl too + 5. we look into the AFL_PATH define (usually /usr/local/lib/afl) + 6. we finally try the current directory + + if all these attempts fail - we return NULL and the caller has to decide + what to do. +*/ static u8 *find_object(u8 *obj, u8 *argv0) { @@ -114,11 +132,9 @@ static u8 *find_object(u8 *obj, u8 *argv0) { if (afl_path) { -#ifdef __ANDROID__ tmp = alloc_printf("%s/%s", afl_path, obj); -#else - tmp = alloc_printf("%s/%s", afl_path, obj); -#endif + + if (debug) DEBUGF("Trying %s\n", tmp); if (!access(tmp, R_OK)) { @@ -131,125 +147,139 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } - if (argv0) slash = strrchr(argv0, '/'); + if (argv0) { - if (slash) { + slash = strrchr(argv0, '/'); - u8 *dir; + if (slash) { - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; + u8 *dir = ck_strdup(argv0); -#ifdef __ANDROID__ - tmp = alloc_printf("%s/%s", dir, obj); -#else - tmp = alloc_printf("%s/%s", dir, obj); -#endif + slash = strrchr(dir, '/'); + *slash = 0; - if (!access(tmp, R_OK)) { + tmp = alloc_printf("%s/%s", dir, obj); - obj_path = dir; - return tmp; - - } + if (debug) DEBUGF("Trying %s\n", tmp); - ck_free(tmp); - ck_free(dir); + if (!access(tmp, R_OK)) { - } + obj_path = dir; + return tmp; - tmp = alloc_printf("%s/%s", AFL_PATH, obj); -#ifdef __ANDROID__ - if (!access(tmp, R_OK)) { + } -#else - if (!access(tmp, R_OK)) { + ck_free(tmp); + tmp = alloc_printf("%s/../lib/afl/%s", dir, obj); -#endif + if (debug) DEBUGF("Trying %s\n", tmp); - obj_path = AFL_PATH; - return tmp; + if (!access(tmp, R_OK)) { - } + u8 *dir2 = alloc_printf("%s/../lib/afl", dir); + obj_path = dir2; + ck_free(dir); + return tmp; - ck_free(tmp); - return NULL; + } -} + ck_free(tmp); + ck_free(dir); -/* Try to find the runtime libraries. If that fails, abort. */ + } -static void find_obj(u8 *argv0) { +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__linux__) || \ + defined(__ANDROID__) || defined(__NetBSD__) + #define HAS_PROC_FS 1 +#endif +#ifdef HAS_PROC_FS + else { + + char *procname = NULL; + #if defined(__FreeBSD__) || defined(__DragonFly__) + procname = "/proc/curproc/file"; + #elif defined(__linux__) || defined(__ANDROID__) + procname = "/proc/self/exe"; + #elif defined(__NetBSD__) + procname = "/proc/curproc/exe"; + #endif + if (procname) { - u8 *afl_path = getenv("AFL_PATH"); - u8 *slash, *tmp; + char exepath[PATH_MAX]; + ssize_t exepath_len = readlink(procname, exepath, sizeof(exepath)); + if (exepath_len > 0 && exepath_len < PATH_MAX) { - if (afl_path) { + exepath[exepath_len] = 0; + slash = strrchr(exepath, '/'); -#ifdef __ANDROID__ - tmp = alloc_printf("%s/afl-compiler-rt.so", afl_path); -#else - tmp = alloc_printf("%s/afl-compiler-rt.o", afl_path); -#endif + if (slash) { - if (!access(tmp, R_OK)) { + *slash = 0; + tmp = alloc_printf("%s/%s", exepath, obj); - obj_path = afl_path; - ck_free(tmp); - return; + if (!access(tmp, R_OK)) { - } + u8 *dir = alloc_printf("%s", exepath); + obj_path = dir; + return tmp; - ck_free(tmp); + } - } + ck_free(tmp); + tmp = alloc_printf("%s/../lib/afl/%s", exepath, obj); - slash = strrchr(argv0, '/'); + if (debug) DEBUGF("Trying %s\n", tmp); - if (slash) { + if (!access(tmp, R_OK)) { - u8 *dir; + u8 *dir = alloc_printf("%s/../lib/afl/", exepath); + obj_path = dir; + return tmp; - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; + } -#ifdef __ANDROID__ - tmp = alloc_printf("%s/afl-compiler-rt.so", dir); -#else - tmp = alloc_printf("%s/afl-compiler-rt.o", dir); -#endif + } - if (!access(tmp, R_OK)) { + } - obj_path = dir; - ck_free(tmp); - return; + } } - ck_free(tmp); - ck_free(dir); +#endif +#undef HAS_PROC_FS } -#ifdef __ANDROID__ - if (!access(AFL_PATH "/afl-compiler-rt.so", R_OK)) { + tmp = alloc_printf("%s/%s", AFL_PATH, obj); -#else - if (!access(AFL_PATH "/afl-compiler-rt.o", R_OK)) { + if (debug) DEBUGF("Trying %s\n", tmp); -#endif + if (!access(tmp, R_OK)) { obj_path = AFL_PATH; - return; + return tmp; + + } + + ck_free(tmp); + + tmp = alloc_printf("./%s", obj); + + if (debug) DEBUGF("Trying %s\n", tmp); + + if (!access(tmp, R_OK)) { + + obj_path = "."; + return tmp; } - FATAL( - "Unable to find 'afl-compiler-rt.o' or 'afl-llvm-pass.so'. Please set " - "AFL_PATH"); + ck_free(tmp); + + if (debug) DEBUGF("Trying ... giving up\n"); + + return NULL; } @@ -288,7 +318,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode >= GCC_PLUGIN) { - alt_cxx = "g++"; + if (compiler_mode == GCC) { + + alt_cxx = clang_mode ? "clang++" : "g++"; + + } else { + + alt_cxx = "g++"; + + } } else { @@ -313,7 +351,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (compiler_mode >= GCC_PLUGIN) { - alt_cc = "gcc"; + if (compiler_mode == GCC) { + + alt_cc = clang_mode ? "clang" : "gcc"; + + } else { + + alt_cc = "gcc"; + + } } else { @@ -337,12 +383,13 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-B"; cc_params[cc_par_cnt++] = obj_path; + if (clang_mode) { cc_params[cc_par_cnt++] = "-no-integrated-as"; } + } if (compiler_mode == GCC_PLUGIN) { - char *fplugin_arg = - alloc_printf("-fplugin=%s", find_object("afl-gcc-pass.so", argvnull)); + char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); cc_params[cc_par_cnt++] = fplugin_arg; } @@ -686,7 +733,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || - getenv("LAF_TRANSFORM_COMPARES") || lto_mode) { + getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || + lto_mode) { cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; @@ -843,6 +891,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path); #endif + #ifdef USEMMAP + cc_params[cc_par_cnt++] = "-lrt"; + #endif + } #endif @@ -934,7 +986,9 @@ int main(int argc, char **argv, char **envp) { } else if (strncmp(callname, "afl-gcc", 7) == 0 || - strncmp(callname, "afl-g++", 7) == 0) { + strncmp(callname, "afl-g++", 7) == 0 || + + strncmp(callname, "afl-clang", 9) == 0) { compiler_mode = GCC; @@ -978,6 +1032,14 @@ int main(int argc, char **argv, char **envp) { } + if (strncmp(callname, "afl-clang", 9) == 0) { + + clang_mode = 1; + + if (strncmp(callname, "afl-clang++", 11) == 0) { plusplus_mode = 1; } + + } + for (i = 1; i < argc; i++) { if (strncmp(argv[i], "--afl", 5) == 0) { @@ -1030,7 +1092,7 @@ int main(int argc, char **argv, char **envp) { if (instrument_mode == 0) instrument_mode = INSTRUMENT_PCGUARD; else if (instrument_mode != INSTRUMENT_PCGUARD) - FATAL("you can not set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); + FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_TRACE_PC together"); } @@ -1048,8 +1110,7 @@ int main(int argc, char **argv, char **envp) { if (instrument_mode == 0) instrument_mode = INSTRUMENT_CFG; else if (instrument_mode != INSTRUMENT_CFG) - FATAL( - "you can not set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); } @@ -1403,9 +1464,15 @@ int main(int argc, char **argv, char **envp) { if (have_llvm) SAYF("afl-cc LLVM version %d with the the binary path \"%s\".\n", LLVM_MAJOR, LLVM_BINDIR); - if (have_lto || have_llvm) SAYF("\n"); #endif +#ifdef USEMMAP + SAYF("Compiled with shm_open support (adds -lrt when linking).\n"); +#else + SAYF("Compiled with shmat support.\n"); +#endif + SAYF("\n"); + SAYF( "Do not be overwhelmed :) afl-cc uses good defaults if no options are " "selected.\n" @@ -1545,7 +1612,7 @@ int main(int argc, char **argv, char **envp) { if (debug) { - SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); + DEBUGF("cd '%s';", getthecwd()); for (i = 0; i < argc; i++) SAYF(" '%s'", argv[i]); SAYF("\n"); @@ -1565,15 +1632,29 @@ int main(int argc, char **argv, char **envp) { if (!be_quiet && cmplog_mode) printf("CmpLog mode by <andreafioraldi@gmail.com>\n"); -#ifndef __ANDROID__ - find_obj(argv[0]); +#ifdef __ANDROID__ + ptr = find_object("afl-compiler-rt.so", argv[0]); +#else + ptr = find_object("afl-compiler-rt.o", argv[0]); #endif + if (!ptr) { + + FATAL( + "Unable to find 'afl-compiler-rt.o'. Please set the AFL_PATH " + "environment variable."); + + } + + if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); } + + ck_free(ptr); + edit_params(argc, argv, envp); if (debug) { - SAYF(cMGN "[D]" cRST " cd '%s';", getthecwd()); + DEBUGF("cd '%s';", getthecwd()); for (i = 0; i < (s32)cc_par_cnt; i++) SAYF(" '%s'", cc_params[i]); SAYF("\n"); |