about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-05-10 08:51:40 +0200
committervan Hauser <vh@thc.org>2020-05-10 08:51:40 +0200
commitd02cfc54b63578f1887d9042466f59ac0cff91ad (patch)
treed8f15617ef003d3694a2b6de831bf229ae340090
parent515de0d68d30a4e69fe5fb971c622391185fc4ba (diff)
downloadafl++-d02cfc54b63578f1887d9042466f59ac0cff91ad.tar.gz
LTO fixes for fuzzbench
-rw-r--r--llvm_mode/GNUmakefile6
-rw-r--r--llvm_mode/afl-clang-fast.c43
2 files changed, 36 insertions, 13 deletions
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
index 6a58f6a5..beebf696 100644
--- a/llvm_mode/GNUmakefile
+++ b/llvm_mode/GNUmakefile
@@ -43,6 +43,7 @@ LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.
 LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
 LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//')
 LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
+LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
 LLVM_STDCXX = gnu++11
 LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0)
 LLVM_LTO   = 0
@@ -200,7 +201,8 @@ override CFLAGS += -Wall \
                -g -Wno-pointer-sign -I ../include/ \
                -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
                -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
-               -DLLVM_VERSION=\"$(LLVMVER)\"  -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
+               -DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
+               -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
                -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
                -DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function
 ifdef AFL_TRACE_PC
@@ -296,7 +298,7 @@ afl-common.o: ../src/afl-common.c
 	$(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
 
 ../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
-	$(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
+	$(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" -Dxxx
 	ln -sf afl-clang-fast ../afl-clang-fast++
 ifneq "$(AFL_CLANG_FLTO)" ""
 ifeq "$(LLVM_LTO)" "1"
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 42b02bdd..027f4035 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -43,13 +43,13 @@ 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   llvm_fullpath[PATH_MAX];
-static u8   instrument_mode, instrument_opt_mode, ngram_size, lto_mode;
-static u8 * lto_flag = AFL_CLANG_FLTO;
-static u8 * march_opt = CFLAGS_OPT;
-static u8   debug;
-static u8   cwd[4096];
-static u8   cmplog_mode;
-u8          use_stdin = 0;                                         /* dummy */
+static u8  instrument_mode, instrument_opt_mode, ngram_size, lto_mode, cpp_mode;
+static u8 *lto_flag = AFL_CLANG_FLTO;
+static u8 *march_opt = CFLAGS_OPT;
+static u8  debug;
+static u8  cwd[4096];
+static u8  cmplog_mode;
+u8         use_stdin = 0;                                          /* dummy */
 
 enum {
 
@@ -184,6 +184,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     else
       sprintf(llvm_fullpath, CLANGPP_BIN);
     cc_params[0] = alt_cxx && *alt_cxx ? alt_cxx : (u8 *)llvm_fullpath;
+    cpp_mode = 1;
 
   } else if (!strcmp(name, "afl-clang-fast") ||
 
@@ -205,12 +206,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   }
 
-  /* There are three ways to compile with afl-clang-fast. In the traditional
+  if (lto_mode && cpp_mode)
+    cc_params[cc_par_cnt++] = "-lc++";  // needed by fuzzbench, early
+
+  /* There are several ways to compile with afl-clang-fast. In the traditional
      mode, we use afl-llvm-pass.so, then there is libLLVMInsTrim.so which is
-     much faster but has less coverage. Finally there is the experimental
-     'trace-pc-guard' mode, we use native LLVM instrumentation callbacks
-     instead. For trace-pc-guard see:
+     faster and creates less map pollution.
+     Then there is the 'trace-pc-guard' mode, we use native LLVM
+     instrumentation callbacks instead. For trace-pc-guard see:
      http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards
+     The best instrumentatation is with the LTO modes, the classic and
+     InsTrimLTO, the latter is faster. The LTO modes are activated by using
+     afl-clang-lto(++)
    */
 
   // laf
@@ -326,6 +333,20 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   cc_params[cc_par_cnt++] = "-Qunused-arguments";
 
+  // in case LLVM is installed not via a package manager or "make install"
+  // e.g. compiled download or compiled from github then it's ./lib directory
+  // might not be in the search path. Add it if so.
+  u8 *libdir = strdup(LLVM_LIBDIR);
+  if (strlen(libdir) && strncmp(libdir, "/usr", 4) &&
+      strncmp(libdir, "/lib", 4)) {
+
+    cc_params[cc_par_cnt++] = "-rpath";
+    cc_params[cc_par_cnt++] = libdir;
+
+  } else
+
+    free(libdir);
+
   /* Detect stray -v calls from ./configure scripts. */
 
   while (--argc) {