aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Changelog.md1
-rw-r--r--include/debug.h52
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc76
3 files changed, 90 insertions, 39 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 182a15b8..25c7a761 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -30,6 +30,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
reporting)
- LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
for a fixed map address (eg. 0x10000)
+ - LTO: skipping ctors and ifuncs in fix map address instrumentation
- LTO: autodictionary mode is a default
- LTO: instrim instrumentation disabled, only classic support used
as it is always better
diff --git a/include/debug.h b/include/debug.h
index 6cc26ec2..f9ebce58 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -218,43 +218,43 @@
/* Die with a verbose non-OS fatal error message. */
-#define FATAL(x...) \
- do { \
- \
- SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
- "\n[-] PROGRAM ABORT : " cRST x); \
+#define FATAL(x...) \
+ do { \
+ \
+ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
+ "\n[-] PROGRAM ABORT : " cRST x); \
SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \
- __FILE__, __LINE__); \
- exit(1); \
- \
+ __FILE__, __LINE__); \
+ exit(1); \
+ \
} while (0)
/* Die by calling abort() to provide a core dump. */
-#define ABORT(x...) \
- do { \
- \
- SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
- "\n[-] PROGRAM ABORT : " cRST x); \
+#define ABORT(x...) \
+ do { \
+ \
+ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
+ "\n[-] PROGRAM ABORT : " cRST x); \
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
- __FILE__, __LINE__); \
- abort(); \
- \
+ __FILE__, __LINE__); \
+ abort(); \
+ \
} while (0)
/* Die while also including the output of perror(). */
-#define PFATAL(x...) \
- do { \
- \
- fflush(stdout); \
- SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
- "\n[-] SYSTEM ERROR : " cRST x); \
+#define PFATAL(x...) \
+ do { \
+ \
+ fflush(stdout); \
+ SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
+ "\n[-] SYSTEM ERROR : " cRST x); \
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \
- __FILE__, __LINE__); \
- SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
- exit(1); \
- \
+ __FILE__, __LINE__); \
+ SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
+ exit(1); \
+ \
} while (0)
/* Die with FATAL() or PFATAL() depending on the value of res (used to
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index abc836aa..fd8e48a7 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -224,22 +224,70 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (map_addr) {
for (GlobalIFunc &IF : M.ifuncs()) {
-
+
StringRef ifunc_name = IF.getName();
Constant *r = IF.getResolver();
StringRef r_name = cast<Function>(r->getOperand(0))->getName();
if (!be_quiet)
- fprintf(stderr, "Found an ifunc with name %s that points to resolver function %s, we cannot instrument this, putting it into a block list.\n",
+ fprintf(stderr,
+ "Warning: Found an ifunc with name %s that points to resolver "
+ "function %s, we cannot instrument this, putting it into a "
+ "block list.\n",
ifunc_name.str().c_str(), r_name.str().c_str());
-
module_block_list.push_back(r_name.str());
}
- // next up: ctors run before __afl_init()
-
- // TODO
+ GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors");
+ if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) {
+
+ ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+
+ if (InitList) {
+
+ for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+
+ if (ConstantStruct *CS =
+ dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
+
+ if (CS->getNumOperands() >= 2) {
+ if (CS->getOperand(1)->isNullValue())
+ break; // Found a null terminator, stop here.
+
+ ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+ int Priority = CI ? CI->getSExtValue() : 0;
+
+ Constant *FP = CS->getOperand(1);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+ if (CE->isCast()) FP = CE->getOperand(0);
+ if (Function *F = dyn_cast<Function>(FP)) {
+
+ if (!F->isDeclaration() &&
+ strncmp(F->getName().str().c_str(), "__afl", 5) != 0 &&
+ Priority <= 5) {
+
+ if (!be_quiet)
+ fprintf(stderr,
+ "Warning: Found constructor function %s with prio "
+ "%u, we cannot instrument this, putting it into a "
+ "block list.\n",
+ F->getName().str().c_str(), Priority);
+ module_block_list.push_back(F->getName().str());
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
}
@@ -260,21 +308,23 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (isIgnoreFunction(&F)) continue;
if (module_block_list.size()) {
-
+
for (auto bname : module_block_list) {
std::string fname = F.getName().str();
if (fname.compare(bname) == 0) {
-
+
if (!be_quiet)
- WARNF("Skipping instrumentation of ifunc resolver function %s",
- fname.c_str());
-
+ WARNF(
+ "Skipping instrumentation of dangerous early running function "
+ "%s",
+ fname.c_str());
+
}
-
+
}
-
+
}
// the instrument file list check