diff options
author | hexcoder- <heiko@hexco.de> | 2020-01-30 21:32:08 +0100 |
---|---|---|
committer | hexcoder- <heiko@hexco.de> | 2020-01-30 21:32:08 +0100 |
commit | ceed66930ef15922cd25e70a4770eaa31309e0ce (patch) | |
tree | fba11ad2bea968742dae9af6c98e667128f3fe72 | |
parent | b13bb64c3b0fb938e7807ab999cbb79906a8c2a4 (diff) | |
download | afl++-ceed66930ef15922cd25e70a4770eaa31309e0ce.tar.gz |
lower requirements for lower llvm/clang versions
3.7.1 works with the exception of InsTrim, 3.8.1 and above is ok
-rw-r--r-- | llvm_mode/LLVMInsTrim.so.cc | 61 | ||||
-rw-r--r-- | llvm_mode/Makefile | 4 | ||||
-rw-r--r-- | llvm_mode/MarkNodes.cc | 11 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-pass.so.cc | 71 | ||||
-rw-r--r-- | llvm_mode/compare-transform-pass.so.cc | 58 | ||||
-rw-r--r-- | llvm_mode/split-compares-pass.so.cc | 156 | ||||
-rw-r--r-- | llvm_mode/split-switches-pass.so.cc | 90 |
7 files changed, 387 insertions, 64 deletions
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc index 39b2dedd..5b7b79e1 100644 --- a/llvm_mode/LLVMInsTrim.so.cc +++ b/llvm_mode/LLVMInsTrim.so.cc @@ -3,10 +3,23 @@ #include <stdarg.h> #include <unistd.h> +#include "llvm/Config/llvm-config.h" +#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 +typedef long double max_align_t; +#endif + #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) #include "llvm/IR/CFG.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/DebugInfo.h" +#else +#include "llvm/Support/CFG.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/DebugInfo.h" +#endif #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LegacyPassManager.h" @@ -16,9 +29,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/IR/DebugInfo.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CFG.h" #include <unordered_set> #include <random> #include <list> @@ -97,7 +108,7 @@ struct InsTrim : public ModulePass { // ripped from aflgo static bool isBlacklisted(const Function *F) { - static const SmallVector<std::string, 4> Blacklist = { + static const char *Blacklist[] = { "asan.", "llvm.", @@ -173,6 +184,8 @@ struct InsTrim : public ModulePass { StringRef instFilename; unsigned int instLine = 0; +#if LLVM_VERSION_MAJOR >= 4 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7) for (auto &BB : F) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); @@ -227,6 +240,48 @@ struct InsTrim : public ModulePass { } +#else + for (auto &BB : F) { + + BasicBlock::iterator IP = BB.getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); + if (Loc.isUnknown()) Loc = IP->getDebugLoc(); + + } + + if (!Loc.isUnknown()) { + + DILocation cDILoc(Loc.getAsMDNode(C)); + + instLine = cDILoc.getLineNumber(); + instFilename = cDILoc.getFilename(); + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + + } + + } + + } + + } + +#endif /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ if (!instrumentBlock) { diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile index e952e5fb..50b1d48c 100644 --- a/llvm_mode/Makefile +++ b/llvm_mode/Makefile @@ -36,7 +36,7 @@ else endif LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null ) -LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 ) +LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-3]|^1[2-9]' && echo 1 || echo 0 ) 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) @@ -201,7 +201,7 @@ endif ln -sf afl-clang-fast ../afl-clang-fast++ ../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps - $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) + -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL) ../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) diff --git a/llvm_mode/MarkNodes.cc b/llvm_mode/MarkNodes.cc index caa8cede..7b22bac0 100644 --- a/llvm_mode/MarkNodes.cc +++ b/llvm_mode/MarkNodes.cc @@ -3,11 +3,22 @@ #include <queue> #include <set> #include <vector> + +#include "llvm/Config/llvm-config.h" +#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 +typedef long double max_align_t; +#endif + #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/BasicBlock.h" +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) #include "llvm/IR/CFG.h" +#else +#include "llvm/Support/CFG.h" +#endif #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index 15cc6127..2cd23adf 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -37,14 +37,26 @@ #include <fstream> #include <sys/time.h> -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/BasicBlock.h" +#include "llvm/Config/llvm-config.h" +#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 +typedef long double max_align_t; +#endif + #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" + +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/CFG.h" +#else +#include "llvm/DebugInfo.h" +#include "llvm/Support/CFG.h" +#endif using namespace llvm; @@ -78,7 +90,7 @@ class AFLCoverage : public ModulePass { // ripped from aflgo static bool isBlacklisted(const Function *F) { - static const SmallVector<std::string, 4> Blacklist = { + static const char *Blacklist[] = { "asan.", "llvm.", @@ -197,6 +209,8 @@ bool AFLCoverage::runOnModule(Module &M) { * For now, just instrument the block if we are not able * to determine our location. */ DebugLoc Loc = IP->getDebugLoc(); +#if LLVM_VERSION_MAJOR >= 4 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7) if (Loc) { DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); @@ -249,6 +263,47 @@ bool AFLCoverage::runOnModule(Module &M) { } +#else + if (!Loc.isUnknown()) { + + DILocation cDILoc(Loc.getAsMDNode(C)); + + unsigned int instLine = cDILoc.getLineNumber(); + StringRef instFilename = cDILoc.getFilename(); + + (void)instLine; + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + + } + + } + + } + + } + +#endif + /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ if (!instrumentBlock) continue; @@ -273,13 +328,19 @@ bool AFLCoverage::runOnModule(Module &M) { // result: a little more speed and less map pollution int more_than_one = -1; // fprintf(stderr, "BB %u: ", cur_loc); - for (BasicBlock *Pred : predecessors(&BB)) { + for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); PI != E; + ++PI) { + + BasicBlock *Pred = *PI; int count = 0; if (more_than_one == -1) more_than_one = 0; // fprintf(stderr, " %p=>", Pred); - for (BasicBlock *Succ : successors(Pred)) { + for (succ_iterator SI = succ_begin(Pred), E = succ_end(Pred); SI != E; + ++SI) { + + BasicBlock *Succ = *SI; // if (count > 0) // fprintf(stderr, "|"); diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 5d924b63..e1332a9d 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -22,9 +22,9 @@ #include <string> #include <fstream> #include <sys/time.h> +#include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" -#include "llvm/IR/DebugInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -32,10 +32,19 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/IR/Verifier.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) +#include "llvm/IR/Verifier.h" +#include "llvm/IR/DebugInfo.h" +#else +#include "llvm/Analysis/Verifier.h" +#include "llvm/DebugInfo.h" +#define nullptr 0 +#endif + #include <set> using namespace llvm; @@ -115,7 +124,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, c = M.getOrInsertFunction("tolower", Int32Ty, Int32Ty #if LLVM_VERSION_MAJOR < 5 , - nullptr + NULL #endif ); #if LLVM_VERSION_MAJOR < 9 @@ -140,6 +149,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, * For now, just instrument the block if we are not able * to determine our location. */ DebugLoc Loc = IP->getDebugLoc(); +#if LLVM_VERSION_MAJOR >= 4 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7) if (Loc) { DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); @@ -192,6 +203,47 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } +#else + if (!Loc.isUnknown()) { + + DILocation cDILoc(Loc.getAsMDNode(C)); + + unsigned int instLine = cDILoc.getLineNumber(); + StringRef instFilename = cDILoc.getFilename(); + + (void)instLine; + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + + } + + } + + } + + } + +#endif + /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ if (!instrumentBlock) continue; diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc index bc25b322..e16993d6 100644 --- a/llvm_mode/split-compares-pass.so.cc +++ b/llvm_mode/split-compares-pass.so.cc @@ -24,16 +24,25 @@ #include <fstream> #include <sys/time.h> +#include "llvm/Config/llvm-config.h" + #include "llvm/Pass.h" -#include "llvm/IR/DebugInfo.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/IR/Verifier.h" #include "llvm/IR/Module.h" #include "llvm/IR/IRBuilder.h" +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) +#include "llvm/IR/Verifier.h" +#include "llvm/IR/DebugInfo.h" +#else +#include "llvm/Analysis/Verifier.h" +#include "llvm/DebugInfo.h" +#define nullptr 0 +#endif using namespace llvm; @@ -66,7 +75,7 @@ class SplitComparesTransform : public ModulePass { static bool isBlacklisted(const Function *F) { - static const SmallVector<std::string, 5> Blacklist = { + static const char *Blacklist[] = { "asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign." @@ -139,6 +148,8 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { * For now, just instrument the block if we are not able * to determine our location. */ DebugLoc Loc = IP->getDebugLoc(); +#if LLVM_VERSION_MAJOR >= 4 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7) if (Loc) { DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); @@ -191,6 +202,47 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { } +#else + if (!Loc.isUnknown()) { + + DILocation cDILoc(Loc.getAsMDNode(C)); + + unsigned int instLine = cDILoc.getLineNumber(); + StringRef instFilename = cDILoc.getFilename(); + + (void)instLine; + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + + } + + } + + } + + } + +#endif + /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ if (!instrumentBlock) continue; @@ -283,7 +335,8 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { * block bb it is now at the position where the old IcmpInst was */ Instruction *icmp_np; icmp_np = CmpInst::Create(Instruction::ICmp, new_pred, op0, op1); - bb->getInstList().insert(bb->getTerminator()->getIterator(), icmp_np); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + icmp_np); /* create a new basic block which holds the new EQ icmp */ Instruction *icmp_eq; @@ -348,7 +401,8 @@ bool SplitComparesTransform::simplifyCompares(Module &M) { * block bb it is now at the position where the old IcmpInst was */ Instruction *fcmp_np; fcmp_np = CmpInst::Create(Instruction::FCmp, new_pred, op0, op1); - bb->getInstList().insert(bb->getTerminator()->getIterator(), fcmp_np); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + fcmp_np); /* create a new basic block which holds the new EQ fcmp */ Instruction *fcmp_eq; @@ -469,20 +523,21 @@ bool SplitComparesTransform::simplifyIntSignedness(Module &M) { s_op0 = BinaryOperator::Create(Instruction::LShr, op0, ConstantInt::get(IntType, bitw - 1)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_op0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_op0); t_op0 = new TruncInst(s_op0, Int1Ty); - bb->getInstList().insert(bb->getTerminator()->getIterator(), t_op0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_op0); s_op1 = BinaryOperator::Create(Instruction::LShr, op1, ConstantInt::get(IntType, bitw - 1)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_op1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_op1); t_op1 = new TruncInst(s_op1, Int1Ty); - bb->getInstList().insert(bb->getTerminator()->getIterator(), t_op1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_op1); /* compare of the sign bits */ icmp_sign_bit = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_op0, t_op1); - bb->getInstList().insert(bb->getTerminator()->getIterator(), icmp_sign_bit); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + icmp_sign_bit); /* create a new basic block which is executed if the signedness bit is * different */ @@ -557,6 +612,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { LLVMContext &C = M.getContext(); +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7) const DataLayout &dl = M.getDataLayout(); /* define unions with floating point and (sign, exponent, mantissa) triples @@ -571,6 +628,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } +#endif + std::vector<CmpInst *> fcomps; /* get all EQ, NE, GT, and LT fcmps. if the other two @@ -669,11 +728,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { Instruction *b_op0, *b_op1; b_op0 = CastInst::Create(Instruction::BitCast, op0, IntegerType::get(C, op_size)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), b_op0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), b_op0); b_op1 = CastInst::Create(Instruction::BitCast, op1, IntegerType::get(C, op_size)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), b_op1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), b_op1); /* isolate signs of value of floating point type */ @@ -684,21 +743,22 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { s_s0 = BinaryOperator::Create(Instruction::LShr, b_op0, ConstantInt::get(b_op0->getType(), op_size - 1)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_s0); t_s0 = new TruncInst(s_s0, Int1Ty); - bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_s0); s_s1 = BinaryOperator::Create(Instruction::LShr, b_op1, ConstantInt::get(b_op1->getType(), op_size - 1)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_s1); t_s1 = new TruncInst(s_s1, Int1Ty); - bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), t_s1); /* compare of the sign bits */ icmp_sign_bit = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_s0, t_s1); - bb->getInstList().insert(bb->getTerminator()->getIterator(), icmp_sign_bit); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + icmp_sign_bit); /* create a new basic block which is executed if the signedness bits are * equal */ @@ -730,16 +790,16 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { Instruction::LShr, b_op1, ConstantInt::get(b_op1->getType(), shiftR_exponent)); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), s_e0); + BasicBlock::iterator(signequal_bb->getTerminator()), s_e0); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), s_e1); + BasicBlock::iterator(signequal_bb->getTerminator()), s_e1); t_e0 = new TruncInst(s_e0, IntExponentTy); t_e1 = new TruncInst(s_e1, IntExponentTy); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), t_e0); + BasicBlock::iterator(signequal_bb->getTerminator()), t_e0); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), t_e1); + BasicBlock::iterator(signequal_bb->getTerminator()), t_e1); if (sizeInBits - precision < exTySizeBytes * 8) { @@ -750,9 +810,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { Instruction::And, t_e1, ConstantInt::get(t_e1->getType(), mask_exponent)); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), m_e0); + BasicBlock::iterator(signequal_bb->getTerminator()), m_e0); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), m_e1); + BasicBlock::iterator(signequal_bb->getTerminator()), m_e1); } else { @@ -780,7 +840,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_exponent = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), icmp_exponent); + BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; @@ -789,7 +849,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_exponent = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1); signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), icmp_exponent); + BasicBlock::iterator(signequal_bb->getTerminator()), icmp_exponent); icmp_exponent_result = BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0); break; @@ -798,7 +858,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } signequal_bb->getInstList().insert( - signequal_bb->getTerminator()->getIterator(), icmp_exponent_result); + BasicBlock::iterator(signequal_bb->getTerminator()), + icmp_exponent_result); { @@ -822,19 +883,19 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { m_f1 = BinaryOperator::Create( Instruction::And, b_op1, ConstantInt::get(b_op1->getType(), mask_fraction)); - middle_bb->getInstList().insert(middle_bb->getTerminator()->getIterator(), - m_f0); - middle_bb->getInstList().insert(middle_bb->getTerminator()->getIterator(), - m_f1); + middle_bb->getInstList().insert( + BasicBlock::iterator(middle_bb->getTerminator()), m_f0); + middle_bb->getInstList().insert( + BasicBlock::iterator(middle_bb->getTerminator()), m_f1); if (needTrunc) { t_f0 = new TruncInst(m_f0, IntFractionTy); t_f1 = new TruncInst(m_f1, IntFractionTy); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), t_f0); + BasicBlock::iterator(middle_bb->getTerminator()), t_f0); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), t_f1); + BasicBlock::iterator(middle_bb->getTerminator()), t_f1); } else { @@ -850,9 +911,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { t_f0 = new TruncInst(b_op0, IntFractionTy); t_f1 = new TruncInst(b_op1, IntFractionTy); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), t_f0); + BasicBlock::iterator(middle_bb->getTerminator()), t_f0); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), t_f1); + BasicBlock::iterator(middle_bb->getTerminator()), t_f1); } else { @@ -882,7 +943,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_fraction = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), icmp_fraction); + BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction); icmp_fraction_result = BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0); break; @@ -891,7 +952,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { icmp_fraction = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1); middle_bb->getInstList().insert( - middle_bb->getTerminator()->getIterator(), icmp_fraction); + BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction); icmp_fraction_result = BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0); break; @@ -899,8 +960,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } - middle_bb->getInstList().insert(middle_bb->getTerminator()->getIterator(), - icmp_fraction_result); + middle_bb->getInstList().insert( + BasicBlock::iterator(middle_bb->getTerminator()), icmp_fraction_result); PHINode *PN = PHINode::Create(Int1Ty, 3, ""); @@ -1037,18 +1098,21 @@ size_t SplitComparesTransform::splitIntCompares(Module &M, unsigned bitw) { s_op0 = BinaryOperator::Create(Instruction::LShr, op0, ConstantInt::get(OldIntType, bitw / 2)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_op0); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_op0); op0_high = new TruncInst(s_op0, NewIntType); - bb->getInstList().insert(bb->getTerminator()->getIterator(), op0_high); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + op0_high); s_op1 = BinaryOperator::Create(Instruction::LShr, op1, ConstantInt::get(OldIntType, bitw / 2)); - bb->getInstList().insert(bb->getTerminator()->getIterator(), s_op1); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), s_op1); op1_high = new TruncInst(s_op1, NewIntType); - bb->getInstList().insert(bb->getTerminator()->getIterator(), op1_high); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + op1_high); icmp_high = CmpInst::Create(Instruction::ICmp, pred, op0_high, op1_high); - bb->getInstList().insert(bb->getTerminator()->getIterator(), icmp_high); + bb->getInstList().insert(BasicBlock::iterator(bb->getTerminator()), + icmp_high); /* now we have to destinguish between == != and > < */ if (pred == CmpInst::ICMP_EQ || pred == CmpInst::ICMP_NE) { @@ -1194,13 +1258,19 @@ bool SplitComparesTransform::runOnModule(Module &M) { << "bit: " << splitIntCompares(M, bitw) << " splitted\n"; bitw >>= 1; +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7) [[clang::fallthrough]]; /*FALLTHRU*/ /* FALLTHROUGH */ +#endif case 32: errs() << "Split-integer-compare-pass " << bitw << "bit: " << splitIntCompares(M, bitw) << " splitted\n"; bitw >>= 1; +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7) [[clang::fallthrough]]; /*FALLTHRU*/ /* FALLTHROUGH */ +#endif case 16: errs() << "Split-integer-compare-pass " << bitw << "bit: " << splitIntCompares(M, bitw) << " splitted\n"; diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc index 3a2838c0..9101dc26 100644 --- a/llvm_mode/split-switches-pass.so.cc +++ b/llvm_mode/split-switches-pass.so.cc @@ -23,8 +23,9 @@ #include <fstream> #include <sys/time.h> +#include "llvm/Config/llvm-config.h" + #include "llvm/ADT/Statistic.h" -#include "llvm/IR/DebugInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -32,10 +33,20 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/IR/Verifier.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/IRBuilder.h" +#if LLVM_VERSION_MAJOR > 3 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) +#include "llvm/IR/Verifier.h" +#include "llvm/IR/DebugInfo.h" +#else +#include "llvm/Analysis/Verifier.h" +#include "llvm/DebugInfo.h" +#define nullptr 0 +#endif + #include <set> using namespace llvm; @@ -69,7 +80,7 @@ class SplitSwitchesTransform : public ModulePass { static bool isBlacklisted(const Function *F) { - static const SmallVector<std::string, 5> Blacklist = { + static const char *Blacklist[] = { "asan.", "llvm.", "sancov.", "__ubsan_handle_", "ign." @@ -140,7 +151,7 @@ BasicBlock *SplitSwitchesTransform::switchConvert( IntegerType * ByteType = IntegerType::get(OrigBlock->getContext(), 8); unsigned BytesInValue = bytesChecked.size(); std::vector<uint8_t> setSizes; - std::vector<std::set<uint8_t>> byteSets(BytesInValue, std::set<uint8_t>()); + std::vector<std::set<uint8_t> > byteSets(BytesInValue, std::set<uint8_t>()); assert(ValTypeBitWidth >= 8 && ValTypeBitWidth <= 64); @@ -213,8 +224,25 @@ BasicBlock *SplitSwitchesTransform::switchConvert( NewNode->getInstList().push_back(Comp); bytesChecked[smallestIndex] = true; - if (std::all_of(bytesChecked.begin(), bytesChecked.end(), - [](bool b) { return b; })) { + bool allBytesAreChecked = true; + + for (std::vector<bool>::iterator BCI = bytesChecked.begin(), + E = bytesChecked.end(); + BCI != E; ++BCI) { + + if (!*BCI) { + + allBytesAreChecked = false; + break; + + } + + } + + // if (std::all_of(bytesChecked.begin(), bytesChecked.end(), + // [](bool b) { return b; })) { + + if (allBytesAreChecked) { assert(Cases.size() == 1); BranchInst::Create(Cases[0].BB, NewDefault, Comp, NewNode); @@ -306,6 +334,10 @@ BasicBlock *SplitSwitchesTransform::switchConvert( bool SplitSwitchesTransform::splitSwitches(Module &M) { +#if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 7) + LLVMContext &C = M.getContext(); +#endif + std::vector<SwitchInst *> switches; /* iterate over all functions, bbs and instruction and add @@ -327,6 +359,8 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { * For now, just instrument the block if we are not able * to determine our location. */ DebugLoc Loc = IP->getDebugLoc(); +#if LLVM_VERSION_MAJOR >= 4 || \ + (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7) if (Loc) { DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); @@ -379,6 +413,47 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { } +#else + if (!Loc.isUnknown()) { + + DILocation cDILoc(Loc.getAsMDNode(C)); + + unsigned int instLine = cDILoc.getLineNumber(); + StringRef instFilename = cDILoc.getFilename(); + + (void)instLine; + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + + } + + } + + } + + } + +#endif + /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ if (!instrumentBlock) continue; @@ -426,8 +501,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { * if the default block is set as an unreachable we avoid creating one * because will never be a valid target.*/ BasicBlock *NewDefault = nullptr; - NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault"); - NewDefault->insertInto(F, Default); + NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault", F, Default); BranchInst::Create(Default, NewDefault); /* Prepare cases vector. */ |