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--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/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
15 files changed, 355 insertions, 1469 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/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/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.");
 
   }