diff options
Diffstat (limited to 'qemu_mode')
33 files changed, 177 insertions, 2819 deletions
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION new file mode 100644 index 00000000..75883247 --- /dev/null +++ b/qemu_mode/QEMUAFL_VERSION @@ -0,0 +1 @@ +21ff343837 diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 3cf678e4..1c5d240c 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -14,12 +14,12 @@ The usual performance cost is 2-5x, which is considerably better than seen so far in experiments with tools such as DynamoRIO and PIN. The idea and much of the initial implementation comes from Andrew Griffiths. -The actual implementation on QEMU 3 (shipped with afl++) is from +The actual implementation on current QEMU (shipped as qemuafl) is from Andrea Fioraldi. Special thanks to abiondo that re-enabled TCG chaining. ## 2) How to use -The feature is implemented with a patch to QEMU 3.1.1. The simplest way +The feature is implemented with a patched QEMU. The simplest way to build it is to run ./build_qemu_support.sh. The script will download, configure, and compile the QEMU binary for you. @@ -58,7 +58,7 @@ directory. If you want to specify a different path for libraries (e.g. to run an arm64 binary on x86_64) use QEMU_LD_PREFIX. -## 3) Bonus feature #1: deferred initialization +## 3) Deferred initialization As for LLVM mode (refer to its README.md for mode details) QEMU mode supports the deferred initialization. @@ -68,7 +68,7 @@ to move the forkserver to a different part, e.g. just before the file is opened (e.g. way after command line parsing and config file loading, etc.) which can be a huge speed improvement. -## 4) Bonus feature #2: persistent mode +## 4) Persistent mode AFL++'s QEMU mode now supports also persistent mode for x86, x86_64, arm and aarch64 targets. @@ -77,11 +77,33 @@ up - but worth the effort. Please see the extra documentation for it: [README.persistent.md](README.persistent.md) -## 5) Bonus feature #3: CompareCoverage +## 5) Snapshot mode + +As an extension to persistent mode, qemuafl can snapshot and restore the memory +state and brk(). Details are in the persistent mode readme. + +The env var that enables the ready to use snapshot mode is AFL_QEMU_SNAPSHOT and +takes a hex address as a value that is the snapshot entrypoint. + +Snapshot mode can work restoring all the writeable pages, that is typically slower than +fork() mode but, on the other hand, it can scale better with multicore. +If the AFL++ Snapshot kernel module is loaded, qemuafl will use it and, in this +case, the speed is better than fork() and also the scaling capabilities. + +## 6) Partial instrumentation + +You can tell QEMU to instrument only a part of the address space. + +Just set AFL_QEMU_INST_RANGES=A,B,C... + +The format of the items in the list is either a range of addresses like 0x123-0x321 +or a module name like module.so (that is matched in the mapped object filename). + +## 7) CompareCoverage CompareCoverage is a sub-instrumentation with effects similar to laf-intel. -The option that enables QEMU CompareCoverage is AFL_COMPCOV_LEVEL. +The environment variable that enables QEMU CompareCoverage is AFL_COMPCOV_LEVEL. There is also ./libcompcov/ which implements CompareCoverage for *cmp functions (splitting memcmp, strncmp, etc. to make these conditions easier solvable by afl-fuzz). @@ -98,10 +120,10 @@ on the x86, x86_64, arm and aarch64 targets. Highly recommended. -## 6) CMPLOG mode +## 8) CMPLOG mode Another new feature is CMPLOG, which is based on the redqueen project. -Here all immidiates in CMP instructions are learned and put into a dynamic +Here all immediates in CMP instructions are learned and put into a dynamic dictionary and applied to all locations in the input that reached that CMP, trying to solve and pass it. This is a very effective feature and it is available for x86, x86_64, arm @@ -110,7 +132,7 @@ and aarch64. To enable it you must pass on the command line of afl-fuzz: -c /path/to/your/target -## 7) Bonus feature #4: Wine mode +## 9) Wine mode AFL++ QEMU can use Wine to fuzz WIn32 PE binaries. Use the -W flag of afl-fuzz. @@ -118,7 +140,7 @@ Note that some binaries require user interaction with the GUI and must be patche For examples look [here](https://github.com/andreafioraldi/WineAFLplusplusDEMO). -## 8) Notes on linking +## 10) Notes on linking The feature is supported only on Linux. Supporting BSD may amount to porting the changes made to linux-user/elfload.c and applying them to @@ -139,7 +161,7 @@ practice, this means two things: Setting AFL_INST_LIBS=1 can be used to circumvent the .text detection logic and instrument every basic block encountered. -## 9) Benchmarking +## 11) Benchmarking If you want to compare the performance of the QEMU instrumentation with that of afl-gcc compiled code against the same target, you need to build the @@ -154,7 +176,7 @@ Comparative measurements of execution speed or instrumentation coverage will be fairly meaningless if the optimization levels or instrumentation scopes don't match. -## 10) Gotchas, feedback, bugs +## 12) Gotchas, feedback, bugs If you need to fix up checksums or do other cleanup on mutated test cases, see examples/custom_mutators/ for a viable solution. @@ -175,7 +197,7 @@ with -march=core2, can help. Beyond that, this is an early-stage mechanism, so fields reports are welcome. You can send them to <afl-users@googlegroups.com>. -## 11) Alternatives: static rewriting +## 13) Alternatives: static rewriting Statically rewriting binaries just once, instead of attempting to translate them at run time, can be a faster alternative. That said, static rewriting is diff --git a/qemu_mode/README.persistent.md b/qemu_mode/README.persistent.md index b6d5d2d0..d9e7e1cc 100644 --- a/qemu_mode/README.persistent.md +++ b/qemu_mode/README.persistent.md @@ -2,7 +2,7 @@ ## 1) Introduction -Persistent mode let you fuzz your target persistently between two +Persistent mode lets you fuzz your target persistently between two addresses - without forking for every fuzzing attempt. This increases the speed by a factor between x2 and x5, hence it is very, very valuable. @@ -14,15 +14,19 @@ and aarch64 targets. ### 2.1) The START address -The start of the persistent loop has to be set with AFL_QEMU_PERSISTENT_ADDR. +The start of the persistent loop has to be set with env var AFL_QEMU_PERSISTENT_ADDR. This address can be the address of whatever instruction. Setting this address to the start of a function makes the usage simple. -If the address is however within a function, either RET or OFFSET (see below -in 2.2 and 2.3) have to be set. +If the address is however within a function, either RET, OFFSET or EXITS +(see below in 2.2, 2.3, 2.6) have to be set. This address (as well as the RET address, see below) has to be defined in hexadecimal with the 0x prefix or as a decimal value. +If both RET and EXITS are not set, QEMU will assume that START points to a +function and will patch the return address (on stack or in the link register) +to return to START (like WinAFL). + *Note:* If the target is compiled with position independant code (PIE/PIC) qemu loads these to a specific base address. For 64 bit you have to add 0x4000000000 (9 zeroes) and for 32 bit 0x40000000 @@ -38,13 +42,9 @@ message that the forkserver was not found. The RET address is the last instruction of the persistent loop. The emulator will emit a jump to START when translating the instruction at RET. -It is optional, and only needed if the the return should not be +It is optional, and only needed if the return should not be at the end of the function to which the START address points into, but earlier. -If it is not set, QEMU will assume that START points to a function and will -patch the return address (on stack or in the link register) to return to START -(like WinAFL). - It is defined by setting AFL_QEMU_PERSISTENT_RET, and too 0x4000000000 has to be set if the target is position independant. @@ -58,10 +58,10 @@ been set (so the end of the loop will be at the end of the function but START will not be at the beginning of it), we need an offset from the ESP pointer to locate the return address to patch. -The value by which the ESP pointer has to be corrected has to set in the -variable AFL_QEMU_PERSISTENT_RETADDR_OFFSET +The value by which the ESP pointer has to be corrected has to be set in the +variable AFL_QEMU_PERSISTENT_RETADDR_OFFSET. -Now to get this value right here some help: +Now to get this value right here is some help: 1. use gdb on the target 2. set a breakpoint to "main" (this is required for PIE/PIC binaries so the addresses are set up) @@ -77,25 +77,51 @@ Now to get this value right here some help: ### 2.4) Resetting the register state It is very, very likely you need to restore the general purpose registers state -when starting a new loop. Because of this you 99% of the time should set +when starting a new loop. Because of this 99% of the time you should set AFL_QEMU_PERSISTENT_GPR=1 -An example, is when you want to use main() as persistent START: +An example is when you want to use main() as persistent START: ```c int main(int argc, char **argv) { if (argc < 2) return 1; - // do stuffs + // do stuff } ``` -If you don't save and restore the registers in x86_64, the paramteter argc +If you don't save and restore the registers in x86_64, the parameter `argc` will be lost at the second execution of the loop. +### 2.5) Resetting the memory state + +This option restores the memory state using the AFL++ Snapshot LKM if loaded. +Otherwise, all the writeable pages are restored. + +To enable this option, set AFL_QEMU_PERSISTENT_MEM=1. + +### 2.6) Reset on exit() + +The user can force QEMU to set the program counter to START instead of executing +the exit_group syscall and exit the program. + +The env variable is AFL_QEMU_PERSISTENT_EXITS. + +### 2.7) Snapshot + +AFL_QEMU_SNAPSHOT=address is just a "syntactical sugar" env variable that is equivalent to +the following set of variables: + +``` +AFL_QEMU_PERSISTENT_ADDR=address +AFL_QEMU_PERSISTENT_GPR=1 +AFL_QEMU_PERSISTENT_MEM=1 +AFL_QEMU_PERSISTENT_EXITS=1 +``` + ## 3) Optional parameters ### 3.1) Loop counter value @@ -114,9 +140,9 @@ the reading of the fuzzing input via a file by reading directly into the memory address space of the target process. All this needs is that the START address has a register that can reach the -memory buffer or that the memory buffer is at a know location. You probably need +memory buffer or that the memory buffer is at a known location. You probably need the value of the size of the buffer (maybe it is in a register when START is -hitted). +hit). The persistent hook will execute a function on every persistent iteration (at the start START) defined in a shared object specified with @@ -125,10 +151,25 @@ AFL_QEMU_PERSISTENT_HOOK=/path/to/hook.so. The signature is: ```c -void afl_persistent_hook(uint64_t* regs, uint64_t guest_base); +void afl_persistent_hook(struct ARCH_regs *regs, + uint64_t guest_base, + uint8_t *input_buf, + uint32_t input_buf_len); ``` +Where ARCH is one of x86, x86_64, arm or arm64. +You have to include `path/to/qemuafl/qemuafl/api.h`. + In this hook, you can inspect and change the saved GPR state at START. +You can also initialize your data structures when QEMU loads the shared object +with: + +`int afl_persistent_hook_init(void);` + +If this routine returns true, the shared mem fuzzing feature of AFL++ is used +and so the input_buf variables of the hook becomes meaningful. Otherwise, +you have to read the input from a file like stdin. + An example that you can use with little modification for your target can be found here: [examples/qemu_persistent_hook](../examples/qemu_persistent_hook) diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 30ac158f..683026bb 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -29,13 +29,10 @@ # will be written to ../afl-qemu-trace. # - -VERSION="3.1.1" -QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz" -QEMU_SHA384="28ff22ec4b8c957309460aa55d0b3188e971be1ea7dfebfb2ecc7903cd20cfebc2a7c97eedfcc7595f708357f1623f8b" +QEMUAFL_VERSION="$(cat ./QEMUAFL_VERSION)" echo "=================================================" -echo "AFL binary-only instrumentation QEMU build script" +echo " QemuAFL build script" echo "=================================================" echo @@ -48,7 +45,7 @@ if [ ! "`uname -s`" = "Linux" ]; then fi -if [ ! -f "patches/afl-qemu-cpu-inl.h" -o ! -f "../config.h" ]; then +if [ ! -f "../config.h" ]; then echo "[-] Error: key files not found - wrong working directory?" exit 1 @@ -63,7 +60,7 @@ if [ ! -f "../afl-showmap" ]; then fi PREREQ_NOTFOUND= -for i in libtool wget automake autoconf sha384sum bison flex iconv patch pkg-config; do +for i in git wget sha384sum bison flex iconv patch pkg-config; do T=`command -v "$i" 2>/dev/null` @@ -111,41 +108,38 @@ fi echo "[+] All checks passed!" -ARCHIVE="`basename -- "$QEMU_URL"`" - -CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` - -if [ ! "$CKSUM" = "$QEMU_SHA384" ]; then - - echo "[*] Downloading QEMU ${VERSION} from the web..." - rm -f "$ARCHIVE" - OK= - while [ -z "$OK" ]; do - wget -c -O "$ARCHIVE" -- "$QEMU_URL" && OK=1 - done - - CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` - -fi - -if [ "$CKSUM" = "$QEMU_SHA384" ]; then - - echo "[+] Cryptographic signature on $ARCHIVE checks out." +echo "[*] Making sure qemuafl is checked out" +git status 1>/dev/null 2>/dev/null +if [ $? -eq 0 ]; then + echo "[*] initializing qemuafl submodule" + git submodule init || exit 1 + git submodule update 2>/dev/null # ignore errors else - - echo "[-] Error: signature mismatch on $ARCHIVE (perhaps download error?), removing archive ..." - rm -f "$ARCHIVE" - exit 1 - + echo "[*] cloning qemuafl" + test -d qemuafl || { + CNT=1 + while [ '!' -d qemuafl -a "$CNT" -lt 4 ]; do + echo "Trying to clone qemuafl (attempt $CNT/3)" + git clone --depth 1 https://github.com/AFLplusplus/qemuafl + CNT=`expr "$CNT" + 1` + done + } fi -echo "[*] Uncompressing archive (this will take a while)..." +test -d qemuafl || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } +echo "[+] Got qemuafl." -rm -rf "qemu-${VERSION}" || exit 1 -tar xf "$ARCHIVE" || exit 1 +cd "qemuafl" || exit 1 +echo "[*] Checking out $QEMUAFL_VERSION" +sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null +git checkout "$QEMUAFL_VERSION" || echo Warning: could not check out to commit $QEMUAFL_VERSION -echo "[+] Unpacking successful." +echo "[*] Making sure imported headers matches" +cp "../../include/config.h" "./qemuafl/imported/" || exit 1 +cp "../../include/cmplog.h" "./qemuafl/imported/" || exit 1 +cp "../../include/snapshot-inl.h" "./qemuafl/imported/" || exit 1 +cp "../../include/types.h" "./qemuafl/imported/" || exit 1 if [ -n "$HOST" ]; then echo "[+] Configuring host architecture to $HOST..." @@ -169,34 +163,7 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then esac fi -cd qemu-$VERSION || exit 1 - -echo Building for CPU target $CPU_TARGET - -echo "[*] Applying patches..." - -patch -p1 <../patches/elfload.diff || exit 1 -patch -p1 <../patches/mips-fpu.diff || exit 1 -patch -p1 <../patches/bsd-elfload.diff || exit 1 -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/i386-translate.diff || exit 1 -patch -p1 <../patches/arm-translate.diff || exit 1 -patch -p1 <../patches/arm-translate-a64.diff || exit 1 -patch -p1 <../patches/i386-ops_sse.diff || exit 1 -patch -p1 <../patches/i386-fpu_helper.diff || exit 1 -patch -p1 <../patches/softfloat.diff || exit 1 -patch -p1 <../patches/configure.diff || exit 1 -patch -p1 <../patches/tcg-runtime.diff || exit 1 -patch -p1 <../patches/tcg-runtime-head.diff || exit 1 -patch -p1 <../patches/translator.diff || exit 1 -patch -p1 <../patches/__init__.py.diff || exit 1 -patch -p1 <../patches/make_strncpy_safe.diff || exit 1 -patch -p1 <../patches/mmap_fixes.diff || exit 1 - -echo "[+] Patching done." +echo "Building for CPU target $CPU_TARGET" if [ "$STATIC" = "1" ]; then @@ -211,7 +178,7 @@ if [ "$STATIC" = "1" ]; then --disable-sdl --disable-seccomp --disable-smartcard --disable-snappy --disable-spice --disable-libssh2 \ --disable-libusb --disable-usb-redir --disable-vde --disable-vhost-net --disable-virglrenderer \ --disable-virtfs --disable-vnc --disable-vte --disable-xen --disable-xen-pci-passthrough --disable-xfsctl \ - --enable-linux-user --disable-system --disable-blobs --disable-tools --enable-capstone=internal \ + --enable-linux-user --disable-system --disable-blobs --disable-tools \ --target-list="${CPU_TARGET}-linux-user" --static --disable-pie --cross-prefix=$CROSS_PREFIX --python="$PYTHONBIN" \ || exit 1 @@ -221,7 +188,7 @@ else # improvement, much to my surprise. Not sure how universal this is.. ./configure --disable-system \ - --enable-linux-user --disable-gtk --disable-sdl --disable-vnc --enable-capstone=internal \ + --enable-linux-user --disable-gtk --disable-sdl --disable-vnc --disable-werror \ --target-list="${CPU_TARGET}-linux-user" --enable-pie $CROSS_PREFIX --python="$PYTHONBIN" || exit 1 fi @@ -236,7 +203,7 @@ echo "[+] Build process successful!" echo "[*] Copying binary..." -cp -f "${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 +cp -f "build/${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 cd .. ls -l ../afl-qemu-trace || exit 1 diff --git a/qemu_mode/patches/__init__.py.diff b/qemu_mode/patches/__init__.py.diff deleted file mode 100644 index 7e189b99..00000000 --- a/qemu_mode/patches/__init__.py.diff +++ /dev/null @@ -1,17 +0,0 @@ ---- a/scripts/tracetool/__init__.py 2020-03-28 13:42:21.937700726 +0100 -+++ b/scripts/tracetool/__init__.py 2020-03-28 13:41:50.991034257 +0100 -@@ -447,12 +447,12 @@ - import tracetool - - format = str(format) -- if len(format) is 0: -+ if len(format) == 0: - raise TracetoolError("format not set") - if not tracetool.format.exists(format): - raise TracetoolError("unknown format: %s" % format) - -- if len(backends) is 0: -+ if len(backends) == 0: - raise TracetoolError("no backends specified") - for backend in backends: - if not tracetool.backend.exists(backend): diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h deleted file mode 100644 index 6fac32ef..00000000 --- a/qemu_mode/patches/afl-qemu-common.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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. - - */ - -#ifndef __AFL_QEMU_COMMON -#define __AFL_QEMU_COMMON - -#include "../../config.h" -#include "../../include/cmplog.h" - -#define PERSISTENT_DEFAULT_MAX_CNT 1000 - -#ifdef CPU_NB_REGS - #define AFL_REGS_NUM CPU_NB_REGS -#elif TARGET_ARM - #define AFL_REGS_NUM 16 -#elif TARGET_AARCH64 - #define AFL_REGS_NUM 32 -#else - #define AFL_REGS_NUM 100 -#endif - -/* NeverZero */ - -#if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO) - #define INC_AFL_AREA(loc) \ - asm volatile( \ - "addb $1, (%0, %1, 1)\n" \ - "adcb $0, (%0, %1, 1)\n" \ - : /* no out */ \ - : "r"(afl_area_ptr), "r"(loc) \ - : "memory", "eax") -#else - #define INC_AFL_AREA(loc) afl_area_ptr[loc]++ -#endif - -typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base, - uint8_t *input_buf, - uint32_t input_buf_len); - -/* Declared in afl-qemu-cpu-inl.h */ - -extern unsigned char *afl_area_ptr; -extern unsigned int afl_inst_rms; -extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -extern abi_ulong afl_persistent_addr; -extern abi_ulong afl_persistent_ret_addr; -extern u8 afl_compcov_level; -extern unsigned char afl_fork_child; -extern unsigned char is_persistent; -extern target_long persistent_stack_offset; -extern unsigned char persistent_first_pass; -extern unsigned char persistent_save_gpr; -extern uint64_t persistent_saved_gpr[AFL_REGS_NUM]; -extern int persisent_retaddr_offset; - -extern u8 * shared_buf; -extern u32 *shared_buf_len; -extern u8 sharedmem_fuzzing; - -extern afl_persistent_hook_fn afl_persistent_hook_ptr; - -extern __thread abi_ulong afl_prev_loc; - -extern struct cmp_map *__afl_cmp_map; -extern __thread u32 __afl_cmp_counter; - -void afl_setup(void); -void afl_forkserver(CPUState *cpu); - -// void afl_debug_dump_saved_regs(void); - -void afl_persistent_loop(void); - -void afl_gen_tcg_plain_call(void *func); - -void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, - void *status); -void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, - void *status); -void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, - floatx80 arg2); - -/* Check if an address is valid in the current mapping */ - -static inline int is_valid_addr(target_ulong addr) { - - int flags; - target_ulong page; - - page = addr & TARGET_PAGE_MASK; - - flags = page_get_flags(page); - if (!(flags & PAGE_VALID) || !(flags & PAGE_READ)) return 0; - - return 1; - -} - -#endif - diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h deleted file mode 100644 index 63b7581d..00000000 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ /dev/null @@ -1,640 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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.1. 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. - - */ - -#include <sys/shm.h> -#include "afl-qemu-common.h" - -#ifndef AFL_QEMU_STATIC_BUILD - #include <dlfcn.h> -#endif - -/*************************** - * VARIOUS AUXILIARY STUFF * - ***************************/ - -/* We use one additional file descriptor to relay "needs translation" - messages between the child and the fork server. */ - -#define TSL_FD (FORKSRV_FD - 1) - -/* This is equivalent to afl-as.h: */ - -static unsigned char - dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ -unsigned char *afl_area_ptr = dummy; /* Exported for afl_gen_trace */ - -/* Exported variables populated by the code patched into elfload.c: */ - -abi_ulong afl_entry_point, /* ELF entry point (_start) */ - afl_start_code, /* .text start pointer */ - afl_end_code; /* .text end pointer */ - -abi_ulong afl_persistent_addr, afl_persistent_ret_addr; -unsigned int afl_persistent_cnt; - -u8 afl_compcov_level; - -__thread abi_ulong afl_prev_loc; - -struct cmp_map *__afl_cmp_map; -__thread u32 __afl_cmp_counter; - -/* Set in the child process in forkserver mode: */ - -static int forkserver_installed = 0; -static int disable_caching = 0; - -unsigned char afl_fork_child; -unsigned int afl_forksrv_pid; -unsigned char is_persistent; -target_long persistent_stack_offset; -unsigned char persistent_first_pass = 1; -unsigned char persistent_save_gpr; -uint64_t persistent_saved_gpr[AFL_REGS_NUM]; -int persisent_retaddr_offset; - -u8 * shared_buf; -u32 *shared_buf_len; -u8 sharedmem_fuzzing; - -afl_persistent_hook_fn afl_persistent_hook_ptr; - -/* Instrumentation ratio: */ - -unsigned int afl_inst_rms = MAP_SIZE; /* Exported for afl_gen_trace */ - -/* Function declarations. */ - -static void afl_wait_tsl(CPUState *, int); -static void afl_request_tsl(target_ulong, target_ulong, uint32_t, uint32_t, - TranslationBlock *, int); - -/* Data structures passed around by the translate handlers: */ - -struct afl_tb { - - target_ulong pc; - target_ulong cs_base; - uint32_t flags; - uint32_t cf_mask; - -}; - -struct afl_tsl { - - struct afl_tb tb; - char is_chain; - -}; - -struct afl_chain { - - struct afl_tb last_tb; - uint32_t cf_mask; - int tb_exit; - -}; - -/* Some forward decls: */ - -static inline TranslationBlock *tb_find(CPUState *, TranslationBlock *, int, - uint32_t); -static inline void tb_add_jump(TranslationBlock *tb, int n, - TranslationBlock *tb_next); -int open_self_maps(void *cpu_env, int fd); -static void afl_map_shm_fuzz(void); - -/************************* - * ACTUAL IMPLEMENTATION * - *************************/ - -/* Set up SHM region and initialize other stuff. */ - -static void afl_map_shm_fuzz(void) { - - char *id_str = getenv(SHM_FUZZ_ENV_VAR); - - if (id_str) { - - u32 shm_id = atoi(id_str); - u8 *map = (u8 *)shmat(shm_id, NULL, 0); - /* Whooooops. */ - - if (!map || map == (void *)-1) { - - perror("[AFL] ERROR: could not access fuzzing shared memory"); - exit(1); - - } - - shared_buf_len = (u32 *)map; - shared_buf = map + sizeof(u32); - - if (getenv("AFL_DEBUG")) { - - fprintf(stderr, "[AFL] DEBUG: successfully got fuzzing shared memory\n"); - - } - - } else { - - fprintf(stderr, - "[AFL] ERROR: variable for fuzzing shared memory is not set\n"); - exit(1); - - } - -} - -void afl_setup(void) { - - char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO"); - - int shm_id; - - if (inst_r) { - - unsigned int r; - - r = atoi(inst_r); - - if (r > 100) r = 100; - if (!r) r = 1; - - afl_inst_rms = MAP_SIZE * r / 100; - - } - - if (id_str) { - - shm_id = atoi(id_str); - afl_area_ptr = shmat(shm_id, NULL, 0); - - if (afl_area_ptr == (void *)-1) exit(1); - - /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap - so that the parent doesn't give up on us. */ - - if (inst_r) afl_area_ptr[0] = 1; - - } - - if (getenv("___AFL_EINS_ZWEI_POLIZEI___")) { // CmpLog forkserver - - id_str = getenv(CMPLOG_SHM_ENV_VAR); - - if (id_str) { - - u32 shm_id = atoi(id_str); - - __afl_cmp_map = shmat(shm_id, NULL, 0); - - if (__afl_cmp_map == (void *)-1) exit(1); - - } - - } - - if (getenv("AFL_INST_LIBS")) { - - afl_start_code = 0; - afl_end_code = (abi_ulong)-1; - - } - - if (getenv("AFL_CODE_START")) - afl_start_code = strtoll(getenv("AFL_CODE_START"), NULL, 16); - if (getenv("AFL_CODE_END")) - afl_end_code = strtoll(getenv("AFL_CODE_END"), NULL, 16); - - /* Maintain for compatibility */ - if (getenv("AFL_QEMU_COMPCOV")) { afl_compcov_level = 1; } - if (getenv("AFL_COMPCOV_LEVEL")) { - - afl_compcov_level = atoi(getenv("AFL_COMPCOV_LEVEL")); - - } - - /* pthread_atfork() seems somewhat broken in util/rcu.c, and I'm - not entirely sure what is the cause. This disables that - behaviour, and seems to work alright? */ - - rcu_disable_atfork(); - - disable_caching = getenv("AFL_QEMU_DISABLE_CACHE") != NULL; - - is_persistent = getenv("AFL_QEMU_PERSISTENT_ADDR") != NULL; - - if (is_persistent) { - - afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 0); - if (getenv("AFL_QEMU_PERSISTENT_RET")) - afl_persistent_ret_addr = - strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 0); - /* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */ - - } - - if (getenv("AFL_QEMU_PERSISTENT_GPR")) persistent_save_gpr = 1; - - if (getenv("AFL_QEMU_PERSISTENT_HOOK")) { - -#ifdef AFL_QEMU_STATIC_BUILD - - fprintf(stderr, - "[AFL] ERROR: you cannot use AFL_QEMU_PERSISTENT_HOOK when " - "afl-qemu-trace is static\n"); - exit(1); - -#else - - persistent_save_gpr = 1; - - void *plib = dlopen(getenv("AFL_QEMU_PERSISTENT_HOOK"), RTLD_NOW); - if (!plib) { - - fprintf(stderr, "[AFL] ERROR: invalid AFL_QEMU_PERSISTENT_HOOK=%s\n", - getenv("AFL_QEMU_PERSISTENT_HOOK")); - exit(1); - - } - - int (*afl_persistent_hook_init_ptr)(void) = - dlsym(plib, "afl_persistent_hook_init"); - if (afl_persistent_hook_init_ptr) - sharedmem_fuzzing = afl_persistent_hook_init_ptr(); - - afl_persistent_hook_ptr = dlsym(plib, "afl_persistent_hook"); - if (!afl_persistent_hook_ptr) { - - fprintf(stderr, - "[AFL] ERROR: failed to find the function " - "\"afl_persistent_hook\" in %s\n", - getenv("AFL_QEMU_PERSISTENT_HOOK")); - exit(1); - - } - -#endif - - } - - if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET")) - persisent_retaddr_offset = - strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0); - - if (getenv("AFL_QEMU_PERSISTENT_CNT")) - afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 0); - else - afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT; - -} - -/* Fork server logic, invoked once we hit _start. */ - -void afl_forkserver(CPUState *cpu) { - - // u32 map_size = 0; - unsigned char tmp[4] = {0}; - - if (forkserver_installed == 1) return; - forkserver_installed = 1; - - if (getenv("AFL_QEMU_DEBUG_MAPS")) open_self_maps(cpu->env_ptr, 0); - - // if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer - - pid_t child_pid; - int t_fd[2]; - u8 child_stopped = 0; - u32 was_killed; - int status = 0; - - // with the max ID value - if (MAP_SIZE <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(MAP_SIZE) | FS_OPT_MAPSIZE); - if (sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ; - if (status) status |= (FS_OPT_ENABLED); - if (getenv("AFL_DEBUG")) - fprintf(stderr, "Debug: Sending status %08x\n", status); - memcpy(tmp, &status, 4); - - /* Tell the parent that we're alive. If the parent doesn't want - to talk, assume that we're not running in forkserver mode. */ - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; - - afl_forksrv_pid = getpid(); - - int first_run = 1; - - if (sharedmem_fuzzing) { - - if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); - - if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) == - (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) - afl_map_shm_fuzz(); - else { - - fprintf(stderr, - "[AFL] ERROR: afl-fuzz is old and does not support" - " shmem input"); - exit(1); - - } - - } - - /* All right, let's await orders... */ - - while (1) { - - /* Whoops, parent dead? */ - - if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); - - /* If we stopped the child in persistent mode, but there was a race - condition and afl-fuzz already issued SIGKILL, write off the old - process. */ - - if (child_stopped && was_killed) { - - child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) exit(8); - - } - - if (!child_stopped) { - - /* Establish a channel with child to grab translation commands. We'll - read from t_fd[0], child will write to TSL_FD. */ - - if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3); - close(t_fd[1]); - - child_pid = fork(); - if (child_pid < 0) exit(4); - - if (!child_pid) { - - /* Child process. Close descriptors and run free. */ - - afl_fork_child = 1; - close(FORKSRV_FD); - close(FORKSRV_FD + 1); - close(t_fd[0]); - return; - - } - - /* Parent. */ - - close(TSL_FD); - - } else { - - /* Special handling for persistent mode: if the child is alive but - currently stopped, simply restart it with SIGCONT. */ - - kill(child_pid, SIGCONT); - child_stopped = 0; - - } - - /* Parent. */ - - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5); - - /* Collect translation requests until child dies and closes the pipe. */ - - afl_wait_tsl(cpu, t_fd[0]); - - /* Get and relay exit status to parent. */ - - if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) exit(6); - - /* In persistent mode, the child stops itself with SIGSTOP to indicate - a successful run. In this case, we want to wake it up without forking - again. */ - - if (WIFSTOPPED(status)) - child_stopped = 1; - else if (unlikely(first_run && is_persistent)) { - - fprintf(stderr, "[AFL] ERROR: no persistent iteration executed\n"); - exit(12); // Persistent is wrong - - } - - first_run = 0; - - if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7); - - } - -} - -/* A simplified persistent mode handler, used as explained in - * llvm_mode/README.md. */ - -void afl_persistent_loop(void) { - - static u32 cycle_cnt; - static struct afl_tsl exit_cmd_tsl = {{-1, 0, 0, 0}, '\0'}; - - if (!afl_fork_child) return; - - if (persistent_first_pass) { - - /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. - On subsequent calls, the parent will take care of that, but on the first - iteration, it's our job to erase any trace of whatever happened - before the loop. */ - - if (is_persistent) { - - memset(afl_area_ptr, 0, MAP_SIZE); - afl_area_ptr[0] = 1; - afl_prev_loc = 0; - - } - - cycle_cnt = afl_persistent_cnt; - persistent_first_pass = 0; - persistent_stack_offset = TARGET_LONG_BITS / 8; - - return; - - } - - if (is_persistent) { - - if (--cycle_cnt) { - - if (write(TSL_FD, &exit_cmd_tsl, sizeof(struct afl_tsl)) != - sizeof(struct afl_tsl)) { - - /* Exit the persistent loop on pipe error */ - afl_area_ptr = dummy; - exit(0); - - } - - raise(SIGSTOP); - - afl_area_ptr[0] = 1; - afl_prev_loc = 0; - - } else { - - afl_area_ptr = dummy; - exit(0); - - } - - } - -} - -/* This code is invoked whenever QEMU decides that it doesn't have a - translation of a particular block and needs to compute it, or when it - decides to chain two TBs together. When this happens, we tell the parent to - mirror the operation, so that the next fork() has a cached copy. */ - -static void afl_request_tsl(target_ulong pc, target_ulong cb, uint32_t flags, - uint32_t cf_mask, TranslationBlock *last_tb, - int tb_exit) { - - if (disable_caching) return; - - struct afl_tsl t; - struct afl_chain c; - - if (!afl_fork_child) return; - - t.tb.pc = pc; - t.tb.cs_base = cb; - t.tb.flags = flags; - t.tb.cf_mask = cf_mask; - t.is_chain = (last_tb != NULL); - - if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) - return; - - if (t.is_chain) { - - c.last_tb.pc = last_tb->pc; - c.last_tb.cs_base = last_tb->cs_base; - c.last_tb.flags = last_tb->flags; - c.cf_mask = cf_mask; - c.tb_exit = tb_exit; - - if (write(TSL_FD, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain)) - return; - - } - -} - -/* This is the other side of the same channel. Since timeouts are handled by - afl-fuzz simply killing the child, we can just wait until the pipe breaks. */ - -static void afl_wait_tsl(CPUState *cpu, int fd) { - - struct afl_tsl t; - struct afl_chain c; - TranslationBlock *tb, *last_tb; - - while (1) { - - u8 invalid_pc = 0; - - /* Broken pipe means it's time to return to the fork server routine. */ - - if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break; - - /* Exit command for persistent */ - - if (t.tb.pc == (target_ulong)(-1)) return; - - tb = tb_htable_lookup(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask); - - if (!tb) { - - /* The child may request to transate a block of memory that is not - mapped in the parent (e.g. jitted code or dlopened code). - This causes a SIGSEV in gen_intermediate_code() and associated - subroutines. We simply avoid caching of such blocks. */ - - if (is_valid_addr(t.tb.pc)) { - - mmap_lock(); - tb = tb_gen_code(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask); - mmap_unlock(); - - } else { - - invalid_pc = 1; - - } - - } - - if (t.is_chain) { - - if (read(fd, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain)) - break; - - if (!invalid_pc) { - - last_tb = tb_htable_lookup(cpu, c.last_tb.pc, c.last_tb.cs_base, - c.last_tb.flags, c.cf_mask); -#define TB_JMP_RESET_OFFSET_INVALID 0xffff - if (last_tb && (last_tb->jmp_reset_offset[c.tb_exit] != - TB_JMP_RESET_OFFSET_INVALID)) { - - tb_add_jump(last_tb, c.tb_exit, tb); - - } - - } - - } - - } - - close(fd); - -} - diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h deleted file mode 100644 index 8553f194..00000000 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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. - - */ - -#include "afl-qemu-common.h" -#include "tcg.h" -#include "tcg-op.h" - -#if TCG_TARGET_REG_BITS == 64 - #define _DEFAULT_MO MO_64 -#else - #define _DEFAULT_MO MO_32 -#endif - -static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2, - TCGMemOp ot, int is_imm) { - - if (cur_loc > afl_end_code || cur_loc < afl_start_code) return; - - if (__afl_cmp_map) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= CMP_MAP_W - 1; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - - switch (ot & MO_SIZE) { - - case MO_64: - gen_helper_afl_cmplog_64(cur_loc_v, arg1, arg2); - break; - case MO_32: - gen_helper_afl_cmplog_32(cur_loc_v, arg1, arg2); - break; - case MO_16: - gen_helper_afl_cmplog_16(cur_loc_v, arg1, arg2); - break; - case MO_8: - gen_helper_afl_cmplog_8(cur_loc_v, arg1, arg2); - break; - default: - break; - - } - - tcg_temp_free(cur_loc_v); - - } else if (afl_compcov_level) { - - if (!is_imm && afl_compcov_level < 2) return; - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - - if (cur_loc >= afl_inst_rms) return; - - switch (ot & MO_SIZE) { - - case MO_64: - gen_helper_afl_compcov_64(cur_loc_v, arg1, arg2); - break; - case MO_32: - gen_helper_afl_compcov_32(cur_loc_v, arg1, arg2); - break; - case MO_16: - gen_helper_afl_compcov_16(cur_loc_v, arg1, arg2); - break; - default: - break; - - } - - tcg_temp_free(cur_loc_v); - - } - -} - -/* Routines for debug */ -/* -static void log_x86_saved_gpr(void) { - - static const char reg_names[CPU_NB_REGS][4] = { - -#ifdef TARGET_X86_64 - [R_EAX] = "rax", - [R_EBX] = "rbx", - [R_ECX] = "rcx", - [R_EDX] = "rdx", - [R_ESI] = "rsi", - [R_EDI] = "rdi", - [R_EBP] = "rbp", - [R_ESP] = "rsp", - [8] = "r8", - [9] = "r9", - [10] = "r10", - [11] = "r11", - [12] = "r12", - [13] = "r13", - [14] = "r14", - [15] = "r15", -#else - [R_EAX] = "eax", - [R_EBX] = "ebx", - [R_ECX] = "ecx", - [R_EDX] = "edx", - [R_ESI] = "esi", - [R_EDI] = "edi", - [R_EBP] = "ebp", - [R_ESP] = "esp", -#endif - - }; - - int i; - for (i = 0; i < CPU_NB_REGS; ++i) { - - fprintf(stderr, "%s = %lx\n", reg_names[i], persistent_saved_gpr[i]); - - } - -} - -static void log_x86_sp_content(void) { - - fprintf(stderr, ">> SP = %lx -> %lx\n", persistent_saved_gpr[R_ESP], -*(unsigned long*)persistent_saved_gpr[R_ESP]); - -}*/ - -static void callback_to_persistent_hook(void) { - - afl_persistent_hook_ptr(persistent_saved_gpr, guest_base, shared_buf, - *shared_buf_len); - -} - -static void gpr_saving(TCGv *cpu_regs, int regs_num) { - - int i; - TCGv_ptr gpr_sv; - - TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); - TCGv first_pass = tcg_temp_local_new(); - TCGv one = tcg_const_tl(1); - tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); - - TCGLabel *lbl_restore_gpr = gen_new_label(); - tcg_gen_brcond_tl(TCG_COND_NE, first_pass, one, lbl_restore_gpr); - - // save GPR registers - for (i = 0; i < regs_num; ++i) { - - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); - tcg_temp_free_ptr(gpr_sv); - - } - - gen_set_label(lbl_restore_gpr); - - afl_gen_tcg_plain_call(&afl_persistent_loop); - - if (afl_persistent_hook_ptr) - afl_gen_tcg_plain_call(callback_to_persistent_hook); - - // restore GPR registers - for (i = 0; i < regs_num; ++i) { - - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); - tcg_temp_free_ptr(gpr_sv); - - } - - tcg_temp_free_ptr(first_pass_ptr); - tcg_temp_free(first_pass); - tcg_temp_free(one); - -} - -static void restore_state_for_persistent(TCGv *cpu_regs, int regs_num, int sp) { - - if (persistent_save_gpr) { - - gpr_saving(cpu_regs, regs_num); - - } else if (afl_persistent_ret_addr == 0) { - - TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); - TCGv stack_off = tcg_temp_new(); - tcg_gen_ld_tl(stack_off, stack_off_ptr, 0); - tcg_gen_sub_tl(cpu_regs[sp], cpu_regs[sp], stack_off); - tcg_temp_free(stack_off); - - } - -} - -#define AFL_QEMU_TARGET_I386_SNIPPET \ - if (is_persistent) { \ - \ - if (s->pc == afl_persistent_addr) { \ - \ - restore_state_for_persistent(cpu_regs, AFL_REGS_NUM, R_ESP); \ - /*afl_gen_tcg_plain_call(log_x86_saved_gpr); \ - afl_gen_tcg_plain_call(log_x86_sp_content);*/ \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - TCGv paddr = tcg_const_tl(afl_persistent_addr); \ - tcg_gen_qemu_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset, \ - _DEFAULT_MO); \ - tcg_temp_free(paddr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - /*afl_gen_tcg_plain_call(log_x86_sp_content);*/ \ - \ - } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ - \ - gen_jmp_im(s, afl_persistent_addr); \ - gen_eob(s); \ - \ - } \ - \ - } - -// SP = 13, LINK = 14 - -#define AFL_QEMU_TARGET_ARM_SNIPPET \ - if (is_persistent) { \ - \ - if (dc->pc == afl_persistent_addr) { \ - \ - if (persistent_save_gpr) gpr_saving(cpu_R, AFL_REGS_NUM); \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - tcg_gen_movi_tl(cpu_R[14], afl_persistent_addr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - \ - } else if (afl_persistent_ret_addr && dc->pc == afl_persistent_ret_addr) { \ - \ - gen_bx_im(dc, afl_persistent_addr); \ - \ - } \ - \ - } - -// SP = 31, LINK = 30 - -#define AFL_QEMU_TARGET_ARM64_SNIPPET \ - if (is_persistent) { \ - \ - if (s->pc == afl_persistent_addr) { \ - \ - if (persistent_save_gpr) gpr_saving(cpu_X, AFL_REGS_NUM); \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - tcg_gen_movi_tl(cpu_X[30], afl_persistent_addr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - \ - } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ - \ - gen_goto_tb(s, 0, afl_persistent_addr); \ - \ - } \ - \ - } - diff --git a/qemu_mode/patches/afl-qemu-floats.h b/qemu_mode/patches/afl-qemu-floats.h deleted file mode 100644 index 2e50cf7e..00000000 --- a/qemu_mode/patches/afl-qemu-floats.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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. - - */ - -#include "tcg.h" -#include "afl-qemu-common.h" - -union afl_float32 { - - float32 f; - struct { - - u64 sign : 1; - u64 exp : 7; - u64 frac : 24; - - }; - -}; - -union afl_float64 { - - float64 f; - struct { - - u64 sign : 1; - u64 exp : 11; - u64 frac : 52; - - }; - -}; - -// TODO 16 and 128 bits floats -// TODO figure out why float*_unpack_canonical does not work - -void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, - void *status) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - // float_status*s = (float_status*)status; - // FloatParts a = float32_unpack_canonical(arg1, s); - // FloatParts b = float32_unpack_canonical(arg2, s); - union afl_float32 a = {.f = arg1}; - union afl_float32 b = {.f = arg2}; - - // if (is_nan(a.cls) || is_nan(b.cls)) return; - - register uintptr_t idx = cur_loc; - - if (a.sign != b.sign) return; - INC_AFL_AREA(idx); - if (a.exp != b.exp) return; - INC_AFL_AREA(idx + 1); - - if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { - - INC_AFL_AREA(idx + 2); - if ((a.frac & 0xff00) == (b.frac & 0xff00)) { INC_AFL_AREA(idx + 3); } - - } - -} - -void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, - void *status) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - // float_status*s = (float_status*)status; - // FloatParts a = float64_unpack_canonical(arg1, s); - // FloatParts b = float64_unpack_canonical(arg2, s); - union afl_float64 a = {.f = arg1}; - union afl_float64 b = {.f = arg2}; - - // if (is_nan(a.cls) || is_nan(b.cls)) return; - - register uintptr_t idx = cur_loc; - - if (a.sign == b.sign) INC_AFL_AREA(idx); - if ((a.exp & 0xff00) == (b.exp & 0xff00)) { - - INC_AFL_AREA(idx + 1); - if ((a.exp & 0xff) == (b.exp & 0xff)) INC_AFL_AREA(idx + 2); - - } - - if ((a.frac & 0xff000000000000) == (b.frac & 0xff000000000000)) { - - INC_AFL_AREA(idx + 3); - if ((a.frac & 0xff0000000000) == (b.frac & 0xff0000000000)) { - - INC_AFL_AREA(idx + 4); - if ((a.frac & 0xff00000000) == (b.frac & 0xff00000000)) { - - INC_AFL_AREA(idx + 5); - if ((a.frac & 0xff000000) == (b.frac & 0xff000000)) { - - INC_AFL_AREA(idx + 6); - if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { - - INC_AFL_AREA(idx + 7); - if ((a.frac & 0xff00) == (b.frac & 0xff00)) INC_AFL_AREA(idx + 8); - - } - - } - - } - - } - - } - -} - -void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, - floatx80 arg2) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - if (floatx80_invalid_encoding(arg1) || floatx80_invalid_encoding(arg2)) - return; - - flag a_sign = extractFloatx80Sign(arg1); - flag b_sign = extractFloatx80Sign(arg2); - - /*if (((extractFloatx80Exp(arg1) == 0x7fff) && - (extractFloatx80Frac(arg1) << 1)) || - ((extractFloatx80Exp(arg2) == 0x7fff) && - (extractFloatx80Frac(arg2) << 1))) - return;*/ - - register uintptr_t idx = cur_loc; - - if (a_sign == b_sign) INC_AFL_AREA(idx); - - if ((arg1.high & 0x7f00) == (arg2.high & 0x7f00)) { - - INC_AFL_AREA(idx + 1); - if ((arg1.high & 0xff) == (arg2.high & 0xff)) INC_AFL_AREA(idx + 2); - - } - - if ((arg1.low & 0xff00000000000000) == (arg2.low & 0xff00000000000000)) { - - INC_AFL_AREA(idx + 3); - if ((arg1.low & 0xff000000000000) == (arg2.low & 0xff000000000000)) { - - INC_AFL_AREA(idx + 4); - if ((arg1.low & 0xff0000000000) == (arg2.low & 0xff0000000000)) { - - INC_AFL_AREA(idx + 5); - if ((arg1.low & 0xff00000000) == (arg2.low & 0xff00000000)) { - - INC_AFL_AREA(idx + 6); - if ((arg1.low & 0xff000000) == (arg2.low & 0xff000000)) { - - INC_AFL_AREA(idx + 7); - if ((arg1.low & 0xff0000) == (arg2.low & 0xff0000)) { - - INC_AFL_AREA(idx + 8); - if ((arg1.low & 0xff00) == (arg2.low & 0xff00)) { - - INC_AFL_AREA(idx + 9); - // if ((arg1.low & 0xff) == (arg2.low & 0xff)) - // INC_AFL_AREA(idx + 10); - - } - - } - - } - - } - - } - - } - - } - -} - diff --git a/qemu_mode/patches/afl-qemu-tcg-inl.h b/qemu_mode/patches/afl-qemu-tcg-inl.h deleted file mode 100644 index f7c662db..00000000 --- a/qemu_mode/patches/afl-qemu-tcg-inl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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_gen_tcg_plain_call(void *func); - -void afl_gen_tcg_plain_call(void *func) { - - TCGOp *op = tcg_emit_op(INDEX_op_call); - - TCGOP_CALLO(op) = 0; - - op->args[0] = (uintptr_t)func; - op->args[1] = 0; - TCGOP_CALLI(op) = 0; - -} - diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h deleted file mode 100644 index 400ebf24..00000000 --- a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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. - - */ - -#include "afl-qemu-common.h" -#include "tcg.h" - -void HELPER(afl_entry_routine)(CPUArchState *env) { - - afl_forkserver(ENV_GET_CPU(env)); - -} - -void HELPER(afl_compcov_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - -} - -void HELPER(afl_compcov_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - -} - -void HELPER(afl_compcov_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { - - INC_AFL_AREA(idx + 6); - if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { - - INC_AFL_AREA(idx + 5); - if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) { - - INC_AFL_AREA(idx + 4); - if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) { - - INC_AFL_AREA(idx + 3); - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - - } - - } - - } - - } - -} - -void HELPER(afl_cmplog_8)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; - - __afl_cmp_map->headers[k].shape = 0; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; - - __afl_cmp_map->headers[k].shape = 1; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 3; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 7; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -#include <sys/mman.h> - -static int area_is_mapped(void *ptr, size_t len) { - - char *p = ptr; - char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); - - int r = msync(page, (p - page) + len, MS_ASYNC); - if (r < 0) return errno != ENOMEM; - return 1; - -} - -void HELPER(afl_cmplog_rtn)(CPUArchState *env) { - -#if defined(TARGET_X86_64) - - void *ptr1 = g2h(env->regs[R_EDI]); - void *ptr2 = g2h(env->regs[R_ESI]); - -#elif defined(TARGET_I386) - - target_ulong *stack = g2h(env->regs[R_ESP]); - - if (!area_is_mapped(stack, sizeof(target_ulong) * 2)) return; - - // when this hook is executed, the retaddr is not on stack yet - void * ptr1 = g2h(stack[0]); - void * ptr2 = g2h(stack[1]); - -#else - - // stupid code to make it compile - void *ptr1 = NULL; - void *ptr2 = NULL; - return; - -#endif - - if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return; - -#if defined(TARGET_X86_64) || defined(TARGET_I386) - uintptr_t k = (uintptr_t)env->eip; -#else - uintptr_t k = 0; -#endif - - k = (k >> 4) ^ (k << 8); - k &= CMP_MAP_W - 1; - - __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 31; - - hits &= CMP_MAP_RTN_H - 1; - __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, - ptr1, 32); - __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, - ptr2, 32); - -} - diff --git a/qemu_mode/patches/afl-qemu-translate-inl.h b/qemu_mode/patches/afl-qemu-translate-inl.h deleted file mode 100644 index 09614f5b..00000000 --- a/qemu_mode/patches/afl-qemu-translate-inl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. 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. - - */ - -#include "afl-qemu-common.h" -#include "tcg-op.h" - -void HELPER(afl_maybe_log)(target_ulong cur_loc) { - - register uintptr_t afl_idx = cur_loc ^ afl_prev_loc; - - INC_AFL_AREA(afl_idx); - - afl_prev_loc = cur_loc >> 1; - -} - -/* Generates TCG code for AFL's tracing instrumentation. */ -static void afl_gen_trace(target_ulong cur_loc) { - - /* Optimize for cur_loc > afl_end_code, which is the most likely case on - Linux systems. */ - - if (cur_loc > afl_end_code || - cur_loc < afl_start_code /*|| !afl_area_ptr*/) // not needed because of - // static dummy buffer - return; - - /* Looks like QEMU always maps to fixed locations, so ASLR is not a - concern. Phew. But instruction addresses may be aligned. Let's mangle - the value to get something quasi-uniform. */ - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 1; - - /* Implement probabilistic instrumentation by looking at scrambled block - address. This keeps the instrumented locations stable across runs. */ - - if (cur_loc >= afl_inst_rms) return; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - gen_helper_afl_maybe_log(cur_loc_v); - tcg_temp_free(cur_loc_v); - -} - diff --git a/qemu_mode/patches/arm-translate-a64.diff b/qemu_mode/patches/arm-translate-a64.diff deleted file mode 100644 index 83856217..00000000 --- a/qemu_mode/patches/arm-translate-a64.diff +++ /dev/null @@ -1,64 +0,0 @@ -diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c -index fd36425..992bf17 100644 ---- a/target/arm/translate-a64.c -+++ b/target/arm/translate-a64.c -@@ -39,6 +39,8 @@ - #include "translate-a64.h" - #include "qemu/atomic128.h" - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - static TCGv_i64 cpu_X[32]; - static TCGv_i64 cpu_pc; - -@@ -3365,6 +3367,12 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t insn) - return; - } - -+ if (rd == 31 && sub_op) { // cmp xX, imm -+ TCGv_i64 tcg_imm = tcg_const_i64(imm); -+ afl_gen_compcov(s->pc, tcg_rn, tcg_imm, is_64bit ? MO_64 : MO_32, 1); -+ tcg_temp_free_i64(tcg_imm); -+ } -+ - tcg_result = tcg_temp_new_i64(); - if (!setflags) { - if (sub_op) { -@@ -3972,6 +3980,9 @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) - - tcg_rm = read_cpu_reg(s, rm, sf); - ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); -+ -+ if (rd == 31 && sub_op) // cmp xX, xY -+ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); - - tcg_result = tcg_temp_new_i64(); - -@@ -4037,6 +4048,9 @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) - - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); - -+ if (rd == 31 && sub_op) // cmp xX, xY -+ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); -+ - tcg_result = tcg_temp_new_i64(); - - if (!setflags) { -@@ -4246,6 +4260,8 @@ static void disas_cc(DisasContext *s, uint32_t insn) - tcg_y = cpu_reg(s, y); - } - tcg_rn = cpu_reg(s, rn); -+ -+ afl_gen_compcov(s->pc, tcg_rn, tcg_y, sf ? MO_64 : MO_32, is_imm); - - /* Set the flags for the new comparison. */ - tcg_tmp = tcg_temp_new_i64(); -@@ -13317,6 +13333,8 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) - static void disas_a64_insn(CPUARMState *env, DisasContext *s) - { - uint32_t insn; -+ -+ AFL_QEMU_TARGET_ARM64_SNIPPET - - insn = arm_ldl_code(env, s->pc, s->sctlr_b); - s->insn = insn; diff --git a/qemu_mode/patches/arm-translate.diff b/qemu_mode/patches/arm-translate.diff deleted file mode 100644 index daa5d43b..00000000 --- a/qemu_mode/patches/arm-translate.diff +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/target/arm/translate.c b/target/arm/translate.c -index 7c4675f..e3d999a 100644 ---- a/target/arm/translate.c -+++ b/target/arm/translate.c -@@ -59,6 +59,8 @@ - #define IS_USER(s) (s->user) - #endif - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - /* We reuse the same 64-bit temporaries for efficiency. */ - static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; - static TCGv_i32 cpu_R[16]; -@@ -9541,6 +9543,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - } else { - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } else { - tcg_gen_sub_i32(tmp, tmp, tmp2); - } -@@ -9550,6 +9553,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - case 0x03: - if (set_cc) { - gen_sub_CC(tmp, tmp2, tmp); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } else { - tcg_gen_sub_i32(tmp, tmp2, tmp); - } -@@ -9604,6 +9608,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - case 0x0a: - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } - tcg_temp_free_i32(tmp); - break; -@@ -10565,7 +10570,7 @@ thumb2_logic_op(int op) - - static int - gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, -- TCGv_i32 t0, TCGv_i32 t1) -+ TCGv_i32 t0, TCGv_i32 t1, int has_imm) - { - int logic_cc; - -@@ -10611,15 +10616,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, - } - break; - case 13: /* sub */ -- if (conds) -+ if (conds) { - gen_sub_CC(t0, t0, t1); -- else -+ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); -+ } else - tcg_gen_sub_i32(t0, t0, t1); - break; - case 14: /* rsb */ -- if (conds) -+ if (conds) { - gen_sub_CC(t0, t1, t0); -- else -+ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); -+ } else - tcg_gen_sub_i32(t0, t1, t0); - break; - default: /* 5, 6, 7, 9, 12, 15. */ -@@ -11085,7 +11092,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) - conds = (insn & (1 << 20)) != 0; - logic_cc = (conds && thumb2_logic_op(op)); - gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); -- if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) -+ if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10))) - goto illegal_op; - tcg_temp_free_i32(tmp2); - if (rd == 13 && -@@ -11955,7 +11962,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) - } - op = (insn >> 21) & 0xf; - if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, -- shifter_out, tmp, tmp2)) -+ shifter_out, tmp, tmp2, insn & (1 << 10))) - goto illegal_op; - tcg_temp_free_i32(tmp2); - rd = (insn >> 8) & 0xf; -@@ -12206,8 +12213,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - if (insn & (1 << 9)) { - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); -- else -+ else { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 10)); -+ } - } else { - if (s->condexec_mask) - tcg_gen_add_i32(tmp, tmp, tmp2); -@@ -12247,6 +12256,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - switch (op) { - case 1: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - break; -@@ -12261,8 +12271,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - case 3: /* sub */ - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); -- else -+ else { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); -+ } - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; -@@ -12308,6 +12320,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - tmp = load_reg(s, rd); - tmp2 = load_reg(s, rm); - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; -@@ -12466,6 +12479,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - break; - case 0xa: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); - rd = 16; - break; - case 0xb: /* cmn */ -@@ -13233,6 +13247,8 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) - return; - } - -+ AFL_QEMU_TARGET_ARM_SNIPPET -+ - insn = arm_ldl_code(env, dc->pc, dc->sctlr_b); - dc->insn = insn; - dc->pc += 4; -@@ -13301,6 +13317,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) - return; - } - -+ AFL_QEMU_TARGET_ARM_SNIPPET -+ - insn = arm_lduw_code(env, dc->pc, dc->sctlr_b); - is_16bit = thumb_insn_is_16bit(dc, insn); - dc->pc += 2; diff --git a/qemu_mode/patches/bsd-elfload.diff b/qemu_mode/patches/bsd-elfload.diff deleted file mode 100644 index 19e44f5b..00000000 --- a/qemu_mode/patches/bsd-elfload.diff +++ /dev/null @@ -1,83 +0,0 @@ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 7cccf3eb..195875af 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -15,6 +15,8 @@ - #undef ELF_ARCH - #endif - -+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -+ - /* from personality.h */ - - /* -@@ -737,9 +739,13 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss) - end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss); - end_addr = HOST_PAGE_ALIGN(elf_bss); - if (end_addr1 < end_addr) { -- mmap((void *)g2h(end_addr1), end_addr - end_addr1, -+ void *p = mmap((void *)g2h(end_addr1), end_addr - end_addr1, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("padzero: cannot mmap"); -+ exit(-1); -+ } - } - } - -@@ -979,9 +985,13 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - - /* Map the last of the bss segment */ - if (last_bss > elf_bss) { -- target_mmap(elf_bss, last_bss-elf_bss, -+ void *p = target_mmap(elf_bss, last_bss-elf_bss, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("load_elf_interp: cannot mmap"); -+ exit(-1); -+ } - } - free(elf_phdata); - -@@ -1522,6 +1532,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - info->start_data = start_data; - info->end_data = end_data; - info->start_stack = bprm->p; -+ if (!afl_start_code) afl_start_code = vaddr; -+ if (!afl_end_code) afl_end_code = vaddr_ef; - - /* Calling set_brk effectively mmaps the pages that we need for the bss and break - sections */ -@@ -1544,11 +1556,29 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - and some applications "depend" upon this behavior. - Since we do not have the power to recompile these, we - emulate the SVr4 behavior. Sigh. */ -- target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, -+ void *p = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("load_elf_binary: cannot mmap"); -+ exit(-1); -+ } - } - - info->entry = elf_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); - - return 0; - } diff --git a/qemu_mode/patches/configure.diff b/qemu_mode/patches/configure.diff deleted file mode 100644 index e265edae..00000000 --- a/qemu_mode/patches/configure.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/configure 2019-08-02 18:04:50.000000000 +0200 -+++ b/configure 2020-02-28 06:31:30.424895061 +0100 -@@ -1479,6 +1479,8 @@ - ;; - --enable-capstone=system) capstone="system" - ;; -+ --enable-capstone=internal) capstone="internal" -+ ;; - --with-git=*) git="$optarg" - ;; - --enable-git-update) git_update=yes -@@ -4604,6 +4606,21 @@ - fi - - ########################################## -+cat > $TMPC << EOF -+#include <dlfcn.h> -+#include <stdlib.h> -+int main(int argc, char **argv) { return dlopen("libc.so", RTLD_NOW) != NULL; } -+EOF -+if compile_prog "" "" ; then -+ : -+elif compile_prog "" "-ldl" ; then -+ LIBS="-ldl $LIBS" -+ libs_qga="-ldl $libs_qga" -+else -+ error_exit "libdl check failed" -+fi -+ -+########################################## - # spice probe - if test "$spice" != "no" ; then - cat > $TMPC << EOF diff --git a/qemu_mode/patches/cpu-exec.diff b/qemu_mode/patches/cpu-exec.diff deleted file mode 100644 index 844be58c..00000000 --- a/qemu_mode/patches/cpu-exec.diff +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c -index 870027d4..0bc87dfc 100644 ---- a/accel/tcg/cpu-exec.c -+++ b/accel/tcg/cpu-exec.c -@@ -36,6 +36,8 @@ - #include "sysemu/cpus.h" - #include "sysemu/replay.h" - -+#include "../patches/afl-qemu-cpu-inl.h" -+ - /* -icount align implementation. */ - - typedef struct SyncClocks { -@@ -397,11 +399,13 @@ static inline TranslationBlock *tb_find(CPUState *cpu, - TranslationBlock *tb; - target_ulong cs_base, pc; - uint32_t flags; -+ bool was_translated = false, was_chained = false; - - tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); - if (tb == NULL) { - mmap_lock(); - tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask); -+ was_translated = true; - mmap_unlock(); - /* We add the TB in the virtual pc hash table for the fast lookup */ - atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb); -@@ -418,6 +422,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu, - /* See if we can patch the calling TB. */ - if (last_tb) { - tb_add_jump(last_tb, tb_exit, tb); -+ was_chained = true; -+ } -+ if (was_translated || was_chained) { -+ afl_request_tsl(pc, cs_base, flags, cf_mask, was_chained ? last_tb : NULL, tb_exit); - } - return tb; - } diff --git a/qemu_mode/patches/elfload.diff b/qemu_mode/patches/elfload.diff deleted file mode 100644 index 011b03ea..00000000 --- a/qemu_mode/patches/elfload.diff +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 5bccd2e2..fd7460b3 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -20,6 +20,8 @@ - - #define ELF_OSABI ELFOSABI_SYSV - -+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -+ - /* from personality.h */ - - /* -@@ -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) { -+ 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 +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; -+ if (!afl_start_code) afl_start_code = vaddr; - } - if (vaddr_ef > info->end_code) { - info->end_code = vaddr_ef; -+ if (!afl_end_code) afl_end_code = vaddr_ef; - } - } - 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/i386-fpu_helper.diff b/qemu_mode/patches/i386-fpu_helper.diff deleted file mode 100644 index 3bd09d9c..00000000 --- a/qemu_mode/patches/i386-fpu_helper.diff +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c -index ea5a0c48..89901315 100644 ---- a/target/i386/fpu_helper.c -+++ b/target/i386/fpu_helper.c -@@ -384,10 +384,16 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index) - - static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; - -+#include "../patches/afl-qemu-common.h" -+ - void helper_fcom_ST0_FT0(CPUX86State *env) - { - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; - } -@@ -396,6 +402,10 @@ void helper_fucom_ST0_FT0(CPUX86State *env) - { - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; - } -@@ -407,6 +417,10 @@ void helper_fcomi_ST0_FT0(CPUX86State *env) - int eflags; - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare(ST0, FT0, &env->fp_status); - eflags = cpu_cc_compute_all(env, CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; -@@ -418,6 +432,10 @@ void helper_fucomi_ST0_FT0(CPUX86State *env) - int eflags; - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); - eflags = cpu_cc_compute_all(env, CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; diff --git a/qemu_mode/patches/i386-ops_sse.diff b/qemu_mode/patches/i386-ops_sse.diff deleted file mode 100644 index d2779ea8..00000000 --- a/qemu_mode/patches/i386-ops_sse.diff +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h -index ed059897..a5296caa 100644 ---- a/target/i386/ops_sse.h -+++ b/target/i386/ops_sse.h -@@ -997,6 +997,8 @@ SSE_HELPER_CMP(cmpord, FPU_CMPORD) - - static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; - -+#include "../patches/afl-qemu-common.h" -+ - void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) - { - int ret; -@@ -1004,6 +1006,11 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) - - s0 = d->ZMM_S(0); - s1 = s->ZMM_S(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); -+ - ret = float32_compare_quiet(s0, s1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1015,6 +1022,11 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s) - - s0 = d->ZMM_S(0); - s1 = s->ZMM_S(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); -+ - ret = float32_compare(s0, s1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1026,6 +1038,11 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s) - - d0 = d->ZMM_D(0); - d1 = s->ZMM_D(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); -+ - ret = float64_compare_quiet(d0, d1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1037,6 +1054,11 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s) - - d0 = d->ZMM_D(0); - d1 = s->ZMM_D(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); -+ - ret = float64_compare(d0, d1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } diff --git a/qemu_mode/patches/i386-translate.diff b/qemu_mode/patches/i386-translate.diff deleted file mode 100644 index f0d1393b..00000000 --- a/qemu_mode/patches/i386-translate.diff +++ /dev/null @@ -1,62 +0,0 @@ -diff --git a/target/i386/translate.c b/target/i386/translate.c -index 0dd5fbe4..0d405fb6 100644 ---- a/target/i386/translate.c -+++ b/target/i386/translate.c -@@ -32,6 +32,8 @@ - #include "trace-tcg.h" - #include "exec/log.h" - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - #define PREFIX_REPZ 0x01 - #define PREFIX_REPNZ 0x02 - #define PREFIX_LOCK 0x04 -@@ -1343,9 +1345,11 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) - tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0, - s1->mem_index, ot | MO_LE); - tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1); -+ afl_gen_compcov(s1->pc, s1->cc_srcT, s1->T1, ot, d == OR_EAX); - } else { - tcg_gen_mov_tl(s1->cc_srcT, s1->T0); - tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1); -+ afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); - gen_op_st_rm_T0_A0(s1, ot, d); - } - gen_op_update2_cc(s1); -@@ -1389,6 +1393,7 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) - tcg_gen_mov_tl(cpu_cc_src, s1->T1); - tcg_gen_mov_tl(s1->cc_srcT, s1->T0); - tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1); -+ afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); - set_cc_op(s1, CC_OP_SUBB + ot); - break; - } -@@ -4508,6 +4513,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - rex_w = -1; - rex_r = 0; - -+ AFL_QEMU_TARGET_I386_SNIPPET -+ - next_byte: - b = x86_ldub_code(env, s); - /* Collect prefixes. */ -@@ -5056,6 +5063,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - tcg_gen_ext16u_tl(s->T0, s->T0); - } - next_eip = s->pc - s->cs_base; -+ if (__afl_cmp_map && next_eip >= afl_start_code && -+ next_eip < afl_end_code) -+ gen_helper_afl_cmplog_rtn(cpu_env); - tcg_gen_movi_tl(s->T1, next_eip); - gen_push_v(s, s->T1); - gen_op_jmp_v(s->T0); -@@ -6544,6 +6554,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - tval = (int16_t)insn_get(env, s, MO_16); - } - next_eip = s->pc - s->cs_base; -+ if (__afl_cmp_map && next_eip >= afl_start_code && -+ next_eip < afl_end_code) -+ gen_helper_afl_cmplog_rtn(cpu_env); - tval += next_eip; - if (dflag == MO_16) { - tval &= 0xffff; diff --git a/qemu_mode/patches/make_strncpy_safe.diff b/qemu_mode/patches/make_strncpy_safe.diff deleted file mode 100644 index 38c7d248..00000000 --- a/qemu_mode/patches/make_strncpy_safe.diff +++ /dev/null @@ -1,31 +0,0 @@ ---- a/util/qemu-sockets.c 2020-03-28 13:55:09.511029429 +0100 -+++ b/util/qemu-sockets.c 2020-03-28 14:01:12.147693937 +0100 -@@ -877,7 +877,7 @@ - - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; -- strncpy(un.sun_path, path, sizeof(un.sun_path)); -+ strncpy(un.sun_path, path, sizeof(un.sun_path) - 1); - - if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { - error_setg_errno(errp, errno, "Failed to bind socket to %s", path); -@@ -922,7 +922,7 @@ - - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; -- strncpy(un.sun_path, saddr->path, sizeof(un.sun_path)); -+ strncpy(un.sun_path, saddr->path, sizeof(un.sun_path) - 1); - - /* connect to peer */ - do { ---- a/block/sheepdog.c 2020-03-28 14:01:57.164360270 +0100 -+++ b/block/sheepdog.c 2020-03-28 14:02:52.781026597 +0100 -@@ -1236,7 +1236,7 @@ - * don't want the send_req to read uninitialized data. - */ - strncpy(buf, filename, SD_MAX_VDI_LEN); -- strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); -+ strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN - 1); - - memset(&hdr, 0, sizeof(hdr)); - if (lock) { diff --git a/qemu_mode/patches/mips-fpu.diff b/qemu_mode/patches/mips-fpu.diff deleted file mode 100644 index 646d167e..00000000 --- a/qemu_mode/patches/mips-fpu.diff +++ /dev/null @@ -1,15 +0,0 @@ ---- a/linux-user/elfload.c 2020-07-13 20:10:37.776374566 -0700 -+++ b/linux-user/elfload.c 2020-07-13 20:11:51.794957015 -0700 -@@ -2667,6 +2667,11 @@ - char *elf_interpreter = NULL; - char *scratch; - -+ memset(&interp_info, 0, sizeof(interp_info)); -+#ifdef TARGET_MIPS -+ interp_info.fp_abi = MIPS_ABI_FP_UNKNOWN; -+#endif -+ - info->start_mmap = (abi_ulong)ELF_START_MMAP; - - load_elf_image(bprm->filename, bprm->fd, info, - diff --git a/qemu_mode/patches/mmap_fixes.diff b/qemu_mode/patches/mmap_fixes.diff deleted file mode 100644 index 1882bd40..00000000 --- a/qemu_mode/patches/mmap_fixes.diff +++ /dev/null @@ -1,165 +0,0 @@ -diff --git a/exec.c b/exec.c -index df5571e..d484098 100644 ---- a/exec.c -+++ b/exec.c -@@ -2457,7 +2457,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) - area = mmap(vaddr, length, PROT_READ | PROT_WRITE, - flags, -1, 0); - } -- if (area != vaddr) { -+ if (area == MAP_FAILED || area != vaddr) { - error_report("Could not remap addr: " - RAM_ADDR_FMT "@" RAM_ADDR_FMT "", - length, addr); -diff --git a/linux-user/mmap.c b/linux-user/mmap.c -index 41e0983..0a8b8e5 100644 ---- a/linux-user/mmap.c -+++ b/linux-user/mmap.c -@@ -612,9 +612,13 @@ static void mmap_reserve(abi_ulong start, abi_ulong size) - real_end -= qemu_host_page_size; - } - if (real_start != real_end) { -- mmap(g2h(real_start), real_end - real_start, PROT_NONE, -+ void *p = mmap(g2h(real_start), real_end - real_start, PROT_NONE, - MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, - -1, 0); -+ if (p == MAP_FAILED) { -+ perror("mmap_reserve: cannot mmap"); -+ exit(-1); -+ } - } - } - -diff --git a/roms/SLOF/tools/sloffs.c b/roms/SLOF/tools/sloffs.c -index 9a1eace..10366f0 100644 ---- a/roms/SLOF/tools/sloffs.c -+++ b/roms/SLOF/tools/sloffs.c -@@ -308,6 +308,10 @@ sloffs_append(const int file, const char *name, const char *dest) - - fstat(fd, &stat); - append = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); -+ if (append == MAP_FAILED) { -+ perror("sloffs_append: cannot mmap for read"); -+ exit(1); -+ } - header = sloffs_header(file); - - if (!header) -@@ -331,6 +335,10 @@ sloffs_append(const int file, const char *name, const char *dest) - write(out, "", 1); - write_start = mmap(NULL, new_len, PROT_READ | PROT_WRITE, - MAP_SHARED, out, 0); -+ if (write_start == MAP_FAILED) { -+ perror("sloffs_append: cannot mmap for read/write"); -+ exit(1); -+ } - - memset(write_start, 0, new_len); - memset(&new_file, 0, sizeof(struct sloffs)); -diff --git a/roms/skiboot/core/test/run-trace.c b/roms/skiboot/core/test/run-trace.c -index 9801688..236b51d 100644 ---- a/roms/skiboot/core/test/run-trace.c -+++ b/roms/skiboot/core/test/run-trace.c -@@ -178,6 +178,10 @@ static void test_parallel(void) - i = (CPUS*len + getpagesize()-1)&~(getpagesize()-1); - p = mmap(NULL, i, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_SHARED, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("test_parallel: cannot mmap"); -+ exit(-1); -+ } - - for (i = 0; i < CPUS; i++) { - fake_cpus[i].trace = p + i * len; -diff --git a/roms/skiboot/external/ffspart/ffspart.c b/roms/skiboot/external/ffspart/ffspart.c -index 7703477..efbbd5b 100644 ---- a/roms/skiboot/external/ffspart/ffspart.c -+++ b/roms/skiboot/external/ffspart/ffspart.c -@@ -379,7 +379,7 @@ int main(int argc, char *argv[]) - } - - data_ptr = mmap(NULL, pactual, PROT_READ, MAP_SHARED, data_fd, 0); -- if (!data_ptr) { -+ if (data_ptr == MAP_FAILED) { - fprintf(stderr, "Couldn't mmap data file for partition '%s': %s\n", - name, strerror(errno)); - rc = -1; -diff --git a/roms/skiboot/extract-gcov.c b/roms/skiboot/extract-gcov.c -index 3d31d1b..ebc03e6 100644 ---- a/roms/skiboot/extract-gcov.c -+++ b/roms/skiboot/extract-gcov.c -@@ -229,7 +229,11 @@ int main(int argc, char *argv[]) - } - - addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); -- assert(addr != NULL); -+ assert(addr != MAP_FAILED); -+ if (addr == MAP_FAILED) { -+ perror("main: cannot mmap"); -+ exit(-1); -+ } - skiboot_dump_size = sb.st_size; - - printf("Skiboot memory dump %p - %p\n", -diff --git a/roms/skiboot/libstb/create-container.c b/roms/skiboot/libstb/create-container.c -index 5cf80a0..64699ad 100644 ---- a/roms/skiboot/libstb/create-container.c -+++ b/roms/skiboot/libstb/create-container.c -@@ -96,7 +96,11 @@ void getSigRaw(ecc_signature_t *sigraw, char *inFile) - assert(r==0); - - infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0); -- assert(infile); -+ assert(infile != MAP_FAILED); -+ if (infile == MAP_FAILED) { -+ perror("getSigRaw: cannot mmap"); -+ exit(-1); -+ } - - signature = d2i_ECDSA_SIG(NULL, (const unsigned char **) &infile, 7 + 2*EC_COORDBYTES); - -@@ -356,7 +360,11 @@ int main(int argc, char* argv[]) - r = fstat(fdin, &s); - assert(r==0); - infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0); -- assert(infile); -+ assert(infile != MAP_FAILED); -+ if (infile == MAP_FAILED) { -+ perror("main: cannot mmap"); -+ exit(-1); -+ } - fdout = open(params.imagefn, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - assert(fdout > 0); - -diff --git a/tests/tcg/multiarch/test-mmap.c b/tests/tcg/multiarch/test-mmap.c -index 11d0e77..14f5919 100644 ---- a/tests/tcg/multiarch/test-mmap.c -+++ b/tests/tcg/multiarch/test-mmap.c -@@ -203,6 +203,7 @@ void check_aligned_anonymous_fixed_mmaps(void) - p1 = mmap(addr, pagesize, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); -+ fail_unless (p1 != MAP_FAILED); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; -@@ -234,6 +235,7 @@ void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) - p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); -+ fail_unless (p1 != MAP_FAILED); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; -@@ -401,6 +403,10 @@ void check_file_fixed_mmaps(void) - p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, pagesize * 3); -+ fail_unless (p1 != MAP_FAILED); -+ fail_unless (p2 != MAP_FAILED); -+ fail_unless (p3 != MAP_FAILED); -+ fail_unless (p4 != MAP_FAILED); - - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - diff --git a/qemu_mode/patches/softfloat.diff b/qemu_mode/patches/softfloat.diff deleted file mode 100644 index 86ffb97f..00000000 --- a/qemu_mode/patches/softfloat.diff +++ /dev/null @@ -1,10 +0,0 @@ -diff --git a/fpu/softfloat.c b/fpu/softfloat.c -index e1eef954..2f8d0d62 100644 ---- a/fpu/softfloat.c -+++ b/fpu/softfloat.c -@@ -7205,3 +7205,5 @@ float128 float128_scalbn(float128 a, int n, float_status *status) - , status); - - } -+ -+#include "../../patches/afl-qemu-floats.h" diff --git a/qemu_mode/patches/syscall.diff b/qemu_mode/patches/syscall.diff deleted file mode 100644 index b635a846..00000000 --- a/qemu_mode/patches/syscall.diff +++ /dev/null @@ -1,102 +0,0 @@ -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index b13a170e..3f5cc902 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -111,6 +111,9 @@ - - #include "qemu.h" - #include "fd-trans.h" -+#include <linux/sockios.h> -+ -+extern unsigned int afl_forksrv_pid; - - #ifndef CLONE_IO - #define CLONE_IO 0x80000000 /* Clone io context */ -@@ -250,7 +253,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ - #endif - - #ifdef __NR_gettid --_syscall0(int, gettid) -+#define __NR_sys_gettid __NR_gettid -+_syscall0(int, sys_gettid) - #else - /* This is a replacement for the host gettid() and must return a host - errno. */ -@@ -5384,7 +5388,7 @@ static void *clone_func(void *arg) - cpu = ENV_GET_CPU(env); - thread_cpu = cpu; - ts = (TaskState *)cpu->opaque; -- info->tid = gettid(); -+ info->tid = sys_gettid(); - task_settid(ts); - if (info->child_tidptr) - put_user_u32(info->tid, info->child_tidptr); -@@ -5529,9 +5533,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, - mapping. We can't repeat the spinlock hack used above because - the child process gets its own copy of the lock. */ - if (flags & CLONE_CHILD_SETTID) -- put_user_u32(gettid(), child_tidptr); -+ put_user_u32(sys_gettid(), child_tidptr); - if (flags & CLONE_PARENT_SETTID) -- put_user_u32(gettid(), parent_tidptr); -+ put_user_u32(sys_gettid(), parent_tidptr); - ts = (TaskState *)cpu->opaque; - if (flags & CLONE_SETTLS) - cpu_set_tls (env, newtls); -@@ -6554,7 +6558,8 @@ static int open_self_cmdline(void *cpu_env, int fd) - return 0; - } - --static int open_self_maps(void *cpu_env, int fd) -+int open_self_maps(void *cpu_env, int fd); -+int open_self_maps(void *cpu_env, int fd) - { - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - TaskState *ts = cpu->opaque; -@@ -7324,10 +7329,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - #ifdef TARGET_NR_stime /* not on alpha */ - case TARGET_NR_stime: - { -- time_t host_time; -- if (get_user_sal(host_time, arg1)) -+ struct timespec ts; -+ ts.tv_nsec = 0; -+ if (get_user_sal(ts.tv_sec, arg1)) { - return -TARGET_EFAULT; -- return get_errno(stime(&host_time)); -+ } -+ return get_errno(clock_settime(CLOCK_REALTIME, &ts)); - } - #endif - #ifdef TARGET_NR_alarm /* not on alpha */ -@@ -10529,7 +10536,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - return TARGET_PAGE_SIZE; - #endif - case TARGET_NR_gettid: -- return get_errno(gettid()); -+ return get_errno(sys_gettid()); - #ifdef TARGET_NR_readahead - case TARGET_NR_readahead: - #if TARGET_ABI_BITS == 32 -@@ -10813,8 +10820,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2))); - - case TARGET_NR_tgkill: -- return get_errno(safe_tgkill((int)arg1, (int)arg2, -- target_to_host_signal(arg3))); -+ { -+ int pid = (int)arg1, -+ tgid = (int)arg2, -+ sig = (int)arg3; -+ -+ /* Not entirely sure if the below is correct for all architectures. */ -+ -+ if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT) -+ pid = tgid = getpid(); -+ -+ ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig))); -+ -+ } - - #ifdef TARGET_NR_set_robust_list - case TARGET_NR_set_robust_list: diff --git a/qemu_mode/patches/tcg-runtime-head.diff b/qemu_mode/patches/tcg-runtime-head.diff deleted file mode 100644 index f250686e..00000000 --- a/qemu_mode/patches/tcg-runtime-head.diff +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h -index 1bd39d13..81ef3973 100644 ---- a/accel/tcg/tcg-runtime.h -+++ b/accel/tcg/tcg-runtime.h -@@ -260,3 +260,14 @@ DEF_HELPER_FLAGS_4(gvec_leu8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) -+ -+DEF_HELPER_FLAGS_1(afl_entry_routine, TCG_CALL_NO_RWG, void, env) -+DEF_HELPER_FLAGS_1(afl_maybe_log, TCG_CALL_NO_RWG, void, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_16, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_32, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_64, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_8, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_16, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_32, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_64, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_1(afl_cmplog_rtn, TCG_CALL_NO_RWG, void, env) diff --git a/qemu_mode/patches/tcg-runtime.diff b/qemu_mode/patches/tcg-runtime.diff deleted file mode 100644 index 15456320..00000000 --- a/qemu_mode/patches/tcg-runtime.diff +++ /dev/null @@ -1,10 +0,0 @@ -diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c -index d0d44844..009ef15a 100644 ---- a/accel/tcg/tcg-runtime.c -+++ b/accel/tcg/tcg-runtime.c -@@ -167,3 +167,5 @@ void HELPER(exit_atomic)(CPUArchState *env) - { - cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); - } -+ -+#include "../../../patches/afl-qemu-tcg-runtime-inl.h" diff --git a/qemu_mode/patches/tcg.diff b/qemu_mode/patches/tcg.diff deleted file mode 100644 index 0aea5afb..00000000 --- a/qemu_mode/patches/tcg.diff +++ /dev/null @@ -1,14 +0,0 @@ -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,9 @@ bool tcg_op_supported(TCGOpcode op) - } - } - -+ -+#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 - and endian swap in tcg_reg_alloc_call(). */ diff --git a/qemu_mode/patches/translate-all.diff b/qemu_mode/patches/translate-all.diff deleted file mode 100644 index ca310b11..00000000 --- a/qemu_mode/patches/translate-all.diff +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c -index 639f0b27..21a45494 100644 ---- a/accel/tcg/translate-all.c -+++ b/accel/tcg/translate-all.c -@@ -59,6 +59,8 @@ - #include "exec/log.h" - #include "sysemu/cpus.h" - -+#include "../patches/afl-qemu-translate-inl.h" -+ - /* #define DEBUG_TB_INVALIDATE */ - /* #define DEBUG_TB_FLUSH */ - /* make various TB consistency checks */ -@@ -1721,6 +1723,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, - tcg_func_start(tcg_ctx); - - tcg_ctx->cpu = ENV_GET_CPU(env); -+ afl_gen_trace(pc); - gen_intermediate_code(cpu, tb); - tcg_ctx->cpu = NULL; - diff --git a/qemu_mode/patches/translator.diff b/qemu_mode/patches/translator.diff deleted file mode 100644 index 842e861d..00000000 --- a/qemu_mode/patches/translator.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c -index afd0a49e..773ea712 100644 ---- a/accel/tcg/translator.c -+++ b/accel/tcg/translator.c -@@ -18,6 +18,8 @@ - #include "exec/log.h" - #include "exec/translator.h" - -+#include "../../../patches/afl-qemu-common.h" -+ - /* Pairs with tcg_clear_temp_count. - To be called by #TranslatorOps.{translate_insn,tb_stop} if - (1) the target is sufficiently clean to support reporting, -@@ -92,6 +94,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, - break; - } - } -+ -+ if (db->pc_next == afl_entry_point) { -+ afl_setup(); -+ gen_helper_afl_entry_routine(cpu_env); -+ } - - /* Disassemble one instruction. The translate_insn hook should - update db->pc_next and db->is_jmp to indicate what should be diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl new file mode 160000 +Subproject 21ff34383764a8c6f66509b3b8d5282468c721e diff --git a/qemu_mode/update_ref.sh b/qemu_mode/update_ref.sh new file mode 100755 index 00000000..13be376f --- /dev/null +++ b/qemu_mode/update_ref.sh @@ -0,0 +1,47 @@ +#/bin/sh + +################################################## +# AFL++ internal tool to update qemuafl ref. +# Usage: ./update_ref.sh <new commit hash> +# If no commit hash was provided, it'll take HEAD. +################################################## + +UC_VERSION_FILE='./QEMUAFL_VERSION' + +NEW_VERSION="$1" + +if [ "$NEW_VERSION" = "-h" ]; then + echo "Internal script to update bound qemuafl version." + echo + echo "Usage: ./update_ref.sh <new commit hash>" + echo "If no commit hash is provided, will use HEAD." + echo "-h to show this help screen." + exit 1 +fi + +git submodule init && git submodule update || exit 1 +cd ./qemuafl || exit 1 +git fetch origin master 1>/dev/null || exit 1 +git stash 1>/dev/null 2>/dev/null +git stash drop 1>/dev/null 2>/dev/null +git checkout master +git pull origin master 1>/dev/null || exit 1 + +if [ -z "$NEW_VERSION" ]; then + # No version provided, take HEAD. + NEW_VERSION=$(git rev-parse --short HEAD) +fi + +if [ -z "$NEW_VERSION" ]; then + echo "Error getting version." + exit 1 +fi + +git checkout "$NEW_VERSION" || exit 1 + +cd .. + +rm "$UC_VERSION_FILE" +echo "$NEW_VERSION" > "$UC_VERSION_FILE" + +echo "Done. New qemuafl version is $NEW_VERSION." |