aboutsummaryrefslogtreecommitdiff
path: root/llvm_mode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_mode')
-rw-r--r--llvm_mode/afl-clang-fast.c73
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc30
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc68
-rw-r--r--llvm_mode/cmplog-instructions-pass.cc19
-rw-r--r--llvm_mode/split-compares-pass.so.cc41
5 files changed, 170 insertions, 61 deletions
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index c0471033..3de5fd7d 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -223,10 +223,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if ((!(getenv("AFL_LLVM_LTO_AUTODICTIONARY") // disabled when autodictionary
- && instrument_mode != INSTRUMENT_LTO)) // and lto_mode is used
- && (getenv("LAF_TRANSFORM_COMPARES") ||
- getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) {
+ if (getenv("LAF_TRANSFORM_COMPARES") ||
+ getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
+
+ if (!be_quiet && getenv("AFL_LLVM_LTO_AUTODICTIONARY") &&
+ instrument_mode != INSTRUMENT_LTO)
+ WARNF(
+ "using AFL_LLVM_LAF_TRANSFORM_COMPARES together with "
+ "AFL_LLVM_LTO_AUTODICTIONARY makes no sense. Use only "
+ "AFL_LLVM_LTO_AUTODICTIONARY.");
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
@@ -716,30 +721,30 @@ int main(int argc, char **argv, char **envp) {
"Environment variables used:\n"
"AFL_CC: path to the C compiler to use\n"
"AFL_CXX: path to the C++ compiler to use\n"
- "AFL_PATH: path to instrumenting pass and runtime "
- "(afl-llvm-rt.*o)\n"
- "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
- "AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
- "AFL_INST_RATIO: percentage of branches to instrument\n"
- "AFL_QUIET: suppress verbose output\n"
"AFL_DEBUG: enable developer debugging output\n"
+ "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
"AFL_HARDEN: adds code hardening to catch memory bugs\n"
- "AFL_USE_ASAN: activate address sanitizer\n"
- "AFL_USE_MSAN: activate memory sanitizer\n"
- "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
- "AFL_USE_CFISAN: activate control flow sanitizer\n"
- "AFL_LLVM_WHITELIST: enable whitelisting (selective "
- "instrumentation)\n"
+ "AFL_INST_RATIO: percentage of branches to instrument\n"
"AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
"AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
- "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n"
- "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison "
- "function calls\n"
- " to cascaded comparisons\n"
"AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to "
"cascaded "
"comp.\n"
- "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n",
+ "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n"
+ " to cascaded comparisons\n"
+ "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison "
+ "function calls\n"
+ "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n"
+ "AFL_LLVM_WHITELIST: enable whitelisting (selective "
+ "instrumentation)\n"
+ "AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
+ "AFL_PATH: path to instrumenting pass and runtime "
+ "(afl-llvm-rt.*o)\n"
+ "AFL_QUIET: suppress verbose output\n"
+ "AFL_USE_ASAN: activate address sanitizer\n"
+ "AFL_USE_CFISAN: activate control flow sanitizer\n"
+ "AFL_USE_MSAN: activate memory sanitizer\n"
+ "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n",
callname, BIN_PATH, BIN_PATH);
SAYF(
@@ -747,21 +752,21 @@ int main(int argc, char **argv, char **envp) {
"AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
"AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG "
"(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n"
- "You can also use the old environment variables:"
- "AFL_LLVM_CTX: use context sensitive coverage\n"
- "AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n"
- "AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n"
- "AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
- "AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub "
+ " You can also use the old environment variables instead:"
+ " AFL_LLVM_CTX: use context sensitive coverage\n"
+ " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n"
+ " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n"
+ " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
+ " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub "
"option to INSTRIM)\n");
#ifdef AFL_CLANG_FLTO
SAYF(
"\nafl-clang-lto specific environment variables:\n"
- "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a "
- "bb\n"
"AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
"global var\n"
+ "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a "
+ "bb\n"
"AFL_REAL_LD: use this lld linker instead of the compiled in path\n"
"\nafl-clang-lto was built with linker target \"%s\" and LTO flags "
"\"%s\"\n"
@@ -796,6 +801,16 @@ int main(int argc, char **argv, char **envp) {
}
+ u8 *ptr2;
+ if (!be_quiet && instrument_mode != INSTRUMENT_LTO &&
+ ((ptr2 = getenv("AFL_MAP_SIZE")) || (ptr2 = getenv("AFL_MAPSIZE")))) {
+
+ u32 map_size = atoi(ptr2);
+ if (map_size != MAP_SIZE)
+ FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast");
+
+ }
+
if (debug) {
SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd());
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index c5e7a2b7..ece3201f 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -608,20 +608,22 @@ bool AFLLTOPass::runOnModule(Module &M) {
}
- // save highest location ID to global variable
- // do this after each function to fail faster
- if (afl_global_id > MAP_SIZE) {
-
- uint32_t pow2map = 1, map = afl_global_id;
- while ((map = map >> 1))
- pow2map++;
- FATAL(
- "We have %u blocks to instrument but the map size is only %u! Edit "
- "config.h and set MAP_SIZE_POW2 from %u to %u, then recompile "
- "afl-fuzz and llvm_mode.",
- afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map);
+ }
- }
+ // save highest location ID to global variable
+ // do this after each function to fail faster
+ if (!be_quiet && afl_global_id > MAP_SIZE) {
+
+ uint32_t pow2map = 1, map = afl_global_id;
+ while ((map = map >> 1))
+ pow2map++;
+ WARNF(
+ "We have %u blocks to instrument but the map size is only %u. Either "
+ "edit config.h and set MAP_SIZE_POW2 from %u to %u, then recompile "
+ "afl-fuzz and llvm_mode and then make this target - or set "
+ "AFL_MAP_SIZE with at least size %u when running afl-fuzz with this "
+ "target.",
+ afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
}
@@ -635,7 +637,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (!f) {
fprintf(stderr,
- "Error: init function could not be found (this hould not "
+ "Error: init function could not be found (this should not "
"happen)\n");
exit(-1);
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index b4249802..71abcd05 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -125,6 +125,7 @@ class AFLCoverage : public ModulePass {
std::list<std::string> myWhitelist;
uint32_t ngram_size = 0;
uint32_t debug = 0;
+ uint32_t map_size = MAP_SIZE;
char * ctx_str = NULL;
};
@@ -192,6 +193,19 @@ bool AFLCoverage::runOnModule(Module &M) {
be_quiet = 1;
+ /*
+ char *ptr;
+ if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
+
+ map_size = atoi(ptr);
+ if (map_size < 8 || map_size > (1 << 29))
+ FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30",
+ map_size); if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
+
+ }
+
+ */
+
/* Decide instrumentation ratio */
char * inst_ratio_str = getenv("AFL_INST_RATIO");
@@ -365,7 +379,7 @@ bool AFLCoverage::runOnModule(Module &M) {
// if yes we store a context ID for this function in the global var
if (has_calls) {
- ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(MAP_SIZE));
+ ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size));
StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext);
StoreCtx->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C, None));
@@ -509,7 +523,7 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Make up cur_loc */
// cur_loc++;
- cur_loc = AFL_R(MAP_SIZE);
+ cur_loc = AFL_R(map_size);
/* There is a problem with Ubuntu 18.04 and llvm 6.0 (see issue #63).
The inline function successors() is not inlined and also not found at runtime
@@ -705,6 +719,56 @@ bool AFLCoverage::runOnModule(Module &M) {
}
+ /*
+ // This is currently disabled because we not only need to create/insert a
+ // function (easy), but also add it as a constructor with an ID < 5
+
+ if (getenv("AFL_LLVM_DONTWRITEID") == NULL) {
+
+ // yes we could create our own function, insert it into ctors ...
+ // but this would be a pain in the butt ... so we use afl-llvm-rt.o
+
+ Function *f = ...
+
+ if (!f) {
+
+ fprintf(stderr,
+ "Error: init function could not be created (this should not
+ happen)\n"); exit(-1);
+
+ }
+
+ ... constructor for f = 4
+
+ BasicBlock *bb = &f->getEntryBlock();
+ if (!bb) {
+
+ fprintf(stderr,
+ "Error: init function does not have an EntryBlock (this should
+ not happen)\n"); exit(-1);
+
+ }
+
+ BasicBlock::iterator IP = bb->getFirstInsertionPt();
+ IRBuilder<> IRB(&(*IP));
+
+ if (map_size <= 0x800000) {
+
+ GlobalVariable *AFLFinalLoc = new GlobalVariable(
+ M, Int32Ty, true, GlobalValue::ExternalLinkage, 0,
+ "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0,
+ false);
+ ConstantInt *const_loc = ConstantInt::get(Int32Ty, map_size);
+ StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
+ StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
+ MDNode::get(C, None));
+
+ }
+
+ }
+
+ */
+
/* Say something nice. */
if (!be_quiet) {
diff --git a/llvm_mode/cmplog-instructions-pass.cc b/llvm_mode/cmplog-instructions-pass.cc
index dc72a3e4..b0ab475d 100644
--- a/llvm_mode/cmplog-instructions-pass.cc
+++ b/llvm_mode/cmplog-instructions-pass.cc
@@ -360,11 +360,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
switch (max_size) {
- case 8: IRB.CreateCall(cmplogHookIns1, args, "tmp"); break;
- case 16: IRB.CreateCall(cmplogHookIns2, args, "tmp"); break;
- case 32: IRB.CreateCall(cmplogHookIns4, args, "tmp"); break;
- case 64: IRB.CreateCall(cmplogHookIns8, args, "tmp"); break;
- default: break;
+ case 8:
+ IRB.CreateCall(cmplogHookIns1, args, "tmp");
+ break;
+ case 16:
+ IRB.CreateCall(cmplogHookIns2, args, "tmp");
+ break;
+ case 32:
+ IRB.CreateCall(cmplogHookIns4, args, "tmp");
+ break;
+ case 64:
+ IRB.CreateCall(cmplogHookIns8, args, "tmp");
+ break;
+ default:
+ break;
}
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index f0615f85..7c657ebf 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -318,10 +318,18 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
CmpInst::Predicate new_pred;
switch (pred) {
- case CmpInst::ICMP_UGE: new_pred = CmpInst::ICMP_UGT; break;
- case CmpInst::ICMP_SGE: new_pred = CmpInst::ICMP_SGT; break;
- case CmpInst::ICMP_ULE: new_pred = CmpInst::ICMP_ULT; break;
- case CmpInst::ICMP_SLE: new_pred = CmpInst::ICMP_SLT; break;
+ case CmpInst::ICMP_UGE:
+ new_pred = CmpInst::ICMP_UGT;
+ break;
+ case CmpInst::ICMP_SGE:
+ new_pred = CmpInst::ICMP_SGT;
+ break;
+ case CmpInst::ICMP_ULE:
+ new_pred = CmpInst::ICMP_ULT;
+ break;
+ case CmpInst::ICMP_SLE:
+ new_pred = CmpInst::ICMP_SLT;
+ break;
default: // keep the compiler happy
continue;
@@ -384,10 +392,18 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
CmpInst::Predicate new_pred;
switch (pred) {
- case CmpInst::FCMP_UGE: new_pred = CmpInst::FCMP_UGT; break;
- case CmpInst::FCMP_OGE: new_pred = CmpInst::FCMP_OGT; break;
- case CmpInst::FCMP_ULE: new_pred = CmpInst::FCMP_ULT; break;
- case CmpInst::FCMP_OLE: new_pred = CmpInst::FCMP_OLT; break;
+ case CmpInst::FCMP_UGE:
+ new_pred = CmpInst::FCMP_UGT;
+ break;
+ case CmpInst::FCMP_OGE:
+ new_pred = CmpInst::FCMP_OGT;
+ break;
+ case CmpInst::FCMP_ULE:
+ new_pred = CmpInst::FCMP_ULT;
+ break;
+ case CmpInst::FCMP_OLE:
+ new_pred = CmpInst::FCMP_OLT;
+ break;
default: // keep the compiler happy
continue;
@@ -855,7 +871,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_exponent_result =
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
break;
- default: continue;
+ default:
+ continue;
}
@@ -958,7 +975,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
icmp_fraction_result =
BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
break;
- default: continue;
+ default:
+ continue;
}
@@ -1004,7 +1022,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
PN->addIncoming(icmp_exponent_result, signequal_bb);
PN->addIncoming(icmp_fraction_result, middle_bb);
break;
- default: continue;
+ default:
+ continue;
}