about summary refs log tree commit diff
path: root/llvm_mode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_mode')
-rw-r--r--llvm_mode/Makefile6
-rw-r--r--llvm_mode/README.neverzero22
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc91
3 files changed, 65 insertions, 54 deletions
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
index 6b277536..76de10c0 100644
--- a/llvm_mode/Makefile
+++ b/llvm_mode/Makefile
@@ -25,11 +25,17 @@ VERSION     = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
 LLVM_CONFIG ?= llvm-config
 #LLVM_OK = $(shell $(LLVM_CONFIG) --version | egrep -q '^[5-6]' && echo 0 || echo 1 )
 LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version | egrep -q '^9|3.0' && echo 1 || echo 0 )
+LLVM_MAJOR = ($shell $(LLVM_CONFIG) --version | sed 's/\..*//')
 
 ifeq "$(LLVM_UNSUPPORTED)" "1"
   $(warn llvm_mode only supports versions 3.8.0 up to 8.x )
 endif
 
+# this is not visible yet:
+ifeq "$(LLVM_MAJOR)" "9"
+  $(info llvm_mode deteted llvm 9, enabling neverZero implementation)
+endif
+
 CFLAGS      ?= -O3 -funroll-loops
 CFLAGS      += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
                -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
diff --git a/llvm_mode/README.neverzero b/llvm_mode/README.neverzero
new file mode 100644
index 00000000..ef873acb
--- /dev/null
+++ b/llvm_mode/README.neverzero
@@ -0,0 +1,22 @@
+Usage
+=====
+
+In larger, complex or reiterative programs the map that collects the edge pairs
+can easily fill up and wrap.
+This is not that much of an issue - unless by chance it wraps just to a 0
+when the program execution ends.
+In this case afl-fuzz is not able to see that the pair has been accessed and
+will ignore it.
+
+NeverZero prevents this behaviour. If a counter wraps, it jumps over the 0
+directly to a 1. This improves path discovery (by a very little amount)
+at a very little cost (one instruction per edge).
+
+This is implemented in afl-gcc, however for llvm_mode this is optional if
+the llvm version is below 9 - as there is a perfomance bug that is only fixed
+in version 9 and onwards.
+
+If you want to enable this for llvm < 9 then set
+
+export AFL_LLVM_NOT_ZERO=1
+
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index 176692e3..cfeff968 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -118,7 +118,9 @@ bool AFLCoverage::runOnModule(Module &M) {
 
   }
 
-  char* neverZero_counters_str = getenv("AFL_NZERO_COUNTS");
+#if LLVM_VERSION_MAJOR < 9
+  char* neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO");
+#endif
 
   /* Get globals for the SHM region and the previous location. Note that
      __afl_prev_loc is thread-local. */
@@ -236,75 +238,56 @@ bool AFLCoverage::runOnModule(Module &M) {
       LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
       Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
 
-      Value *Incr;
- //     if (neverZero_counters_str == NULL || neverZero_counters_str[0] != '4')
-        Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
-
-      if (neverZero_counters_str != NULL) {
-          /* hexcoder: Realize a counter that skips zero during overflow.
-           * Once this counter reaches its maximum value, it next increments to 1
-           *
-           * Instead of
-           * Counter + 1 -> Counter
-           * we inject now this
-           * Counter + 1 -> {Counter, OverflowFlag}
-           * Counter + OverflowFlag -> Counter
-           */
-           
-          // Solution #1 - creates
-          //mov    ecx,edx
-          //add    cl,0x1
-          //adc    dl,0x1
-/*
-          if (neverZero_counters_str[0] == '1') {
-            CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
-            AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
-            Value *SumWithOverflowBit = AddOv;
-            Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0),  // sum 
-                                 IRB.CreateZExt( // convert from one bit type to 8 bits type 
-                                                IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
-                                                Int8Ty));
-
-          // Solution #2 - creates the same code as #1
+      Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
+
+#if LLVM_VERSION_MAJOR < 9
+      if (neverZero_counters_str != NULL) { // with llvm 9 we make this the default as the bug in llvm is then fixed
+#endif
+        /* hexcoder: Realize a counter that skips zero during overflow.
+         * Once this counter reaches its maximum value, it next increments to 1
+         *
+         * Instead of
+         * Counter + 1 -> Counter
+         * we inject now this
+         * Counter + 1 -> {Counter, OverflowFlag}
+         * Counter + OverflowFlag -> Counter
+         */
+/*       // we keep the old solutions just in case
+         // Solution #1
+         if (neverZero_counters_str[0] == '1') {
+           CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
+           AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
+           Value *SumWithOverflowBit = AddOv;
+           Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0),  // sum 
+                                IRB.CreateZExt( // convert from one bit type to 8 bits type 
+                                               IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
+                                               Int8Ty));
+          // Solution #2
           } else if (neverZero_counters_str[0] == '2') {
-            auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
-            Incr = IRB.CreateAdd(Incr, cf);
-           
-          // Solution #3 - creates
-          //add    cl,0x1
-          //cmp    cl,0x1
-          //adc    cl,0x0
-          } else if (neverZero_counters_str[0] == '3') {
-            auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
-            Incr = IRB.CreateAdd(Incr, cf);
-          // Solution #4 - creates
-          // cmp    dl, $0xff
-          // sete   cl
-          // add    dl,cl
-          // add    dl,0x01
-          } else if (neverZero_counters_str[0] == '4') {
              auto cf = IRB.CreateICmpEQ(Counter, ConstantInt::get(Int8Ty, 255));
              Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf);
              Incr = IRB.CreateAdd(Counter, HowMuch);
-
-          } else if (neverZero_counters_str[0] == '5') {
+          // Solution #3
+          } else if (neverZero_counters_str[0] == '3') {
 */
+          // this is the solution we choose because llvm9 should do the right thing here
             auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
             auto carry = IRB.CreateZExt(cf, Int8Ty);
             Incr = IRB.CreateAdd(Incr, carry);
 /*
-          } else if (neverZero_counters_str[0] == '6') {
+         // Solution #4
+         } else if (neverZero_counters_str[0] == '4') {
             auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
             auto carry = IRB.CreateZExt(cf, Int8Ty);
             Incr = IRB.CreateAdd(Incr, carry);
-           
-          // no other implementations yet
-          } else {
+         } else {
             fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str);
             exit(-1);
-          }
+         }
 */
+#if LLVM_VERSION_MAJOR < 9
       }
+#endif
 
       IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));