diff --git a/src/AFLplusplus-stable/src/afl-as.c b/src/AFLplusplus-stable/src/afl-as.c index 4e9cf6a..f9fe2b9 100644 --- a/src/AFLplusplus-stable/src/afl-as.c +++ b/src/AFLplusplus-stable/src/afl-as.c @@ -91,244 +91,114 @@ static u8 use_64bit = 0; to keep the code simple. */ static void edit_params(int argc, char **argv) { -<<<<<<< HEAD - u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS"); - u32 i, input_index; -#ifdef __APPLE__ - u8 use_clang_as = 0; - if (clang_mode && !afl_as) { - use_clang_as = 1; - afl_as = getenv("AFL_CC"); - if (!afl_as) afl_as = getenv("AFL_CXX"); - if (!afl_as) afl_as = "clang"; - } -#endif - if (!tmp_dir) { tmp_dir = getenv("TEMP"); } - if (!tmp_dir) { tmp_dir = getenv("TMP"); } - if (!tmp_dir) { tmp_dir = "/tmp"; } - as_params = ck_alloc((argc + 32) * sizeof(u8 *)); - if (unlikely((INT_MAX - 32) < argc || !as_params)) { - FATAL("Too many parameters passed to as"); - } - as_params[0] = afl_as ? afl_as : (u8 *)"as"; - as_params[argc] = 0; - for (input_index = argc - 1; input_index > 0; input_index--) { - input_file = argv[input_index]; - if (strncmp(input_file, "-g", 2)) break; - } - if (input_index == 0) - FATAL("Could not find input file (not called through afl-gcc?)"); - for (i = 1; (s32)i < argc; i++) { - if (i == input_index) continue; - if (!strcmp(argv[i], "--64")) { - use_64bit = 1; - } else if (!strcmp(argv[i], "--32")) { - use_64bit = 0; - } -#ifdef __APPLE__ - if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) { -======= - + // 获取临时目录路径和AFL_AS环境变量 u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS"); u32 i, input_index; #ifdef __APPLE__ - u8 use_clang_as = 0; - /* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work - with the code generated by newer versions of clang that are hand-built - by the user. See the thread here: https://goo.gl/HBWDtn. - - To work around this, when using clang and running without AFL_AS - specified, we will actually call 'clang -c' instead of 'as -q' to - compile the assembly file. - - The tools aren't cmdline-compatible, but at least for now, we can - seemingly get away with this by making only very minor tweaks. Thanks - to Nico Weber for the idea. */ - + // 在MacOS下,若使用clang且没有设置AFL_AS,则使用clang作为汇编器 if (clang_mode && !afl_as) { - use_clang_as = 1; - - afl_as = getenv("AFL_CC"); - if (!afl_as) afl_as = getenv("AFL_CXX"); - if (!afl_as) afl_as = "clang"; - + afl_as = getenv("AFL_CC"); // 获取AFL_CC环境变量 + if (!afl_as) afl_as = getenv("AFL_CXX"); // 获取AFL_CXX环境变量 + if (!afl_as) afl_as = "clang"; // 默认使用clang } +#endif -#endif /* __APPLE__ */ - - /* Although this is not documented, GCC also uses TEMP and TMP when TMPDIR - is not set. We need to check these non-standard variables to properly - handle the pass_thru logic later on. */ - + // 如果TMPDIR环境变量为空,尝试从TEMP和TMP获取临时目录 if (!tmp_dir) { tmp_dir = getenv("TEMP"); } if (!tmp_dir) { tmp_dir = getenv("TMP"); } - if (!tmp_dir) { tmp_dir = "/tmp"; } + if (!tmp_dir) { tmp_dir = "/tmp"; } // 默认临时目录为"/tmp" + // 为汇编参数分配内存,确保不会超过最大参数个数 as_params = ck_alloc((argc + 32) * sizeof(u8 *)); if (unlikely((INT_MAX - 32) < argc || !as_params)) { - - FATAL("Too many parameters passed to as"); - + FATAL("Too many parameters passed to as"); // 参数过多,终止 } + // 设置汇编器命令 as_params[0] = afl_as ? afl_as : (u8 *)"as"; - as_params[argc] = 0; - /* Find the input file. It's usually located near the end. - Assume there won't be any arguments referring to files after the input - file, e.g. as input.s -o output.o */ + // 查找输入文件,通常位于命令行参数的最后 for (input_index = argc - 1; input_index > 0; input_index--) { - input_file = argv[input_index]; - /* Clang may add debug arguments after the input file. */ + // 如果遇到调试选项,跳过 if (strncmp(input_file, "-g", 2)) break; - } + // 如果没有找到输入文件,输出错误信息 if (input_index == 0) FATAL("Could not find input file (not called through afl-gcc?)"); + // 遍历参数,处理与汇编相关的选项 for (i = 1; (s32)i < argc; i++) { + if (i == input_index) continue; // 跳过输入文件 - if (i == input_index) continue; - + // 处理64位和32位选项 if (!strcmp(argv[i], "--64")) { - use_64bit = 1; - } else if (!strcmp(argv[i], "--32")) { - use_64bit = 0; - } #ifdef __APPLE__ - - /* The Apple case is a bit different... */ - + // 在MacOS下,处理架构选项 if (!strcmp(argv[i], "-arch") && i + 1 < (u32)argc) { - ->>>>>>> e12b99bad19de97a02e9fe14b9b2c048338b2ab7 if (!strcmp(argv[i + 1], "x86_64")) use_64bit = 1; else if (!strcmp(argv[i + 1], "i386")) FATAL("Sorry, 32-bit Apple platforms are not supported."); -<<<<<<< HEAD } - if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q"))) - continue; #endif - as_params[as_par_cnt++] = argv[i]; - } -#ifdef __APPLE__ - if (use_clang_as) { - as_params[as_par_cnt++] = "-c"; - as_params[as_par_cnt++] = "-x"; - as_params[as_par_cnt++] = "assembler"; - } -#endif - if (input_file[0] == '-') { - if (!strcmp(input_file + 1, "-version")) { - just_version = 1; - modified_file = input_file; - goto wrap_things_up; - } - if (input_file[1]) { - FATAL("Incorrect use (not called through afl-gcc?)"); - } else { - input_file = NULL; - } - } else { -======= - - } - - /* Strip options that set the preference for a particular upstream - assembler in Xcode. */ + // 跳过不相关的选项 if (clang_mode && (!strcmp(argv[i], "-q") || !strcmp(argv[i], "-Q"))) continue; - -#endif /* __APPLE__ */ - + + // 将参数添加到汇编器参数列表 as_params[as_par_cnt++] = argv[i]; - } #ifdef __APPLE__ - - /* When calling clang as the upstream assembler, append -c -x assembler - and hope for the best. */ - + // 如果使用clang作为汇编器,追加相关选项 if (use_clang_as) { - as_params[as_par_cnt++] = "-c"; as_params[as_par_cnt++] = "-x"; as_params[as_par_cnt++] = "assembler"; - } +#endif -#endif /* __APPLE__ */ - + // 如果输入文件是"-"参数,检查是否为版本信息 if (input_file[0] == '-') { - if (!strcmp(input_file + 1, "-version")) { - just_version = 1; modified_file = input_file; - goto wrap_things_up; - + goto wrap_things_up; // 跳到结束处理 } - if (input_file[1]) { - FATAL("Incorrect use (not called through afl-gcc?)"); - } else { - - input_file = NULL; - + input_file = NULL; // 没有文件参数 } - } else { - - /* Check if this looks like a standard invocation as a part of an attempt - to compile a program, rather than using gcc on an ad-hoc .s file in - a format we may not understand. This works around an issue compiling - NSS. */ - ->>>>>>> e12b99bad19de97a02e9fe14b9b2c048338b2ab7 + // 检查输入文件是否为临时文件,并决定是否需要通过工具传递 if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) && strncmp(input_file, "/var/tmp/", 9) && strncmp(input_file, "/tmp/", 5) && getenv("AFL_AS_FORCE_INSTRUMENT") == NULL) { -<<<<<<< HEAD pass_thru = 1; } else if (getenv("AFL_AS_FORCE_INSTRUMENT")) { - unsetenv("AFL_AS_FORCE_INSTRUMENT"); + unsetenv("AFL_AS_FORCE_INSTRUMENT"); // 强制插桩的环境变量取消 } } - modified_file = alloc_printf("%s/.afl-%u-%u-%u.s", tmp_dir, (u32)getpid(), - (u32)time(NULL), (u32)random()); -======= - - pass_thru = 1; - - } else if (getenv("AFL_AS_FORCE_INSTRUMENT")) { - - unsetenv("AFL_AS_FORCE_INSTRUMENT"); - - } - - } + // 为汇编文件生成一个唯一的临时文件名 modified_file = alloc_printf("%s/.afl-%u-%u-%u.s", tmp_dir, (u32)getpid(), (u32)time(NULL), (u32)random()); +} >>>>>>> e12b99bad19de97a02e9fe14b9b2c048338b2ab7 wrap_things_up: @@ -383,15 +253,6 @@ static void add_instrumentation(void) { if (!outf) { PFATAL("fdopen() failed"); } while (fgets(line, MAX_LINE, inf)) { -<<<<<<< HEAD -======= - - /* In some cases, we want to defer writing the instrumentation trampoline - until after all the labels, macros, comments, etc. If we're in this - mode, and if the line starts with a tab followed by a character, dump - the trampoline now. */ - ->>>>>>> e12b99bad19de97a02e9fe14b9b2c048338b2ab7 if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok && instrument_next && line[0] == '\t' && isalpha(line[1])) { diff --git a/src/AFLplusplus-stable/src/afl-cc.c b/src/AFLplusplus-stable/src/afl-cc.c index c2f9cf6..5dd4c8b 100644 --- a/src/AFLplusplus-stable/src/afl-cc.c +++ b/src/AFLplusplus-stable/src/afl-cc.c @@ -1895,196 +1895,132 @@ param_st parse_fsanitize(aflcc_state_t *aflcc, u8 *cur_argv, u8 scan) { these have_*, otherwise they may not work as expected. */ void add_sanitizers(aflcc_state_t *aflcc, char **envp) { -<<<<<<< HEAD - if (getenv("AFL_USE_ASAN") || aflcc->have_asan) { - if (getenv("AFL_USE_MSAN") || aflcc->have_msan) - FATAL("ASAN and MSAN are mutually exclusive"); - if (getenv("AFL_HARDEN")) - FATAL("ASAN and AFL_HARDEN are mutually exclusive"); - if (aflcc->compiler_mode == GCC_PLUGIN && !aflcc->have_staticasan) { - insert_param(aflcc, "-static-libasan"); - } - add_defs_fortify(aflcc, 0); - if (!aflcc->have_asan) { - insert_param(aflcc, "-fsanitize=address"); - insert_param(aflcc, "-fno-common"); - } - aflcc->have_asan = 1; - } else if (getenv("AFL_USE_MSAN") || aflcc->have_msan) { - if (getenv("AFL_USE_ASAN") || aflcc->have_asan) - FATAL("ASAN and MSAN are mutually exclusive"); - if (getenv("AFL_HARDEN")) - FATAL("MSAN and AFL_HARDEN are mutually exclusive"); - add_defs_fortify(aflcc, 0); - if (!aflcc->have_msan) { insert_param(aflcc, "-fsanitize=memory"); } - aflcc->have_msan = 1; - } - if (getenv("AFL_USE_UBSAN") || aflcc->have_ubsan) { - if (!aflcc->have_ubsan) { - insert_param(aflcc, "-fsanitize=undefined"); - insert_param(aflcc, "-fsanitize-undefined-trap-on-error"); - insert_param(aflcc, "-fno-sanitize-recover=all"); - } - if (!aflcc->have_fp) { - insert_param(aflcc, "-fno-omit-frame-pointer"); - aflcc->have_fp = 1; - } - aflcc->have_ubsan = 1; - } - if (getenv("AFL_USE_TSAN") || aflcc->have_tsan) { - if (!aflcc->have_fp) { - insert_param(aflcc, "-fno-omit-frame-pointer"); - aflcc->have_fp = 1; - } - if (!aflcc->have_tsan) { insert_param(aflcc, "-fsanitize=thread"); } - aflcc->have_tsan = 1; - } - if (getenv("AFL_USE_LSAN") && !aflcc->have_lsan) { - insert_param(aflcc, "-fsanitize=leak"); - add_defs_lsan_ctrl(aflcc); - aflcc->have_lsan = 1; - } - if (getenv("AFL_USE_CFISAN") || aflcc->have_cfisan) { - if (aflcc->compiler_mode == GCC_PLUGIN || aflcc->compiler_mode == GCC) { - if (!aflcc->have_fcf) { insert_param(aflcc, "-fcf-protection=full"); } - } else { - if (!aflcc->lto_mode && !aflcc->have_flto) { - uint32_t i = 0, found = 0; - while (envp[i] != NULL && !found) { - if (strncmp("-flto", envp[i++], 5) == 0) found = 1; - } - if (!found) { insert_param(aflcc, "-flto"); } - aflcc->have_flto = 1; - } - if (!aflcc->have_cfisan) { insert_param(aflcc, "-fsanitize=cfi"); } - if (!aflcc->have_hidden) { - insert_param(aflcc, "-fvisibility=hidden"); - aflcc->have_hidden = 1; - } - aflcc->have_cfisan = 1; - } - } -======= - + // 如果启用了 ASAN (地址消毒器),则进行相关配置 if (getenv("AFL_USE_ASAN") || aflcc->have_asan) { + // 如果同时启用了 MSAN (内存消毒器),则报错,因为 ASAN 和 MSAN 不能同时使用 if (getenv("AFL_USE_MSAN") || aflcc->have_msan) FATAL("ASAN and MSAN are mutually exclusive"); + // 如果启用了 AFL_HARDEN,则报错,因为 ASAN 和 AFL_HARDEN 不能同时使用 if (getenv("AFL_HARDEN")) FATAL("ASAN and AFL_HARDEN are mutually exclusive"); + // 如果是 GCC 插件模式,并且没有启用静态 ASAN 库,则添加静态 ASAN 库的选项 if (aflcc->compiler_mode == GCC_PLUGIN && !aflcc->have_staticasan) { - insert_param(aflcc, "-static-libasan"); - } + // 添加 fortify 配置,0表示没有额外的强化 add_defs_fortify(aflcc, 0); - if (!aflcc->have_asan) { + // 如果没有启用 ASAN,则添加相应的编译选项来启用地址消毒 + if (!aflcc->have_asan) { insert_param(aflcc, "-fsanitize=address"); insert_param(aflcc, "-fno-common"); - } - aflcc->have_asan = 1; - - } else if (getenv("AFL_USE_MSAN") || aflcc->have_msan) { + aflcc->have_asan = 1; // 标记已经启用了 ASAN + } + // 如果启用了 MSAN (内存消毒器),则进行相关配置 + else if (getenv("AFL_USE_MSAN") || aflcc->have_msan) { + // 如果同时启用了 ASAN,则报错,因为 ASAN 和 MSAN 不能同时使用 if (getenv("AFL_USE_ASAN") || aflcc->have_asan) FATAL("ASAN and MSAN are mutually exclusive"); + // 如果启用了 AFL_HARDEN,则报错,因为 MSAN 和 AFL_HARDEN 不能同时使用 if (getenv("AFL_HARDEN")) FATAL("MSAN and AFL_HARDEN are mutually exclusive"); + // 添加 fortify 配置,0表示没有额外的强化 add_defs_fortify(aflcc, 0); + + // 如果没有启用 MSAN,则添加相应的编译选项来启用内存消毒 if (!aflcc->have_msan) { insert_param(aflcc, "-fsanitize=memory"); } - aflcc->have_msan = 1; + aflcc->have_msan = 1; // 标记已经启用了 MSAN } + // 如果启用了 UBSAN (未定义行为消毒器),则进行相关配置 if (getenv("AFL_USE_UBSAN") || aflcc->have_ubsan) { + // 如果没有启用 UBSAN,则添加相应的编译选项来启用未定义行为消毒 if (!aflcc->have_ubsan) { - insert_param(aflcc, "-fsanitize=undefined"); insert_param(aflcc, "-fsanitize-undefined-trap-on-error"); insert_param(aflcc, "-fno-sanitize-recover=all"); - } + // 如果没有启用帧指针,则添加相应的选项来启用帧指针 if (!aflcc->have_fp) { - insert_param(aflcc, "-fno-omit-frame-pointer"); aflcc->have_fp = 1; - } - aflcc->have_ubsan = 1; - + aflcc->have_ubsan = 1; // 标记已经启用了 UBSAN } + // 如果启用了 TSAN (线程消毒器),则进行相关配置 if (getenv("AFL_USE_TSAN") || aflcc->have_tsan) { + // 如果没有启用帧指针,则添加相应的选项来启用帧指针 if (!aflcc->have_fp) { - insert_param(aflcc, "-fno-omit-frame-pointer"); aflcc->have_fp = 1; - } + // 如果没有启用 TSAN,则添加相应的编译选项来启用线程消毒 if (!aflcc->have_tsan) { insert_param(aflcc, "-fsanitize=thread"); } - aflcc->have_tsan = 1; + aflcc->have_tsan = 1; // 标记已经启用了 TSAN } + // 如果启用了 LSAN (泄漏消毒器),则进行相关配置 if (getenv("AFL_USE_LSAN") && !aflcc->have_lsan) { + // 添加编译选项来启用泄漏消毒 insert_param(aflcc, "-fsanitize=leak"); + + // 添加 LSAN 控制的定义 add_defs_lsan_ctrl(aflcc); - aflcc->have_lsan = 1; - + + aflcc->have_lsan = 1; // 标记已经启用了 LSAN } + // 如果启用了 CFISAN (控制流完整性消毒器),则进行相关配置 if (getenv("AFL_USE_CFISAN") || aflcc->have_cfisan) { + // 如果是 GCC 插件模式或 GCC 模式,则启用完整的控制流保护 if (aflcc->compiler_mode == GCC_PLUGIN || aflcc->compiler_mode == GCC) { + // 如果没有启用控制流保护,则添加相应选项 if (!aflcc->have_fcf) { insert_param(aflcc, "-fcf-protection=full"); } } else { + // 如果没有启用 LTO (链接时优化),则添加 LTO 选项 if (!aflcc->lto_mode && !aflcc->have_flto) { - uint32_t i = 0, found = 0; while (envp[i] != NULL && !found) { - if (strncmp("-flto", envp[i++], 5) == 0) found = 1; - } - if (!found) { insert_param(aflcc, "-flto"); } - aflcc->have_flto = 1; - + aflcc->have_flto = 1; // 标记已经启用了 LTO } + // 如果没有启用 CFISAN,则添加相应选项来启用控制流完整性消毒 if (!aflcc->have_cfisan) { insert_param(aflcc, "-fsanitize=cfi"); } + // 如果没有启用隐藏符号,则启用隐藏符号选项 if (!aflcc->have_hidden) { - insert_param(aflcc, "-fvisibility=hidden"); aflcc->have_hidden = 1; - } - aflcc->have_cfisan = 1; - + aflcc->have_cfisan = 1; // 标记已经启用了 CFISAN } - } - ->>>>>>> e12b99bad19de97a02e9fe14b9b2c048338b2ab7 } /* Add params to enable LLVM SanCov, the native PCGUARD */ @@ -2635,10 +2571,13 @@ void add_gcc_plugin(aflcc_state_t *aflcc) { /* Add some miscellaneous params required by our instrumentation. */ void add_misc_params(aflcc_state_t *aflcc) { + // 如果环境变量 AFl_NO_BUILTIN 或其他相关环境变量被设置,或者启用了 LTO 模式 + // 则禁用内置的字符串和内存比较函数 if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_ALL") || getenv("AFL_LLVM_CMPLOG") || aflcc->lto_mode) { + // 禁用常见的字符串和内存比较函数的内置实现,防止与模糊测试产生冲突 insert_param(aflcc, "-fno-builtin-strcmp"); insert_param(aflcc, "-fno-builtin-strncmp"); insert_param(aflcc, "-fno-builtin-strcasecmp"); @@ -2650,31 +2589,46 @@ void add_misc_params(aflcc_state_t *aflcc) { } - if (!aflcc->have_pic) { insert_param(aflcc, "-fPIC"); } + // 如果没有启用位置无关代码(PIC),则添加 -fPIC 参数 + if (!aflcc->have_pic) { + insert_param(aflcc, "-fPIC"); + } + // 如果环境变量 AFL_HARDEN 被设置,启用栈保护等安全选项 if (getenv("AFL_HARDEN")) { + // 启用所有函数的栈保护 insert_param(aflcc, "-fstack-protector-all"); - if (!aflcc->fortify_set) add_defs_fortify(aflcc, 2); - + // 如果未设置 Fortify,设置 Fortify 防护等级 + if (!aflcc->fortify_set) + add_defs_fortify(aflcc, 2); } + // 如果环境变量 AFL_DONT_OPTIMIZE 未设置,启用优化选项 if (!getenv("AFL_DONT_OPTIMIZE")) { + // 启用调试符号生成 insert_param(aflcc, "-g"); - if (!aflcc->have_o) insert_param(aflcc, "-O3"); - if (!aflcc->have_unroll) insert_param(aflcc, "-funroll-loops"); + + // 如果没有设置 -O 优化级别,设置为 -O3(最高优化) + if (!aflcc->have_o) + insert_param(aflcc, "-O3"); + + // 如果没有设置循环展开,启用循环展开优化 + if (!aflcc->have_unroll) + insert_param(aflcc, "-funroll-loops"); + + // 以下代码被注释掉了,但如果有指定架构优化选项(如 -march),也可以启用 // if (strlen(aflcc->march_opt) > 1 && aflcc->march_opt[0] == '-') // insert_param(aflcc, aflcc->march_opt); - } + // 如果设置了 x_set 标志,插入 -x none 参数 if (aflcc->x_set) { insert_param(aflcc, "-x"); insert_param(aflcc, "none"); - } } @@ -3659,50 +3613,86 @@ static void edit_params(aflcc_state_t *aflcc, u32 argc, char **argv, } /* Main entry point */ -int main(int argc, char **argv, char **envp) { - - aflcc_state_t *aflcc = malloc(sizeof(aflcc_state_t)); - aflcc_state_init(aflcc, (u8 *)argv[0]); - - check_environment_vars(envp); - - find_built_deps(aflcc); - - compiler_mode_by_callname(aflcc); - compiler_mode_by_environ(aflcc); - compiler_mode_by_cmdline(aflcc, argc, argv); - - instrument_mode_by_environ(aflcc); - - mode_final_checkout(aflcc, argc, argv); - - process_params(aflcc, 1, argc, argv); - - maybe_usage(aflcc, argc, argv); +classDiagram + class AFLCCMain { + +main(argc, argv, envp) + +initializeState() + +checkEnvironmentVariables() + +findDependencies() + +determineCompilerMode() + +determineInstrumentationMode() + +finalizeMode() + +processParameters() + +maybeShowUsage() + +notifyMode() + +debugArguments() + +editParameters() + +executeCompiler() + } - mode_notification(aflcc); + class AFLCCState { + -cc_params: char** + -cc_par_cnt: u32 + -passthrough: u8 + -debug: u8 + +aflcc_state_init(state, prog_name) + } - if (aflcc->debug) debugf_args(argc, argv); + class EnvironmentChecker { + +check_environment_vars(envp) + } - edit_params(aflcc, argc, argv, envp); + class DependencyFinder { + +find_built_deps(aflcc) + } - if (aflcc->debug) - debugf_args((s32)aflcc->cc_par_cnt, (char **)aflcc->cc_params); + class CompilerModeHandler { + +compiler_mode_by_callname(aflcc) + +compiler_mode_by_environ(aflcc) + +compiler_mode_by_cmdline(aflcc, argc, argv) + } - if (aflcc->passthrough) { + class InstrumentationModeHandler { + +instrument_mode_by_environ(aflcc) + } - argv[0] = aflcc->cc_params[0]; - execvp(aflcc->cc_params[0], (char **)argv); + class ModeFinalizer { + +mode_final_checkout(aflcc, argc, argv) + } - } else { + class ParameterProcessor { + +process_params(aflcc, start_idx, argc, argv) + } - execvp(aflcc->cc_params[0], (char **)aflcc->cc_params); + class UsageNotifier { + +maybe_usage(aflcc, argc, argv) + } - } + class ModeNotifier { + +mode_notification(aflcc) + } - FATAL("Oops, failed to execute '%s' - check your PATH", aflcc->cc_params[0]); + class Debugger { + +debugf_args(argc, argv) + } - return 0; + class ParameterEditor { + +edit_params(aflcc, argc, argv, envp) + } -} + class Executor { + +execute_compiler(aflcc, argv) + } + AFLCCMain --> AFLCCState : 使用 + AFLCCMain --> EnvironmentChecker : 使用 + AFLCCMain --> DependencyFinder : 使用 + AFLCCMain --> CompilerModeHandler : 使用 + AFLCCMain --> InstrumentationModeHandler : 使用 + AFLCCMain --> ModeFinalizer : 使用 + AFLCCMain --> ParameterProcessor : 使用 + AFLCCMain --> UsageNotifier : 使用 + AFLCCMain --> ModeNotifier : 使用 + AFLCCMain --> Debugger : 使用 + AFLCCMain --> ParameterEditor : 使用 + AFLCCMain --> Executor : 使用 \ No newline at end of file