From 45be91ff48554569be7f1ba6e4fc1de57e7286c3 Mon Sep 17 00:00:00 2001 From: Hexcoder Date: Tue, 25 Jun 2019 22:03:59 +0200 Subject: experimental implementation of counters that skip zero on overflow. Enable with AFL_NZERO_COUNTS=1 during compilation of target. --- llvm_mode/afl-llvm-pass.so.cc | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index d46db7c0..2d283f1f 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -118,6 +118,9 @@ bool AFLCoverage::runOnModule(Module &M) { } + char* neverZero_counters_str = getenv("AFL_NZERO_COUNTS"); + bool enable_neverZero_counters = neverZero_counters_str && '1' == *neverZero_counters_str; + /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -234,7 +237,32 @@ bool AFLCoverage::runOnModule(Module &M) { LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); + + Value *Incr; + if (enable_neverZero_counters) { + /* 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 + */ + 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)); + } else { + /* standard AFL behavior: wrapping counters */ + Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); + } + IRB.CreateStore(Incr, MapPtrIdx) ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -- cgit 1.4.1 From aa4fc44a8018326c97e681fe4663b49de173b5a5 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 27 Jun 2019 15:43:51 +0200 Subject: 2 different implementations --- llvm_mode/afl-llvm-pass.so.cc | 53 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 2d283f1f..d20ca8dd 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -119,7 +119,6 @@ bool AFLCoverage::runOnModule(Module &M) { } char* neverZero_counters_str = getenv("AFL_NZERO_COUNTS"); - bool enable_neverZero_counters = neverZero_counters_str && '1' == *neverZero_counters_str; /* Get globals for the SHM region and the previous location. Note that __afl_prev_loc is thread-local. */ @@ -230,16 +229,16 @@ bool AFLCoverage::runOnModule(Module &M) { LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *MapPtrIdx = - IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); + Value *MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); /* Update bitmap */ LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *Incr; - if (enable_neverZero_counters) { + Value *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 * @@ -249,27 +248,43 @@ bool AFLCoverage::runOnModule(Module &M) { * Counter + 1 -> {Counter, OverflowFlag} * Counter + OverflowFlag -> Counter */ - CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, - Counter, ConstantInt::get(Int8Ty, 1)); + + // Solution #1 - creates + //mov dl,BYTE PTR [rsi+rdi*1] + //mov ecx,edx + //add cl,0x1 + //adc dl,0x1 + /* + 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)); - } else { - /* standard AFL behavior: wrapping counters */ - Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); + 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 + ///* + auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1)); + Incr = IRB.CreateAdd(Incr, cf); + //*/ + + // Solution #3 - creates + //mov cl,BYTE PTR [rsi+rdx*1] + //add cl,0x1 + //cmp cl,0x1 + //adc cl,0x0 + /* + auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0)); + Incr = IRB.CreateAdd(Incr, cf); + */ } - IRB.CreateStore(Incr, MapPtrIdx) - ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); /* Set prev_loc to cur_loc >> 1 */ - StoreInst *Store = - IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1), AFLPrevLoc); + StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1), AFLPrevLoc); Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); inst_blocks++; -- cgit 1.4.1 From 00b22e37df4a4dff32cfe0037de1550c1917387f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 3 Jul 2019 16:36:31 +0200 Subject: select implementations --- llvm_mode/afl-llvm-pass.so.cc | 54 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index d20ca8dd..b77835c5 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -236,7 +236,9 @@ bool AFLCoverage::runOnModule(Module &M) { LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); + 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. @@ -250,34 +252,46 @@ bool AFLCoverage::runOnModule(Module &M) { */ // Solution #1 - creates - //mov dl,BYTE PTR [rsi+rdi*1] //mov ecx,edx //add cl,0x1 //adc dl,0x1 - /* - 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)); - */ + 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 - ///* - auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1)); - Incr = IRB.CreateAdd(Incr, cf); - //*/ + } else if (neverZero_counters_str[0] == '2') { + auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1)); + Incr = IRB.CreateAdd(Incr, cf); // Solution #3 - creates - //mov cl,BYTE PTR [rsi+rdx*1] //add cl,0x1 //cmp cl,0x1 //adc cl,0x0 - /* - auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0)); - Incr = IRB.CreateAdd(Incr, cf); - */ + } 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); + + // no other implementations yet + } else { + fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str); + exit(-1); + } } IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -- cgit 1.4.1 From 04c92c84705af4c602f134ed9a63b82be5ef75c9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 3 Jul 2019 19:10:48 +0200 Subject: notzero for afl-gcc --- afl-as.h | 2 ++ llvm_mode/afl-llvm-pass.so.cc | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/afl-as.h b/afl-as.h index ebd57109..2c84f9f3 100644 --- a/afl-as.h +++ b/afl-as.h @@ -189,6 +189,7 @@ static const u8* main_payload_32 = " orb $1, (%edx, %edi, 1)\n" #else " incb (%edx, %edi, 1)\n" + " adcb $0, (%edx, %edi, 1)\n" #endif /* ^SKIP_COUNTS */ "\n" "__afl_return:\n" @@ -417,6 +418,7 @@ static const u8* main_payload_64 = " orb $1, (%rdx, %rcx, 1)\n" #else " incb (%rdx, %rcx, 1)\n" + " adcb $0, (%rdx, %rcx, 1)\n" #endif /* ^SKIP_COUNTS */ "\n" "__afl_return:\n" diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index b77835c5..6b2232f2 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -287,6 +287,16 @@ bool AFLCoverage::runOnModule(Module &M) { Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf); Incr = IRB.CreateAdd(Counter, HowMuch); + } else if (neverZero_counters_str[0] == '5') { + 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') { + 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 { fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str); -- cgit 1.4.1 From 9199967022284da0ee4d78459d8d34513540cf32 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 4 Jul 2019 11:19:18 +0200 Subject: this is the best solution IMHO --- llvm_mode/afl-llvm-pass.so.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 6b2232f2..176692e3 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -237,7 +237,7 @@ bool AFLCoverage::runOnModule(Module &M) { Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); Value *Incr; - if (neverZero_counters_str == NULL || neverZero_counters_str[0] != '4') + // if (neverZero_counters_str == NULL || neverZero_counters_str[0] != '4') Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); if (neverZero_counters_str != NULL) { @@ -255,6 +255,7 @@ bool AFLCoverage::runOnModule(Module &M) { //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)); @@ -276,7 +277,6 @@ bool AFLCoverage::runOnModule(Module &M) { } 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 @@ -288,10 +288,11 @@ bool AFLCoverage::runOnModule(Module &M) { Incr = IRB.CreateAdd(Counter, HowMuch); } else if (neverZero_counters_str[0] == '5') { +*/ 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') { auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1)); auto carry = IRB.CreateZExt(cf, Int8Ty); @@ -302,6 +303,7 @@ bool AFLCoverage::runOnModule(Module &M) { fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str); exit(-1); } +*/ } IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); -- cgit 1.4.1 From 7f6aaa53147afd4feb549214f49d0f5f69e4af6c Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 5 Jul 2019 11:28:08 +0200 Subject: final touches --- docs/ChangeLog | 2 + docs/env_variables.txt | 7 +++- llvm_mode/Makefile | 6 +++ llvm_mode/README.neverzero | 22 +++++++++++ llvm_mode/afl-llvm-pass.so.cc | 91 ++++++++++++++++++------------------------- 5 files changed, 72 insertions(+), 56 deletions(-) create mode 100644 llvm_mode/README.neverzero (limited to 'llvm_mode/afl-llvm-pass.so.cc') diff --git a/docs/ChangeLog b/docs/ChangeLog index 73c69196..a533de05 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -17,6 +17,8 @@ sending a mail to . Version ++2.52d (tbd): ----------------------------- + - added never zero counters for afl-gcc and optional (because of an + optimization issue in llvm < 9) for llvm_mode (AFL_LLVM_NEVER_ZERO=1) - added whitelist support for llvm_mode via AFL_LLVM_WHITELIST to allow only to instrument what is actually interesting. Gives more speed and less map pollution (originally by choller@mozilla) diff --git a/docs/env_variables.txt b/docs/env_variables.txt index 725dc82e..f8c6c86a 100644 --- a/docs/env_variables.txt +++ b/docs/env_variables.txt @@ -108,8 +108,11 @@ Then there are a few specific features that are only available in llvm_mode: OTHER ===== - - Setting AFL_NZERO_COUNTS=1 during compilation will use counters - that skip zero on overflow. + - Setting export AFL_LLVM_NOT_ZERO=1 during compilation will use counters + that skip zero on overflow. This is the default for llvm >= 9, + however for llvm versions below that this will increase an unnecessary + slowdown due a performance issue that is only fixed in llvm 9+. + This feature increases path discovery by a little bit. Note that AFL_INST_RATIO will behave a bit differently than for afl-gcc, because functions are *not* instrumented unconditionally - so low values 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)); -- cgit 1.4.1