about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/env_variables.md3
-rw-r--r--include/envs.h2
-rw-r--r--src/afl-cc.c42
3 files changed, 43 insertions, 4 deletions
diff --git a/docs/env_variables.md b/docs/env_variables.md
index ef67abec..4824860c 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -64,6 +64,9 @@ fairly broad use of environment variables instead:
     optimizations, set `AFL_DONT_OPTIMIZE`. However, if `-O...` and/or
     `-fno-unroll-loops` are set, these are not overridden.
 
+  - The optimization level can also be set with `AFL_OPT_LEVEL`, e.g.
+    `AFL_OPT_LEVEL=z` for `-Oz`
+
   - Setting `AFL_HARDEN` automatically adds code hardening options when invoking
     the downstream compiler. This currently includes `-D_FORTIFY_SOURCE=2` and
     `-fstack-protector-all`. The setting is useful for catching non-crashing
diff --git a/include/envs.h b/include/envs.h
index 3accbda0..202de752 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -49,7 +49,7 @@ static char *afl_environment_variables[] = {
     "AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS",
     "AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH",
     "AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE",
-    "AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER",
+    "AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER", "AFL_OPT_LEVEL",
     "AFL_FUZZER_ARGS",  // oss-fuzz
     "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST",
     "AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE",
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 7afab850..677a6b2f 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -98,7 +98,8 @@ typedef enum {
 
 } compiler_mode_id;
 
-static u8 cwd[4096];
+static u8   cwd[4096];
+static char opt_level = '3';
 
 char instrument_mode_string[18][18] = {
 
@@ -881,9 +882,17 @@ static void instrument_mode_old_environ(aflcc_state_t *aflcc) {
 */
 static void instrument_mode_new_environ(aflcc_state_t *aflcc) {
 
+  u8 *ptr2;
+
+  if ((ptr2 = getenv("AFL_OPT_LEVEL"))) {
+
+    opt_level = ptr2[0];  // ignore invalid data
+
+  }
+
   if (!getenv("AFL_LLVM_INSTRUMENT")) { return; }
 
-  u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
+  ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
 
   while (ptr2) {
 
@@ -2561,6 +2570,33 @@ void add_gcc_plugin(aflcc_state_t *aflcc) {
 
 }
 
+char *get_opt_level() {
+
+  static char levels[8][8] = {"-O0", "-O1", "-O2",    "-O3",
+                              "-Oz", "-Os", "-Ofast", "-Og"};
+  switch (opt_level) {
+
+    case '0':
+      return levels[0];
+    case '1':
+      return levels[1];
+    case '2':
+      return levels[2];
+    case 'z':
+      return levels[4];
+    case 's':
+      return levels[5];
+    case 'f':
+      return levels[6];
+    case 'g':
+      return levels[7];
+    default:
+      return levels[3];
+
+  }
+
+}
+
 /* Add some miscellaneous params required by our instrumentation. */
 void add_misc_params(aflcc_state_t *aflcc) {
 
@@ -2592,7 +2628,7 @@ void add_misc_params(aflcc_state_t *aflcc) {
   if (!getenv("AFL_DONT_OPTIMIZE")) {
 
     insert_param(aflcc, "-g");
-    if (!aflcc->have_o) insert_param(aflcc, "-O3");
+    if (!aflcc->have_o) insert_param(aflcc, get_opt_level());
     if (!aflcc->have_unroll) insert_param(aflcc, "-funroll-loops");
     // if (strlen(aflcc->march_opt) > 1 && aflcc->march_opt[0] == '-')
     //     insert_param(aflcc, aflcc->march_opt);