about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile2
-rw-r--r--GNUmakefile.llvm9
-rw-r--r--docs/docs2.md124
-rw-r--r--docs/env_variables.md7
-rw-r--r--frida_mode/test/bloaty/GNUmakefile114
-rw-r--r--frida_mode/test/bloaty/Makefile13
-rwxr-xr-xfrida_mode/test/bloaty/get_symbol_addr.py36
-rw-r--r--instrumentation/README.cmplog.md20
-rw-r--r--instrumentation/README.ctx.md38
-rw-r--r--instrumentation/README.gcc_plugin.md172
-rw-r--r--instrumentation/README.instrument_list.md109
-rw-r--r--instrumentation/README.laf-intel.md66
-rw-r--r--instrumentation/README.llvm.md229
-rw-r--r--instrumentation/README.lto.md322
-rw-r--r--instrumentation/README.neverzero.md41
-rw-r--r--instrumentation/README.ngram.md28
-rw-r--r--instrumentation/README.out_of_line.md19
-rw-r--r--instrumentation/README.persistent_mode.md114
-rw-r--r--instrumentation/README.snapshot.md18
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc18
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc16
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc1119
-rw-r--r--instrumentation/afl-llvm-pass.so.cc70
-rw-r--r--instrumentation/compare-transform-pass.so.cc87
-rw-r--r--instrumentation/split-compares-pass.so.cc97
-rw-r--r--instrumentation/split-switches-pass.so.cc73
-rw-r--r--src/afl-cc.c43
-rw-r--r--src/afl-fuzz-mutators.c3
28 files changed, 883 insertions, 2124 deletions
diff --git a/Dockerfile b/Dockerfile
index 18fb6367..a3c70746 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -16,6 +16,8 @@ env NO_ARCH_OPT 1
 RUN apt-get update && \
     apt-get -y install --no-install-suggests --no-install-recommends \
     automake \
+    cmake \
+    meson \
     ninja-build \
     bison flex \
     build-essential \
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 64e5beb2..1e2c411d 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -308,7 +308,7 @@ ifeq "$(TEST_MMAP)" "1"
 endif
 
 PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o 
-PROGS        = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./cmplog-switches-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./afl-llvm-lto-instrumentation.so ./SanitizerCoverageLTO.so
+PROGS        = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./cmplog-switches-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./SanitizerCoverageLTO.so
 
 # If prerequisites are not given, warn, do not build anything, and exit with code 0
 ifeq "$(LLVMVER)" ""
@@ -410,11 +410,6 @@ endif
 ./SanitizerCoverageLTO.so: instrumentation/SanitizerCoverageLTO.so.cc
 ifeq "$(LLVM_LTO)" "1"
 	$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
-endif
-
-./afl-llvm-lto-instrumentation.so: instrumentation/afl-llvm-lto-instrumentation.so.cc instrumentation/afl-llvm-common.o
-ifeq "$(LLVM_LTO)" "1"
-	$(CXX) $(CLANG_CPPFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
 	$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto.o
 	@$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m64 -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto-64.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
 	@$(CLANG_BIN) $(CFLAGS_SAFE) $(CPPFLAGS) -Wno-unused-result -O0 $(AFL_CLANG_FLTO) -m32 -fPIC -c instrumentation/afl-llvm-rt-lto.o.c -o ./afl-llvm-rt-lto-32.o 2>/dev/null; if [ "$$?" = "0" ]; then : ; fi
@@ -480,7 +475,7 @@ install: all
 	@if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi
 	@rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt*.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt*.o
 	@if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o ;fi
-	@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-lto-instrumentation.so ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
+	@if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi
 	@if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi
 	@if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o ;fi
 	@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o ; fi
diff --git a/docs/docs2.md b/docs/docs2.md
new file mode 100644
index 00000000..23ef61c5
--- /dev/null
+++ b/docs/docs2.md
@@ -0,0 +1,124 @@
+# Restructure AFL++'s documentation - Case Study
+
+## Problem statement
+
+AFL++ inherited it's documentation from the original Google AFL project.
+Since then it has been massively improved - feature and performance wise -
+and although the documenation has likewise been continued it has grown out
+of proportion.
+The documentation is done by non-natives to the English language, plus
+none of us has a writer background.
+
+We see questions on AFL++ usage on mailing lists (e.g. afl-users), discord
+channels, web forums and as issues in our repository.
+Most of them could be answered if people would read through all the
+documentation.
+
+This only increases as AFL++ has been on the top of Google's fuzzbench
+statistics (which measures the performance of fuzzers) and has been
+integrated in Google's oss-fuzz and clusterfuzz - and is in many Unix
+packaging repositories, e.g. Debian, FreeBSD, etc.
+
+AFL++ had 44 (!) documentation files with 13k total lines of content.
+This was way too much.
+
+## Proposal abstract
+
+AFL++'s documentatin needs a complete overhaul, both on a
+organisation/structural level as well as the content.
+
+Overall the following actions have to be performed:
+  * Create a better structure of documentation so it is easier to find the
+    information that is being looked for, combining and/or splitting up the
+    existing documents as needed.
+  * Rewrite some documentation to remove duplication. Several information is
+    present several times in the documentation. These should be removed to
+    where needed so that we have as little bloat as possible.
+  * The documents have been written and modified by a lot of different people,
+    most of them non-native English speaker. Hence an overall review where
+    parts should be rewritten has to be performed and then the rewrite done.
+  * Create a cheat-sheet for a very short best-setup build and run of AFL++
+  * Pictures explain more than 1000 words. We need at least 4 images that
+    explain the workflow with AFL++:
+      - the build workflow
+      - the fuzzing workflow
+      - the fuzzing campaign management workflow
+      - the overall workflow that is an overview of the above
+      - maybe more? where the technical writes seems it necessary for
+        understanding.
+
+Requirements:
+  * Documentation has to be in Markdown format
+  * Images have to be either in SVG or PNG format.
+  * All documentation should be (moved) in(to) docs/
+
+## Project description
+
+We created our proposal by discussing in the team what the issues are and
+what was needed to fix it.
+This resulted in the [project proposal](https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/docs.md).
+
+We did not want to be selected by a writer but select a writer ourselves, so
+we combed through the list and reviewed every single one of them.
+We were not looking for coders writing technical documentation, but rather
+someone who is an experienced writer and has documented experience with
+structuring documentation.
+Few fit that profile and we sent out messages to 6 people.
+We finally decided on Jana because she had a strong background in technical
+documentation and structuring information.
+She had no technical experience in fuzzing whatsoever, but we saw that as
+a plus - of course this made the whole process longer to explain details,
+but overall ensured that the documentation can be read by (mostly) everyone.
+
+We communicated via video calls every few weeks and she kept a public kanban
+board about her todos, additional we used a Signal channel.
+Her changes were imported via PRs where we discussed details.
+
+The project was off to a good start, but then Jana got pregnant with serious
+side effects that made working impossible for her for a longer time, hence
+the schedule was thrown back.
+She offered to rescind the payment and we select a new writer, but we saw
+little opportunity in that, as that would mean a new selection of a writer,
+someone else with a different vision on how the result should look like so
+basically a full restart of the project and a large impact on our own time.
+So we agreed on - after discussion with the Google GSoD team - that she
+continues the project after the GSoD completion deadline as best as she can.
+
+End of November she took one week off from work and fully dedicated her time
+for the documenation which brought the project a big step forward.
+
+Originally the project should have been ended begin of October, but now - at
+nearing the end of November, we are at about 85% completion, with the end
+being expected around mid of December.
+
+## Metrics
+
+We merged most of the changes in our development branch and are getting 
+close to a state where the user documentation part is completed and we
+can create a new release. Only then the new documentatin is actually visible
+to users. Therefore no metrics could be collected so far.
+
+We plan on a user-assisted QA review end of November/begin of December.
+
+The documentation was reviewed by a few test users so far however who gave
+it a thumbs up.
+
+## Summary
+
+The GSoD project itself is great. It helps to get the documentation back in
+line.
+It was and is a larger time investment from our side, but we expected that.
+When the project is done, the documentation will be more accessible by users
+and also need less maintenance by us.
+There is still follow-up work to be done by us afterwards (web site for the
+docs, etc.).
+
+Not sure what we would do differently next time. I think we prepared best as
+possible and reacted best as possible to the unexpected.
+
+Recommendations for other organizations who would like to participate in GSoD:
+ - expect the process to take a larger part of your time. the writer needs
+   your full support.
+ - have someone dedicated from the dev/org side to support, educate and
+   supervice the writer
+ - set clear goals and expectations
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 2a004235..cce9ff56 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -171,7 +171,7 @@ config.h to at least 18 and maybe up to 20 for this as otherwise too many map
 collisions occur.
 
 For more information, see
-[instrumentation/README.ctx.md](../instrumentation/README.ctx.md).
+[instrumentation/README.llvm.md#6) AFL++ Context Sensitive Branch Coverage](../instrumentation/README.llvm.md#6-afl-context-sensitive-branch-coverage).
 
 #### INSTRUMENT LIST (selectively instrument files and functions)
 
@@ -247,7 +247,7 @@ in config.h to at least 18 and maybe up to 20 for this as otherwise too many map
 collisions occur.
 
 For more information, see
-[instrumentation/README.ngram.md](../instrumentation/README.ngram.md).
+[instrumentation/README.llvm.md#7) AFL++ N-Gram Branch Coverage](../instrumentation/README.llvm.md#7-afl-n-gram-branch-coverage).
 
 #### NOT_ZERO
 
@@ -261,9 +261,6 @@ For more information, see
     If the target performs only a few loops, then this will give a small
     performance boost.
 
-For more information, see
-[instrumentation/README.neverzero.md](../instrumentation/README.neverzero.md).
-
 #### Thread safe instrumentation counters (in all modes)
 
 Setting `AFL_LLVM_THREADSAFE_INST` will inject code that implements thread safe
diff --git a/frida_mode/test/bloaty/GNUmakefile b/frida_mode/test/bloaty/GNUmakefile
new file mode 100644
index 00000000..7ef4fe81
--- /dev/null
+++ b/frida_mode/test/bloaty/GNUmakefile
@@ -0,0 +1,114 @@
+PWD:=$(shell pwd)/
+ROOT:=$(PWD)../../../
+BUILD_DIR:=$(PWD)build/
+
+AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
+AFLPP_QEMU_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/qemu_hook.so
+
+# LIBFUZZER_LIB:=/usr/lib/llvm-12/lib/libFuzzer.a
+
+BLOATY_GIT_REPO:=https://github.com/google/bloaty.git
+BLOATY_DIR:=$(BUILD_DIR)bloaty/
+TEST_BIN:=$(BLOATY_DIR)fuzz_target
+
+ifeq "$(shell uname)" "Darwin"
+TEST_BIN_LDFLAGS:=-undefined dynamic_lookup -Wl,-no_pie
+endif
+
+TEST_DATA_DIR:=$(BUILD_DIR)in/
+TEST_DATA_SRC:=$(BLOATY_DIR)tests/testdata/fuzz_corpus/
+DUMMY_DATA_FILE:=$(BUILD_DIR)default_seed
+
+FRIDA_OUT:=$(BUILD_DIR)frida-out
+QEMU_OUT:=$(BUILD_DIR)qemu-out
+
+ifndef ARCH
+
+ARCH=$(shell uname -m)
+ifeq "$(ARCH)" "aarch64"
+ ARCH:=arm64
+endif
+
+ifeq "$(ARCH)" "i686"
+ ARCH:=x86
+endif
+endif
+
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+
+AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
+
+ifeq "$(ARCH)" "aarch64"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
+endif
+
+ifeq "$(ARCH)" "x86_64"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
+endif
+
+ifeq "$(ARCH)" "x86"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
+endif
+
+.PHONY: all clean frida hook
+
+all: $(TEST_BIN)
+	make -C $(ROOT)frida_mode/
+
+32:
+	CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
+
+$(BUILD_DIR):
+	mkdir -p $@
+
+########## BLOATY #######
+
+$(BLOATY_DIR): | $(BUILD_DIR)
+	git clone --depth 1 $(BLOATY_GIT_REPO) $@
+
+$(TEST_BIN): $(BLOATY_DIR)
+	cd $(BLOATY_DIR) && CC=clang CXX=clang++ CCC=clang++ LIB_FUZZING_ENGINE="-fsanitize=fuzzer" cmake -G Ninja -DBUILD_TESTING=false $(BLOATY_DIR)
+	cd $(BLOATY_DIR) && CC=clang CXX=clang++ CCC=clang++ ninja -j $(shell nproc)
+
+########## DUMMY #######
+
+$(TEST_DATA_DIR): | $(BLOATY_DIR) $(BUILD_DIR)
+	cp -av $(TEST_DATA_SRC) $@
+
+$(DUMMY_DATA_FILE): | $(TEST_DATA_DIR)
+	dd if=/dev/zero bs=1048576 count=1 of=$@
+
+###### TEST DATA #######
+
+clean:
+	rm -rf $(BUILD_DIR)
+
+frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE)
+	AFL_FRIDA_PERSISTENT_CNT=1000000 \
+	AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
+	AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
+	AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
+	$(ROOT)afl-fuzz \
+		-i $(TEST_DATA_DIR) \
+		-o $(FRIDA_OUT) \
+		-m none \
+		-d \
+		-O \
+		-V 30 \
+		-- \
+			$(TEST_BIN) $(DUMMY_DATA_FILE)
+
+qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE) $(DUMMY_DATA_FILE)
+	AFL_QEMU_PERSISTENT_CNT=1000000 \
+	AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \
+	AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
+	AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \
+	$(ROOT)afl-fuzz \
+		-i $(TEST_DATA_DIR) \
+		-o $(QEMU_OUT) \
+		-m none \
+		-d \
+		-Q \
+		-V 30 \
+		-- \
+			$(TEST_BIN) $(DUMMY_DATA_FILE)
diff --git a/frida_mode/test/bloaty/Makefile b/frida_mode/test/bloaty/Makefile
new file mode 100644
index 00000000..07b139e9
--- /dev/null
+++ b/frida_mode/test/bloaty/Makefile
@@ -0,0 +1,13 @@
+all:
+	@echo trying to use GNU make...
+	@gmake all || echo please install GNUmake
+
+32:
+	@echo trying to use GNU make...
+	@gmake 32 || echo please install GNUmake
+
+clean:
+	@gmake clean
+
+frida:
+	@gmake frida
diff --git a/frida_mode/test/bloaty/get_symbol_addr.py b/frida_mode/test/bloaty/get_symbol_addr.py
new file mode 100755
index 00000000..1c46e010
--- /dev/null
+++ b/frida_mode/test/bloaty/get_symbol_addr.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+import argparse
+from elftools.elf.elffile import ELFFile
+
+def process_file(file, symbol, base):
+    with open(file, 'rb') as f:
+        elf = ELFFile(f)
+        symtab = elf.get_section_by_name('.symtab')
+        mains = symtab.get_symbol_by_name(symbol)
+        if len(mains) != 1:
+            print ("Failed to find main")
+            return 1
+
+        main_addr = mains[0]['st_value']
+        main = base + main_addr
+        print ("0x%016x" % main)
+        return 0
+
+def hex_value(x):
+    return int(x, 16)
+
+def main():
+    parser = argparse.ArgumentParser(description='Process some integers.')
+    parser.add_argument('-f', '--file', dest='file', type=str,
+                    help='elf file name', required=True)
+    parser.add_argument('-s', '--symbol', dest='symbol', type=str,
+                    help='symbol name', required=True)
+    parser.add_argument('-b', '--base', dest='base', type=hex_value,
+                    help='elf base address', required=True)
+
+    args = parser.parse_args()
+    return process_file (args.file, args.symbol, args.base)
+
+if __name__ == "__main__":
+    ret = main()
+    exit(ret)
diff --git a/instrumentation/README.cmplog.md b/instrumentation/README.cmplog.md
index a796c7a7..146b4620 100644
--- a/instrumentation/README.cmplog.md
+++ b/instrumentation/README.cmplog.md
@@ -1,11 +1,12 @@
 # CmpLog instrumentation
 
-The CmpLog instrumentation enables logging of comparison operands in a
-shared memory.
+The CmpLog instrumentation enables logging of comparison operands in a shared
+memory.
 
-These values can be used by various mutators built on top of it.
-At the moment we support the RedQueen mutator (input-2-state instructions only), 
-for details see [the RedQueen paper](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf).
+These values can be used by various mutators built on top of it. At the moment,
+we support the RedQueen mutator (input-2-state instructions only), for details
+see
+[the RedQueen paper](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf).
 
 ## Build
 
@@ -14,7 +15,8 @@ program.
 
 The first version is built using the regular AFL++ instrumentation.
 
-The second one, the CmpLog binary, is built with setting AFL_LLVM_CMPLOG during the compilation.
+The second one, the CmpLog binary, is built with setting AFL_LLVM_CMPLOG during
+the compilation.
 
 For example:
 
@@ -32,8 +34,8 @@ unset AFL_LLVM_CMPLOG
 
 ## Use
 
-AFL++ has the new `-c` option that needs to be used to specify the CmpLog binary (the second
-build).
+AFL++ has the new `-c` option that needs to be used to specify the CmpLog binary
+(the second build).
 
 For example:
 
@@ -41,4 +43,4 @@ For example:
 afl-fuzz -i input -o output -c ./program.cmplog -m none -- ./program.afl @@
 ```
 
-Be sure to use `-m none` because CmpLog can map a lot of pages.
+Be sure to use `-m none` because CmpLog can map a lot of pages.
\ No newline at end of file
diff --git a/instrumentation/README.ctx.md b/instrumentation/README.ctx.md
deleted file mode 100644
index 335e9921..00000000
--- a/instrumentation/README.ctx.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# AFL Context Sensitive Branch Coverage
-
-## What is this?
-
-This is an LLVM-based implementation of the context sensitive branch coverage.
-
-Basically every function gets its own ID and, every time when an edge is logged,
-all the IDs in the callstack are hashed and combined with the edge transition
-hash to augment the classic edge coverage with the information about the
-calling context.
-
-So if both function A and function B call a function C, the coverage
-collected in C will be different.
-
-In math the coverage is collected as follows:
-`map[current_location_ID ^ previous_location_ID >> 1 ^ hash_callstack_IDs] += 1`
-
-The callstack hash is produced XOR-ing the function IDs to avoid explosion with
-recursive functions.
-
-## Usage
-
-Set the `AFL_LLVM_INSTRUMENT=CTX` or `AFL_LLVM_CTX=1` environment variable.
-
-It is highly recommended to increase the MAP_SIZE_POW2 definition in
-config.h to at least 18 and maybe up to 20 for this as otherwise too
-many map collisions occur.
-
-## Caller Branch Coverage
-
-If the context sensitive coverage introduces too may collisions and becoming
-detrimental, the user can choose to augment edge coverage with just the
-called function ID, instead of the entire callstack hash.
-
-In math the coverage is collected as follows:
-`map[current_location_ID ^ previous_location_ID >> 1 ^ previous_callee_ID] += 1`
-
-Set the `AFL_LLVM_INSTRUMENT=CALLER` or `AFL_LLVM_CALLER=1` environment variable.
diff --git a/instrumentation/README.gcc_plugin.md b/instrumentation/README.gcc_plugin.md
index 230ceb73..f251415b 100644
--- a/instrumentation/README.gcc_plugin.md
+++ b/instrumentation/README.gcc_plugin.md
@@ -1,64 +1,68 @@
 # GCC-based instrumentation for afl-fuzz
 
-See [../README.md](../README.md) for the general instruction manual.
-See [README.llvm.md](README.llvm.md) for the LLVM-based instrumentation.
+For the general instruction manual, see [../README.md](../README.md).
+For the LLVM-based instrumentation, see [README.llvm.md](README.llvm.md).
 
 This document describes how to build and use `afl-gcc-fast` and `afl-g++-fast`,
 which instrument the target with the help of gcc plugins.
 
-TLDR:
-  * check the version of your gcc compiler: `gcc --version`
-  * `apt-get install gcc-VERSION-plugin-dev` or similar to install headers for gcc plugins
-  * `gcc` and `g++` must match the gcc-VERSION you installed headers for. You can set `AFL_CC`/`AFL_CXX`
-    to point to these!
-  * `make`
-  * just use `afl-gcc-fast`/`afl-g++-fast` normally like you would do with `afl-clang-fast`
+TL;DR:
+* Check the version of your gcc compiler: `gcc --version`
+* `apt-get install gcc-VERSION-plugin-dev` or similar to install headers for gcc
+  plugins.
+* `gcc` and `g++` must match the gcc-VERSION you installed headers for. You can
+  set `AFL_CC`/`AFL_CXX` to point to these!
+* `make`
+* Just use `afl-gcc-fast`/`afl-g++-fast` normally like you would do with
+  `afl-clang-fast`.
 
 ## 1) Introduction
 
-The code in this directory allows to instrument programs for AFL using
-true compiler-level instrumentation, instead of the more crude
-assembly-level rewriting approach taken by afl-gcc and afl-clang. This has
-several interesting properties:
+The code in this directory allows to instrument programs for AFL++ using true
+compiler-level instrumentation, instead of the more crude assembly-level
+rewriting approach taken by afl-gcc and afl-clang. This has several interesting
+properties:
 
-  - The compiler can make many optimizations that are hard to pull off when
-    manually inserting assembly. As a result, some slow, CPU-bound programs will
-    run up to around faster.
+- The compiler can make many optimizations that are hard to pull off when
+  manually inserting assembly. As a result, some slow, CPU-bound programs will
+  run up to around faster.
 
-    The gains are less pronounced for fast binaries, where the speed is limited
-    chiefly by the cost of creating new processes. In such cases, the gain will
-    probably stay within 10%.
+  The gains are less pronounced for fast binaries, where the speed is limited
+  chiefly by the cost of creating new processes. In such cases, the gain will
+  probably stay within 10%.
 
-  - The instrumentation is CPU-independent. At least in principle, you should
-    be able to rely on it to fuzz programs on non-x86 architectures (after
-    building `afl-fuzz` with `AFL_NOX86=1`).
+- The instrumentation is CPU-independent. At least in principle, you should be
+  able to rely on it to fuzz programs on non-x86 architectures (after building
+  `afl-fuzz` with `AFL_NOX86=1`).
 
-  - Because the feature relies on the internals of GCC, it is gcc-specific
-    and will *not* work with LLVM (see [README.llvm.md](README.llvm.md) for an alternative).
+- Because the feature relies on the internals of GCC, it is gcc-specific and
+  will *not* work with LLVM (see [README.llvm.md](README.llvm.md) for an
+  alternative).
 
 Once this implementation is shown to be sufficiently robust and portable, it
-will probably replace afl-gcc. For now, it can be built separately and
-co-exists with the original code.
+will probably replace afl-gcc. For now, it can be built separately and co-exists
+with the original code.
 
 The idea and much of the implementation comes from Laszlo Szekeres.
 
 ## 2) How to use
 
-In order to leverage this mechanism, you need to have modern enough GCC
-(>= version 4.5.0) and the plugin development headers installed on your system. That
+In order to leverage this mechanism, you need to have modern enough GCC (>=
+version 4.5.0) and the plugin development headers installed on your system. That
 should be all you need. On Debian machines, these headers can be acquired by
 installing the `gcc-VERSION-plugin-dev` packages.
 
 To build the instrumentation itself, type `make`. This will generate binaries
-called `afl-gcc-fast` and `afl-g++-fast` in the parent directory. 
+called `afl-gcc-fast` and `afl-g++-fast` in the parent directory.
 
-The gcc and g++ compiler links have to point to gcc-VERSION - or set these
-by pointing the environment variables `AFL_CC`/`AFL_CXX` to them.
-If the `CC`/`CXX` environment variables have been set, those compilers will be 
-preferred over those from the `AFL_CC`/`AFL_CXX` settings.
+The gcc and g++ compiler links have to point to gcc-VERSION - or set these by
+pointing the environment variables `AFL_CC`/`AFL_CXX` to them. If the `CC`/`CXX`
+environment variables have been set, those compilers will be preferred over
+those from the `AFL_CC`/`AFL_CXX` settings.
 
 Once this is done, you can instrument third-party code in a way similar to the
-standard operating mode of AFL, e.g.:
+standard operating mode of AFL++, e.g.:
+
 ```
   CC=/path/to/afl/afl-gcc-fast
   CXX=/path/to/afl/afl-g++-fast
@@ -66,15 +70,15 @@ standard operating mode of AFL, e.g.:
   ./configure [...options...]
   make
 ```
+
 Note: We also used `CXX` to set the C++ compiler to `afl-g++-fast` for C++ code.
 
 The tool honors roughly the same environmental variables as `afl-gcc` (see
-[env_variables.md](../docs/env_variables.md). This includes `AFL_INST_RATIO`,
-`AFL_USE_ASAN`, `AFL_HARDEN`, and `AFL_DONT_OPTIMIZE`.
+[docs/env_variables.md](../docs/env_variables.md). This includes
+`AFL_INST_RATIO`, `AFL_USE_ASAN`, `AFL_HARDEN`, and `AFL_DONT_OPTIMIZE`.
 
-Note: if you want the GCC plugin to be installed on your system for all
-users, you need to build it before issuing 'make install' in the parent
-directory.
+Note: if you want the GCC plugin to be installed on your system for all users,
+you need to build it before issuing 'make install' in the parent directory.
 
 ## 3) Gotchas, feedback, bugs
 
@@ -83,93 +87,15 @@ reports to afl@aflplus.plus.
 
 ## 4) Bonus feature #1: deferred initialization
 
-AFL tries to optimize performance by executing the targeted binary just once,
-stopping it just before main(), and then cloning this "main" process to get
-a steady supply of targets to fuzz.
-
-Although this approach eliminates much of the OS-, linker- and libc-level
-costs of executing the program, it does not always help with binaries that
-perform other time-consuming initialization steps - say, parsing a large config
-file before getting to the fuzzed data.
-
-In such cases, it's beneficial to initialize the forkserver a bit later, once
-most of the initialization work is already done, but before the binary attempts
-to read the fuzzed input and parse it; in some cases, this can offer a 10x+
-performance gain. You can implement delayed initialization in GCC mode in a
-fairly simple way.
-
-First, locate a suitable location in the code where the delayed cloning can
-take place. This needs to be done with *extreme* care to avoid breaking the
-binary. In particular, the program will probably malfunction if you select
-a location after:
-
-  - The creation of any vital threads or child processes - since the forkserver
-    can't clone them easily.
-
-  - The initialization of timers via setitimer() or equivalent calls.
-
-  - The creation of temporary files, network sockets, offset-sensitive file
-    descriptors, and similar shared-state resources - but only provided that
-    their state meaningfully influences the behavior of the program later on.
-
-  - Any access to the fuzzed input, including reading the metadata about its
-    size.
-
-With the location selected, add this code in the appropriate spot:
-
-```
-#ifdef __AFL_HAVE_MANUAL_CONTROL
-  __AFL_INIT();
-#endif
-```
-
-You don't need the #ifdef guards, but they will make the program still work as
-usual when compiled with a compiler other than afl-gcc-fast/afl-clang-fast.
-
-Finally, recompile the program with afl-gcc-fast (afl-gcc or afl-clang will
-*not* generate a deferred-initialization binary) - and you should be all set!
+See
+[README.persistent_mode.md#3) Deferred initialization](README.persistent_mode.md#3-deferred-initialization).
 
 ## 5) Bonus feature #2: persistent mode
 
-Some libraries provide APIs that are stateless, or whose state can be reset in
-between processing different input files. When such a reset is performed, a
-single long-lived process can be reused to try out multiple test cases,
-eliminating the need for repeated `fork()` calls and the associated OS overhead.
-
-The basic structure of the program that does this would be:
-
-```
-  while (__AFL_LOOP(1000)) {
-
-    /* Read input data. */
-    /* Call library code to be fuzzed. */
-    /* Reset state. */
-
-  }
-
-  /* Exit normally */
-```
-
-The numerical value specified within the loop controls the maximum number
-of iterations before AFL will restart the process from scratch. This minimizes
-the impact of memory leaks and similar glitches; 1000 is a good starting point.
-
-A more detailed template is shown in ../utils/persistent_mode/.
-Similarly to the previous mode, the feature works only with afl-gcc-fast or
-afl-clang-fast; #ifdef guards can be used to suppress it when using other
-compilers.
-
-Note that as with the previous mode, the feature is easy to misuse; if you
-do not reset the critical state fully, you may end up with false positives or
-waste a whole lot of CPU power doing nothing useful at all. Be particularly
-wary of memory leaks and the state of file descriptors.
-
-When running in this mode, the execution paths will inherently vary a bit
-depending on whether the input loop is being entered for the first time or
-executed again. To avoid spurious warnings, the feature implies
-`AFL_NO_VAR_CHECK` and hides the "variable path" warnings in the UI.
+See
+[README.persistent_mode.md#4) Persistent mode](README.persistent_mode.md#4-persistent-mode).
 
 ## 6) Bonus feature #3: selective instrumentation
 
-It can be more effective to fuzzing to only instrument parts of the code.
-For details see [README.instrument_list.md](README.instrument_list.md).
+It can be more effective to fuzzing to only instrument parts of the code. For
+details, see [README.instrument_list.md](README.instrument_list.md).
\ No newline at end of file
diff --git a/instrumentation/README.instrument_list.md b/instrumentation/README.instrument_list.md
index 7db9c055..b412b600 100644
--- a/instrumentation/README.instrument_list.md
+++ b/instrumentation/README.instrument_list.md
@@ -1,80 +1,84 @@
 # Using AFL++ with partial instrumentation
 
-  This file describes two different mechanisms to selectively instrument
-  only specific parts in the target.
+This file describes two different mechanisms to selectively instrument only
+specific parts in the target.
 
-  Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc.
+Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc.
 
 ## 1) Description and purpose
 
 When building and testing complex programs where only a part of the program is
-the fuzzing target, it often helps to only instrument the necessary parts of
-the program, leaving the rest uninstrumented. This helps to focus the fuzzer
-on the important parts of the program, avoiding undesired noise and
-disturbance by uninteresting code being exercised.
+the fuzzing target, it often helps to only instrument the necessary parts of the
+program, leaving the rest uninstrumented. This helps to focus the fuzzer on the
+important parts of the program, avoiding undesired noise and disturbance by
+uninteresting code being exercised.
 
 For this purpose, "partial instrumentation" support is provided by AFL++ that
 allows to specify what should be instrumented and what not.
 
-Both mechanisms can be used together.
+Both mechanisms for partial instrumentation can be used together.
 
 ## 2) Selective instrumentation with __AFL_COVERAGE_... directives
 
-In this mechanism the selective instrumentation is done in the source code.
+In this mechanism, the selective instrumentation is done in the source code.
 
-After the includes a special define has to be made, eg.:
+After the includes, a special define has to be made, e.g.:
 
 ```
 #include <stdio.h>
 #include <stdint.h>
 // ...
- 
+
 __AFL_COVERAGE();  // <- required for this feature to work
 ```
 
-If you want to disable the coverage at startup until you specify coverage
-should be started, then add `__AFL_COVERAGE_START_OFF();` at that position.
+If you want to disable the coverage at startup until you specify coverage should
+be started, then add `__AFL_COVERAGE_START_OFF();` at that position.
 
-From here on out you have the following macros available that you can use
-in any function where you want:
+From here on out, you have the following macros available that you can use in
+any function where you want:
 
-  * `__AFL_COVERAGE_ON();` - enable coverage from this point onwards
-  * `__AFL_COVERAGE_OFF();` - disable coverage from this point onwards
-  * `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
-  * `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
+* `__AFL_COVERAGE_ON();` - Enable coverage from this point onwards.
+* `__AFL_COVERAGE_OFF();` - Disable coverage from this point onwards.
+* `__AFL_COVERAGE_DISCARD();` - Reset all coverage gathered until this point.
+* `__AFL_COVERAGE_SKIP();` - Mark this test case as unimportant. Whatever
+  happens, afl-fuzz will ignore it.
 
-A special function is `__afl_coverage_interesting`.
-To use this, you must define `void __afl_coverage_interesting(u8 val, u32 id);`.
-Then you can use this function globally, where the `val` parameter can be set
-by you, the `id` parameter is for afl-fuzz and will be overwritten.
-Note that useful parameters for `val` are: 1, 2, 3, 4, 8, 16, 32, 64, 128.
-A value of e.g. 33 will be seen as 32 for coverage purposes.
+A special function is `__afl_coverage_interesting`. To use this, you must define
+`void __afl_coverage_interesting(u8 val, u32 id);`. Then you can use this
+function globally, where the `val` parameter can be set by you, the `id`
+parameter is for afl-fuzz and will be overwritten. Note that useful parameters
+for `val` are: 1, 2, 3, 4, 8, 16, 32, 64, 128. A value of, e.g., 33 will be seen
+as 32 for coverage purposes.
 
 ## 3) Selective instrumentation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
 
-This feature is equivalent to llvm 12 sancov feature and allows to specify
-on a filename and/or function name level to instrument these or skip them.
+This feature is equivalent to llvm 12 sancov feature and allows to specify on a
+filename and/or function name level to instrument these or skip them.
 
 ### 3a) How to use the partial instrumentation mode
 
 In order to build with partial instrumentation, you need to build with
-afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++.
-The only required change is that you need to set either the environment variable
-AFL_LLVM_ALLOWLIST or AFL_LLVM_DENYLIST set with a filename.
+afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++. The only
+required change is that you need to set either the environment variable
+`AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` set with a filename.
 
 That file should contain the file names or functions that are to be instrumented
-(AFL_LLVM_ALLOWLIST) or are specifically NOT to be instrumented (AFL_LLVM_DENYLIST).
+(`AFL_LLVM_ALLOWLIST`) or are specifically NOT to be instrumented
+(`AFL_LLVM_DENYLIST`).
+
+GCC_PLUGIN: you can use either `AFL_LLVM_ALLOWLIST` or `AFL_GCC_ALLOWLIST` (or
+the same for `_DENYLIST`), both work.
 
-GCC_PLUGIN: you can use either AFL_LLVM_ALLOWLIST or AFL_GCC_ALLOWLIST (or the
-same for _DENYLIST), both work.
+For matching to succeed, the function/file name that is being compiled must end
+in the function/file name entry contained in this instrument file list. That is
+to avoid breaking the match when absolute paths are used during compilation.
 
-For matching to succeed, the function/file name that is being compiled must end in the
-function/file name entry contained in this instrument file list. That is to avoid
-breaking the match when absolute paths are used during compilation.
+**NOTE:** In builds with optimization enabled, functions might be inlined and
+would not match!
 
-**NOTE:** In builds with optimization enabled, functions might be inlined and would not match!
+For example, if your source tree looks like this:
 
-For example if your source tree looks like this:
 ```
 project/
 project/feature_a/a1.cpp
@@ -83,36 +87,45 @@ project/feature_b/b1.cpp
 project/feature_b/b2.cpp
 ```
 
-and you only want to test feature_a, then create an "instrument file list" file containing:
+And you only want to test feature_a, then create an "instrument file list" file
+containing:
+
 ```
 feature_a/a1.cpp
 feature_a/a2.cpp
 ```
 
-However if the "instrument file list" file contains only this, it works as well:
+However, if the "instrument file list" file contains only this, it works as
+well:
+
 ```
 a1.cpp
 a2.cpp
 ```
-but it might lead to files being unwantedly instrumented if the same filename
+
+But it might lead to files being unwantedly instrumented if the same filename
 exists somewhere else in the project directories.
 
-You can also specify function names. Note that for C++ the function names
-must be mangled to match! `nm` can print these names.
+You can also specify function names. Note that for C++ the function names must
+be mangled to match! `nm` can print these names.
+
+AFL++ is able to identify whether an entry is a filename or a function. However,
+if you want to be sure (and compliant to the sancov allow/blocklist format), you
+can specify source file entries like this:
 
-AFL++ is able to identify whether an entry is a filename or a function.
-However if you want to be sure (and compliant to the sancov allow/blocklist
-format), you can specify source file entries like this:
 ```
 src: *malloc.c
 ```
-and function entries like this:
+
+And function entries like this:
+
 ```
 fun: MallocFoo
 ```
+
 Note that whitespace is ignored and comments (`# foo`) are supported.
 
 ### 3b) UNIX-style pattern matching
 
 You can add UNIX-style pattern matching in the "instrument file list" entries.
-See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
+See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
\ No newline at end of file
diff --git a/instrumentation/README.laf-intel.md b/instrumentation/README.laf-intel.md
index 789055ed..3cde10c3 100644
--- a/instrumentation/README.laf-intel.md
+++ b/instrumentation/README.laf-intel.md
@@ -2,19 +2,17 @@
 
 ## Introduction
 
-This originally is the work of an individual nicknamed laf-intel.
-His blog [Circumventing Fuzzing Roadblocks with Compiler Transformations](https://lafintel.wordpress.com/)
-and gitlab repo [laf-llvm-pass](https://gitlab.com/laf-intel/laf-llvm-pass/)
-describe some code transformations that
-help AFL++ to enter conditional blocks, where conditions consist of
-comparisons of large values.
+This originally is the work of an individual nicknamed laf-intel. His blog
+[Circumventing Fuzzing Roadblocks with Compiler Transformations](https://lafintel.wordpress.com/)
+and GitLab repo [laf-llvm-pass](https://gitlab.com/laf-intel/laf-llvm-pass/)
+describe some code transformations that help AFL++ to enter conditional blocks,
+where conditions consist of comparisons of large values.
 
 ## Usage
 
-By default these passes will not run when you compile programs using 
-afl-clang-fast. Hence, you can use AFL as usual.
-To enable the passes you must set environment variables before you
-compile the target project.
+By default, these passes will not run when you compile programs using
+afl-clang-fast. Hence, you can use AFL++ as usual. To enable the passes, you
+must set environment variables before you compile the target project.
 
 The following options exist:
 
@@ -24,32 +22,30 @@ Enables the split-switches pass.
 
 `export AFL_LLVM_LAF_TRANSFORM_COMPARES=1`
 
-Enables the transform-compares pass (strcmp, memcmp, strncmp,
-strcasecmp, strncasecmp).
+Enables the transform-compares pass (strcmp, memcmp, strncmp, strcasecmp,
+strncasecmp).
 
 `export AFL_LLVM_LAF_SPLIT_COMPARES=1`
 
-Enables the split-compares pass.
-By default it will 
+Enables the split-compares pass. By default, it will
 1. simplify operators >= (and <=) into chains of > (<) and == comparisons
-2. change signed integer comparisons to a chain of sign-only comparison
-and unsigned integer comparisons
-3. split all unsigned integer comparisons with bit widths of
-64, 32 or 16 bits to chains of 8 bits comparisons.
-
-You can change the behaviour of the last step by setting
-`export AFL_LLVM_LAF_SPLIT_COMPARES_BITW=<bit_width>`, where 
-bit_width may be 64, 32 or 16. For example, a bit_width of 16
-would split larger comparisons down to 16 bit comparisons.
-
-A new experimental feature is splitting floating point comparisons into a
-series of sign, exponent and mantissa comparisons followed by splitting each
-of them into 8 bit comparisons when necessary.
-It is activated with the `AFL_LLVM_LAF_SPLIT_FLOATS` setting.
-Please note that full IEEE 754 functionality is not preserved, that is
-values of nan and infinity will probably behave differently.
-
-Note that setting this automatically activates `AFL_LLVM_LAF_SPLIT_COMPARES`
-
-You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled :-)
-
+2. change signed integer comparisons to a chain of sign-only comparison and
+   unsigned integer comparisons
+3. split all unsigned integer comparisons with bit widths of 64, 32, or 16 bits
+   to chains of 8 bits comparisons.
+
+You can change the behavior of the last step by setting `export
+AFL_LLVM_LAF_SPLIT_COMPARES_BITW=<bit_width>`, where bit_width may be 64, 32, or
+16. For example, a bit_width of 16 would split larger comparisons down to 16 bit
+comparisons.
+
+A new experimental feature is splitting floating point comparisons into a series
+of sign, exponent and mantissa comparisons followed by splitting each of them
+into 8 bit comparisons when necessary. It is activated with the
+`AFL_LLVM_LAF_SPLIT_FLOATS` setting. Please note that full IEEE 754
+functionality is not preserved, that is values of nan and infinity will probably
+behave differently.
+
+Note that setting this automatically activates `AFL_LLVM_LAF_SPLIT_COMPARES`.
+
+You can also set `AFL_LLVM_LAF_ALL` and have all of the above enabled. :-)
\ No newline at end of file
diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md
index dbb604f2..88ea0127 100644
--- a/instrumentation/README.llvm.md
+++ b/instrumentation/README.llvm.md
@@ -1,72 +1,79 @@
 # Fast LLVM-based instrumentation for afl-fuzz
 
-  (See [../README.md](../README.md) for the general instruction manual.)
+For the general instruction manual, see [../README.md](../README.md).
 
-  (See [README.gcc_plugin.md](README.gcc_plugin.md) for the GCC-based instrumentation.)
+For the GCC-based instrumentation, see
+[README.gcc_plugin.md](README.gcc_plugin.md).
 
 ## 1) Introduction
 
 ! llvm_mode works with llvm versions 3.8 up to 13 !
 
-The code in this directory allows you to instrument programs for AFL using
-true compiler-level instrumentation, instead of the more crude
-assembly-level rewriting approach taken by afl-gcc and afl-clang. This has
-several interesting properties:
+The code in this directory allows you to instrument programs for AFL++ using
+true compiler-level instrumentation, instead of the more crude assembly-level
+rewriting approach taken by afl-gcc and afl-clang. This has several interesting
+properties:
 
-  - The compiler can make many optimizations that are hard to pull off when
-    manually inserting assembly. As a result, some slow, CPU-bound programs will
-    run up to around 2x faster.
+- The compiler can make many optimizations that are hard to pull off when
+  manually inserting assembly. As a result, some slow, CPU-bound programs will
+  run up to around 2x faster.
 
-    The gains are less pronounced for fast binaries, where the speed is limited
-    chiefly by the cost of creating new processes. In such cases, the gain will
-    probably stay within 10%.
+  The gains are less pronounced for fast binaries, where the speed is limited
+  chiefly by the cost of creating new processes. In such cases, the gain will
+  probably stay within 10%.
 
-  - The instrumentation is CPU-independent. At least in principle, you should
-    be able to rely on it to fuzz programs on non-x86 architectures (after
-    building afl-fuzz with AFL_NO_X86=1).
+- The instrumentation is CPU-independent. At least in principle, you should be
+  able to rely on it to fuzz programs on non-x86 architectures (after building
+  afl-fuzz with AFL_NO_X86=1).
 
-  - The instrumentation can cope a bit better with multi-threaded targets.
+- The instrumentation can cope a bit better with multi-threaded targets.
 
-  - Because the feature relies on the internals of LLVM, it is clang-specific
-    and will *not* work with GCC (see ../gcc_plugin/ for an alternative once
-    it is available).
+- Because the feature relies on the internals of LLVM, it is clang-specific and
+  will *not* work with GCC (see ../gcc_plugin/ for an alternative once it is
+  available).
 
 Once this implementation is shown to be sufficiently robust and portable, it
 will probably replace afl-clang. For now, it can be built separately and
 co-exists with the original code.
 
-The idea and much of the intial implementation came from Laszlo Szekeres.
+The idea and much of the initial implementation came from Laszlo Szekeres.
 
 ## 2a) How to use this - short
 
 Set the `LLVM_CONFIG` variable to the clang version you want to use, e.g.
+
 ```
 LLVM_CONFIG=llvm-config-9 make
 ```
+
 In case you have your own compiled llvm version specify the full path:
+
 ```
 LLVM_CONFIG=~/llvm-project/build/bin/llvm-config make
 ```
+
 If you try to use a new llvm version on an old Linux this can fail because of
 old c++ libraries. In this case usually switching to gcc/g++ to compile
 llvm_mode will work:
+
 ```
 LLVM_CONFIG=llvm-config-7 REAL_CC=gcc REAL_CXX=g++ make
 ```
-It is highly recommended to use the newest clang version you can put your
-hands on :)
+
+It is highly recommended to use the newest clang version you can put your hands
+on :)
 
 Then look at [README.persistent_mode.md](README.persistent_mode.md).
 
 ## 2b) How to use this - long
 
 In order to leverage this mechanism, you need to have clang installed on your
-system. You should also make sure that the llvm-config tool is in your path
-(or pointed to via LLVM_CONFIG in the environment).
+system. You should also make sure that the llvm-config tool is in your path (or
+pointed to via LLVM_CONFIG in the environment).
 
-Note that if you have several LLVM versions installed, pointing LLVM_CONFIG
-to the version you want to use will switch compiling to this specific
-version - if you installation is set up correctly :-)
+Note that if you have several LLVM versions installed, pointing LLVM_CONFIG to
+the version you want to use will switch compiling to this specific version - if
+you installation is set up correctly :-)
 
 Unfortunately, some systems that do have clang come without llvm-config or the
 LLVM development headers; one example of this is FreeBSD. FreeBSD users will
@@ -75,15 +82,15 @@ load modules (you'll see "Service unavailable" when loading afl-llvm-pass.so).
 
 To solve all your problems, you can grab pre-built binaries for your OS from:
 
-  https://llvm.org/releases/download.html
+[https://llvm.org/releases/download.html](https://llvm.org/releases/download.html)
 
 ...and then put the bin/ directory from the tarball at the beginning of your
 $PATH when compiling the feature and building packages later on. You don't need
 to be root for that.
 
-To build the instrumentation itself, type 'make'. This will generate binaries
-called afl-clang-fast and afl-clang-fast++ in the parent directory. Once this
-is done, you can instrument third-party code in a way similar to the standard
+To build the instrumentation itself, type `make`. This will generate binaries
+called afl-clang-fast and afl-clang-fast++ in the parent directory. Once this is
+done, you can instrument third-party code in a way similar to the standard
 operating mode of AFL, e.g.:
 
 ```
@@ -93,81 +100,137 @@ operating mode of AFL, e.g.:
 
 Be sure to also include CXX set to afl-clang-fast++ for C++ code.
 
-Note that afl-clang-fast/afl-clang-fast++ are just pointers to afl-cc.
-You can also use afl-cc/afl-c++ and instead direct it to use LLVM
-instrumentation by either setting `AFL_CC_COMPILER=LLVM` or pass the parameter
-`--afl-llvm` via CFLAGS/CXXFLAGS/CPPFLAGS.
+Note that afl-clang-fast/afl-clang-fast++ are just pointers to afl-cc. You can
+also use afl-cc/afl-c++ and instead direct it to use LLVM instrumentation by
+either setting `AFL_CC_COMPILER=LLVM` or pass the parameter `--afl-llvm` via
+CFLAGS/CXXFLAGS/CPPFLAGS.
 
 The tool honors roughly the same environmental variables as afl-gcc (see
 [docs/env_variables.md](../docs/env_variables.md)). This includes AFL_USE_ASAN,
-AFL_HARDEN, and AFL_DONT_OPTIMIZE. However AFL_INST_RATIO is not honored
-as it does not serve a good purpose with the more effective PCGUARD analysis.
+AFL_HARDEN, and AFL_DONT_OPTIMIZE. However AFL_INST_RATIO is not honored as it
+does not serve a good purpose with the more effective PCGUARD analysis.
 
 ## 3) Options
 
-Several options are present to make llvm_mode faster or help it rearrange
-the code to make afl-fuzz path discovery easier.
+Several options are present to make llvm_mode faster or help it rearrange the
+code to make afl-fuzz path discovery easier.
 
-If you need just to instrument specific parts of the code, you can the instrument file list
-which C/C++ files to actually instrument. See [README.instrument_list.md](README.instrument_list.md)
+If you need just to instrument specific parts of the code, you can the
+instrument file list which C/C++ files to actually instrument. See
+[README.instrument_list.md](README.instrument_list.md)
 
-For splitting memcmp, strncmp, etc. please see [README.laf-intel.md](README.laf-intel.md)
+For splitting memcmp, strncmp, etc. please see
+[README.laf-intel.md](README.laf-intel.md)
 
 Then there are different ways of instrumenting the target:
 
-1. An better instrumentation strategy uses LTO and link time
-instrumentation. Note that not all targets can compile in this mode, however
-if it works it is the best option you can use.
-Simply use afl-clang-lto/afl-clang-lto++ to use this option.
-See [README.lto.md](README.lto.md)
+1. An better instrumentation strategy uses LTO and link time instrumentation.
+   Note that not all targets can compile in this mode, however if it works it is
+   the best option you can use. Simply use afl-clang-lto/afl-clang-lto++ to use
+   this option. See [README.lto.md](README.lto.md).
 
-2. Alternativly you can choose a completely different coverage method:
+2. Alternatively you can choose a completely different coverage method:
 
-2a. N-GRAM coverage - which combines the previous visited edges with the
-current one. This explodes the map but on the other hand has proven to be
-effective for fuzzing.
-See [README.ngram.md](README.ngram.md)
+2a. N-GRAM coverage - which combines the previous visited edges with the current
+    one. This explodes the map but on the other hand has proven to be effective
+    for fuzzing. See
+    [7) AFL++ N-Gram Branch Coverage](#7-afl-n-gram-branch-coverage).
 
 2b. Context sensitive coverage - which combines the visited edges with an
-individual caller ID (the function that called the current one)
-[README.ctx.md](README.ctx.md)
+    individual caller ID (the function that called the current one). See
+    [6) AFL++ Context Sensitive Branch Coverage](#6-afl-context-sensitive-branch-coverage).
 
-Then - additionally to one of the instrumentation options above - there is
-a very effective new instrumentation option called CmpLog as an alternative to
-laf-intel that allow AFL++ to apply mutations similar to Redqueen.
-See [README.cmplog.md](README.cmplog.md)
+Then - additionally to one of the instrumentation options above - there is a
+very effective new instrumentation option called CmpLog as an alternative to
+laf-intel that allow AFL++ to apply mutations similar to Redqueen. See
+[README.cmplog.md](README.cmplog.md).
 
-Finally if your llvm version is 8 or lower, you can activate a mode that
-prevents that a counter overflow result in a 0 value. This is good for
-path discovery, but the llvm implementation for x86 for this functionality
-is not optimal and was only fixed in llvm 9.
-You can set this with AFL_LLVM_NOT_ZERO=1
-See [README.neverzero.md](README.neverzero.md)
+Finally, if your llvm version is 8 or lower, you can activate a mode that
+prevents that a counter overflow result in a 0 value. This is good for path
+discovery, but the llvm implementation for x86 for this functionality is not
+optimal and was only fixed in llvm 9. You can set this with AFL_LLVM_NOT_ZERO=1.
 
-Support for thread safe counters has been added for all modes.
-Activate it with `AFL_LLVM_THREADSAFE_INST=1`. The tradeoff is better precision
-in multi threaded apps for a slightly higher instrumentation overhead.
-This also disables the nozero counter default for performance reasons.
+Support for thread safe counters has been added for all modes. Activate it with
+`AFL_LLVM_THREADSAFE_INST=1`. The tradeoff is better precision in multi threaded
+apps for a slightly higher instrumentation overhead. This also disables the
+nozero counter default for performance reasons.
 
-## 4) Snapshot feature
+## 4) deferred initialization, persistent mode, shared memory fuzzing
 
-To speed up fuzzing you can use a linux loadable kernel module which enables
-a snapshot feature.
-See [README.snapshot.md](README.snapshot.md)
+This is the most powerful and effective fuzzing you can do. Please see
+[README.persistent_mode.md](README.persistent_mode.md) for a full explanation.
 
-## 5) Gotchas, feedback, bugs
+## 5) Bonus feature: 'dict2file' pass
 
-This is an early-stage mechanism, so field reports are welcome. You can send bug
-reports to <afl-users@googlegroups.com>.
+Just specify `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` and during compilation
+all constant string compare parameters will be written to this file to be used
+with afl-fuzz' `-x` option.
 
-## 6) deferred initialization, persistent mode, shared memory fuzzing
+## 6) AFL++ Context Sensitive Branch Coverage
 
-This is the most powerful and effective fuzzing you can do.
-Please see [README.persistent_mode.md](README.persistent_mode.md) for a
-full explanation.
+### What is this?
 
-## 7) Bonus feature: 'dict2file' pass
+This is an LLVM-based implementation of the context sensitive branch coverage.
 
-Just specify `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` and during compilation
-all constant string compare parameters will be written to this file to be
-used with afl-fuzz' `-x` option.
+Basically every function gets its own ID and, every time when an edge is logged,
+all the IDs in the callstack are hashed and combined with the edge transition
+hash to augment the classic edge coverage with the information about the calling
+context.
+
+So if both function A and function B call a function C, the coverage collected
+in C will be different.
+
+In math the coverage is collected as follows: `map[current_location_ID ^
+previous_location_ID >> 1 ^ hash_callstack_IDs] += 1`
+
+The callstack hash is produced XOR-ing the function IDs to avoid explosion with
+recursive functions.
+
+### Usage
+
+Set the `AFL_LLVM_INSTRUMENT=CTX` or `AFL_LLVM_CTX=1` environment variable.
+
+It is highly recommended to increase the MAP_SIZE_POW2 definition in config.h to
+at least 18 and maybe up to 20 for this as otherwise too many map collisions
+occur.
+
+### Caller Branch Coverage
+
+If the context sensitive coverage introduces too may collisions and becoming
+detrimental, the user can choose to augment edge coverage with just the called
+function ID, instead of the entire callstack hash.
+
+In math the coverage is collected as follows: `map[current_location_ID ^
+previous_location_ID >> 1 ^ previous_callee_ID] += 1`
+
+Set the `AFL_LLVM_INSTRUMENT=CALLER` or `AFL_LLVM_CALLER=1` environment
+variable.
+
+## 7) AFL++ N-Gram Branch Coverage
+
+### Source
+
+This is an LLVM-based implementation of the n-gram branch coverage proposed in
+the paper
+["Be Sensitive and Collaborative: Analyzing Impact of Coverage Metrics in Greybox Fuzzing"](https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf)
+by Jinghan Wang, et. al.
+
+Note that the original implementation (available
+[here](https://github.com/bitsecurerlab/afl-sensitive)) is built on top of AFL's
+qemu_mode. This is essentially a port that uses LLVM vectorized instructions
+(available from llvm versions 4.0.1 and higher) to achieve the same results when
+compiling source code.
+
+In math the branch coverage is performed as follows: `map[current_location ^
+prev_location[0] >> 1 ^ prev_location[1] >> 1 ^ ... up to n-1`] += 1`
+
+### Usage
+
+The size of `n` (i.e., the number of branches to remember) is an option that is
+specified either in the `AFL_LLVM_INSTRUMENT=NGRAM-{value}` or the
+`AFL_LLVM_NGRAM_SIZE` environment variable. Good values are 2, 4, or 8, valid
+are 2-16.
+
+It is highly recommended to increase the MAP_SIZE_POW2 definition in config.h to
+at least 18 and maybe up to 20 for this as otherwise too many map collisions
+occur.
\ No newline at end of file
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index 6174cdc0..a74425dc 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -1,55 +1,56 @@
 # afl-clang-lto - collision free instrumentation at link time
 
-## TLDR;
+## TL;DR:
 
-This version requires a current llvm 11+ compiled from the github master.
+This version requires a current llvm 11+ compiled from the GitHub master.
 
 1. Use afl-clang-lto/afl-clang-lto++ because it is faster and gives better
-   coverage than anything else that is out there in the AFL world
+   coverage than anything else that is out there in the AFL world.
 
-2. You can use it together with llvm_mode: laf-intel and the instrument file listing
-   features and can be combined with cmplog/Redqueen
+2. You can use it together with llvm_mode: laf-intel and the instrument file
+   listing features and can be combined with cmplog/Redqueen.
 
-3. It only works with llvm 11+
+3. It only works with llvm 11+.
 
-4. AUTODICTIONARY feature! see below
+4. AUTODICTIONARY feature (see below)!
 
-5. If any problems arise be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`.
-   Some targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`.
+5. If any problems arise, be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`. Some
+   targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`.
 
 ## Introduction and problem description
 
-A big issue with how AFL/AFL++ works is that the basic block IDs that are
-set during compilation are random - and hence naturally the larger the number
-of instrumented locations, the higher the number of edge collisions are in the
-map. This can result in not discovering new paths and therefore degrade the
+A big issue with how AFL++ works is that the basic block IDs that are set during
+compilation are random - and hence naturally the larger the number of
+instrumented locations, the higher the number of edge collisions are in the map.
+This can result in not discovering new paths and therefore degrade the
 efficiency of the fuzzing process.
 
-*This issue is underestimated in the fuzzing community!*
-With a 2^16 = 64kb standard map at already 256 instrumented blocks there is
-on average one collision. On average a target has 10.000 to 50.000
-instrumented blocks hence the real collisions are between 750-18.000!
+*This issue is underestimated in the fuzzing community!* With a 2^16 = 64kb
+standard map at already 256 instrumented blocks, there is on average one
+collision. On average, a target has 10.000 to 50.000 instrumented blocks, hence
+the real collisions are between 750-18.000!
 
-To reach a solution that prevents any collisions took several approaches
-and many dead ends until we got to this:
+To reach a solution that prevents any collisions took several approaches and
+many dead ends until we got to this:
 
- * We instrument at link time when we have all files pre-compiled
- * To instrument at link time we compile in LTO (link time optimization) mode
- * Our compiler (afl-clang-lto/afl-clang-lto++) takes care of setting the
-   correct LTO options and runs our own afl-ld linker instead of the system
-   linker
- * The LLVM linker collects all LTO files to link and instruments them so that
-   we have non-colliding edge overage
- * We use a new (for afl) edge coverage - which is the same as in llvm
-   -fsanitize=coverage edge coverage mode :)
+* We instrument at link time when we have all files pre-compiled.
+* To instrument at link time, we compile in LTO (link time optimization) mode.
+* Our compiler (afl-clang-lto/afl-clang-lto++) takes care of setting the correct
+  LTO options and runs our own afl-ld linker instead of the system linker.
+* The LLVM linker collects all LTO files to link and instruments them so that we
+  have non-colliding edge overage.
+* We use a new (for afl) edge coverage - which is the same as in llvm
+  -fsanitize=coverage edge coverage mode. :)
 
 The result:
- * 10-25% speed gain compared to llvm_mode
- * guaranteed non-colliding edge coverage :-)
- * The compile time especially for binaries to an instrumented library can be
-   much longer
+
+* 10-25% speed gain compared to llvm_mode
+* guaranteed non-colliding edge coverage :-)
+* The compile time, especially for binaries to an instrumented library, can be
+  much longer.
 
 Example build output from a libtiff build:
+
 ```
 libtool: link: afl-clang-lto -g -O2 -Wall -W -o thumbnail thumbnail.o  ../libtiff/.libs/libtiff.a ../port/.libs/libport.a -llzma -ljbig -ljpeg -lz -lm
 afl-clang-lto++2.63d by Marc "vanHauser" Heuse <mh@mh-sec.de> in mode LTO
@@ -62,21 +63,24 @@ AUTODICTIONARY: 11 strings found
 
 ### Installing llvm version 11 or 12
 
-llvm 11 or even 12 should be available in all current Linux repositories.
-If you use an outdated Linux distribution read the next section.
+llvm 11 or even 12 should be available in all current Linux repositories. If you
+use an outdated Linux distribution, read the next section.
 
 ### Installing llvm from the llvm repository (version 12+)
 
 Installing the llvm snapshot builds is easy and mostly painless:
 
-In the follow line change `NAME` for your Debian or Ubuntu release name
+In the following line, change `NAME` for your Debian or Ubuntu release name
 (e.g. buster, focal, eon, etc.):
+
 ```
 echo deb http://apt.llvm.org/NAME/ llvm-toolchain-NAME NAME >> /etc/apt/sources.list
 ```
-then add the pgp key of llvm and install the packages:
+
+Then add the pgp key of llvm and install the packages:
+
 ```
-wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - 
+wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
 apt-get update && apt-get upgrade -y
 apt-get install -y clang-12 clang-tools-12 libc++1-12 libc++-12-dev \
     libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \
@@ -87,7 +91,8 @@ apt-get install -y clang-12 clang-tools-12 libc++1-12 libc++-12-dev \
 
 ### Building llvm yourself (version 12+)
 
-Building llvm from github takes quite some long time and is not painless:
+Building llvm from GitHub takes quite some time and is not painless:
+
 ```sh
 sudo apt install binutils-dev  # this is *essential*!
 git clone --depth=1 https://github.com/llvm/llvm-project
@@ -126,10 +131,12 @@ sudo make install
 
 Just use afl-clang-lto like you did with afl-clang-fast or afl-gcc.
 
-Also the instrument file listing (AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST -> [README.instrument_list.md](README.instrument_list.md)) and
-laf-intel/compcov (AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work.
+Also, the instrument file listing (AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST ->
+[README.instrument_list.md](README.instrument_list.md)) and laf-intel/compcov
+(AFL_LLVM_LAF_* -> [README.laf-intel.md](README.laf-intel.md)) work.
 
 Example:
+
 ```
 CC=afl-clang-lto CXX=afl-clang-lto++ RANLIB=llvm-ranlib AR=llvm-ar ./configure
 make
@@ -143,51 +150,48 @@ NOTE: some targets also need to set the linker, try both `afl-clang-lto` and
 Note: this is highly discouraged! Try to compile to static libraries with
 afl-clang-lto instead of shared libraries!
 
-To make instrumented shared libraries work with afl-clang-lto you have to do
+To make instrumented shared libraries work with afl-clang-lto, you have to do
 quite some extra steps.
 
-Every shared library you want to instrument has to be individually compiled.
-The environment variable `AFL_LLVM_LTO_DONTWRITEID=1` has to be set during
-compilation.
-Additionally the environment variable `AFL_LLVM_LTO_STARTID` has to be set to
-the added edge count values of all previous compiled instrumented shared
-libraries for that target.
-E.g. for the first shared library this would be `AFL_LLVM_LTO_STARTID=0` and
-afl-clang-lto will then report how many edges have been instrumented (let's say
-it reported 1000 instrumented edges).
-The second shared library then has to be set to that value
+Every shared library you want to instrument has to be individually compiled. The
+environment variable `AFL_LLVM_LTO_DONTWRITEID=1` has to be set during
+compilation. Additionally, the environment variable `AFL_LLVM_LTO_STARTID` has
+to be set to the added edge count values of all previous compiled instrumented
+shared libraries for that target. E.g., for the first shared library this would
+be `AFL_LLVM_LTO_STARTID=0` and afl-clang-lto will then report how many edges
+have been instrumented (let's say it reported 1000 instrumented edges). The
+second shared library then has to be set to that value
 (`AFL_LLVM_LTO_STARTID=1000` in our example), for the third to all previous
 counts added, etc.
 
-The final program compilation step then may *not* have `AFL_LLVM_LTO_DONTWRITEID`
-set, and `AFL_LLVM_LTO_STARTID` must be set to all edge counts added of all shared
-libraries it will be linked to.
+The final program compilation step then may *not* have
+`AFL_LLVM_LTO_DONTWRITEID` set, and `AFL_LLVM_LTO_STARTID` must be set to all
+edge counts added of all shared libraries it will be linked to.
 
-This is quite some hands-on work, so better stay away from instrumenting
-shared libraries :-)
+This is quite some hands-on work, so better stay away from instrumenting shared
+libraries. :-)
 
 ## AUTODICTIONARY feature
 
 While compiling, a dictionary based on string comparisons is automatically
-generated and put into the target binary. This dictionary is transfered to afl-fuzz
-on start. This improves coverage statistically by 5-10% :)
+generated and put into the target binary. This dictionary is transferred to
+afl-fuzz on start. This improves coverage statistically by 5-10%. :)
 
-Note that if for any reason you do not want to use the autodictionary feature
+Note that if for any reason you do not want to use the autodictionary feature,
 then just set the environment variable `AFL_NO_AUTODICT` when starting afl-fuzz.
 
 ## Fixed memory map
 
 To speed up fuzzing a little bit more, it is possible to set a fixed shared
-memory map.
-Recommended is the value 0x10000.
+memory map. Recommended is the value 0x10000.
 
-In most cases this will work without any problems. However if a target uses
-early constructors, ifuncs or a deferred forkserver this can crash the target.
+In most cases, this will work without any problems. However, if a target uses
+early constructors, ifuncs, or a deferred forkserver, this can crash the target.
 
-Also on unusual operating systems/processors/kernels or weird libraries the
+Also, on unusual operating systems/processors/kernels or weird libraries the
 recommended 0x10000 address might not work, so then change the fixed address.
 
-To enable this feature set AFL_LLVM_MAP_ADDR with the address.
+To enable this feature, set `AFL_LLVM_MAP_ADDR` with the address.
 
 ## Document edge IDs
 
@@ -206,143 +210,155 @@ these.
 An example of a hard to solve target is ffmpeg. Here is how to successfully
 instrument it:
 
-1. Get and extract the current ffmpeg and change to its directory
+1. Get and extract the current ffmpeg and change to its directory.
 
 2. Running configure with --cc=clang fails and various other items will fail
    when compiling, so we have to trick configure:
 
-```
-./configure --enable-lto --disable-shared --disable-inline-asm
-```
-
-3. Now the configuration is done - and we edit the settings in `./ffbuild/config.mak`
-   (-: the original line, +: what to change it into):
-```
--CC=gcc
-+CC=afl-clang-lto
--CXX=g++
-+CXX=afl-clang-lto++
--AS=gcc
-+AS=llvm-as
--LD=gcc
-+LD=afl-clang-lto++
--DEPCC=gcc
-+DEPCC=afl-clang-lto
--DEPAS=gcc
-+DEPAS=afl-clang-lto++
--AR=ar
-+AR=llvm-ar
--AR_CMD=ar
-+AR_CMD=llvm-ar
--NM_CMD=nm -g
-+NM_CMD=llvm-nm -g
--RANLIB=ranlib -D
-+RANLIB=llvm-ranlib -D
-```
-
-4. Then type make, wait for a long time and you are done :)
+    ```
+    ./configure --enable-lto --disable-shared --disable-inline-asm
+    ```
+
+3. Now the configuration is done - and we edit the settings in
+   `./ffbuild/config.mak` (-: the original line, +: what to change it into):
+
+    ```
+    -CC=gcc
+    +CC=afl-clang-lto
+    -CXX=g++
+    +CXX=afl-clang-lto++
+    -AS=gcc
+    +AS=llvm-as
+    -LD=gcc
+    +LD=afl-clang-lto++
+    -DEPCC=gcc
+    +DEPCC=afl-clang-lto
+    -DEPAS=gcc
+    +DEPAS=afl-clang-lto++
+    -AR=ar
+    +AR=llvm-ar
+    -AR_CMD=ar
+    +AR_CMD=llvm-ar
+    -NM_CMD=nm -g
+    +NM_CMD=llvm-nm -g
+    -RANLIB=ranlib -D
+    +RANLIB=llvm-ranlib -D
+    ```
+
+4. Then type make, wait for a long time, and you are done. :)
 
 ### Example: WebKit jsc
 
 Building jsc is difficult as the build script has bugs.
 
-1. checkout Webkit: 
-```
-svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
-cd WebKit
-```
+1. Checkout Webkit:
+
+    ```
+    svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
+    cd WebKit
+    ```
 
 2. Fix the build environment:
-```
-mkdir -p WebKitBuild/Release
-cd WebKitBuild/Release
-ln -s ../../../../../usr/bin/llvm-ar-12 llvm-ar-12
-ln -s ../../../../../usr/bin/llvm-ranlib-12 llvm-ranlib-12
-cd ../..
-```
 
-3. Build :)
+    ```
+    mkdir -p WebKitBuild/Release
+    cd WebKitBuild/Release
+    ln -s ../../../../../usr/bin/llvm-ar-12 llvm-ar-12
+    ln -s ../../../../../usr/bin/llvm-ranlib-12 llvm-ranlib-12
+    cd ../..
+    ```
 
-```
-Tools/Scripts/build-jsc --jsc-only --cli --cmakeargs="-DCMAKE_AR='llvm-ar-12' -DCMAKE_RANLIB='llvm-ranlib-12' -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CC_FLAGS='-O3 -lrt' -DCMAKE_CXX_FLAGS='-O3 -lrt' -DIMPORTED_LOCATION='/lib/x86_64-linux-gnu/' -DCMAKE_CC=afl-clang-lto -DCMAKE_CXX=afl-clang-lto++ -DENABLE_STATIC_JSC=ON"
-```
+3. Build. :)
+
+    ```
+    Tools/Scripts/build-jsc --jsc-only --cli --cmakeargs="-DCMAKE_AR='llvm-ar-12' -DCMAKE_RANLIB='llvm-ranlib-12' -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_CC_FLAGS='-O3 -lrt' -DCMAKE_CXX_FLAGS='-O3 -lrt' -DIMPORTED_LOCATION='/lib/x86_64-linux-gnu/' -DCMAKE_CC=afl-clang-lto -DCMAKE_CXX=afl-clang-lto++ -DENABLE_STATIC_JSC=ON"
+    ```
 
 ## Potential issues
 
-### compiling libraries fails
+### Compiling libraries fails
 
 If you see this message:
+
 ```
 /bin/ld: libfoo.a: error adding symbols: archive has no index; run ranlib to add one
 ```
-This is because usually gnu gcc ranlib is being called which cannot deal with clang LTO files.
-The solution is simple: when you ./configure you also have to set RANLIB=llvm-ranlib and AR=llvm-ar
+
+This is because usually gnu gcc ranlib is being called which cannot deal with
+clang LTO files. The solution is simple: when you `./configure`, you also have
+to set `RANLIB=llvm-ranlib` and `AR=llvm-ar`.
 
 Solution:
+
 ```
 AR=llvm-ar RANLIB=llvm-ranlib CC=afl-clang-lto CXX=afl-clang-lto++ ./configure --disable-shared
 ```
-and on some targets you have to set AR=/RANLIB= even for make as the configure script does not save it.
-Other targets ignore environment variables and need the parameters set via
-`./configure --cc=... --cxx= --ranlib= ...` etc. (I am looking at you ffmpeg!).
 
+And on some targets you have to set `AR=/RANLIB=` even for `make` as the
+configure script does not save it. Other targets ignore environment variables
+and need the parameters set via `./configure --cc=... --cxx= --ranlib= ...` etc.
+(I am looking at you ffmpeg!)
+
+If you see this message:
 
-If you see this message
 ```
 assembler command failed ...
 ```
-then try setting `llvm-as` for configure:
+
+Then try setting `llvm-as` for configure:
+
 ```
 AS=llvm-as  ...
 ```
 
-### compiling programs still fail
+### Compiling programs still fail
 
 afl-clang-lto is still work in progress.
 
 Known issues:
-  * Anything that llvm 11+ cannot compile, afl-clang-lto cannot compile either - obviously
-  * Anything that does not compile with LTO, afl-clang-lto cannot compile either - obviously
+* Anything that llvm 11+ cannot compile, afl-clang-lto cannot compile either -
+  obviously.
+* Anything that does not compile with LTO, afl-clang-lto cannot compile either -
+  obviously.
 
-Hence if building a target with afl-clang-lto fails try to build it with llvm12
-and LTO enabled (`CC=clang-12` `CXX=clang++-12` `CFLAGS=-flto=full` and
-`CXXFLAGS=-flto=full`).
+Hence, if building a target with afl-clang-lto fails, try to build it with
+llvm12 and LTO enabled (`CC=clang-12`, `CXX=clang++-12`, `CFLAGS=-flto=full`,
+and `CXXFLAGS=-flto=full`).
 
-If this succeeeds then there is an issue with afl-clang-lto. Please report at
-[https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226)
+If this succeeds, then there is an issue with afl-clang-lto. Please report at
+[https://github.com/AFLplusplus/AFLplusplus/issues/226](https://github.com/AFLplusplus/AFLplusplus/issues/226).
 
 Even some targets where clang-12 fails can be build if the fail is just in
 `./configure`, see `Solving difficult targets` above.
 
 ## History
 
-This was originally envisioned by hexcoder- in Summer 2019, however we saw no
-way to create a pass that is run at link time - although there is a option
-for this in the PassManager: EP_FullLinkTimeOptimizationLast
-("Fun" info - nobody knows what this is doing. And the developer who
-implemented this didn't respond to emails.)
-
-In December then came the idea to implement this as a pass that is run via
-the llvm "opt" program, which is performed via an own linker that afterwards
-calls the real linker.
-This was first implemented in January and work ... kinda.
-The LTO time instrumentation worked, however "how" the basic blocks were
-instrumented was a problem, as reducing duplicates turned out to be very,
-very difficult with a program that has so many paths and therefore so many
-dependencies. A lot of strategies were implemented - and failed.
-And then sat solvers were tried, but with over 10.000 variables that turned
-out to be a dead-end too.
+This was originally envisioned by hexcoder- in Summer 2019. However, we saw no
+way to create a pass that is run at link time - although there is a option for
+this in the PassManager: EP_FullLinkTimeOptimizationLast. ("Fun" info - nobody
+knows what this is doing. And the developer who implemented this didn't respond
+to emails.)
+
+In December then came the idea to implement this as a pass that is run via the
+llvm "opt" program, which is performed via an own linker that afterwards calls
+the real linker. This was first implemented in January and work ... kinda. The
+LTO time instrumentation worked, however, "how" the basic blocks were
+instrumented was a problem, as reducing duplicates turned out to be very, very
+difficult with a program that has so many paths and therefore so many
+dependencies. A lot of strategies were implemented - and failed. And then sat
+solvers were tried, but with over 10.000 variables that turned out to be a
+dead-end too.
 
 The final idea to solve this came from domenukk who proposed to insert a block
-into an edge and then just use incremental counters ... and this worked!
-After some trials and errors to implement this vanhauser-thc found out that
-there is actually an llvm function for this: SplitEdge() :-)
+into an edge and then just use incremental counters ... and this worked! After
+some trials and errors to implement this vanhauser-thc found out that there is
+actually an llvm function for this: SplitEdge() :-)
 
-Still more problems came up though as this only works without bugs from
-llvm 9 onwards, and with high optimization the link optimization ruins
-the instrumented control flow graph.
+Still more problems came up though as this only works without bugs from llvm 9
+onwards, and with high optimization the link optimization ruins the instrumented
+control flow graph.
 
-This is all now fixed with llvm 11+. The llvm's own linker is now able to
-load passes and this bypasses all problems we had.
+This is all now fixed with llvm 11+. The llvm's own linker is now able to load
+passes and this bypasses all problems we had.
 
-Happy end :)
+Happy end :)
\ No newline at end of file
diff --git a/instrumentation/README.neverzero.md b/instrumentation/README.neverzero.md
deleted file mode 100644
index 9bcae324..00000000
--- a/instrumentation/README.neverzero.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# NeverZero counters for LLVM instrumentation
-
-## Usage
-
-In larger, complex or reiterative programs the byte sized counters that collect
-the edge coverage can easily fill up and wrap around.
-This is not that much of an issue - unless by chance it wraps just to a value
-of zero when the program execution ends.
-In this case afl-fuzz is not able to see that the edge has been accessed and
-will ignore it.
-
-NeverZero prevents this behaviour. If a counter wraps, it jumps over the value
-0 directly to a 1. This improves path discovery (by a very little amount)
-at a very little cost (one instruction per edge).
-
-(The alternative of saturated counters has been tested also and proved to be
-inferior in terms of path discovery.)
-
-This is implemented in afl-gcc and afl-gcc-fast, however for llvm_mode this is
-optional if multithread safe counters are selected or the llvm version is below
-9 - as there are severe performance costs in these cases.
-
-If you want to enable this for llvm versions below 9 or thread safe counters
-then set
-
-```
-export AFL_LLVM_NOT_ZERO=1
-```
-
-In case you are on llvm 9 or greater and you do not want this behaviour then
-you can set:
-```
-AFL_LLVM_SKIP_NEVERZERO=1
-```
-If the target does not have extensive loops or functions that are called
-a lot then this can give a small performance boost.
-
-Please note that the default counter implementations are not thread safe!
-
-Support for thread safe counters in mode LLVM CLASSIC can be activated with setting
-`AFL_LLVM_THREADSAFE_INST=1`.
\ No newline at end of file
diff --git a/instrumentation/README.ngram.md b/instrumentation/README.ngram.md
deleted file mode 100644
index da61ef32..00000000
--- a/instrumentation/README.ngram.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# AFL N-Gram Branch Coverage
-
-## Source
-
-This is an LLVM-based implementation of the n-gram branch coverage proposed in
-the paper ["Be Sensitive and Collaborative: Analzying Impact of Coverage Metrics
-in Greybox Fuzzing"](https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf),
-by Jinghan Wang, et. al.
-
-Note that the original implementation (available
-[here](https://github.com/bitsecurerlab/afl-sensitive))
-is built on top of AFL's QEMU mode.
-This is essentially a port that uses LLVM vectorized instructions (available from
-llvm versions 4.0.1 and higher) to achieve the same results when compiling source code.
-
-In math the branch coverage is performed as follows:
-`map[current_location ^ prev_location[0] >> 1 ^ prev_location[1] >> 1 ^ ... up to n-1`] += 1`
-
-## Usage
-
-The size of `n` (i.e., the number of branches to remember) is an option
-that is specified either in the `AFL_LLVM_INSTRUMENT=NGRAM-{value}` or the
-`AFL_LLVM_NGRAM_SIZE` environment variable.
-Good values are 2, 4 or 8, valid are 2-16.
-
-It is highly recommended to increase the MAP_SIZE_POW2 definition in
-config.h to at least 18 and maybe up to 20 for this as otherwise too
-many map collisions occur.
diff --git a/instrumentation/README.out_of_line.md b/instrumentation/README.out_of_line.md
deleted file mode 100644
index 346fe98d..00000000
--- a/instrumentation/README.out_of_line.md
+++ /dev/null
@@ -1,19 +0,0 @@
-## Using AFL++ without inlined instrumentation
-
-  This file describes how you can disable inlining of instrumentation.
-
-
-By default, the GCC plugin will duplicate the effects of calling
-`__afl_trace` (see `afl-gcc-rt.o.c`) in instrumented code, instead of
-issuing function calls.
-
-The calls are presumed to be slower, more so because the rt file
-itself is not optimized by the compiler.
-
-Setting `AFL_GCC_OUT_OF_LINE=1` in the environment while compiling code
-with the plugin will disable this inlining, issuing calls to the
-unoptimized runtime instead.
-
-You probably don't want to do this, but it might be useful in certain
-AFL debugging scenarios, and it might work as a fallback in case
-something goes wrong with the inlined instrumentation.
diff --git a/instrumentation/README.persistent_mode.md b/instrumentation/README.persistent_mode.md
index c6ba2103..14e59f4a 100644
--- a/instrumentation/README.persistent_mode.md
+++ b/instrumentation/README.persistent_mode.md
@@ -3,23 +3,23 @@
 ## 1) Introduction
 
 In persistent mode, AFL++ fuzzes a target multiple times in a single forked
-process, instead of forking a new process for each fuzz execution.
-This is the most effective way to fuzz, as the speed can easily be x10 or x20
-times faster without any disadvanges.
-*All professional fuzzing uses this mode.*
+process, instead of forking a new process for each fuzz execution. This is the
+most effective way to fuzz, as the speed can easily be x10 or x20 times faster
+without any disadvantages. *All professional fuzzing uses this mode.*
 
 Persistent mode requires that the target can be called in one or more functions,
 and that it's state can be completely reset so that multiple calls can be
 performed without resource leaks, and that earlier runs will have no impact on
-future runs (an indicator for this is the `stability` value in the `afl-fuzz`
-UI, if this decreases to lower values in persistent mode compared to
-non-persistent mode, that the fuzz target keeps state).
+future runs. An indicator for this is the `stability` value in the `afl-fuzz`
+UI. If this decreases to lower values in persistent mode compared to
+non-persistent mode, then the fuzz target keeps state.
 
 Examples can be found in [utils/persistent_mode](../utils/persistent_mode).
 
-## 2) TLDR;
+## 2) TL;DR:
 
 Example `fuzz_target.c`:
+
 ```c
 #include "what_you_need_for_your_target.h"
 
@@ -27,7 +27,7 @@ __AFL_FUZZ_INIT();
 
 main() {
 
-  // anything else here, eg. command line arguments, initialization, etc.
+  // anything else here, e.g. command line arguments, initialization, etc.
 
 #ifdef __AFL_HAVE_MANUAL_CONTROL
   __AFL_INIT();
@@ -54,14 +54,16 @@ main() {
 
 }
 ```
+
 And then compile:
+
 ```
 afl-clang-fast -o fuzz_target fuzz_target.c -lwhat_you_need_for_your_target
 ```
-And that is it!
-The speed increase is usually x10 to x20.
 
-If you want to be able to compile the target without afl-clang-fast/lto then
+And that is it! The speed increase is usually x10 to x20.
+
+If you want to be able to compile the target without afl-clang-fast/lto, then
 add this just after the includes:
 
 ```c
@@ -72,20 +74,20 @@ add this just after the includes:
   #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
   #define __AFL_FUZZ_INIT() void sync(void);
   #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
-  #define __AFL_INIT() sync() 
+  #define __AFL_INIT() sync()
 #endif
 ```
 
 ## 3) Deferred initialization
 
-AFL tries to optimize performance by executing the targeted binary just once,
-stopping it just before `main()`, and then cloning this "main" process to get
-a steady supply of targets to fuzz.
+AFL++ tries to optimize performance by executing the targeted binary just once,
+stopping it just before `main()`, and then cloning this "main" process to get a
+steady supply of targets to fuzz.
 
-Although this approach eliminates much of the OS-, linker- and libc-level
-costs of executing the program, it does not always help with binaries that
-perform other time-consuming initialization steps - say, parsing a large config
-file before getting to the fuzzed data.
+Although this approach eliminates much of the OS-, linker- and libc-level costs
+of executing the program, it does not always help with binaries that perform
+other time-consuming initialization steps - say, parsing a large config file
+before getting to the fuzzed data.
 
 In such cases, it's beneficial to initialize the forkserver a bit later, once
 most of the initialization work is already done, but before the binary attempts
@@ -93,22 +95,21 @@ to read the fuzzed input and parse it; in some cases, this can offer a 10x+
 performance gain. You can implement delayed initialization in LLVM mode in a
 fairly simple way.
 
-First, find a suitable location in the code where the delayed cloning can 
-take place. This needs to be done with *extreme* care to avoid breaking the
-binary. In particular, the program will probably malfunction if you select
-a location after:
+First, find a suitable location in the code where the delayed cloning can take
+place. This needs to be done with *extreme* care to avoid breaking the binary.
+In particular, the program will probably malfunction if you select a location
+after:
 
-  - The creation of any vital threads or child processes - since the forkserver
-    can't clone them easily.
+- The creation of any vital threads or child processes - since the forkserver
+  can't clone them easily.
 
-  - The initialization of timers via `setitimer()` or equivalent calls.
+- The initialization of timers via `setitimer()` or equivalent calls.
 
-  - The creation of temporary files, network sockets, offset-sensitive file
-    descriptors, and similar shared-state resources - but only provided that
-    their state meaningfully influences the behavior of the program later on.
+- The creation of temporary files, network sockets, offset-sensitive file
+  descriptors, and similar shared-state resources - but only provided that their
+  state meaningfully influences the behavior of the program later on.
 
-  - Any access to the fuzzed input, including reading the metadata about its
-    size.
+- Any access to the fuzzed input, including reading the metadata about its size.
 
 With the location selected, add this code in the appropriate spot:
 
@@ -126,13 +127,12 @@ Finally, recompile the program with afl-clang-fast/afl-clang-lto/afl-gcc-fast
 (afl-gcc or afl-clang will *not* generate a deferred-initialization binary) -
 and you should be all set!
 
-
 ## 4) Persistent mode
 
 Some libraries provide APIs that are stateless, or whose state can be reset in
 between processing different input files. When such a reset is performed, a
 single long-lived process can be reused to try out multiple test cases,
-eliminating the need for repeated fork() calls and the associated OS overhead.
+eliminating the need for repeated `fork()` calls and the associated OS overhead.
 
 The basic structure of the program that does this would be:
 
@@ -145,34 +145,34 @@ The basic structure of the program that does this would be:
 
   }
 
-  /* Exit normally */
+  /* Exit normally. */
 ```
 
-The numerical value specified within the loop controls the maximum number
-of iterations before AFL will restart the process from scratch. This minimizes
+The numerical value specified within the loop controls the maximum number of
+iterations before AFL++ will restart the process from scratch. This minimizes
 the impact of memory leaks and similar glitches; 1000 is a good starting point,
-and going much higher increases the likelihood of hiccups without giving you
-any real performance benefits.
+and going much higher increases the likelihood of hiccups without giving you any
+real performance benefits.
 
-A more detailed template is shown in `../utils/persistent_mode/.`
-Similarly to the previous mode, the feature works only with afl-clang-fast; 
-`#ifdef` guards can be used to suppress it when using other compilers.
+A more detailed template is shown in
+[utils/persistent_mode](../utils/persistent_mode). Similarly to the deferred
+initialization, the feature works only with afl-clang-fast; `#ifdef` guards can
+be used to suppress it when using other compilers.
 
-Note that as with the previous mode, the feature is easy to misuse; if you
-do not fully reset the critical state, you may end up with false positives or
-waste a whole lot of CPU power doing nothing useful at all. Be particularly
+Note that as with the deferred initialization, the feature is easy to misuse; if
+you do not fully reset the critical state, you may end up with false positives
+or waste a whole lot of CPU power doing nothing useful at all. Be particularly
 wary of memory leaks and of the state of file descriptors.
 
-PS. Because there are task switches still involved, the mode isn't as fast as
-"pure" in-process fuzzing offered, say, by LLVM's LibFuzzer; but it is a lot
-faster than the normal `fork()` model, and compared to in-process fuzzing,
-should be a lot more robust.
+When running in this mode, the execution paths will inherently vary a bit
+depending on whether the input loop is being entered for the first time or
+executed again.
 
 ## 5) Shared memory fuzzing
 
-You can speed up the fuzzing process even more by receiving the fuzzing data
-via shared memory instead of stdin or files.
-This is a further speed multiplier of about 2x.
+You can speed up the fuzzing process even more by receiving the fuzzing data via
+shared memory instead of stdin or files. This is a further speed multiplier of
+about 2x.
 
 Setting this up is very easy:
 
@@ -181,14 +181,18 @@ After the includes set the following macro:
 ```c
 __AFL_FUZZ_INIT();
 ```
-Directly at the start of main - or if you are using the deferred forkserver
-with `__AFL_INIT()` then *after* `__AFL_INIT()` :
+
+Directly at the start of main - or if you are using the deferred forkserver with
+`__AFL_INIT()`, then *after* `__AFL_INIT()`:
+
 ```c
   unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
 ```
 
 Then as first line after the `__AFL_LOOP` while loop:
+
 ```c
   int len = __AFL_FUZZ_TESTCASE_LEN;
 ```
-and that is all!
+
+And that is all!
\ No newline at end of file
diff --git a/instrumentation/README.snapshot.md b/instrumentation/README.snapshot.md
deleted file mode 100644
index c794c2fd..00000000
--- a/instrumentation/README.snapshot.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# AFL++ snapshot feature
-
-**NOTE:** the snapshot lkm is currently not supported and needs a maintainer :-)
-
-Snapshotting is a feature that makes a snapshot from a process and then
-restores its state, which is faster then forking it again.
-
-All targets compiled with llvm_mode are automatically enabled for the
-snapshot feature.
-
-To use the snapshot feature for fuzzing compile and load this kernel
-module: [https://github.com/AFLplusplus/AFL-Snapshot-LKM](https://github.com/AFLplusplus/AFL-Snapshot-LKM)
-
-Note that is has little value for persistent (__AFL_LOOP) fuzzing.
-
-## Notes
-
-Snapshot does not work with multithreaded targets yet. Still in WIP, it is now usable only for single threaded applications.
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 4e25221a..37726607 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -621,7 +621,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
             bool   isStrncasecmp = true;
             bool   isIntMemcpy = true;
             bool   isStdString = true;
-            bool   addedNull = false;
             size_t optLen = 0;
 
             Function *Callee = callInst->getCalledFunction();
@@ -801,7 +800,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
                   if (literalLength + 1 == optLength) {
 
                     Str2.append("\0", 1);  // add null byte
-                    // addedNull = true;
 
                   }
 
@@ -909,8 +907,8 @@ bool ModuleSanitizerCoverage::instrumentModule(
 
                 if (optLen < 2) { continue; }
                 if (literalLength + 1 == optLen) {  // add null byte
+
                   thestring.append("\0", 1);
-                  addedNull = true;
 
                 }
 
@@ -922,14 +920,18 @@ bool ModuleSanitizerCoverage::instrumentModule(
             // was not already added
             if (!isMemcmp) {
 
-              if (addedNull == false && thestring[optLen - 1] != '\0') {
+              /*
+                            if (addedNull == false && thestring[optLen - 1] !=
+                 '\0') {
 
-                thestring.append("\0", 1);  // add null byte
-                optLen++;
+                              thestring.append("\0", 1);  // add null byte
+                              optLen++;
 
-              }
+                            }
 
-              if (!isStdString) {
+              */
+              if (!isStdString &&
+                  thestring.find('\0', 0) != std::string::npos) {
 
                 // ensure we do not have garbage
                 size_t offset = thestring.find('\0', 0);
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 7c04c0c5..bf07a154 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -291,7 +291,6 @@ bool AFLdict2filePass::runOnModule(Module &M) {
           bool   isIntMemcpy = true;
           bool   isStdString = true;
           bool   isStrstr = true;
-          bool   addedNull = false;
           size_t optLen = 0;
 
           Function *Callee = callInst->getCalledFunction();
@@ -590,8 +589,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
               if (optLen < 2) { continue; }
               if (literalLength + 1 == optLen) {  // add null byte
+
                 thestring.append("\0", 1);
-                addedNull = true;
 
               }
 
@@ -603,14 +602,17 @@ bool AFLdict2filePass::runOnModule(Module &M) {
           // was not already added
           if (!isMemcmp) {
 
-            if (addedNull == false && thestring[optLen - 1] != '\0') {
+            /*
+                        if (addedNull == false && thestring[optLen - 1] != '\0')
+               {
 
-              thestring.append("\0", 1);  // add null byte
-              optLen++;
+                          thestring.append("\0", 1);  // add null byte
+                          optLen++;
 
-            }
+                        }
 
-            if (!isStdString) {
+            */
+            if (!isStdString && thestring.find('\0', 0) != std::string::npos) {
 
               // ensure we do not have garbage
               size_t offset = thestring.find('\0', 0);
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
deleted file mode 100644
index cd43b437..00000000
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
-   american fuzzy lop++ - LLVM LTO instrumentation pass
-   ----------------------------------------------------
-
-   Written by Marc Heuse <mh@mh-sec.de>
-
-   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:
-
-     https://www.apache.org/licenses/LICENSE-2.0
-
-   This library is plugged into LLVM when invoking clang through afl-clang-lto.
-
- */
-
-#define AFL_LLVM_PASS
-
-#include "config.h"
-#include "debug.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include <list>
-#include <memory>
-#include <string>
-#include <fstream>
-#include <set>
-#include <iostream>
-
-#include "llvm/Config/llvm-config.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/CFG.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/MemorySSAUpdater.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Pass.h"
-#include "llvm/IR/Constants.h"
-
-#include "afl-llvm-common.h"
-
-using namespace llvm;
-
-namespace {
-
-class AFLLTOPass : public ModulePass {
-
- public:
-  static char ID;
-
-  AFLLTOPass() : ModulePass(ID) {
-
-    char *ptr;
-
-    if (getenv("AFL_DEBUG")) debug = 1;
-    if ((ptr = getenv("AFL_LLVM_LTO_STARTID")) != NULL)
-      if ((afl_global_id = (uint32_t)atoi(ptr)) < 0 ||
-          afl_global_id >= MAP_SIZE)
-        FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is not between 0 and %u\n",
-              ptr, MAP_SIZE - 1);
-
-    skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
-
-  }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-
-    ModulePass::getAnalysisUsage(AU);
-    AU.addRequired<DominatorTreeWrapperPass>();
-    AU.addRequired<LoopInfoWrapperPass>();
-
-  }
-
-  bool runOnModule(Module &M) override;
-
- protected:
-  uint32_t               afl_global_id = 1, autodictionary = 1;
-  uint32_t               function_minimum_size = 1;
-  uint32_t               inst_blocks = 0, inst_funcs = 0, total_instr = 0;
-  unsigned long long int map_addr = 0x10000;
-  const char *           skip_nozero = NULL;
-  const char *           use_threadsafe_counters = nullptr;
-
-};
-
-}  // namespace
-
-bool AFLLTOPass::runOnModule(Module &M) {
-
-  LLVMContext &            C = M.getContext();
-  std::vector<std::string> dictionary;
-  //  std::vector<CallInst *>          calls;
-  DenseMap<Value *, std::string *> valueMap;
-  std::vector<BasicBlock *>        BlockList;
-  std::ofstream                    dFile;
-  char *                           ptr;
-  size_t                           found = 0;
-
-  srand((unsigned int)time(NULL));
-
-  unsigned long long int moduleID =
-      (((unsigned long long int)(rand() & 0xffffffff)) << 32) | getpid();
-
-  IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
-  IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
-  IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
-
-  /* Show a banner */
-  setvbuf(stdout, NULL, _IONBF, 0);
-
-  if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
-
-    SAYF(cCYA "afl-llvm-lto" VERSION cRST
-              " by Marc \"vanHauser\" Heuse <mh@mh-sec.de>\n");
-
-  } else
-
-    be_quiet = 1;
-
-  use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
-
-  if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
-
-    dFile.open(ptr, std::ofstream::out | std::ofstream::app);
-    if (!dFile.is_open()) WARNF("Cannot access document file %s", ptr);
-
-  }
-
-  // we make this the default as the fixed map has problems with
-  // defered forkserver, early constructors, ifuncs and maybe more
-  /*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
-  map_addr = 0;
-
-  if ((ptr = getenv("AFL_LLVM_MAP_ADDR"))) {
-
-    uint64_t val;
-    if (!*ptr || !strcmp(ptr, "0") || !strcmp(ptr, "0x0")) {
-
-      map_addr = 0;
-
-    } else if (getenv("AFL_LLVM_MAP_DYNAMIC")) {
-
-      FATAL(
-          "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together");
-
-    } else if (strncmp(ptr, "0x", 2) != 0) {
-
-      map_addr = 0x10000;  // the default
-
-    } else {
-
-      val = strtoull(ptr, NULL, 16);
-      if (val < 0x100 || val > 0xffffffff00000000) {
-
-        FATAL(
-            "AFL_LLVM_MAP_ADDR must be a value between 0x100 and "
-            "0xffffffff00000000");
-
-      }
-
-      map_addr = val;
-
-    }
-
-  }
-
-  if (debug) { fprintf(stderr, "map address is 0x%llx\n", map_addr); }
-
-  /* Get/set the globals for the SHM region. */
-
-  GlobalVariable *AFLMapPtr = NULL;
-  Value *         MapPtrFixed = NULL;
-
-  if (!map_addr) {
-
-    AFLMapPtr =
-        new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
-                           GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
-
-  } else {
-
-    ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
-    MapPtrFixed =
-        ConstantExpr::getIntToPtr(MapAddr, PointerType::getUnqual(Int8Ty));
-
-  }
-
-  ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
-  ConstantInt *One = ConstantInt::get(Int8Ty, 1);
-
-  // This dumps all inialized global strings - might be useful in the future
-  /*
-  for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) {
-
-    GlobalVariable &GV=*G;
-    if (!GV.getName().str().empty()) {
-
-      fprintf(stderr, "Global Variable: %s", GV.getName().str().c_str());
-      if (GV.hasInitializer())
-        if (auto *Val = dyn_cast<ConstantDataArray>(GV.getInitializer()))
-          fprintf(stderr, " Value: \"%s\"", Val->getAsString().str().c_str());
-      fprintf(stderr, "\n");
-
-    }
-
-  }
-
-  */
-
-  scanForDangerousFunctions(&M);
-
-  /* Instrument all the things! */
-
-  int inst_blocks = 0;
-
-  for (auto &F : M) {
-
-    /*For debugging
-    AttributeSet X = F.getAttributes().getFnAttributes();
-    fprintf(stderr, "DEBUG: Module %s Function %s attributes %u\n",
-      M.getName().str().c_str(), F.getName().str().c_str(),
-      X.getNumAttributes());
-    */
-
-    if (F.size() < function_minimum_size) continue;
-    if (isIgnoreFunction(&F)) continue;
-
-    // the instrument file list check
-    AttributeList Attrs = F.getAttributes();
-#if LLVM_VERSION_MAJOR < 14
-    if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
-
-#else
-    if (Attrs.hasFnAttr(StringRef("skipinstrument"))) {
-
-#endif
-
-      if (debug)
-        fprintf(stderr,
-                "DEBUG: Function %s is not in a source file that was specified "
-                "in the instrument file list\n",
-                F.getName().str().c_str());
-      continue;
-
-    }
-
-    std::vector<BasicBlock *> InsBlocks;
-
-    if (autodictionary) {
-
-      /*  Some implementation notes.
-       *
-       *  We try to handle 3 cases:
-       *  - memcmp("foo", arg, 3) <- literal string
-       *  - static char globalvar[] = "foo";
-       *    memcmp(globalvar, arg, 3) <- global variable
-       *  - char localvar[] = "foo";
-       *    memcmp(locallvar, arg, 3) <- local variable
-       *
-       *  The local variable case is the hardest. We can only detect that
-       *  case if there is no reassignment or change in the variable.
-       *  And it might not work across llvm version.
-       *  What we do is hooking the initializer function for local variables
-       *  (llvm.memcpy.p0i8.p0i8.i64) and note the string and the assigned
-       *  variable. And if that variable is then used in a compare function
-       *  we use that noted string.
-       *  This seems not to work for tokens that have a size <= 4 :-(
-       *
-       *  - if the compared length is smaller than the string length we
-       *    save the full string. This is likely better for fuzzing but
-       *    might be wrong in a few cases depending on optimizers
-       *
-       *  - not using StringRef because there is a bug in the llvm 11
-       *    checkout I am using which sometimes points to wrong strings
-       *
-       *  Over and out. Took me a full day. damn. mh/vh
-       */
-
-      for (auto &BB : F) {
-
-        for (auto &IN : BB) {
-
-          CallInst *callInst = nullptr;
-          CmpInst * cmpInst = nullptr;
-
-          if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
-
-            Value *      op = cmpInst->getOperand(1);
-            ConstantInt *ilen = dyn_cast<ConstantInt>(op);
-
-            if (ilen && ilen->uge(0xffffffffffffffff) == false) {
-
-              u64 val2 = 0, val = ilen->getZExtValue();
-              u32 len = 0;
-              if (val > 0x10000 && val < 0xffffffff) len = 4;
-              if (val > 0x100000001 && val < 0xffffffffffffffff) len = 8;
-
-              if (len) {
-
-                auto c = cmpInst->getPredicate();
-
-                switch (c) {
-
-                  case CmpInst::FCMP_OGT:  // fall through
-                  case CmpInst::FCMP_OLE:  // fall through
-                  case CmpInst::ICMP_SLE:  // fall through
-                  case CmpInst::ICMP_SGT:
-
-                    // signed comparison and it is a negative constant
-                    if ((len == 4 && (val & 80000000)) ||
-                        (len == 8 && (val & 8000000000000000))) {
-
-                      if ((val & 0xffff) != 1) val2 = val - 1;
-                      break;
-
-                    }
-
-                    // fall through
-
-                  case CmpInst::FCMP_UGT:  // fall through
-                  case CmpInst::FCMP_ULE:  // fall through
-                  case CmpInst::ICMP_UGT:  // fall through
-                  case CmpInst::ICMP_ULE:
-                    if ((val & 0xffff) != 0xfffe) val2 = val + 1;
-                    break;
-
-                  case CmpInst::FCMP_OLT:  // fall through
-                  case CmpInst::FCMP_OGE:  // fall through
-                  case CmpInst::ICMP_SLT:  // fall through
-                  case CmpInst::ICMP_SGE:
-
-                    // signed comparison and it is a negative constant
-                    if ((len == 4 && (val & 80000000)) ||
-                        (len == 8 && (val & 8000000000000000))) {
-
-                      if ((val & 0xffff) != 1) val2 = val - 1;
-                      break;
-
-                    }
-
-                    // fall through
-
-                  case CmpInst::FCMP_ULT:  // fall through
-                  case CmpInst::FCMP_UGE:  // fall through
-                  case CmpInst::ICMP_ULT:  // fall through
-                  case CmpInst::ICMP_UGE:
-                    if ((val & 0xffff) != 1) val2 = val - 1;
-                    break;
-
-                  default:
-                    val2 = 0;
-
-                }
-
-                dictionary.push_back(std::string((char *)&val, len));
-                found++;
-
-                if (val2) {
-
-                  dictionary.push_back(std::string((char *)&val2, len));
-                  found++;
-
-                }
-
-              }
-
-            }
-
-          }
-
-          if ((callInst = dyn_cast<CallInst>(&IN))) {
-
-            bool   isStrcmp = true;
-            bool   isMemcmp = true;
-            bool   isStrncmp = true;
-            bool   isStrcasecmp = true;
-            bool   isStrncasecmp = true;
-            bool   isIntMemcpy = true;
-            bool   isStdString = true;
-            bool   addedNull = false;
-            size_t optLen = 0;
-
-            Function *Callee = callInst->getCalledFunction();
-            if (!Callee) continue;
-            if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
-            std::string FuncName = Callee->getName().str();
-
-            isStrcmp &= (!FuncName.compare("strcmp") ||
-                         !FuncName.compare("xmlStrcmp") ||
-                         !FuncName.compare("xmlStrEqual") ||
-                         !FuncName.compare("g_strcmp0") ||
-                         !FuncName.compare("curl_strequal") ||
-                         !FuncName.compare("strcsequal"));
-            isMemcmp &=
-                (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
-                 !FuncName.compare("CRYPTO_memcmp") ||
-                 !FuncName.compare("OPENSSL_memcmp") ||
-                 !FuncName.compare("memcmp_const_time") ||
-                 !FuncName.compare("memcmpct"));
-            isStrncmp &= (!FuncName.compare("strncmp") ||
-                          !FuncName.compare("xmlStrncmp") ||
-                          !FuncName.compare("curl_strnequal"));
-            isStrcasecmp &= (!FuncName.compare("strcasecmp") ||
-                             !FuncName.compare("stricmp") ||
-                             !FuncName.compare("ap_cstr_casecmp") ||
-                             !FuncName.compare("OPENSSL_strcasecmp") ||
-                             !FuncName.compare("xmlStrcasecmp") ||
-                             !FuncName.compare("g_strcasecmp") ||
-                             !FuncName.compare("g_ascii_strcasecmp") ||
-                             !FuncName.compare("Curl_strcasecompare") ||
-                             !FuncName.compare("Curl_safe_strcasecompare") ||
-                             !FuncName.compare("cmsstrcasecmp"));
-            isStrncasecmp &= (!FuncName.compare("strncasecmp") ||
-                              !FuncName.compare("strnicmp") ||
-                              !FuncName.compare("ap_cstr_casecmpn") ||
-                              !FuncName.compare("OPENSSL_strncasecmp") ||
-                              !FuncName.compare("xmlStrncasecmp") ||
-                              !FuncName.compare("g_ascii_strncasecmp") ||
-                              !FuncName.compare("Curl_strncasecompare") ||
-                              !FuncName.compare("g_strncasecmp"));
-            isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64");
-            isStdString &=
-                ((FuncName.find("basic_string") != std::string::npos &&
-                  FuncName.find("compare") != std::string::npos) ||
-                 (FuncName.find("basic_string") != std::string::npos &&
-                  FuncName.find("find") != std::string::npos));
-
-            /* we do something different here, putting this BB and the
-               successors in a block map */
-            if (!FuncName.compare("__afl_persistent_loop")) {
-
-              BlockList.push_back(&BB);
-              /*
-                            for (succ_iterator SI = succ_begin(&BB), SE =
-                 succ_end(&BB); SI != SE; ++SI) {
-
-                              BasicBlock *succ = *SI;
-                              BlockList.push_back(succ);
-
-                            }
-
-              */
-
-            }
-
-            if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
-                !isStrncasecmp && !isIntMemcpy && !isStdString)
-              continue;
-
-            /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function
-             * prototype */
-            FunctionType *FT = Callee->getFunctionType();
-
-            isStrcmp &= FT->getNumParams() == 2 &&
-                        FT->getReturnType()->isIntegerTy(32) &&
-                        FT->getParamType(0) == FT->getParamType(1) &&
-                        FT->getParamType(0) ==
-                            IntegerType::getInt8PtrTy(M.getContext());
-            isStrcasecmp &= FT->getNumParams() == 2 &&
-                            FT->getReturnType()->isIntegerTy(32) &&
-                            FT->getParamType(0) == FT->getParamType(1) &&
-                            FT->getParamType(0) ==
-                                IntegerType::getInt8PtrTy(M.getContext());
-            isMemcmp &= FT->getNumParams() == 3 &&
-                        FT->getReturnType()->isIntegerTy(32) &&
-                        FT->getParamType(0)->isPointerTy() &&
-                        FT->getParamType(1)->isPointerTy() &&
-                        FT->getParamType(2)->isIntegerTy();
-            isStrncmp &= FT->getNumParams() == 3 &&
-                         FT->getReturnType()->isIntegerTy(32) &&
-                         FT->getParamType(0) == FT->getParamType(1) &&
-                         FT->getParamType(0) ==
-                             IntegerType::getInt8PtrTy(M.getContext()) &&
-                         FT->getParamType(2)->isIntegerTy();
-            isStrncasecmp &= FT->getNumParams() == 3 &&
-                             FT->getReturnType()->isIntegerTy(32) &&
-                             FT->getParamType(0) == FT->getParamType(1) &&
-                             FT->getParamType(0) ==
-                                 IntegerType::getInt8PtrTy(M.getContext()) &&
-                             FT->getParamType(2)->isIntegerTy();
-            isStdString &= FT->getNumParams() >= 2 &&
-                           FT->getParamType(0)->isPointerTy() &&
-                           FT->getParamType(1)->isPointerTy();
-
-            if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
-                !isStrncasecmp && !isIntMemcpy && !isStdString)
-              continue;
-
-            /* is a str{n,}{case,}cmp/memcmp, check if we have
-             * str{case,}cmp(x, "const") or str{case,}cmp("const", x)
-             * strn{case,}cmp(x, "const", ..) or strn{case,}cmp("const", x, ..)
-             * memcmp(x, "const", ..) or memcmp("const", x, ..) */
-            Value *Str1P = callInst->getArgOperand(0),
-                  *Str2P = callInst->getArgOperand(1);
-            std::string Str1, Str2;
-            StringRef   TmpStr;
-            bool        HasStr1;
-            getConstantStringInfo(Str1P, TmpStr);
-            if (TmpStr.empty()) {
-
-              HasStr1 = false;
-
-            } else {
-
-              HasStr1 = true;
-              Str1 = TmpStr.str();
-
-            }
-
-            bool HasStr2;
-            getConstantStringInfo(Str2P, TmpStr);
-            if (TmpStr.empty()) {
-
-              HasStr2 = false;
-
-            } else {
-
-              HasStr2 = true;
-              Str2 = TmpStr.str();
-
-            }
-
-            if (debug)
-              fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
-                      FuncName.c_str(), Str1P, Str1P->getName().str().c_str(),
-                      Str1.c_str(), HasStr1 == true ? "true" : "false", Str2P,
-                      Str2P->getName().str().c_str(), Str2.c_str(),
-                      HasStr2 == true ? "true" : "false");
-
-            // we handle the 2nd parameter first because of llvm memcpy
-            if (!HasStr2) {
-
-              auto *Ptr = dyn_cast<ConstantExpr>(Str2P);
-              if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
-
-                if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
-
-                  if (Var->hasInitializer()) {
-
-                    if (auto *Array = dyn_cast<ConstantDataArray>(
-                            Var->getInitializer())) {
-
-                      HasStr2 = true;
-                      Str2 = Array->getRawDataValues().str();
-
-                    }
-
-                  }
-
-                }
-
-              }
-
-            }
-
-            // for the internal memcpy routine we only care for the second
-            // parameter and are not reporting anything.
-            if (isIntMemcpy == true) {
-
-              if (HasStr2 == true) {
-
-                Value *      op2 = callInst->getArgOperand(2);
-                ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
-                if (ilen) {
-
-                  uint64_t literalLength = Str2.size();
-                  uint64_t optLength = ilen->getZExtValue();
-                  if (optLength > literalLength + 1) {
-
-                    optLength = Str2.length() + 1;
-
-                  }
-
-                  if (literalLength + 1 == optLength) {
-
-                    Str2.append("\0", 1);  // add null byte
-                    // addedNull = true;
-
-                  }
-
-                }
-
-                valueMap[Str1P] = new std::string(Str2);
-
-                if (debug)
-                  fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), Str1P);
-                continue;
-
-              }
-
-              continue;
-
-            }
-
-            // Neither a literal nor a global variable?
-            // maybe it is a local variable that we saved
-            if (!HasStr2) {
-
-              std::string *strng = valueMap[Str2P];
-              if (strng && !strng->empty()) {
-
-                Str2 = *strng;
-                HasStr2 = true;
-                if (debug)
-                  fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(),
-                          Str2P);
-
-              }
-
-            }
-
-            if (!HasStr1) {
-
-              auto Ptr = dyn_cast<ConstantExpr>(Str1P);
-
-              if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
-
-                if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
-
-                  if (Var->hasInitializer()) {
-
-                    if (auto *Array = dyn_cast<ConstantDataArray>(
-                            Var->getInitializer())) {
-
-                      HasStr1 = true;
-                      Str1 = Array->getRawDataValues().str();
-
-                    }
-
-                  }
-
-                }
-
-              }
-
-            }
-
-            // Neither a literal nor a global variable?
-            // maybe it is a local variable that we saved
-            if (!HasStr1) {
-
-              std::string *strng = valueMap[Str1P];
-              if (strng && !strng->empty()) {
-
-                Str1 = *strng;
-                HasStr1 = true;
-                if (debug)
-                  fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(),
-                          Str1P);
-
-              }
-
-            }
-
-            /* handle cases of one string is const, one string is variable */
-            if (!(HasStr1 ^ HasStr2)) continue;
-
-            std::string thestring;
-
-            if (HasStr1)
-              thestring = Str1;
-            else
-              thestring = Str2;
-
-            optLen = thestring.length();
-            if (optLen < 2 || (optLen == 2 && !thestring[1])) { continue; }
-
-            if (isMemcmp || isStrncmp || isStrncasecmp) {
-
-              Value *      op2 = callInst->getArgOperand(2);
-              ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
-
-              if (ilen) {
-
-                uint64_t literalLength = optLen;
-                optLen = ilen->getZExtValue();
-                if (optLen > literalLength + 1) { optLen = literalLength + 1; }
-                if (optLen < 2) { continue; }
-                if (literalLength + 1 == optLen) {  // add null byte
-                  thestring.append("\0", 1);
-                  addedNull = true;
-
-                }
-
-              }
-
-            }
-
-            // add null byte if this is a string compare function and a null
-            // was not already added
-            if (!isMemcmp) {
-
-              if (addedNull == false && thestring[optLen - 1] != '\0') {
-
-                thestring.append("\0", 1);  // add null byte
-                optLen++;
-
-              }
-
-              if (!isStdString) {
-
-                // ensure we do not have garbage
-                size_t offset = thestring.find('\0', 0);
-                if (offset + 1 < optLen) optLen = offset + 1;
-                thestring = thestring.substr(0, optLen);
-
-              }
-
-            }
-
-            if (!be_quiet) {
-
-              fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
-                      thestring.length());
-              for (uint8_t i = 0; i < thestring.length(); i++) {
-
-                uint8_t c = thestring[i];
-                if (c <= 32 || c >= 127)
-                  fprintf(stderr, "\\x%02x", c);
-                else
-                  fprintf(stderr, "%c", c);
-
-              }
-
-              fprintf(stderr, "\"\n");
-
-            }
-
-            // we take the longer string, even if the compare was to a
-            // shorter part. Note that depending on the optimizer of the
-            // compiler this can be wrong, but it is more likely that this
-            // is helping the fuzzer
-            if (optLen != thestring.length()) optLen = thestring.length();
-            if (optLen > MAX_AUTO_EXTRA) optLen = MAX_AUTO_EXTRA;
-            if (optLen < MIN_AUTO_EXTRA)  // too short? skip
-              continue;
-
-            dictionary.push_back(thestring.substr(0, optLen));
-
-          }
-
-        }
-
-      }
-
-    }
-
-    for (auto &BB : F) {
-
-      if (F.size() == 1) {
-
-        InsBlocks.push_back(&BB);
-        continue;
-
-      }
-
-      uint32_t succ = 0;
-      for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB); SI != SE;
-           ++SI)
-        if ((*SI)->size() > 0) succ++;
-      if (succ < 2)  // no need to instrument
-        continue;
-
-      if (BlockList.size()) {
-
-        int skip = 0;
-        for (uint32_t k = 0; k < BlockList.size(); k++) {
-
-          if (&BB == BlockList[k]) {
-
-            if (debug)
-              fprintf(stderr,
-                      "DEBUG: Function %s skipping BB with/after __afl_loop\n",
-                      F.getName().str().c_str());
-            skip = 1;
-
-          }
-
-        }
-
-        if (skip) continue;
-
-      }
-
-      InsBlocks.push_back(&BB);
-
-    }
-
-    if (InsBlocks.size() > 0) {
-
-      uint32_t i = InsBlocks.size();
-
-      do {
-
-        --i;
-        BasicBlock *              newBB = NULL;
-        BasicBlock *              origBB = &(*InsBlocks[i]);
-        std::vector<BasicBlock *> Successors;
-        Instruction *             TI = origBB->getTerminator();
-        uint32_t                  fs = origBB->getParent()->size();
-        uint32_t                  countto;
-
-        for (succ_iterator SI = succ_begin(origBB), SE = succ_end(origBB);
-             SI != SE; ++SI) {
-
-          BasicBlock *succ = *SI;
-          Successors.push_back(succ);
-
-        }
-
-        if (fs == 1) {
-
-          newBB = origBB;
-          countto = 1;
-
-        } else {
-
-          if (TI == NULL || TI->getNumSuccessors() < 2) continue;
-          countto = Successors.size();
-
-        }
-
-        // if (Successors.size() != TI->getNumSuccessors())
-        //  FATAL("Different successor numbers %lu <-> %u\n", Successors.size(),
-        //        TI->getNumSuccessors());
-
-        for (uint32_t j = 0; j < countto; j++) {
-
-          if (fs != 1) newBB = llvm::SplitEdge(origBB, Successors[j]);
-
-          if (!newBB) {
-
-            if (!be_quiet) WARNF("Split failed!");
-            continue;
-
-          }
-
-          if (dFile.is_open()) {
-
-            dFile << "ModuleID=" << moduleID
-                  << " Function=" << F.getName().str()
-                  << " edgeID=" << afl_global_id << "\n";
-
-          }
-
-          BasicBlock::iterator IP = newBB->getFirstInsertionPt();
-          IRBuilder<>          IRB(&(*IP));
-
-          /* Set the ID of the inserted basic block */
-
-          ConstantInt *CurLoc = ConstantInt::get(Int32Ty, afl_global_id++);
-
-          /* Load SHM pointer */
-
-          Value *MapPtrIdx;
-
-          if (map_addr) {
-
-            MapPtrIdx = IRB.CreateGEP(MapPtrFixed, CurLoc);
-
-          } else {
-
-            LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
-            MapPtr->setMetadata(M.getMDKindID("nosanitize"),
-                                MDNode::get(C, None));
-            MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
-
-          }
-
-          /* Update bitmap */
-
-          if (use_threadsafe_counters) {
-
-            IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
-#if LLVM_VERSION_MAJOR >= 13
-                                llvm::MaybeAlign(1),
-#endif
-                                llvm::AtomicOrdering::Monotonic);
-
-          } else {
-
-            LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
-            Counter->setMetadata(M.getMDKindID("nosanitize"),
-                                 MDNode::get(C, None));
-
-            Value *Incr = IRB.CreateAdd(Counter, One);
-
-            if (skip_nozero == NULL) {
-
-              auto cf = IRB.CreateICmpEQ(Incr, Zero);
-              auto carry = IRB.CreateZExt(cf, Int8Ty);
-              Incr = IRB.CreateAdd(Incr, carry);
-
-            }
-
-            IRB.CreateStore(Incr, MapPtrIdx)
-                ->setMetadata(M.getMDKindID("nosanitize"),
-                              MDNode::get(C, None));
-
-          }
-
-          // done :)
-
-          inst_blocks++;
-
-        }
-
-      } while (i > 0);
-
-    }
-
-  }
-
-  if (dFile.is_open()) dFile.close();
-
-  // save highest location ID to global variable
-  // do this after each function to fail faster
-  if (!be_quiet && afl_global_id > MAP_SIZE &&
-      afl_global_id > FS_OPT_MAX_MAPSIZE) {
-
-    uint32_t pow2map = 1, map = afl_global_id;
-    while ((map = map >> 1))
-      pow2map++;
-    WARNF(
-        "We have %u blocks to instrument but the map size is only %u. Either "
-        "edit config.h and set MAP_SIZE_POW2 from %d to %u, then recompile "
-        "afl-fuzz and llvm_mode and then make this target - or set "
-        "AFL_MAP_SIZE with at least size %u when running afl-fuzz with this "
-        "target.",
-        afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
-
-  }
-
-  if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) {
-
-    // yes we could create our own function, insert it into ctors ...
-    // but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
-
-    Function *f = M.getFunction("__afl_auto_init_globals");
-
-    if (!f) {
-
-      fprintf(stderr,
-              "Error: init function could not be found (this should not "
-              "happen)\n");
-      exit(-1);
-
-    }
-
-    BasicBlock *bb = &f->getEntryBlock();
-    if (!bb) {
-
-      fprintf(stderr,
-              "Error: init function does not have an EntryBlock (this should "
-              "not happen)\n");
-      exit(-1);
-
-    }
-
-    BasicBlock::iterator IP = bb->getFirstInsertionPt();
-    IRBuilder<>          IRB(&(*IP));
-
-    if (map_addr) {
-
-      GlobalVariable *AFLMapAddrFixed = new GlobalVariable(
-          M, Int64Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr");
-      ConstantInt *MapAddr = ConstantInt::get(Int64Ty, map_addr);
-      StoreInst *  StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
-      StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"),
-                                MDNode::get(C, None));
-
-    }
-
-    if (getenv("AFL_LLVM_LTO_DONTWRITEID") == NULL) {
-
-      uint32_t write_loc = (((afl_global_id + 63) >> 6) << 6);
-
-      GlobalVariable *AFLFinalLoc = new GlobalVariable(
-          M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, "__afl_final_loc");
-      ConstantInt *const_loc = ConstantInt::get(Int32Ty, write_loc);
-      StoreInst *  StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
-      StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
-                                 MDNode::get(C, None));
-
-    }
-
-    if (dictionary.size()) {
-
-      size_t memlen = 0, count = 0;
-
-      // sort and unique the dictionary
-      std::sort(dictionary.begin(), dictionary.end());
-      auto last = std::unique(dictionary.begin(), dictionary.end());
-      dictionary.erase(last, dictionary.end());
-
-      for (auto token : dictionary) {
-
-        memlen += token.length();
-        count++;
-
-      }
-
-      if (!be_quiet)
-        printf("AUTODICTIONARY: %zu string%s found\n", count,
-               count == 1 ? "" : "s");
-
-      if (count) {
-
-        auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]);
-
-        count = 0;
-
-        size_t offset = 0;
-        for (auto token : dictionary) {
-
-          if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
-
-            ptrhld.get()[offset++] = (uint8_t)token.length();
-            memcpy(ptrhld.get() + offset, token.c_str(), token.length());
-            offset += token.length();
-            count++;
-
-          }
-
-        }
-
-        GlobalVariable *AFLDictionaryLen =
-            new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
-                               0, "__afl_dictionary_len");
-        ConstantInt *const_len = ConstantInt::get(Int32Ty, offset);
-        StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen);
-        StoreDictLen->setMetadata(M.getMDKindID("nosanitize"),
-                                  MDNode::get(C, None));
-
-        ArrayType *ArrayTy = ArrayType::get(IntegerType::get(C, 8), offset);
-        GlobalVariable *AFLInternalDictionary = new GlobalVariable(
-            M, ArrayTy, true, GlobalValue::ExternalLinkage,
-            ConstantDataArray::get(C,
-                                   *(new ArrayRef<char>(ptrhld.get(), offset))),
-            "__afl_internal_dictionary");
-        AFLInternalDictionary->setInitializer(ConstantDataArray::get(
-            C, *(new ArrayRef<char>(ptrhld.get(), offset))));
-        AFLInternalDictionary->setConstant(true);
-
-        GlobalVariable *AFLDictionary = new GlobalVariable(
-            M, PointerType::get(Int8Ty, 0), false, GlobalValue::ExternalLinkage,
-            0, "__afl_dictionary");
-
-        Value *AFLDictOff = IRB.CreateGEP(AFLInternalDictionary, Zero);
-        Value *AFLDictPtr =
-            IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Ty, 0));
-        StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary);
-        StoreDict->setMetadata(M.getMDKindID("nosanitize"),
-                               MDNode::get(C, None));
-
-      }
-
-    }
-
-  }
-
-  /* Say something nice. */
-
-  if (!be_quiet) {
-
-    if (!inst_blocks)
-      WARNF("No instrumentation targets found.");
-    else {
-
-      char modeline[100];
-      snprintf(modeline, sizeof(modeline), "%s%s%s%s%s",
-               getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
-               getenv("AFL_USE_ASAN") ? ", ASAN" : "",
-               getenv("AFL_USE_MSAN") ? ", MSAN" : "",
-               getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
-               getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
-      OKF("Instrumented %d locations with no collisions (on average %llu "
-          "collisions would be in afl-gcc/vanilla AFL) (%s mode).",
-          inst_blocks, calculateCollisions(inst_blocks), modeline);
-
-    }
-
-  }
-
-  return true;
-
-}
-
-char AFLLTOPass::ID = 0;
-
-static void registerAFLLTOPass(const PassManagerBuilder &,
-                               legacy::PassManagerBase &PM) {
-
-  PM.add(new AFLLTOPass());
-
-}
-
-static RegisterPass<AFLLTOPass> X("afl-lto", "afl++ LTO instrumentation pass",
-                                  false, false);
-
-static RegisterStandardPasses RegisterAFLLTOPass(
-    PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerAFLLTOPass);
-
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 41a3e178..21ce0cf9 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -45,18 +45,12 @@ typedef long double max_align_t;
 #endif
 
 #include "llvm/IR/IRBuilder.h"
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
-#else
 #include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#endif
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
 
 #if LLVM_VERSION_MAJOR > 3 || \
     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
@@ -74,26 +68,17 @@ using namespace llvm;
 
 namespace {
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-class AFLCoverage : public PassInfoMixin<AFLCoverage> {
- public:
-  AFLCoverage() {
-#else
 class AFLCoverage : public ModulePass {
+
  public:
   static char ID;
   AFLCoverage() : ModulePass(ID) {
-#endif
 
     initInstrumentList();
 
   }
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-#else
   bool runOnModule(Module &M) override;
-#endif
 
  protected:
   uint32_t    ngram_size = 0;
@@ -107,41 +92,7 @@ class AFLCoverage : public ModulePass {
 
 }  // namespace
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
-llvmGetPassPluginInfo() {
-  return {
-    LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1",
-    /* lambda to insert our pass into the pass pipeline. */
-    [](PassBuilder &PB) {
-#if 1
-       using OptimizationLevel = typename PassBuilder::OptimizationLevel;
-       PB.registerOptimizerLastEPCallback(
-         [](ModulePassManager &MPM, OptimizationLevel OL) {
-           MPM.addPass(AFLCoverage());
-         }
-       );
-/* TODO LTO registration */
-#else
-       using PipelineElement = typename PassBuilder::PipelineElement;
-       PB.registerPipelineParsingCallback(
-         [](StringRef Name, ModulePassManager &MPM, ArrayRef<PipelineElement>) {
-            if ( Name == "AFLCoverage" ) {
-              MPM.addPass(AFLCoverage());
-              return true;
-            } else {
-              return false;
-            }
-         }
-       );
-#endif
-    }
-  };
-}
-#else
-
 char AFLCoverage::ID = 0;
-#endif
 
 /* needed up to 3.9.0 */
 #if LLVM_VERSION_MAJOR == 3 && \
@@ -167,13 +118,7 @@ uint64_t PowerOf2Ceil(unsigned in) {
     (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
   #define AFL_HAVE_VECTOR_INTRINSICS 1
 #endif
-
-
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
-#else
 bool AFLCoverage::runOnModule(Module &M) {
-#endif
 
   LLVMContext &C = M.getContext();
 
@@ -188,10 +133,6 @@ bool AFLCoverage::runOnModule(Module &M) {
   u32             rand_seed;
   unsigned int    cur_loc = 0;
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-  auto PA = PreservedAnalyses::all();
-#endif
-
   /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
   gettimeofday(&tv, &tz);
   rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@@ -1029,15 +970,10 @@ bool AFLCoverage::runOnModule(Module &M) {
 
   }
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-  return PA;
-#else
   return true;
-#endif
 
 }
 
-#if LLVM_VERSION_MAJOR < 7 /* use old pass manager */
 static void registerAFLPass(const PassManagerBuilder &,
                             legacy::PassManagerBase &PM) {
 
@@ -1050,4 +986,4 @@ static RegisterStandardPasses RegisterAFLPass(
 
 static RegisterStandardPasses RegisterAFLPass0(
     PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);
-#endif
+
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index 5fd8efb1..1ec2bbfe 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -26,17 +26,11 @@
 
 #include "llvm/ADT/Statistic.h"
 #include "llvm/IR/IRBuilder.h"
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
-#else
 #include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#endif
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -58,28 +52,28 @@ using namespace llvm;
 
 namespace {
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-class CompareTransform : public PassInfoMixin<CompareTransform> {
-
- public:
-  CompareTransform() {
-#else
 class CompareTransform : public ModulePass {
 
  public:
   static char ID;
   CompareTransform() : ModulePass(ID) {
-#endif
 
     initInstrumentList();
 
   }
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-#else
   bool runOnModule(Module &M) override;
+
+#if LLVM_VERSION_MAJOR < 4
+  const char *getPassName() const override {
+
+#else
+  StringRef      getPassName() const override {
+
 #endif
+    return "transforms compare functions";
+
+  }
 
  private:
   bool transformCmps(Module &M, const bool processStrcmp,
@@ -91,40 +85,7 @@ class CompareTransform : public ModulePass {
 
 }  // namespace
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
-llvmGetPassPluginInfo() {
-  return {
-    LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1",
-    /* lambda to insert our pass into the pass pipeline. */
-    [](PassBuilder &PB) {
-#if 1
-       using OptimizationLevel = typename PassBuilder::OptimizationLevel;
-       PB.registerOptimizerLastEPCallback(
-         [](ModulePassManager &MPM, OptimizationLevel OL) {
-           MPM.addPass(CompareTransform());
-         }
-       );
-/* TODO LTO registration */
-#else
-       using PipelineElement = typename PassBuilder::PipelineElement;
-       PB.registerPipelineParsingCallback(
-         [](StringRef Name, ModulePassManager &MPM, ArrayRef<PipelineElement>) {
-            if ( Name == "comparetransform" ) {
-              MPM.addPass(CompareTransform());
-              return true;
-            } else {
-              return false;
-            }
-         }
-       );
-#endif
-    }
-  };
-}
-#else
 char CompareTransform::ID = 0;
-#endif
 
 bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
                                      const bool processMemcmp,
@@ -484,6 +445,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
     }
 
+    // the following is in general OK, but strncmp is sometimes used in binary
+    // data structures and this can result in crashes :( so it is commented out
+    /*
+
     // add null termination character implicit in c strings
     if (!isMemcmp && TmpConstStr[TmpConstStr.length() - 1]) {
 
@@ -491,10 +456,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
     }
 
+    */
+
     // in the unusual case the const str has embedded null
     // characters, the string comparison functions should terminate
     // at the first null
-    if (!isMemcmp) {
+    if (!isMemcmp && TmpConstStr.find('\0') != std::string::npos) {
 
       TmpConstStr.assign(TmpConstStr, 0, TmpConstStr.find('\0') + 1);
 
@@ -631,11 +598,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
 }
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
-#else
 bool CompareTransform::runOnModule(Module &M) {
-#endif
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
     printf(
@@ -644,26 +607,13 @@ bool CompareTransform::runOnModule(Module &M) {
   else
     be_quiet = 1;
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-  auto PA = PreservedAnalyses::all();
-#endif
-
   transformCmps(M, true, true, true, true, true);
   verifyModule(M);
 
-#if LLVM_MAJOR >= 7 /* use new pass manager */
-/*  if (modified) {
-    PA.abandon<XX_Manager>();
-  }*/
-
-  return PA;
-#else
   return true;
-#endif
 
 }
 
-#if LLVM_MAJOR < 7 /* use old pass manager */
 static void registerCompTransPass(const PassManagerBuilder &,
                                   legacy::PassManagerBase &PM) {
 
@@ -682,5 +632,4 @@ static RegisterStandardPasses RegisterCompTransPass0(
 static RegisterStandardPasses RegisterCompTransPassLTO(
     PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass);
 #endif
-#endif
 
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 8ea67a21..d1254e40 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1,7 +1,6 @@
 /*
  * Copyright 2016 laf-intel
  * extended for floating point by Heiko Eißfeldt
- * adapted to new pass manager by Heiko Eißfeldt
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,15 +28,8 @@
 
 #include "llvm/Pass.h"
 #include "llvm/Support/raw_ostream.h"
-
-#if LLVM_MAJOR >= 7
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
-#else
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#endif
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/IR/Module.h"
 
@@ -61,26 +53,27 @@ using namespace llvm;
 
 namespace {
 
-#if LLVM_MAJOR >= 7
-class SplitComparesTransform : public PassInfoMixin<SplitComparesTransform> {
- public:
-//  static char ID;
-  SplitComparesTransform() : enableFPSplit(0) {
-#else
 class SplitComparesTransform : public ModulePass {
+
  public:
   static char ID;
   SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
-#endif
 
     initInstrumentList();
+
   }
 
-#if LLVM_MAJOR >= 7
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-#else
   bool runOnModule(Module &M) override;
+#if LLVM_VERSION_MAJOR >= 4
+  StringRef getPassName() const override {
+
+#else
+  const char *getPassName() const override {
+
 #endif
+    return "AFL_SplitComparesTransform";
+
+  }
 
  private:
   int enableFPSplit;
@@ -169,40 +162,7 @@ class SplitComparesTransform : public ModulePass {
 
 }  // namespace
 
-#if LLVM_MAJOR >= 7
-extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
-llvmGetPassPluginInfo() {
-  return {
-    LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1",
-    /* lambda to insert our pass into the pass pipeline. */
-    [](PassBuilder &PB) {
-#if 1
-       using OptimizationLevel = typename PassBuilder::OptimizationLevel;
-       PB.registerOptimizerLastEPCallback(
-         [](ModulePassManager &MPM, OptimizationLevel OL) {
-           MPM.addPass(SplitComparesTransform());
-         }
-       );
-/* TODO LTO registration */
-#else
-       using PipelineElement = typename PassBuilder::PipelineElement;
-       PB.registerPipelineParsingCallback(
-         [](StringRef Name, ModulePassManager &MPM, ArrayRef<PipelineElement>) {
-            if ( Name == "splitcompares" ) {
-              MPM.addPass(SplitComparesTransform());
-              return true;
-            } else {
-              return false;
-            }
-         }
-       );
-#endif
-    }
-  };
-}
-#else
 char SplitComparesTransform::ID = 0;
-#endif
 
 /// This function splits FCMP instructions with xGE or xLE predicates into two
 /// FCMP instructions with predicate xGT or xLT and EQ
@@ -1356,11 +1316,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
 
 }
 
-#if LLVM_MAJOR >= 7
-PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
-#else
 bool SplitComparesTransform::runOnModule(Module &M) {
-#endif
 
   char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
   if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
@@ -1371,7 +1327,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
       getenv("AFL_DEBUG") != NULL) {
 
-    errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by "
+    errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
               "heiko@hexco.de (splitting icmp to "
            << target_bitwidth << " bit)\n";
 
@@ -1383,10 +1339,6 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   }
 
-#if LLVM_MAJOR >= 7
-  auto PA = PreservedAnalyses::all();
-#endif
-
   if (enableFPSplit) {
 
     count = splitFPCompares(M);
@@ -1419,13 +1371,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
           auto op0 = CI->getOperand(0);
           auto op1 = CI->getOperand(1);
-          if (!op0 || !op1) {
-#if LLVM_MAJOR >= 7
-            return PA;
-#else
-            return false;
-#endif
-          }
+          if (!op0 || !op1) { return false; }
           auto iTy1 = dyn_cast<IntegerType>(op0->getType());
           if (iTy1 && isa<IntegerType>(op1->getType())) {
 
@@ -1474,25 +1420,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
   }
 
-  if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
-      getenv("AFL_DEBUG") != NULL) {
-    errs() << count << " comparisons found\n";
-  }
-
-#if LLVM_MAJOR >= 7
-/*  if (modified) {
-    PA.abandon<XX_Manager>();
-  }*/
-
-  return PA;
-#else
   return true;
-#endif
 
 }
 
-#if LLVM_MAJOR < 7 /* use old pass manager */
-
 static void registerSplitComparesPass(const PassManagerBuilder &,
                                       legacy::PassManagerBase &PM) {
 
@@ -1516,4 +1447,4 @@ static RegisterPass<SplitComparesTransform> X("splitcompares",
                                               "AFL++ split compares",
                                               true /* Only looks at CFG */,
                                               true /* Analysis Pass */);
-#endif
+
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index ca8cdc9b..1e32a31d 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -27,17 +27,11 @@
 
 #include "llvm/ADT/Statistic.h"
 #include "llvm/IR/IRBuilder.h"
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
-#else
 #include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#endif
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -60,25 +54,16 @@ using namespace llvm;
 
 namespace {
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-class SplitSwitchesTransform : public PassInfoMixin<SplitSwitchesTransform> {
-
- public:
-  SplitSwitchesTransform() {
-#else
 class SplitSwitchesTransform : public ModulePass {
 
  public:
   static char ID;
   SplitSwitchesTransform() : ModulePass(ID) {
-#endif
+
     initInstrumentList();
 
   }
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-#else
   bool runOnModule(Module &M) override;
 
 #if LLVM_VERSION_MAJOR >= 4
@@ -91,7 +76,6 @@ class SplitSwitchesTransform : public ModulePass {
     return "splits switch constructs";
 
   }
-#endif
 
   struct CaseExpr {
 
@@ -119,40 +103,7 @@ class SplitSwitchesTransform : public ModulePass {
 
 }  // namespace
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
-llvmGetPassPluginInfo() {
-  return {
-    LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1",
-    /* lambda to insert our pass into the pass pipeline. */
-    [](PassBuilder &PB) {
-#if 1
-       using OptimizationLevel = typename PassBuilder::OptimizationLevel;
-       PB.registerOptimizerLastEPCallback(
-         [](ModulePassManager &MPM, OptimizationLevel OL) {
-           MPM.addPass(SplitSwitchesTransform());
-         }
-       );
-/* TODO LTO registration */
-#else
-       using PipelineElement = typename PassBuilder::PipelineElement;
-       PB.registerPipelineParsingCallback(
-         [](StringRef Name, ModulePassManager &MPM, ArrayRef<PipelineElement>) {
-            if ( Name == "splitswitches" ) {
-              MPM.addPass(SplitSwitchesTransform());
-              return true;
-            } else {
-              return false;
-            }
-         }
-       );
-#endif
-    }
-  };
-}
-#else
 char SplitSwitchesTransform::ID = 0;
-#endif
 
 /* switchConvert - Transform simple list of Cases into list of CaseRange's */
 BasicBlock *SplitSwitchesTransform::switchConvert(
@@ -464,37 +415,19 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
 
 }
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-PreservedAnalyses SplitSwitchesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
-#else
 bool SplitSwitchesTransform::runOnModule(Module &M) {
-#endif
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
     printf("Running split-switches-pass by laf.intel@gmail.com\n");
   else
     be_quiet = 1;
-
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-  auto PA = PreservedAnalyses::all();
-#endif
-
   splitSwitches(M);
   verifyModule(M);
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-/*  if (modified) {
-    PA.abandon<XX_Manager>();
-  }*/
-
-  return PA;
-#else
   return true;
-#endif
 
 }
 
-#if LLVM_VERSION_MAJOR < 7 /* use old pass manager */
 static void registerSplitSwitchesTransPass(const PassManagerBuilder &,
                                            legacy::PassManagerBase &PM) {
 
@@ -514,4 +447,4 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO(
     PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
     registerSplitSwitchesTransPass);
 #endif
-#endif
+
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 58d978ea..9c6e9b3e 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -462,17 +462,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } else {
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
-#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/split-switches-pass.so", obj_path);
-#endif
+
       }
 
     }
@@ -487,17 +482,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } else {
 
-#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
-        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
-#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/compare-transform-pass.so", obj_path);
-#endif
 
       }
 
@@ -513,18 +502,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } else {
 
-#if LLVM_MAJOR >= 7
-        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
-//        cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
-#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/split-compares-pass.so", obj_path);
-#endif
 
       }
 
@@ -554,17 +536,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
             alloc_printf("%s/cmplog-switches-pass.so", obj_path);
 
         // reuse split switches from laf
-#if LLVM_MAJOR >= 7
-        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
-#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] =
             alloc_printf("%s/split-switches-pass.so", obj_path);
-#endif
 
       }
 
@@ -590,15 +566,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       free(ld_path);
 
       cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
-
-      if (instrument_mode == INSTRUMENT_CFG ||
-          instrument_mode == INSTRUMENT_PCGUARD)
-        cc_params[cc_par_cnt++] = alloc_printf(
-            "-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
-      else
-
-        cc_params[cc_par_cnt++] = alloc_printf(
-            "-Wl,-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", obj_path);
+      cc_params[cc_par_cnt++] =
+          alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
       cc_params[cc_par_cnt++] = lto_flag;
 
     } else {
@@ -654,15 +623,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
       } else {
 
-#if LLVM_MAJOR >= 7
-        cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
-        cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
-#else
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = "-load";
         cc_params[cc_par_cnt++] = "-Xclang";
         cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
-#endif
+
       }
 
     }
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index ca060f3c..e0dfd6b0 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -255,6 +255,7 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
   if (!mutator->afl_custom_init_trim) {
 
+    notrim = 1;
     ACTF("optional symbol 'afl_custom_init_trim' not found.");
 
   }
@@ -263,6 +264,7 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
   if (!mutator->afl_custom_trim) {
 
+    notrim = 1;
     ACTF("optional symbol 'afl_custom_trim' not found.");
 
   }
@@ -271,6 +273,7 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
   if (!mutator->afl_custom_post_trim) {
 
+    notrim = 1;
     ACTF("optional symbol 'afl_custom_post_trim' not found.");
 
   }