aboutsummaryrefslogtreecommitdiff
path: root/llvm_mode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_mode')
-rw-r--r--llvm_mode/GNUmakefile375
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc3
-rw-r--r--llvm_mode/Makefile372
-rw-r--r--llvm_mode/afl-clang-fast.c73
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc3
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc73
-rw-r--r--llvm_mode/llvm-ngram-coverage.h2
7 files changed, 484 insertions, 417 deletions
diff --git a/llvm_mode/GNUmakefile b/llvm_mode/GNUmakefile
new file mode 100644
index 00000000..006d115d
--- /dev/null
+++ b/llvm_mode/GNUmakefile
@@ -0,0 +1,375 @@
+#
+# american fuzzy lop++ - LLVM instrumentation
+# -----------------------------------------
+#
+# Written by Laszlo Szekeres <lszekeres@google.com> and
+# Michal Zalewski
+#
+# LLVM integration design comes from Laszlo Szekeres.
+#
+# Copyright 2015, 2016 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+# For Heiko:
+#TEST_MMAP=1
+HASH=\#
+
+PREFIX ?= /usr/local
+HELPER_PATH ?= $(PREFIX)/lib/afl
+BIN_PATH ?= $(PREFIX)/bin
+DOC_PATH ?= $(PREFIX)/share/doc/afl
+MISC_PATH ?= $(PREFIX)/share/afl
+MAN_PATH ?= $(PREFIX)/man/man8
+
+VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
+
+ifeq "$(shell uname)" "OpenBSD"
+ LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
+ HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
+ ifeq "$(HAS_OPT)" "1"
+ $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9")
+ endif
+else
+ LLVM_CONFIG ?= llvm-config
+endif
+
+LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null )
+LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 )
+LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
+LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//')
+LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
+LLVM_STDCXX = gnu++11
+LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0)
+LLVM_LTO = 0
+
+ifeq "$(LLVMVER)" ""
+ $(warning [!] llvm_mode needs llvm-config, which was not found)
+endif
+
+ifeq "$(LLVM_UNSUPPORTED)" "1"
+ $(warning llvm_mode only supports llvm versions 3.8.0 up to 11)
+endif
+
+ifeq "$(LLVM_MAJOR)" "9"
+ $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
+ $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation)
+ LLVM_LTO = 1
+endif
+
+ifeq "$(LLVM_NEW_API)" "1"
+ $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
+ $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation)
+ LLVM_STDCXX = c++14
+ LLVM_LTO = 1
+endif
+
+ifeq "$(LLVM_LTO)" "0"
+ $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.)
+endif
+
+ifeq "$(LLVM_APPLE)" "1"
+ $(warning llvm_mode will not compile with Xcode clang...)
+endif
+
+# We were using llvm-config --bindir to get the location of clang, but
+# this seems to be busted on some distros, so using the one in $PATH is
+# probably better.
+
+CC = $(LLVM_BINDIR)/clang
+CXX = $(LLVM_BINDIR)/clang++
+
+ifeq "$(shell test -e $(CC) || echo 1 )" "1"
+ # llvm-config --bindir may not providing a valid path, so ...
+ ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1"
+ # we found one in the local install directory, lets use these
+ CC = $(BIN_DIR)/clang
+ CXX = $(BIN_DIR)/clang++
+ else
+ # hope for the best
+ $(warning we have trouble finding clang/clang++ - llvm-config is not helping us)
+ CC = clang
+ CXX = clang++
+ endif
+endif
+
+# sanity check.
+# Are versions of clang --version and llvm-config --version equal?
+CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p')
+
+ifneq "$(CLANGVER)" "$(LLVMVER)"
+ CC = $(shell $(LLVM_CONFIG) --bindir)/clang
+ CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++
+endif
+
+# After we set CC/CXX we can start makefile magic tests
+
+ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ CFLAGS_OPT = -march=native
+endif
+
+ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ AFL_CLANG_FLTO ?= -flto=full
+else
+ ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ AFL_CLANG_FLTO ?= -flto=thin
+ else
+ ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ AFL_CLANG_FLTO ?= -flto
+ endif
+ endif
+endif
+
+ifneq "$(AFL_CLANG_FLTO)" ""
+ifeq "$(AFL_REAL_LD)" ""
+ AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null)
+ ifeq "$(AFL_REAL_LD)" ""
+ AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null)
+ endif
+endif
+endif
+
+CFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
+override CFLAGS = -Wall \
+ -g -Wno-pointer-sign -I ../include/ \
+ -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
+ -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
+ -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
+ -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function
+ifdef AFL_TRACE_PC
+ CFLAGS += -DUSE_TRACE_PC=1
+endif
+
+CXXFLAGS ?= -O3 -funroll-loops -D_FORTIFY_SOURCE=2
+override CXXFLAGS += -Wall -g -I ../include/ \
+ -DVERSION=\"$(VERSION)\" -Wno-variadic-macros
+
+CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS)
+CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
+
+
+# User teor2345 reports that this is required to make things work on MacOS X.
+ifeq "$(shell uname)" "Darwin"
+ CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
+endif
+
+ifeq "$(shell uname)" "OpenBSD"
+ CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
+endif
+
+ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ CFLAGS += -DAFL_CLANG_FUSELD=1
+endif
+
+ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
+ SHMAT_OK=1
+else
+ SHMAT_OK=0
+ CFLAGS+=-DUSEMMAP=1
+ LDFLAGS += -lrt
+endif
+
+ifeq "$(TEST_MMAP)" "1"
+ SHMAT_OK=0
+ CFLAGS+=-DUSEMMAP=1
+ LDFLAGS += -lrt
+endif
+
+ifndef AFL_TRACE_PC
+ PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
+else
+ PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
+endif
+
+# If prerequisites are not given, warn, do not build anything, and exit with code 0
+ifeq "$(LLVMVER)" ""
+ NO_BUILD = 1
+endif
+
+ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00"
+ NO_BUILD = 1
+endif
+
+ifeq "$(NO_BUILD)" "1"
+ TARGETS = no_build
+else
+ TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done
+endif
+
+LLVM_MIN_4_0_1 = $(shell awk 'function tonum(ver, a) {split(ver,a,"."); return a[1]*1000000+a[2]*1000+a[3]} BEGIN { exit tonum(ARGV[1]) >= tonum(ARGV[2]) }' $(LLVMVER) 4.0.1; echo $$?)
+
+all: $(TARGETS)
+
+ifeq "$(SHMAT_OK)" "1"
+
+test_shm:
+ @echo "[+] shmat seems to be working."
+ @rm -f .test2
+
+else
+
+test_shm:
+ @echo "[-] shmat seems not to be working, switching to mmap implementation"
+
+endif
+
+no_build:
+ @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m"
+
+test_deps:
+ifndef AFL_TRACE_PC
+ @echo "[*] Checking for working 'llvm-config'..."
+ ifneq "$(LLVM_APPLE)" "1"
+ @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 )
+ endif
+else
+ @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)."
+endif
+ @echo "[*] Checking for working '$(CC)'..."
+ @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
+ @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'"
+ifneq "$(CLANGVER)" "$(LLVMVER)"
+ @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)"
+ @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang"
+else
+ @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good."
+endif
+ @echo "[*] Checking for '../afl-showmap'..."
+ @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 )
+ @echo "[+] All set and ready to build."
+
+afl-common.o: ../src/afl-common.c
+ $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
+
+../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
+ $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
+ ln -sf afl-clang-fast ../afl-clang-fast++
+ifneq "$(AFL_CLANG_FLTO)" ""
+ifeq "$(LLVM_LTO)" "1"
+ ln -sf afl-clang-fast ../afl-clang-lto
+ ln -sf afl-clang-fast ../afl-clang-lto++
+endif
+endif
+
+../afl-ld: afl-ld.c
+ifneq "$(AFL_CLANG_FLTO)" ""
+ifeq "$(LLVM_LTO)" "1"
+ $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+ ln -sf afl-ld ../ld
+ @rm -f .test-instr
+ @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto"
+ @rm -f .test-instr
+endif
+endif
+../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps
+ -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL)
+
+../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps
+ifeq "$(LLVM_MIN_4_0_1)" "0"
+ $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER))
+endif
+ $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
+
+../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc
+ifeq "$(LLVM_LTO)" "1"
+ $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
+endif
+
+../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc
+ifeq "$(LLVM_LTO)" "1"
+ $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL)
+endif
+
+# laf
+../split-switches-pass.so: split-switches-pass.so.cc | test_deps
+ $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps
+ $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+../split-compares-pass.so: split-compares-pass.so.cc | test_deps
+ $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+# /laf
+
+../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps
+ $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+
+../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps
+ $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
+
+../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
+ $(CC) $(CFLAGS) -fPIC -c $< -o $@
+
+../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
+ @printf "[*] Building 32-bit variant of the runtime (-m32)... "
+ @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+
+../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
+ @printf "[*] Building 64-bit variant of the runtime (-m64)... "
+ @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
+
+test_build: $(PROGS)
+ @echo "[*] Testing the CC wrapper and instrumentation output..."
+ unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
+ ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
+ echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr
+ @rm -f test-instr
+ @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
+ @echo "[+] All right, the instrumentation seems to be working!"
+
+all_done: test_build
+ @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs."
+
+.NOTPARALLEL: clean
+
+install: all
+ install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
+ifndef AFL_TRACE_PC
+ if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f afl-clang-lto -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi
+else
+ if [ -f ../afl-clang-fast -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
+endif
+ if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi
+ if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi
+ set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi
+ install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/
+ install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md
+
+vpath % ..
+%.8: %
+ @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@
+ @echo .SH NAME >> ../$@
+ @echo .B $* >> ../$@
+ @echo >> ../$@
+ @echo .SH SYNOPSIS >> ../$@
+ @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@
+ @echo >> ../$@
+ @echo .SH OPTIONS >> ../$@
+ @echo .nf >> ../$@
+ @../$* -h 2>&1 | tail -n +4 >> ../$@
+ @echo >> ../$@
+ @echo .SH AUTHOR >> ../$@
+ @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ../$@
+ @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@
+ @echo >> ../$@
+ @echo .SH LICENSE >> ../$@
+ @echo Apache License Version 2.0, January 2004 >> ../$@
+ ln -sf afl-clang-fast.8 ../afl-clang-fast++.8
+ifneq "$(AFL_CLANG_FLTO)" ""
+ifeq "$(LLVM_LTO)" "1"
+ ln -sf afl-clang-fast.8 ../afl-clang-lto.8
+ ln -sf afl-clang-fast.8 ../afl-clang-lto++.8
+endif
+endif
+
+clean:
+ rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo
+ rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index a94eb907..8b23942c 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -509,10 +509,11 @@ struct InsTrim : public ModulePass {
if (!be_quiet) {
char modeline[100];
- snprintf(modeline, sizeof(modeline), "%s%s%s%s",
+ 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 %u locations (%llu, %llu) (%s mode)\n", total_instr,
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
index 9626665c..0b306dde 100644
--- a/llvm_mode/Makefile
+++ b/llvm_mode/Makefile
@@ -1,370 +1,2 @@
-#
-# american fuzzy lop++ - LLVM instrumentation
-# -----------------------------------------
-#
-# Written by Laszlo Szekeres <lszekeres@google.com> and
-# Michal Zalewski
-#
-# LLVM integration design comes from Laszlo Szekeres.
-#
-# Copyright 2015, 2016 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-
-# For Heiko:
-#TEST_MMAP=1
-HASH=\#
-
-PREFIX ?= /usr/local
-HELPER_PATH ?= $(PREFIX)/lib/afl
-BIN_PATH ?= $(PREFIX)/bin
-DOC_PATH ?= $(PREFIX)/share/doc/afl
-MISC_PATH ?= $(PREFIX)/share/afl
-MAN_PATH ?= $(PREFIX)/man/man8
-
-VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
-
-ifeq "$(shell uname)" "OpenBSD"
- LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
- HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
- ifeq "$(HAS_OPT)" "1"
- $(error llvm_mode needs a complete llvm installation (versions 3.8.0 up to 11) -> e.g. "pkg_add llvm-7.0.1p9")
- endif
-else
- LLVM_CONFIG ?= llvm-config
-endif
-
-LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null )
-LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^3\.[0-7]|^1[2-9]' && echo 1 || echo 0 )
-LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
-LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//')
-LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
-LLVM_STDCXX = gnu++11
-LLVM_APPLE = $(shell clang -v 2>&1 | grep -iq apple && echo 1 || echo 0)
-LLVM_LTO = 0
-
-ifeq "$(LLVMVER)" ""
- $(warning [!] llvm_mode needs llvm-config, which was not found)
-endif
-
-ifeq "$(LLVM_UNSUPPORTED)" "1"
- $(warning llvm_mode only supports llvm versions 3.8.0 up to 11)
-endif
-
-ifeq "$(LLVM_MAJOR)" "9"
- $(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
- $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation)
- LLVM_LTO = 1
-endif
-
-ifeq "$(LLVM_NEW_API)" "1"
- $(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
- $(info [+] llvm_mode detected llvm 9, enabling afl-clang-lto LTO implementation)
- LLVM_STDCXX = c++14
- LLVM_LTO = 1
-endif
-
-ifeq "$(LLVM_LTO)" "0"
- $(info [+] llvm_mode detected llvm < 9, afl-clang-lto LTO will not be build.)
-endif
-
-ifeq "$(LLVM_APPLE)" "1"
- $(warning llvm_mode will not compile with Xcode clang...)
-endif
-
-# We were using llvm-config --bindir to get the location of clang, but
-# this seems to be busted on some distros, so using the one in $PATH is
-# probably better.
-
-CC = $(LLVM_BINDIR)/clang
-CXX = $(LLVM_BINDIR)/clang++
-
-ifeq "$(shell test -e $(CC) || echo 1 )" "1"
- # llvm-config --bindir may not providing a valid path, so ...
- ifeq "$(shell test -e '$(BIN_DIR)/clang' && echo 1)" "1"
- # we found one in the local install directory, lets use these
- CC = $(BIN_DIR)/clang
- CXX = $(BIN_DIR)/clang++
- else
- # hope for the best
- $(warning we have trouble finding clang/clang++ - llvm-config is not helping us)
- CC = clang
- CXX = clang++
- endif
-endif
-
-# sanity check.
-# Are versions of clang --version and llvm-config --version equal?
-CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p')
-
-ifneq "$(CLANGVER)" "$(LLVMVER)"
- CC = $(shell $(LLVM_CONFIG) --bindir)/clang
- CXX = $(shell $(LLVM_CONFIG) --bindir)/clang++
-endif
-
-# After we set CC/CXX we can start makefile magic tests
-
-ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- CFLAGS_OPT = -march=native
-endif
-
-ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=full -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- AFL_CLANG_FLTO ?= -flto=full
-else
- ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto=thin -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- AFL_CLANG_FLTO ?= -flto=thin
- else
- ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- AFL_CLANG_FLTO ?= -flto
- endif
- endif
-endif
-
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(AFL_REAL_LD)" ""
- AFL_REAL_LD = $(shell readlink /bin/ld 2>/dev/null)
- ifeq "$(AFL_REAL_LD)" ""
- AFL_REAL_LD = $(shell readlink /usr/bin/ld 2>/dev/null)
- endif
-endif
-endif
-
-CFLAGS ?= -O3 -funroll-loops
-override CFLAGS = -Wall \
- -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I ../include/ \
- -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
- -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
- -DLLVM_VERSION=\"$(LLVMVER)\" -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
- -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" -Wno-unused-function
-ifdef AFL_TRACE_PC
- CFLAGS += -DUSE_TRACE_PC=1
-endif
-
-CXXFLAGS ?= -O3 -funroll-loops
-override CXXFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -I ../include/ \
- -DVERSION=\"$(VERSION)\" -Wno-variadic-macros
-
-CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS)
-CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
-
-
-# User teor2345 reports that this is required to make things work on MacOS X.
-ifeq "$(shell uname)" "Darwin"
- CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
-endif
-
-ifeq "$(shell uname)" "OpenBSD"
- CLANG_LFL += `$(LLVM_CONFIG) --libdir`/libLLVM.so
-endif
-
-ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
- CFLAGS += -DAFL_CLANG_FUSELD=1
-endif
-
-ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
- SHMAT_OK=1
-else
- SHMAT_OK=0
- CFLAGS+=-DUSEMMAP=1
- LDFLAGS += -lrt
-endif
-
-ifeq "$(TEST_MMAP)" "1"
- SHMAT_OK=0
- CFLAGS+=-DUSEMMAP=1
- LDFLAGS += -lrt
-endif
-
-ifndef AFL_TRACE_PC
- PROGS = ../afl-clang-fast ../afl-ld ../afl-llvm-pass.so ../afl-llvm-lto-whitelist.so ../afl-llvm-lto-instrumentation.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
-else
- PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
-endif
-
-# If prerequisites are not given, warn, do not build anything, and exit with code 0
-ifeq "$(LLVMVER)" ""
- NO_BUILD = 1
-endif
-
-ifneq "$(LLVM_UNSUPPORTED)$(LLVM_APPLE)" "00"
- NO_BUILD = 1
-endif
-
-ifeq "$(NO_BUILD)" "1"
- TARGETS = no_build
-else
- TARGETS = test_shm test_deps $(PROGS) afl-clang-fast.8 test_build all_done
-endif
-
-all: $(TARGETS)
-
-ifeq "$(SHMAT_OK)" "1"
-
-test_shm:
- @echo "[+] shmat seems to be working."
- @rm -f .test2
-
-else
-
-test_shm:
- @echo "[-] shmat seems not to be working, switching to mmap implementation"
-
-endif
-
-no_build:
- @printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m"
-
-test_deps:
-ifndef AFL_TRACE_PC
- @echo "[*] Checking for working 'llvm-config'..."
- ifneq "$(LLVM_APPLE)" "1"
- @type $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 )
- endif
-else
- @echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)."
-endif
- @echo "[*] Checking for working '$(CC)'..."
- @type $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
- @echo "[*] Checking for matching versions of '$(CC)' and '$(LLVM_CONFIG)'"
-ifneq "$(CLANGVER)" "$(LLVMVER)"
- @echo "[!] WARNING: we have llvm-config version $(LLVMVER) and a clang version $(CLANGVER)"
- @echo "[!] Retrying with the clang compiler from llvm: CC=`llvm-config --bindir`/clang"
-else
- @echo "[*] We have llvm-config version $(LLVMVER) with a clang version $(CLANGVER), good."
-endif
- @echo "[*] Checking for '../afl-showmap'..."
- @test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 )
- @echo "[+] All set and ready to build."
-
-afl-common.o: ../src/afl-common.c
- $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
-
-../afl-clang-fast: afl-clang-fast.c afl-common.o | test_deps
- $(CC) $(CFLAGS) $< afl-common.o -o $@ $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\"
- ln -sf afl-clang-fast ../afl-clang-fast++
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(LLVM_LTO)" "1"
- ln -sf afl-clang-fast ../afl-clang-lto
- ln -sf afl-clang-fast ../afl-clang-lto++
-endif
-endif
-
-../afl-ld: afl-ld.c
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(LLVM_LTO)" "1"
- $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
- ln -sf afl-ld ../ld
- @rm -f .test-instr
- @-export AFL_QUIET=1 AFL_PATH=.. PATH="..:$(PATH)" ; ../afl-clang-lto -Wl,--afl -o .test-instr ../test-instr.c && echo "[+] afl-clang-lto and afl-ld seem to work fine :)" || echo "[!] WARNING: clang seems to have a hardcoded "'/bin/ld'" - check README.lto"
- @rm -f .test-instr
-endif
-endif
-../libLLVMInsTrim.so: LLVMInsTrim.so.cc MarkNodes.cc | test_deps
- -$(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL)
-
-../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps
- $(CXX) $(CLANG_CFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
-
-../afl-llvm-lto-whitelist.so: afl-llvm-lto-whitelist.so.cc
-ifeq "$(LLVM_LTO)" "1"
- $(CXX) $(CLANG_CFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL)
-endif
-
-../afl-llvm-lto-instrumentation.so: afl-llvm-lto-instrumentation.so.cc MarkNodes.cc
-ifeq "$(LLVM_LTO)" "1"
- $(CXX) $(CLANG_CFL) -Wno-writable-strings -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< MarkNodes.cc -o $@ $(CLANG_LFL)
-endif
-
-# laf
-../split-switches-pass.so: split-switches-pass.so.cc | test_deps
- $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-../compare-transform-pass.so: compare-transform-pass.so.cc | test_deps
- $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-../split-compares-pass.so: split-compares-pass.so.cc | test_deps
- $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-# /laf
-
-../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps
- $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-
-../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps
- $(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
-
-../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
- $(CC) $(CFLAGS) -fPIC -c $< -o $@
-
-../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
- @printf "[*] Building 32-bit variant of the runtime (-m32)... "
- @$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
-
-../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
- @printf "[*] Building 64-bit variant of the runtime (-m64)... "
- @$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
-
-test_build: $(PROGS)
- @echo "[*] Testing the CC wrapper and instrumentation output..."
- unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
- ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
- echo 1 | ASAN_OPTIONS=detect_leaks=0 ../afl-showmap -m none -q -o .test-instr1 ./test-instr
- @rm -f test-instr
- @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
- @echo "[+] All right, the instrumentation seems to be working!"
-
-all_done: test_build
- @echo "[+] All done! You can now use '../afl-clang-fast' to compile programs."
-
-.NOTPARALLEL: clean
-
-install: all
- install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
-ifndef AFL_TRACE_PC
- if [ -f ../afl-clang-fast -a -f ../libLLVMInsTrim.so -a -f ../afl-llvm-rt.o ]; then set -e; install -m 755 ../afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 ../libLLVMInsTrim.so ../afl-llvm-pass.so ../afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
- if [ -f afl-clang-lto -a -f afl-ld ]; then set -e; install -m 755 afl-clang-lto $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 afl-ld $${DESTDIR}$(HELPER_PATH); ln -sf afl-ld $${DESTDIR}$(HELPER_PATH)/ld; install -m 755 afl-llvm-lto-instrumentation.so $${DESTDIR}$(HELPER_PATH); install -m 755 afl-llvm-lto-whitelist.so $${DESTDIR}$(HELPER_PATH); fi
-else
- if [ -f afl-clang-fast -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi
-endif
- if [ -f ../afl-llvm-rt-32.o ]; then set -e; install -m 755 ../afl-llvm-rt-32.o $${DESTDIR}$(HELPER_PATH); fi
- if [ -f ../afl-llvm-rt-64.o ]; then set -e; install -m 755 ../afl-llvm-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
- if [ -f ../compare-transform-pass.so ]; then set -e; install -m 755 ../compare-transform-pass.so $${DESTDIR}$(HELPER_PATH); fi
- if [ -f ../split-compares-pass.so ]; then set -e; install -m 755 ../split-compares-pass.so $${DESTDIR}$(HELPER_PATH); fi
- if [ -f ../split-switches-pass.so ]; then set -e; install -m 755 ../split-switches-pass.so $${DESTDIR}$(HELPER_PATH); fi
- if [ -f ../cmplog-instructions-pass.so ]; then set -e; install -m 755 ../cmplog-*-pass.so $${DESTDIR}$(HELPER_PATH); fi
- set -e; if [ -f ../afl-clang-fast ] ; then ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang++ ; else ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ../afl-gcc $${DESTDIR}$(BIN_PATH)/afl-clang++; fi
- install -m 644 README.*.md $${DESTDIR}$(DOC_PATH)/
- install -m 644 -T README.md $${DESTDIR}$(DOC_PATH)/README.llvm_mode.md
-
-vpath % ..
-%.8: %
- @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ../$@
- @echo .SH NAME >> ../$@
- @echo .B $* >> ../$@
- @echo >> ../$@
- @echo .SH SYNOPSIS >> ../$@
- @../$* -h 2>&1 | head -n 3 | tail -n 1 | sed 's/^\.\///' >> ../$@
- @echo >> ../$@
- @echo .SH OPTIONS >> ../$@
- @echo .nf >> ../$@
- @../$* -h 2>&1 | tail -n +4 >> ../$@
- @echo >> ../$@
- @echo .SH AUTHOR >> ../$@
- @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse <mh@mh-sec.de>, Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <domenukk@gmail.com>" >> ../$@
- @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ../$@
- @echo >> ../$@
- @echo .SH LICENSE >> ../$@
- @echo Apache License Version 2.0, January 2004 >> ../$@
- ln -sf afl-clang-fast.8 ../afl-clang-fast++.8
-ifneq "$(AFL_CLANG_FLTO)" ""
-ifeq "$(LLVM_LTO)" "1"
- ln -sf afl-clang-fast.8 ../afl-clang-lto.8
- ln -sf afl-clang-fast.8 ../afl-clang-lto++.8
-endif
-endif
-
-clean:
- rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo
- rm -f $(PROGS) afl-common.o ../afl-clang-fast++ ../afl-clang-lto ../afl-clang-lto++ ../afl-clang*.8 ../ld
+all:
+ @echo please use GNU make, thanks!
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 34df5671..5fc09252 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -48,7 +48,6 @@ static u8 debug;
static u8 cwd[4096];
static u8 cmplog_mode;
u8 use_stdin = 0; /* dummy */
-u8 be_quiet = 0;
u8 *getthecwd() {
@@ -135,9 +134,9 @@ static void find_obj(u8 *argv0) {
/* Copy argv to cc_params, making the necessary edits. */
-static void edit_params(u32 argc, char **argv) {
+static void edit_params(u32 argc, char **argv, char **envp) {
- u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0;
+ u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0;
u8 has_llvm_config = 0;
u8 *name;
@@ -324,8 +323,6 @@ static void edit_params(u32 argc, char **argv) {
/* Detect stray -v calls from ./configure scripts. */
- if (argc == 1 && !strcmp(argv[1], "-v")) maybe_linking = 0;
-
while (--argc) {
u8 *cur = *(++argv);
@@ -336,16 +333,11 @@ static void edit_params(u32 argc, char **argv) {
if (!strcmp(cur, "-x")) x_set = 1;
- if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E"))
- maybe_linking = 0;
-
if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
asan_set = 1;
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
- if (!strcmp(cur, "-shared")) maybe_linking = 0;
-
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined"))
continue;
@@ -395,6 +387,22 @@ static void edit_params(u32 argc, char **argv) {
}
+ if (getenv("AFL_USE_CFISAN")) {
+
+ if (!lto_mode) {
+
+ uint32_t i = 0, found = 0;
+ while (envp[i] != NULL && !found)
+ if (strncmp("-flto", envp[i++], 5) == 0) found = 1;
+ if (!found) cc_params[cc_par_cnt++] = "-flto";
+
+ }
+
+ cc_params[cc_par_cnt++] = "-fsanitize=cfi";
+ cc_params[cc_par_cnt++] = "-fvisibility=hidden";
+
+ }
+
#ifdef USE_TRACE_PC
if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
@@ -483,44 +491,40 @@ static void edit_params(u32 argc, char **argv) {
#endif /* ^__APPLE__ */
"_I(); } while (0)";
- // if (maybe_linking) {
+ if (x_set) {
- if (x_set) {
+ cc_params[cc_par_cnt++] = "-x";
+ cc_params[cc_par_cnt++] = "none";
- cc_params[cc_par_cnt++] = "-x";
- cc_params[cc_par_cnt++] = "none";
-
- }
+ }
#ifndef __ANDROID__
- switch (bit_mode) {
+ switch (bit_mode) {
- case 0:
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path);
- break;
+ case 0:
+ cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt.o", obj_path);
+ break;
- case 32:
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path);
+ case 32:
+ cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-32.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m32 is not supported by your compiler");
+ if (access(cc_params[cc_par_cnt - 1], R_OK))
+ FATAL("-m32 is not supported by your compiler");
- break;
+ break;
- case 64:
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path);
+ case 64:
+ cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-rt-64.o", obj_path);
- if (access(cc_params[cc_par_cnt - 1], R_OK))
- FATAL("-m64 is not supported by your compiler");
+ if (access(cc_params[cc_par_cnt - 1], R_OK))
+ FATAL("-m64 is not supported by your compiler");
- break;
+ break;
- }
+ }
#endif
- // }
-
cc_params[cc_par_cnt] = NULL;
}
@@ -596,6 +600,7 @@ int main(int argc, char **argv, char **envp) {
"AFL_USE_ASAN: activate address sanitizer\n"
"AFL_USE_MSAN: activate memory sanitizer\n"
"AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
+ "AFL_USE_CFISAN: activate control flow sanitizer\n"
"AFL_LLVM_WHITELIST: enable whitelisting (selective "
"instrumentation)\n"
"AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
@@ -685,7 +690,7 @@ int main(int argc, char **argv, char **envp) {
find_obj(argv[0]);
#endif
- edit_params(argc, argv);
+ edit_params(argc, argv, envp);
if (debug) {
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index febb8950..4bc16f17 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -392,10 +392,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
else {
char modeline[100];
- snprintf(modeline, sizeof(modeline), "%s%s%s%s",
+ 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 %u locations with no collisions (on average %llu "
"collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index fefd9edd..5fe98d8b 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -131,14 +131,40 @@ class AFLCoverage : public ModulePass {
char AFLCoverage::ID = 0;
+/* needed up to 3.9.0 */
+#if LLVM_VERSION_MAJOR == 3 && \
+ (LLVM_VERSION_MINOR < 9 || \
+ (LLVM_VERSION_MINOR == 9 && LLVM_VERSION_PATCH < 1))
+uint64_t PowerOf2Ceil(unsigned in) {
+
+ uint64_t in64 = in - 1;
+ in64 |= (in64 >> 1);
+ in64 |= (in64 >> 2);
+ in64 |= (in64 >> 4);
+ in64 |= (in64 >> 8);
+ in64 |= (in64 >> 16);
+ in64 |= (in64 >> 32);
+ return in64 + 1;
+
+}
+
+#endif
+
+/* #if LLVM_VERSION_STRING >= "4.0.1" */
+#if LLVM_VERSION_MAJOR >= 4 || \
+ (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
+#define AFL_HAVE_VECTOR_INTRINSICS 1
+#endif
bool AFLCoverage::runOnModule(Module &M) {
LLVMContext &C = M.getContext();
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
IntegerType *IntLocTy =
IntegerType::getIntNTy(C, sizeof(PREV_LOC_T) * CHAR_BIT);
+#endif
struct timeval tv;
struct timezone tz;
u32 rand_seed;
@@ -179,27 +205,39 @@ bool AFLCoverage::runOnModule(Module &M) {
char *neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO");
#endif
- /* Decide previous location vector size (must be a power of two) */
+ unsigned PrevLocSize;
char *ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE");
if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE");
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
+ /* Decide previous location vector size (must be a power of two) */
+ VectorType *PrevLocTy;
+
if (ngram_size_str)
if (sscanf(ngram_size_str, "%u", &ngram_size) != 1 || ngram_size < 2 ||
ngram_size > MAX_NGRAM_SIZE)
FATAL(
- "Bad value of AFL_NGRAM_SIZE (must be between 2 and MAX_NGRAM_SIZE)");
+ "Bad value of AFL_NGRAM_SIZE (must be between 2 and MAX_NGRAM_SIZE "
+ "(%u))",
+ MAX_NGRAM_SIZE);
- unsigned PrevLocSize;
if (ngram_size == 1) ngram_size = 0;
if (ngram_size)
PrevLocSize = ngram_size - 1;
else
+#else
+ if (ngram_size_str)
+ FATAL(
+ "Sorry, n-gram branch coverage is not supported with llvm version %s!",
+ LLVM_VERSION_STRING);
+#endif
PrevLocSize = 1;
- uint64_t PrevLocVecSize = PowerOf2Ceil(PrevLocSize);
- VectorType *PrevLocTy;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
+ uint64_t PrevLocVecSize = PowerOf2Ceil(PrevLocSize);
if (ngram_size) PrevLocTy = VectorType::get(IntLocTy, PrevLocVecSize);
+#endif
/* Get globals for the SHM region and the previous location. Note that
__afl_prev_loc is thread-local. */
@@ -209,6 +247,7 @@ bool AFLCoverage::runOnModule(Module &M) {
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
GlobalVariable *AFLPrevLoc;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
if (ngram_size)
#ifdef __ANDROID__
AFLPrevLoc = new GlobalVariable(
@@ -222,15 +261,17 @@ bool AFLCoverage::runOnModule(Module &M) {
/* AddressSpace */ 0, /* IsExternallyInitialized */ false);
#endif
else
+#endif
#ifdef __ANDROID__
AFLPrevLoc = new GlobalVariable(
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
#else
- AFLPrevLoc = new GlobalVariable(
- M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", 0,
- GlobalVariable::GeneralDynamicTLSModel, 0, false);
+ AFLPrevLoc = new GlobalVariable(
+ M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", 0,
+ GlobalVariable::GeneralDynamicTLSModel, 0, false);
#endif
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
/* Create the vector shuffle mask for updating the previous block history.
Note that the first element of the vector will store cur_loc, so just set
it to undef to allow the optimizer to do its thing. */
@@ -244,6 +285,7 @@ bool AFLCoverage::runOnModule(Module &M) {
PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize));
Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle);
+#endif
// other constants we need
ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
@@ -420,9 +462,11 @@ bool AFLCoverage::runOnModule(Module &M) {
ConstantInt *CurLoc;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
if (ngram_size)
CurLoc = ConstantInt::get(IntLocTy, cur_loc);
else
+#endif
CurLoc = ConstantInt::get(Int32Ty, cur_loc);
/* Load prev_loc */
@@ -431,6 +475,7 @@ bool AFLCoverage::runOnModule(Module &M) {
PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
Value *PrevLocTrans;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
/* "For efficiency, we propose to hash the tuple as a key into the
hit_count map as (prev_block_trans << 1) ^ curr_block_trans, where
prev_block_trans = (block_trans_1 ^ ... ^ block_trans_(n-1)" */
@@ -438,6 +483,7 @@ bool AFLCoverage::runOnModule(Module &M) {
if (ngram_size)
PrevLocTrans = IRB.CreateXorReduce(PrevLoc);
else
+#endif
PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty());
/* Load SHM pointer */
@@ -446,11 +492,13 @@ bool AFLCoverage::runOnModule(Module &M) {
MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
Value *MapPtrIdx;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
if (ngram_size)
MapPtrIdx = IRB.CreateGEP(
MapPtr,
IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, CurLoc), Int32Ty));
else
+#endif
MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocTrans, CurLoc));
/* Update bitmap */
@@ -536,6 +584,7 @@ bool AFLCoverage::runOnModule(Module &M) {
StoreInst *Store;
+#ifdef AFL_HAVE_VECTOR_INTRINSICS
if (ngram_size) {
Value *ShuffledPrevLoc = IRB.CreateShuffleVector(
@@ -546,7 +595,10 @@ bool AFLCoverage::runOnModule(Module &M) {
Store = IRB.CreateStore(UpdatedPrevLoc, AFLPrevLoc);
Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
- } else {
+ } else
+
+#endif
+ {
Store = IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1),
AFLPrevLoc);
@@ -568,10 +620,11 @@ bool AFLCoverage::runOnModule(Module &M) {
else {
char modeline[100];
- snprintf(modeline, sizeof(modeline), "%s%s%s%s",
+ 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 %u locations (%s mode, ratio %u%%).", inst_blocks,
modeline, inst_ratio);
diff --git a/llvm_mode/llvm-ngram-coverage.h b/llvm_mode/llvm-ngram-coverage.h
index 4459bcd7..488b4fe7 100644
--- a/llvm_mode/llvm-ngram-coverage.h
+++ b/llvm_mode/llvm-ngram-coverage.h
@@ -12,7 +12,7 @@ typedef u64 PREV_LOC_T;
#endif
/* Maximum ngram size */
-#define MAX_NGRAM_SIZE 128
+#define MAX_NGRAM_SIZE 128U
#endif