about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--afl-as.c2
-rw-r--r--afl-fuzz.c6
-rw-r--r--config.h2
-rw-r--r--docs/ChangeLog10
-rw-r--r--docs/README18
-rw-r--r--docs/perf_tips.txt2
-rw-r--r--docs/power_schedules.txt2
-rw-r--r--llvm_mode/split-compares-pass.so.cc8
-rw-r--r--llvm_mode/split-switches-pass.so.cc4
-rwxr-xr-xqemu_mode/build_qemu_support.sh1
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h4
-rw-r--r--qemu_mode/patches/afl-qemu-tcg-inl.h165
-rw-r--r--qemu_mode/patches/afl-qemu-translate-inl.h17
-rw-r--r--qemu_mode/patches/elfload.diff44
-rw-r--r--qemu_mode/patches/elfload2.diff47
-rw-r--r--qemu_mode/patches/tcg.diff171
16 files changed, 244 insertions, 259 deletions
diff --git a/afl-as.c b/afl-as.c
index 55b14c9d..94595f24 100644
--- a/afl-as.c
+++ b/afl-as.c
@@ -377,7 +377,7 @@ static void add_instrumentation(void) {
     }
 
     /* Label of some sort. This may be a branch destination, but we need to
-       tread carefully and account for several different formatting
+       read carefully and account for several different formatting
        conventions. */
 
 #ifdef __APPLE__
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 6ea836d6..b775803d 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -4066,7 +4066,7 @@ static void show_stats(void) {
 
   /* Lord, forgive me this. */
 
-  SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH2 bHB
+  SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB
        bH bSTOP cCYA " overall results " bSTG bH2 bH2 bRT "\n");
 
   if (dumb_mode) {
@@ -4833,7 +4833,7 @@ static u32 calculate_score(struct queue_entry* q) {
       break;
 
     default:
-      PFATAL ("Unkown Power Schedule");
+      PFATAL ("Unknown Power Schedule");
   }
   if (factor > MAX_FACTOR) 
     factor = MAX_FACTOR;
@@ -8085,7 +8085,7 @@ int main(int argc, char** argv) {
     case LIN:     OKF ("Using linear power schedule (LIN)"); break;
     case QUAD:    OKF ("Using quadratic power schedule (QUAD)"); break;
     case EXPLORE: OKF ("Using exploration-based constant power schedule (EXPLORE)"); break;
-    default : FATAL ("Unkown power schedule"); break;
+    default : FATAL ("Unknown power schedule"); break;
   }
 
   if (getenv("AFL_NO_FORKSRV"))    no_forkserver    = 1;
diff --git a/config.h b/config.h
index 2ae510ea..cebf7c39 100644
--- a/config.h
+++ b/config.h
@@ -21,7 +21,7 @@
 
 /* Version string: */
 
-#define VERSION             "++2.52c"
+#define VERSION             "++2.52d"
 
 /******************************************************
  *                                                    *
diff --git a/docs/ChangeLog b/docs/ChangeLog
index e1d66767..3d93821f 100644
--- a/docs/ChangeLog
+++ b/docs/ChangeLog
@@ -14,7 +14,15 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 
 -----------------------------
-Version ++2.52c (2019-05-28):
+Version ++2.52d (tbd):
+-----------------------------
+
+  - ... your idea or patch?
+
+
+
+-----------------------------
+Version ++2.52c (2019-06-05):
 -----------------------------
 
   - Applied community patches. See docs/PATCHES for the full list.
diff --git a/docs/README b/docs/README
index e2ddf1ef..d1b05b5a 100644
--- a/docs/README
+++ b/docs/README
@@ -28,7 +28,7 @@ american fuzzy lop plus plus
   Released under terms and conditions of Apache License, Version 2.0.
 
   For new versions and additional information, check out:
-  http://lcamtuf.coredump.cx/afl/
+  https://github.com/vanhauser-thc/AFLplusplus
 
   To compare notes with other users or get notified about major new features,
   send a mail to <afl-users+subscribe@googlegroups.com>.
@@ -513,21 +513,11 @@ Thank you!
 15) Contact
 -----------
 
-Questions? Concerns? Bug reports? The author can be usually reached at
-<lcamtuf@google.com>.
+Questions? Concerns? Bug reports? The contributors can be reached via
+https://github.com/vanhauser-thc/AFLplusplus
 
-There is also a mailing list for the project; to join, send a mail to
+There is also a mailing list for the afl project; to join, send a mail to
 <afl-users+subscribe@googlegroups.com>. Or, if you prefer to browse
 archives first, try:
 
   https://groups.google.com/group/afl-users
-
-PS. If you wish to submit raw code to be incorporated into the project, please
-be aware that the copyright on most of AFL is claimed by Google. While you do
-retain copyright on your contributions, they do ask people to agree to a simple
-CLA first:
-
-  https://cla.developers.google.com/clas
-
-Sorry about the hassle. Of course, no CLA is required for feature requests or
-bug reports.
diff --git a/docs/perf_tips.txt b/docs/perf_tips.txt
index 287284fc..263065c0 100644
--- a/docs/perf_tips.txt
+++ b/docs/perf_tips.txt
@@ -191,7 +191,7 @@ There are several OS-level factors that may affect fuzzing speed:
   - Use the afl-system-config script to set all proc/sys settings above
 
   - Disable all the spectre, meltdown etc. security countermeasures in the
-    kernel if your machine is properly seperated:
+    kernel if your machine is properly separated:
     "ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off
      no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable
      nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off
diff --git a/docs/power_schedules.txt b/docs/power_schedules.txt
index 578ff020..cb4ca6e7 100644
--- a/docs/power_schedules.txt
+++ b/docs/power_schedules.txt
@@ -27,7 +27,7 @@ where *α(i)* is the performance score that AFL uses to compute for the seed inp
   
 More details can be found in our paper that was recently accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).
 
-PS: In parallel mode (several instances with shared queue), we suggest to run the master using the exploit schedule (-p exploit) and the slaves with a combination of cut-off-exponential (-p coe), exponential (-p fast; default), and explore (-p explore) schedules. In single mode, the default settings will do. **EDIT:** In parallel mode, AFLFast seems to perform poorly because the path probability estimates are incorrect for the imported seeds. Pull requests to fix this issue by syncing the estimates accross instances are appreciated :)
+PS: In parallel mode (several instances with shared queue), we suggest to run the master using the exploit schedule (-p exploit) and the slaves with a combination of cut-off-exponential (-p coe), exponential (-p fast; default), and explore (-p explore) schedules. In single mode, the default settings will do. **EDIT:** In parallel mode, AFLFast seems to perform poorly because the path probability estimates are incorrect for the imported seeds. Pull requests to fix this issue by syncing the estimates across instances are appreciated :)
 
 Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
 Released under terms and conditions of Apache License, Version 2.0.
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index 5c16c408..25ccb3b4 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -259,7 +259,7 @@ bool SplitComparesTransform::simplifySignedness(Module &M) {
     Instruction *icmp_inv_sig_cmp;
     BasicBlock* sign_bb = BasicBlock::Create(C, "sign", end_bb->getParent(), end_bb);
     if (pred == CmpInst::ICMP_SGT) {
-      /* if we check for > and the op0 positiv and op1 negative then the final
+      /* if we check for > and the op0 positive and op1 negative then the final
        * result is true. if op0 negative and op1 pos, the cmp must result
        * in false
        */
@@ -369,7 +369,7 @@ bool SplitComparesTransform::splitCompares(Module &M, unsigned bitw) {
 
     BasicBlock* end_bb = bb->splitBasicBlock(BasicBlock::iterator(IcmpInst));
 
-    /* create the comparison of the top halfs of the original operands */
+    /* create the comparison of the top halves of the original operands */
     Instruction *s_op0, *op0_high, *s_op1, *op1_high, *icmp_high;
 
     s_op0 = BinaryOperator::Create(Instruction::LShr, op0, ConstantInt::get(OldIntType, bitw / 2));
@@ -403,7 +403,7 @@ bool SplitComparesTransform::splitCompares(Module &M, unsigned bitw) {
       cmp_low_bb->getInstList().push_back(icmp_low);
       BranchInst::Create(end_bb, cmp_low_bb);
 
-      /* dependant on the cmp of the high parts go to the end or go on with
+      /* dependent on the cmp of the high parts go to the end or go on with
        * the comparison */
       auto term = bb->getTerminator();
       if (pred == CmpInst::ICMP_EQ) {
@@ -448,7 +448,7 @@ bool SplitComparesTransform::splitCompares(Module &M, unsigned bitw) {
       term->eraseFromParent();
       BranchInst::Create(end_bb, inv_cmp_bb, icmp_high, bb);
 
-      /* create a bb which handles the cmp of the lower halfs */
+      /* create a bb which handles the cmp of the lower halves */
       BasicBlock* cmp_low_bb = BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
       op0_low = new TruncInst(op0, NewIntType);
       cmp_low_bb->getInstList().push_back(op0_low);
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index bed39bc3..45847f88 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -152,7 +152,7 @@ BasicBlock* SplitSwitchesTransform::switchConvert(CaseVector Cases, std::vector<
         }
         PHINode *PN = cast<PHINode>(I);
 
-        /* Only update the first occurence. */
+        /* Only update the first occurrence. */
         unsigned Idx = 0, E = PN->getNumIncomingValues();
         for (; Idx != E; ++Idx) {
           if (PN->getIncomingBlock(Idx) == OrigBlock) {
@@ -278,7 +278,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
      }
      PHINode *PN = cast<PHINode>(I);
 
-     /* Only update the first occurence. */
+     /* Only update the first occurrence. */
      unsigned Idx = 0, E = PN->getNumIncomingValues();
      for (; Idx != E; ++Idx) {
        if (PN->getIncomingBlock(Idx) == OrigBlock) {
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 959ce0b9..1e952f4e 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -133,7 +133,6 @@ patch -p1 <../patches/cpu-exec.diff || exit 1
 patch -p1 <../patches/syscall.diff || exit 1
 patch -p1 <../patches/translate-all.diff || exit 1
 patch -p1 <../patches/tcg.diff || exit 1
-patch -p1 <../patches/elfload2.diff || exit 1
 
 echo "[+] Patching done."
 
diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h
index 97c6ea35..32030408 100644
--- a/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -9,6 +9,8 @@
 
    TCG instrumentation and block chaining support by Andrea Biondo
                                       <andrea.biondo965@gmail.com>
+   QEMU 3.1.0 port and thread-safety by Andrea Fioraldi
+                                      <andreafioraldi@gmail.com>
 
    Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
 
@@ -19,7 +21,7 @@
      http://www.apache.org/licenses/LICENSE-2.0
 
    This code is a shim patched into the separately-distributed source
-   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality
+   code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality
    to implement AFL-style instrumentation and to take care of the remaining
    parts of the AFL fork server logic.
 
diff --git a/qemu_mode/patches/afl-qemu-tcg-inl.h b/qemu_mode/patches/afl-qemu-tcg-inl.h
new file mode 100644
index 00000000..fab3d9e3
--- /dev/null
+++ b/qemu_mode/patches/afl-qemu-tcg-inl.h
@@ -0,0 +1,165 @@
+/*
+   american fuzzy lop - high-performance binary-only instrumentation
+   -----------------------------------------------------------------
+
+   Written by Andrew Griffiths <agriffiths@google.com> and
+              Michal Zalewski <lcamtuf@google.com>
+
+   Idea & design very much by Andrew Griffiths.
+
+   TCG instrumentation and block chaining support by Andrea Biondo
+                                      <andrea.biondo965@gmail.com>
+   QEMU 3.1.0 port and thread-safety by Andrea Fioraldi
+                                      <andreafioraldi@gmail.com>
+
+   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   This code is a shim patched into the separately-distributed source
+   code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality
+   to implement AFL-style instrumentation and to take care of the remaining
+   parts of the AFL fork server logic.
+
+   The resulting QEMU binary is essentially a standalone instrumentation
+   tool; for an example of how to leverage it for other purposes, you can
+   have a look at afl-showmap.c.
+
+ */
+
+void afl_maybe_log(void* cur_loc);
+
+/* Note: we convert the 64 bit args to 32 bit and do some alignment
+   and endian swap. Maybe it would be better to do the alignment
+   and endian swap in tcg_reg_alloc_call(). */
+void tcg_gen_afl_maybe_log_call(target_ulong cur_loc)
+{
+    int real_args, pi;
+    unsigned sizemask, flags;
+    TCGOp *op;
+
+    TCGTemp *arg = tcgv_ptr_temp( tcg_const_tl(cur_loc) );
+
+    flags = 0;
+    sizemask = dh_sizemask(void, 0) | dh_sizemask(ptr, 1);
+
+#if defined(__sparc__) && !defined(__arch64__) \
+    && !defined(CONFIG_TCG_INTERPRETER)
+    /* We have 64-bit values in one register, but need to pass as two
+       separate parameters.  Split them.  */
+    int orig_sizemask = sizemask;
+    TCGv_i64 retl, reth;
+    TCGTemp *split_args[MAX_OPC_PARAM];
+
+    retl = NULL;
+    reth = NULL;
+    if (sizemask != 0) {
+        real_args = 0;
+        int is_64bit = sizemask & (1 << 2);
+        if (is_64bit) {
+            TCGv_i64 orig = temp_tcgv_i64(arg);
+            TCGv_i32 h = tcg_temp_new_i32();
+            TCGv_i32 l = tcg_temp_new_i32();
+            tcg_gen_extr_i64_i32(l, h, orig);
+            split_args[real_args++] = tcgv_i32_temp(h);
+            split_args[real_args++] = tcgv_i32_temp(l);
+        } else {
+            split_args[real_args++] = arg;
+        }
+        nargs = real_args;
+        args = split_args;
+        sizemask = 0;
+    }
+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+    int is_64bit = sizemask & (1 << 2);
+    int is_signed = sizemask & (2 << 2);
+    if (!is_64bit) {
+        TCGv_i64 temp = tcg_temp_new_i64();
+        TCGv_i64 orig = temp_tcgv_i64(arg);
+        if (is_signed) {
+            tcg_gen_ext32s_i64(temp, orig);
+        } else {
+            tcg_gen_ext32u_i64(temp, orig);
+        }
+        arg = tcgv_i64_temp(temp);
+    }
+#endif /* TCG_TARGET_EXTEND_ARGS */
+
+    op = tcg_emit_op(INDEX_op_call);
+
+    pi = 0;
+
+    TCGOP_CALLO(op) = 0;
+
+    real_args = 0;
+    int is_64bit = sizemask & (1 << 2);
+    if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+        /* some targets want aligned 64 bit args */
+        if (real_args & 1) {
+            op->args[pi++] = TCG_CALL_DUMMY_ARG;
+            real_args++;
+        }
+#endif
+       /* If stack grows up, then we will be placing successive
+          arguments at lower addresses, which means we need to
+          reverse the order compared to how we would normally
+          treat either big or little-endian.  For those arguments
+          that will wind up in registers, this still works for
+          HPPA (the only current STACK_GROWSUP target) since the
+          argument registers are *also* allocated in decreasing
+          order.  If another such target is added, this logic may
+          have to get more complicated to differentiate between
+          stack arguments and register arguments.  */
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
+        op->args[pi++] = temp_arg(arg + 1);
+        op->args[pi++] = temp_arg(arg);
+#else
+        op->args[pi++] = temp_arg(arg);
+        op->args[pi++] = temp_arg(arg + 1);
+#endif
+        real_args += 2;
+    }
+
+    op->args[pi++] = temp_arg(arg);
+    real_args++;
+
+    op->args[pi++] = (uintptr_t)&afl_maybe_log;
+    op->args[pi++] = flags;
+    TCGOP_CALLI(op) = real_args;
+
+    /* Make sure the fields didn't overflow.  */
+    tcg_debug_assert(TCGOP_CALLI(op) == real_args);
+    tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
+
+#if defined(__sparc__) && !defined(__arch64__) \
+    && !defined(CONFIG_TCG_INTERPRETER)
+    /* Free all of the parts we allocated above.  */
+    real_args = 0;
+    int is_64bit = orig_sizemask & (1 << 2);
+    if (is_64bit) {
+        tcg_temp_free_internal(args[real_args++]);
+        tcg_temp_free_internal(args[real_args++]);
+    } else {
+        real_args++;
+    }
+    if (orig_sizemask & 1) {
+        /* The 32-bit ABI returned two 32-bit pieces.  Re-assemble them.
+           Note that describing these as TCGv_i64 eliminates an unnecessary
+           zero-extension that tcg_gen_concat_i32_i64 would create.  */
+        tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth);
+        tcg_temp_free_i64(retl);
+        tcg_temp_free_i64(reth);
+    }
+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
+    int is_64bit = sizemask & (1 << 2);
+    if (!is_64bit) {
+        tcg_temp_free_internal(arg);
+    }
+#endif /* TCG_TARGET_EXTEND_ARGS */
+}
+
diff --git a/qemu_mode/patches/afl-qemu-translate-inl.h b/qemu_mode/patches/afl-qemu-translate-inl.h
index 543c2e4e..74c827f5 100644
--- a/qemu_mode/patches/afl-qemu-translate-inl.h
+++ b/qemu_mode/patches/afl-qemu-translate-inl.h
@@ -9,6 +9,8 @@
 
    TCG instrumentation and block chaining support by Andrea Biondo
                                       <andrea.biondo965@gmail.com>
+   QEMU 3.1.0 port and thread-safety by Andrea Fioraldi
+                                      <andreafioraldi@gmail.com>
 
    Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
 
@@ -19,7 +21,7 @@
      http://www.apache.org/licenses/LICENSE-2.0
 
    This code is a shim patched into the separately-distributed source
-   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality
+   code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality
    to implement AFL-style instrumentation and to take care of the remaining
    parts of the AFL fork server logic.
 
@@ -37,19 +39,17 @@ extern unsigned char *afl_area_ptr;
 extern unsigned int afl_inst_rms;
 extern abi_ulong afl_start_code, afl_end_code;
 
-void tcg_gen_afl_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
+void tcg_gen_afl_maybe_log_call(target_ulong cur_loc);
 
-
-void afl_maybe_log(abi_ulong cur_loc) {
+void afl_maybe_log(void* cur_loc) { 
 
   static __thread abi_ulong prev_loc;
 
-  afl_area_ptr[cur_loc ^ prev_loc]++;
-  prev_loc = cur_loc >> 1;
+  afl_area_ptr[(abi_ulong)cur_loc ^ prev_loc]++;
+  prev_loc = (abi_ulong)cur_loc >> 1;
 
 }
 
-
 /* Generates TCG code for AFL's tracing instrumentation. */
 static void afl_gen_trace(target_ulong cur_loc) {
 
@@ -71,7 +71,6 @@ static void afl_gen_trace(target_ulong cur_loc) {
 
   if (cur_loc >= afl_inst_rms) return;
 
-  TCGTemp *args[1] = { tcgv_i64_temp( tcg_const_tl(cur_loc) ) };
-  tcg_gen_afl_callN(afl_maybe_log, NULL, 1, args);
+  tcg_gen_afl_maybe_log_call(cur_loc);
   
 }
diff --git a/qemu_mode/patches/elfload.diff b/qemu_mode/patches/elfload.diff
index c8f6e80a..011b03ea 100644
--- a/qemu_mode/patches/elfload.diff
+++ b/qemu_mode/patches/elfload.diff
@@ -1,5 +1,5 @@
 diff --git a/linux-user/elfload.c b/linux-user/elfload.c
-index 5bccd2e2..94e928a4 100644
+index 5bccd2e2..fd7460b3 100644
 --- a/linux-user/elfload.c
 +++ b/linux-user/elfload.c
 @@ -20,6 +20,8 @@
@@ -11,16 +11,29 @@ index 5bccd2e2..94e928a4 100644
  /* from personality.h */
  
  /*
-@@ -2301,6 +2303,8 @@ static void load_elf_image(const char *image_name, int image_fd,
+@@ -2301,6 +2303,21 @@ static void load_elf_image(const char *image_name, int image_fd,
      info->brk = 0;
      info->elf_flags = ehdr->e_flags;
  
-+    if (!afl_entry_point) afl_entry_point = info->entry;
++    if (!afl_entry_point) {
++      char *ptr;
++      if ((ptr = getenv("AFL_ENTRYPOINT")) != NULL) {
++        afl_entry_point = strtoul(ptr, NULL, 16);
++      } else {
++        afl_entry_point = info->entry;
++      }
++#ifdef TARGET_ARM
++      /* The least significant bit indicates Thumb mode. */
++      afl_entry_point = afl_entry_point & ~(target_ulong)1;
++#endif
++    }
++    if (getenv("AFL_DEBUG") != NULL)
++      fprintf(stderr, "AFL forkserver entrypoint: %p\n", (void*)afl_entry_point);
 +
      for (i = 0; i < ehdr->e_phnum; i++) {
          struct elf_phdr *eppnt = phdr + i;
          if (eppnt->p_type == PT_LOAD) {
-@@ -2335,9 +2339,11 @@ static void load_elf_image(const char *image_name, int image_fd,
+@@ -2335,9 +2352,11 @@ static void load_elf_image(const char *image_name, int image_fd,
              if (elf_prot & PROT_EXEC) {
                  if (vaddr < info->start_code) {
                      info->start_code = vaddr;
@@ -32,3 +45,26 @@ index 5bccd2e2..94e928a4 100644
                  }
              }
              if (elf_prot & PROT_WRITE) {
+@@ -2662,6 +2681,22 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
+        change some of these later */
+     bprm->p = setup_arg_pages(bprm, info);
+ 
++    // On PowerPC64 the entry point is the _function descriptor_
++    // of the entry function. For AFL to properly initialize,
++    // afl_entry_point needs to be set to the actual first instruction
++    // as opposed executed by the target program. This as opposed to 
++    // where the function's descriptor sits in memory.
++    // copied from PPC init_thread
++#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
++    if (get_ppc64_abi(infop) < 2) {
++        uint64_t val;
++        get_user_u64(val, infop->entry + 8);
++        _regs->gpr[2] = val + infop->load_bias;
++        get_user_u64(val, infop->entry);
++        infop->entry = val + infop->load_bias;
++    }
++#endif
++
+     scratch = g_new0(char, TARGET_PAGE_SIZE);
+     if (STACK_GROWS_DOWN) {
+         bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
diff --git a/qemu_mode/patches/elfload2.diff b/qemu_mode/patches/elfload2.diff
deleted file mode 100644
index 045060d4..00000000
--- a/qemu_mode/patches/elfload2.diff
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/linux-user/elfload.c	2019-06-03 13:06:40.755755923 +0200
-+++ b/linux-user/elfload.c	2019-06-03 13:33:01.315709801 +0200
-@@ -2303,7 +2303,20 @@
-     info->brk = 0;
-     info->elf_flags = ehdr->e_flags;
- 
--    if (!afl_entry_point) afl_entry_point = info->entry;
-+    if (!afl_entry_point) {
-+      char *ptr;
-+      if ((ptr = getenv("AFL_ENTRYPOINT")) != NULL) {
-+        afl_entry_point = strtoul(ptr, NULL, 16);
-+      } else {
-+        afl_entry_point = info->entry;
-+      }
-+#ifdef TARGET_ARM
-+      /* The least significant bit indicates Thumb mode. */
-+      afl_entry_point = afl_entry_point & ~(target_ulong)1;
-+#endif
-+    }
-+    if (getenv("AFL_DEBUG") != NULL)
-+      fprintf(stderr, "AFL forkserver entrypoint: %p\n", (void*)afl_entry_point);
- 
-     for (i = 0; i < ehdr->e_phnum; i++) {
-         struct elf_phdr *eppnt = phdr + i;
-@@ -2668,6 +2681,22 @@
-        change some of these later */
-     bprm->p = setup_arg_pages(bprm, info);
- 
-+    // On PowerPC64 the entry point is the _function descriptor_
-+    // of the entry function. For AFL to properly initialize,
-+    // afl_entry_point needs to be set to the actual first instruction
-+    // as opposed executed by the target program. This as opposed to 
-+    // where the function's descriptor sits in memory.
-+    // copied from PPC init_thread
-+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
-+    if (get_ppc64_abi(infop) < 2) {
-+        uint64_t val;
-+        get_user_u64(val, infop->entry + 8);
-+        _regs->gpr[2] = val + infop->load_bias;
-+        get_user_u64(val, infop->entry);
-+        infop->entry = val + infop->load_bias;
-+    }
-+#endif
-+
-     scratch = g_new0(char, TARGET_PAGE_SIZE);
-     if (STACK_GROWS_DOWN) {
-         bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
diff --git a/qemu_mode/patches/tcg.diff b/qemu_mode/patches/tcg.diff
index f53a1acf..0aea5afb 100644
--- a/qemu_mode/patches/tcg.diff
+++ b/qemu_mode/patches/tcg.diff
@@ -2,179 +2,12 @@ diff --git a/tcg/tcg.c b/tcg/tcg.c
 index e85133ef..54b9b390 100644
 --- a/tcg/tcg.c
 +++ b/tcg/tcg.c
-@@ -1612,6 +1612,176 @@ bool tcg_op_supported(TCGOpcode op)
+@@ -1612,6 +1612,9 @@ bool tcg_op_supported(TCGOpcode op)
      }
  }
  
 +
-+/* Call the instrumentation function from the TCG IR */
-+void tcg_gen_afl_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
-+{
-+    int i, real_args, nb_rets, pi;
-+    unsigned sizemask, flags;
-+    TCGOp *op;
-+
-+    flags = 0;
-+    sizemask = 0;
-+
-+#if defined(__sparc__) && !defined(__arch64__) \
-+    && !defined(CONFIG_TCG_INTERPRETER)
-+    /* We have 64-bit values in one register, but need to pass as two
-+       separate parameters.  Split them.  */
-+    int orig_sizemask = sizemask;
-+    int orig_nargs = nargs;
-+    TCGv_i64 retl, reth;
-+    TCGTemp *split_args[MAX_OPC_PARAM];
-+
-+    retl = NULL;
-+    reth = NULL;
-+    if (sizemask != 0) {
-+        for (i = real_args = 0; i < nargs; ++i) {
-+            int is_64bit = sizemask & (1 << (i+1)*2);
-+            if (is_64bit) {
-+                TCGv_i64 orig = temp_tcgv_i64(args[i]);
-+                TCGv_i32 h = tcg_temp_new_i32();
-+                TCGv_i32 l = tcg_temp_new_i32();
-+                tcg_gen_extr_i64_i32(l, h, orig);
-+                split_args[real_args++] = tcgv_i32_temp(h);
-+                split_args[real_args++] = tcgv_i32_temp(l);
-+            } else {
-+                split_args[real_args++] = args[i];
-+            }
-+        }
-+        nargs = real_args;
-+        args = split_args;
-+        sizemask = 0;
-+    }
-+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
-+    for (i = 0; i < nargs; ++i) {
-+        int is_64bit = sizemask & (1 << (i+1)*2);
-+        int is_signed = sizemask & (2 << (i+1)*2);
-+        if (!is_64bit) {
-+            TCGv_i64 temp = tcg_temp_new_i64();
-+            TCGv_i64 orig = temp_tcgv_i64(args[i]);
-+            if (is_signed) {
-+                tcg_gen_ext32s_i64(temp, orig);
-+            } else {
-+                tcg_gen_ext32u_i64(temp, orig);
-+            }
-+            args[i] = tcgv_i64_temp(temp);
-+        }
-+    }
-+#endif /* TCG_TARGET_EXTEND_ARGS */
-+
-+    op = tcg_emit_op(INDEX_op_call);
-+
-+    pi = 0;
-+    if (ret != NULL) {
-+#if defined(__sparc__) && !defined(__arch64__) \
-+    && !defined(CONFIG_TCG_INTERPRETER)
-+        if (orig_sizemask & 1) {
-+            /* The 32-bit ABI is going to return the 64-bit value in
-+               the %o0/%o1 register pair.  Prepare for this by using
-+               two return temporaries, and reassemble below.  */
-+            retl = tcg_temp_new_i64();
-+            reth = tcg_temp_new_i64();
-+            op->args[pi++] = tcgv_i64_arg(reth);
-+            op->args[pi++] = tcgv_i64_arg(retl);
-+            nb_rets = 2;
-+        } else {
-+            op->args[pi++] = temp_arg(ret);
-+            nb_rets = 1;
-+        }
-+#else
-+        if (TCG_TARGET_REG_BITS < 64 && (sizemask & 1)) {
-+#ifdef HOST_WORDS_BIGENDIAN
-+            op->args[pi++] = temp_arg(ret + 1);
-+            op->args[pi++] = temp_arg(ret);
-+#else
-+            op->args[pi++] = temp_arg(ret);
-+            op->args[pi++] = temp_arg(ret + 1);
-+#endif
-+            nb_rets = 2;
-+        } else {
-+            op->args[pi++] = temp_arg(ret);
-+            nb_rets = 1;
-+        }
-+#endif
-+    } else {
-+        nb_rets = 0;
-+    }
-+    TCGOP_CALLO(op) = nb_rets;
-+
-+    real_args = 0;
-+    for (i = 0; i < nargs; i++) {
-+        int is_64bit = sizemask & (1 << (i+1)*2);
-+        if (TCG_TARGET_REG_BITS < 64 && is_64bit) {
-+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
-+            /* some targets want aligned 64 bit args */
-+            if (real_args & 1) {
-+                op->args[pi++] = TCG_CALL_DUMMY_ARG;
-+                real_args++;
-+            }
-+#endif
-+           /* If stack grows up, then we will be placing successive
-+              arguments at lower addresses, which means we need to
-+              reverse the order compared to how we would normally
-+              treat either big or little-endian.  For those arguments
-+              that will wind up in registers, this still works for
-+              HPPA (the only current STACK_GROWSUP target) since the
-+              argument registers are *also* allocated in decreasing
-+              order.  If another such target is added, this logic may
-+              have to get more complicated to differentiate between
-+              stack arguments and register arguments.  */
-+#if defined(HOST_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
-+            op->args[pi++] = temp_arg(args[i] + 1);
-+            op->args[pi++] = temp_arg(args[i]);
-+#else
-+            op->args[pi++] = temp_arg(args[i]);
-+            op->args[pi++] = temp_arg(args[i] + 1);
-+#endif
-+            real_args += 2;
-+            continue;
-+        }
-+
-+        op->args[pi++] = temp_arg(args[i]);
-+        real_args++;
-+    }
-+    op->args[pi++] = (uintptr_t)func;
-+    op->args[pi++] = flags;
-+    TCGOP_CALLI(op) = real_args;
-+
-+    /* Make sure the fields didn't overflow.  */
-+    tcg_debug_assert(TCGOP_CALLI(op) == real_args);
-+    tcg_debug_assert(pi <= ARRAY_SIZE(op->args));
-+
-+#if defined(__sparc__) && !defined(__arch64__) \
-+    && !defined(CONFIG_TCG_INTERPRETER)
-+    /* Free all of the parts we allocated above.  */
-+    for (i = real_args = 0; i < orig_nargs; ++i) {
-+        int is_64bit = orig_sizemask & (1 << (i+1)*2);
-+        if (is_64bit) {
-+            tcg_temp_free_internal(args[real_args++]);
-+            tcg_temp_free_internal(args[real_args++]);
-+        } else {
-+            real_args++;
-+        }
-+    }
-+    if (orig_sizemask & 1) {
-+        /* The 32-bit ABI returned two 32-bit pieces.  Re-assemble them.
-+           Note that describing these as TCGv_i64 eliminates an unnecessary
-+           zero-extension that tcg_gen_concat_i32_i64 would create.  */
-+        tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth);
-+        tcg_temp_free_i64(retl);
-+        tcg_temp_free_i64(reth);
-+    }
-+#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
-+    for (i = 0; i < nargs; ++i) {
-+        int is_64bit = sizemask & (1 << (i+1)*2);
-+        if (!is_64bit) {
-+            tcg_temp_free_internal(args[i]);
-+        }
-+    }
-+#endif /* TCG_TARGET_EXTEND_ARGS */
-+}
-+
++#include "../../patches/afl-qemu-tcg-inl.h"
 +
  /* Note: we convert the 64 bit args to 32 bit and do some alignment
     and endian swap. Maybe it would be better to do the alignment