mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 02:28:09 +00:00
final touches
This commit is contained in:
@ -17,6 +17,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
Version ++2.52d (tbd):
|
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
|
- added whitelist support for llvm_mode via AFL_LLVM_WHITELIST to allow
|
||||||
only to instrument what is actually interesting. Gives more speed and less
|
only to instrument what is actually interesting. Gives more speed and less
|
||||||
map pollution (originally by choller@mozilla)
|
map pollution (originally by choller@mozilla)
|
||||||
|
@ -108,8 +108,11 @@ Then there are a few specific features that are only available in llvm_mode:
|
|||||||
|
|
||||||
OTHER
|
OTHER
|
||||||
=====
|
=====
|
||||||
- Setting AFL_NZERO_COUNTS=1 during compilation will use counters
|
- Setting export AFL_LLVM_NOT_ZERO=1 during compilation will use counters
|
||||||
that skip zero on overflow.
|
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,
|
Note that AFL_INST_RATIO will behave a bit differently than for afl-gcc,
|
||||||
because functions are *not* instrumented unconditionally - so low values
|
because functions are *not* instrumented unconditionally - so low values
|
||||||
|
@ -25,11 +25,17 @@ VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
|
|||||||
LLVM_CONFIG ?= llvm-config
|
LLVM_CONFIG ?= llvm-config
|
||||||
#LLVM_OK = $(shell $(LLVM_CONFIG) --version | egrep -q '^[5-6]' && echo 0 || echo 1 )
|
#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_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"
|
ifeq "$(LLVM_UNSUPPORTED)" "1"
|
||||||
$(warn llvm_mode only supports versions 3.8.0 up to 8.x )
|
$(warn llvm_mode only supports versions 3.8.0 up to 8.x )
|
||||||
endif
|
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 ?= -O3 -funroll-loops
|
||||||
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
|
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
|
||||||
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
||||||
|
22
llvm_mode/README.neverzero
Normal file
22
llvm_mode/README.neverzero
Normal file
@ -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
|
||||||
|
|
@ -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
|
/* Get globals for the SHM region and the previous location. Note that
|
||||||
__afl_prev_loc is thread-local. */
|
__afl_prev_loc is thread-local. */
|
||||||
@ -236,75 +238,56 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
|
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
|
||||||
Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
||||||
|
|
||||||
Value *Incr;
|
Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
|
||||||
// if (neverZero_counters_str == NULL || neverZero_counters_str[0] != '4')
|
|
||||||
Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
|
|
||||||
|
|
||||||
if (neverZero_counters_str != NULL) {
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
/* hexcoder: Realize a counter that skips zero during overflow.
|
if (neverZero_counters_str != NULL) { // with llvm 9 we make this the default as the bug in llvm is then fixed
|
||||||
* Once this counter reaches its maximum value, it next increments to 1
|
#endif
|
||||||
*
|
/* hexcoder: Realize a counter that skips zero during overflow.
|
||||||
* Instead of
|
* Once this counter reaches its maximum value, it next increments to 1
|
||||||
* Counter + 1 -> Counter
|
*
|
||||||
* we inject now this
|
* Instead of
|
||||||
* Counter + 1 -> {Counter, OverflowFlag}
|
* Counter + 1 -> Counter
|
||||||
* Counter + OverflowFlag -> Counter
|
* we inject now this
|
||||||
*/
|
* Counter + 1 -> {Counter, OverflowFlag}
|
||||||
|
* Counter + OverflowFlag -> Counter
|
||||||
// Solution #1 - creates
|
*/
|
||||||
//mov ecx,edx
|
/* // we keep the old solutions just in case
|
||||||
//add cl,0x1
|
// Solution #1
|
||||||
//adc dl,0x1
|
if (neverZero_counters_str[0] == '1') {
|
||||||
/*
|
CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
|
||||||
if (neverZero_counters_str[0] == '1') {
|
AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
||||||
CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
|
Value *SumWithOverflowBit = AddOv;
|
||||||
AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum
|
||||||
Value *SumWithOverflowBit = AddOv;
|
IRB.CreateZExt( // convert from one bit type to 8 bits type
|
||||||
Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum
|
IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
|
||||||
IRB.CreateZExt( // convert from one bit type to 8 bits type
|
Int8Ty));
|
||||||
IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
|
// Solution #2
|
||||||
Int8Ty));
|
|
||||||
|
|
||||||
// Solution #2 - creates the same code as #1
|
|
||||||
} else if (neverZero_counters_str[0] == '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));
|
auto cf = IRB.CreateICmpEQ(Counter, ConstantInt::get(Int8Ty, 255));
|
||||||
Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf);
|
Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf);
|
||||||
Incr = IRB.CreateAdd(Counter, HowMuch);
|
Incr = IRB.CreateAdd(Counter, HowMuch);
|
||||||
|
// Solution #3
|
||||||
} else if (neverZero_counters_str[0] == '5') {
|
} 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 cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
|
||||||
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
||||||
Incr = IRB.CreateAdd(Incr, carry);
|
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 cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
|
||||||
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
auto carry = IRB.CreateZExt(cf, Int8Ty);
|
||||||
Incr = IRB.CreateAdd(Incr, carry);
|
Incr = IRB.CreateAdd(Incr, carry);
|
||||||
|
} else {
|
||||||
// no other implementations yet
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str);
|
fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user