mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-05 23:01:33 +00:00
In GNUmakefile.llvm, several variables are unconditionally populated by expanding $(LLVMVER) and $(LLVM_CONFIG) inside shell commands. However, when LLVM is not present, both those variables are empty, meaning that the shell commands end up malformed and emit harmless, but noisy, errors like this one: /bin/sh: --: invalid option Usage: /bin/sh [GNU long option] [option] ... /bin/sh [GNU long option] [option] script-file ... GNU long options: --debug --debugger --dump-po-strings --dump-strings --help --init-file --login --noediting --noprofile --norc --posix --pretty-print --rcfile --rpm-requires --restricted --verbose --version Shell options: -ilrsD or -c command or -O shopt_option (invocation only) -abefhkmnptuvxBCHP or -o option /bin/sh: line 1: test: -gt: unary operator expected /bin/sh: line 1: test: -lt: unary operator expected /bin/sh: line 1: test: -ge: unary operator expected /bin/sh: line 1: test: -ge: unary operator expected Fix the problem by only populating the "downstream" variables if the upstream ones have values.
576 lines
26 KiB
Plaintext
576 lines
26 KiB
Plaintext
# 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:
|
|
#
|
|
# https://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)/share/man/man8
|
|
|
|
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d")
|
|
|
|
VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2)
|
|
|
|
SYS = $(shell uname -s)
|
|
|
|
override LLVM_TOO_NEW_DEFAULT := 18
|
|
override LLVM_TOO_OLD_DEFAULT := 13
|
|
|
|
ifeq "$(SYS)" "OpenBSD"
|
|
LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
|
|
HAS_OPT = $(shell test -x $(BIN_PATH)/opt && echo 0 || echo 1)
|
|
ifeq "$(HAS_OPT)" "1"
|
|
$(warning llvm_mode needs a complete llvm installation (versions 6.0 up to 13) -> e.g. "pkg_add llvm-7.0.1p9")
|
|
endif
|
|
else
|
|
# Small function to use Bash to detect the latest available clang and clang++ binaries, if using them by that name fails
|
|
override _CLANG_VERSIONS_TO_TEST := $(patsubst %,-%,$(shell seq $(LLVM_TOO_NEW_DEFAULT) -1 $(LLVM_TOO_OLD_DEFAULT)))
|
|
detect_newest=$(shell for v in "" $(_CLANG_VERSIONS_TO_TEST); do test -n "$$(command -v -- $1$$v)" && { echo "$1$$v"; break; }; done)
|
|
LLVM_CONFIG ?= $(call detect_newest,llvm-config)
|
|
endif
|
|
|
|
ifneq "$(LLVM_CONFIG)" ""
|
|
override LLVM_RAW_VER := $(shell $(LLVM_CONFIG) --version 2>/dev/null)
|
|
LLVMVER := $(subst svn,,$(subst git,,$(LLVM_RAW_VER)))
|
|
|
|
LLVM_BINDIR := $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
|
|
LLVM_LIBDIR := $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
|
|
endif
|
|
|
|
ifneq "$(LLVMVER)" ""
|
|
LLVM_MAJOR := $(firstword $(subst ., ,$(LLVMVER)))
|
|
LLVM_MINOR := $(firstword $(subst ., ,$(subst $(LLVM_MAJOR).,,$(LLVMVER))))
|
|
LLVM_TOO_NEW := $(shell test $(LLVM_MAJOR) -gt $(LLVM_TOO_NEW_DEFAULT) && echo 1 || echo 0)
|
|
LLVM_TOO_OLD := $(shell test $(LLVM_MAJOR) -lt $(LLVM_TOO_OLD_DEFAULT) && echo 1 || echo 0)
|
|
LLVM_NEW_API := $(shell test $(LLVM_MAJOR) -ge 10 && echo 1 || echo 0)
|
|
LLVM_NEWER_API := $(shell test $(LLVM_MAJOR) -ge 16 && echo 1 || echo 0)
|
|
LLVM_13_OK := $(shell test $(LLVM_MAJOR) -ge 13 && echo 1 || echo 0)
|
|
LLVM_HAVE_LTO := $(shell test $(LLVM_MAJOR) -ge 12 && echo 1 || echo 0)
|
|
endif
|
|
|
|
LLVM_STDCXX := gnu++11
|
|
LLVM_LTO := 0
|
|
LLVM_UNSUPPORTED := $(shell echo "$(LLVMVER)" | grep -E -q '^[0-2]\.|^3\.[0-8]\.' && echo 1 || echo 0)
|
|
# Uncomment to see the values assigned above
|
|
# $(foreach var,LLVM_CONFIG LLVMVER LLVM_MAJOR LLVM_MINOR LLVM_TOO_NEW LLVM_TOO_OLD LLVM_TOO_NEW_DEFAULT LLVM_TOO_OLD_DEFAULT LLVM_NEW_API LLVM_NEWER_API LLVM_13_OK LLVM_HAVE_LTO LLVM_BINDIR LLVM_LIBDIR LLVM_STDCXX LLVM_APPLE_XCODE LLVM_LTO LLVM_UNSUPPORTED,$(warning $(var) = $($(var))))
|
|
|
|
ifeq "$(LLVMVER)" ""
|
|
$(warning [!] llvm_mode needs llvm-config, which was not found. Set LLVM_CONFIG to its path and retry.)
|
|
endif
|
|
|
|
ifeq "$(LLVM_UNSUPPORTED)" "1"
|
|
$(error llvm_mode only supports llvm from version 3.8 onwards)
|
|
endif
|
|
|
|
ifeq "$(LLVM_TOO_NEW)" "1"
|
|
$(warning you are using an in-development llvm version - this might break llvm_mode!)
|
|
endif
|
|
|
|
ifeq "$(LLVM_TOO_OLD)" "1"
|
|
$(warning you are using an outdated LLVM version! Please use at least LLVM 13 or newer!)
|
|
$(shell sleep 2)
|
|
endif
|
|
|
|
# No switching the meaning of LLVM_TOO_OLD
|
|
LLVM_TOO_OLD=1
|
|
|
|
ifeq "$(LLVM_MAJOR)" "9"
|
|
$(info [+] llvm_mode detected llvm 9, enabling neverZero implementation)
|
|
LLVM_TOO_OLD=0
|
|
endif
|
|
|
|
ifeq "$(LLVM_NEW_API)" "1"
|
|
$(info [+] llvm_mode detected llvm 10+, enabling neverZero implementation and c++14)
|
|
LLVM_STDCXX = c++14
|
|
LLVM_TOO_OLD=0
|
|
endif
|
|
|
|
ifeq "$(LLVM_NEWER_API)" "1"
|
|
$(info [+] llvm_mode detected llvm 16+, enabling c++17)
|
|
LLVM_STDCXX = c++17
|
|
endif
|
|
|
|
ifeq "$(LLVM_HAVE_LTO)" "1"
|
|
$(info [+] llvm_mode detected llvm 12+, enabling afl-lto LTO implementation)
|
|
LLVM_LTO = 1
|
|
endif
|
|
|
|
ifeq "$(LLVM_LTO)" "0"
|
|
$(info [+] llvm_mode detected llvm < 12, afl-lto LTO will not be build.)
|
|
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++
|
|
|
|
LLVM_APPLE_XCODE := $(shell $(CC) -v 2>&1 | grep -q Apple && echo 1 || echo 0)
|
|
ifeq "$(LLVM_APPLE_XCODE)" "1"
|
|
$(warning llvm_mode will not compile with Xcode clang...)
|
|
endif
|
|
|
|
# llvm-config --bindir may not providing a valid path, so ...
|
|
ifeq "$(shell test -e $(CC) || echo 1 )" "1"
|
|
# however we must ensure that this is not a "CC=gcc make"
|
|
ifeq "$(shell command -v $(CC) 2> /dev/null)" ""
|
|
# we do not have a valid CC variable so we try alternatives
|
|
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
|
|
else
|
|
# hope for the best
|
|
$(warning we have trouble finding clang - llvm-config is not helping us)
|
|
CC = clang
|
|
endif
|
|
endif
|
|
endif
|
|
# llvm-config --bindir may not providing a valid path, so ...
|
|
ifeq "$(shell test -e $(CXX) || echo 1 )" "1"
|
|
# however we must ensure that this is not a "CXX=g++ make"
|
|
ifeq "$(shell command -v $(CXX) 2> /dev/null)" ""
|
|
# we do not have a valid CXX variable so we try alternatives
|
|
ifeq "$(shell test -e '$(BIN_DIR)/clang++' && echo 1)" "1"
|
|
# we found one in the local install directory, lets use these
|
|
CXX = $(BIN_DIR)/clang++
|
|
else
|
|
# hope for the best
|
|
$(warning we have trouble finding clang++ - llvm-config is not helping us)
|
|
CXX = clang++
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
# sanity check.
|
|
# Are versions of clang --version and llvm-config --version equal?
|
|
CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ (1?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
|
|
|
# I disable this because it does not make sense with what we did before (marc)
|
|
# We did exactly set these 26 lines above with these values, and it would break
|
|
# "CC=gcc make" etc. usages
|
|
ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" ""
|
|
CC_SAVE := $(LLVM_BINDIR)/clang
|
|
else
|
|
CC_SAVE := $(CC)
|
|
endif
|
|
ifeq "$(findstring clang, $(shell $(CXX) --version 2>/dev/null))" ""
|
|
CXX_SAVE := $(LLVM_BINDIR)/clang++
|
|
else
|
|
CXX_SAVE := $(CXX)
|
|
endif
|
|
|
|
CLANG_BIN := $(CC_SAVE)
|
|
CLANGPP_BIN := $(CXX_SAVE)
|
|
|
|
ifeq "$(CC_SAVE)" "$(LLVM_BINDIR)/clang"
|
|
USE_BINDIR = 1
|
|
else
|
|
ifeq "$(CXX_SAVE)" "$(LLVM_BINDIR)/clang++"
|
|
USE_BINDIR = 1
|
|
else
|
|
USE_BINDIR = 0
|
|
endif
|
|
endif
|
|
|
|
# On old platform we cannot compile with clang because std++ libraries are too
|
|
# old. For these we need to use gcc/g++, so if we find REAL_CC and REAL_CXX
|
|
# variable we override the compiler variables here
|
|
ifneq "$(REAL_CC)" ""
|
|
CC = $(REAL_CC)
|
|
endif
|
|
ifneq "$(REAL_CXX)" ""
|
|
CXX = $(REAL_CXX)
|
|
endif
|
|
|
|
#
|
|
# Now it can happen that CC points to clang - but there is no clang on the
|
|
# system. Then we fall back to cc
|
|
#
|
|
ifeq "$(shell command -v $(CC) 2>/dev/null)" ""
|
|
CC = cc
|
|
endif
|
|
ifeq "$(shell command -v $(CXX) 2>/dev/null)" ""
|
|
CXX = c++
|
|
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; }' | $(CLANG_BIN) -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; }' | $(CLANG_BIN) -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; }' | $(CLANG_BIN) -x c - -flto -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
|
AFL_CLANG_FLTO ?= -flto
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
|
ifeq "$(AFL_REAL_LD)" ""
|
|
ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
|
|
AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
|
|
else ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
|
|
AFL_REAL_LD = $(shell command -v ld.lld)
|
|
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
|
|
ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
|
|
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
|
|
else
|
|
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)) and its of a different version than LLMV ($(TMP_LDLDD_VERSION) vs. $(LLVMVER)) - cannot enable LTO mode)
|
|
AFL_REAL_LD=
|
|
LLVM_LTO = 0
|
|
endif
|
|
undefine TMP_LDLDD_VERSION
|
|
else
|
|
$(warning ld.lld not found, cannot enable LTO mode)
|
|
LLVM_LTO = 0
|
|
endif
|
|
endif
|
|
else
|
|
$(warning clang option -flto is not working - maybe LLVMgold.so not found - cannot enable LTO mode)
|
|
LLVM_LTO = 0
|
|
endif
|
|
endif
|
|
|
|
AFL_CLANG_FUSELD=
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=$$(command -v ld) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
|
AFL_CLANG_FUSELD=1
|
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(AFL_REAL_LD) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
|
AFL_CLANG_LDPATH=1
|
|
endif
|
|
else
|
|
$(warning -fuse-ld is not working, cannot enable LTO mode)
|
|
LLVM_LTO = 0
|
|
endif
|
|
endif
|
|
|
|
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fdebug-prefix-map=$(CURDIR)=llvm_mode -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
|
AFL_CLANG_DEBUG_PREFIX = -fdebug-prefix-map="$(CURDIR)=llvm_mode"
|
|
else
|
|
AFL_CLANG_DEBUG_PREFIX =
|
|
endif
|
|
|
|
CFLAGS ?= -O3 -funroll-loops -fPIC
|
|
# -D_FORTIFY_SOURCE=1
|
|
CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign \
|
|
-I ./include/ -I ./instrumentation/ \
|
|
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
|
|
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
|
|
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
|
|
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" \
|
|
-DAFL_CLANG_LDPATH=\"$(AFL_CLANG_LDPATH)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
|
|
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) \
|
|
-Wno-unused-function $(AFL_CLANG_DEBUG_PREFIX)
|
|
ifndef LLVM_DEBUG
|
|
CFLAGS_SAFE += -Wno-deprecated
|
|
endif
|
|
|
|
ifdef CODE_COVERAGE
|
|
override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1
|
|
override LDFLAGS += -ldl
|
|
endif
|
|
|
|
override CFLAGS += $(CFLAGS_SAFE)
|
|
|
|
ifdef AFL_TRACE_PC
|
|
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
|
|
endif
|
|
|
|
CXXFLAGS ?= -O3 -funroll-loops -fPIC
|
|
# -D_FORTIFY_SOURCE=1
|
|
override CXXFLAGS += -Wall -g -I ./include/ \
|
|
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros -Wno-deprecated-copy-with-dtor \
|
|
-DLLVM_MINOR=$(LLVM_MINOR) -DLLVM_MAJOR=$(LLVM_MAJOR)
|
|
|
|
ifneq "$(shell $(LLVM_CONFIG) --includedir) 2> /dev/null" ""
|
|
CLANG_CFL = -I$(shell $(LLVM_CONFIG) --includedir)
|
|
endif
|
|
ifneq "$(LLVM_CONFIG)" ""
|
|
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
|
|
endif
|
|
CLANG_CPPFL = $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fno-exceptions -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
|
|
CLANG_LFL = $$($(LLVM_CONFIG) --ldflags) $(LDFLAGS)
|
|
|
|
# wasm fuzzing: disable thread-local storage and unset LLVM debug flag
|
|
ifdef WAFL_MODE
|
|
$(info Compiling libraries for use with WAVM)
|
|
CLANG_CPPFL += -DNDEBUG -DNO_TLS
|
|
endif
|
|
|
|
# User teor2345 reports that this is required to make things work on MacOS X.
|
|
ifeq "$(SYS)" "Darwin"
|
|
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
|
|
override LLVM_HAVE_LTO := 0
|
|
override LLVM_LTO := 0
|
|
else
|
|
CLANG_CPPFL += -Wl,-znodelete
|
|
endif
|
|
|
|
ifeq "$(SYS)" "OpenBSD"
|
|
CLANG_LFL += $$($(LLVM_CONFIG) --libdir)/libLLVM.so
|
|
CLANG_CPPFL += -mno-retpoline
|
|
CFLAGS += -mno-retpoline
|
|
# Needed for unwind symbols
|
|
LDFLAGS += -lc++abi -lpthread
|
|
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_SAFE += -DUSEMMAP=1
|
|
LDFLAGS += -Wno-deprecated-declarations
|
|
endif
|
|
|
|
ifeq "$(TEST_MMAP)" "1"
|
|
SHMAT_OK=0
|
|
CFLAGS_SAFE += -DUSEMMAP=1
|
|
LDFLAGS += -Wno-deprecated-declarations
|
|
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 ./SanitizerCoverageLTO.so ./injection-pass.so
|
|
|
|
# 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_XCODE)" "00"
|
|
NO_BUILD = 1
|
|
endif
|
|
|
|
ifeq "$(NO_BUILD)" "1"
|
|
TARGETS = test_shm $(PROGS_ALWAYS) afl-cc.8
|
|
else
|
|
TARGETS = test_shm test_deps $(PROGS) afl-cc.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 $$?)
|
|
|
|
.PHONY: all
|
|
all: $(TARGETS)
|
|
|
|
.PHONY: test_shm
|
|
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
|
|
|
|
.PHONY: no_build
|
|
no_build:
|
|
@printf "%b\\n" "\\033[0;31mPrerequisites are not met, skipping build llvm_mode\\033[0m"
|
|
|
|
.PHONY: test_deps
|
|
test_deps:
|
|
@echo "[*] Checking for working 'llvm-config'..."
|
|
ifneq "$(LLVM_APPLE_XCODE)" "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-11 or something like that.)"; exit 1 )
|
|
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)"
|
|
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."
|
|
|
|
instrumentation/afl-common.o: ./src/afl-common.c
|
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
|
|
|
|
./afl-cc: src/afl-cc.c instrumentation/afl-common.o
|
|
$(CC) $(CLANG_CFL) $(CFLAGS) $(CPPFLAGS) $< instrumentation/afl-common.o -o $@ -DLLVM_MINOR=$(LLVM_MINOR) -DLLVM_MAJOR=$(LLVM_MAJOR) $(LDFLAGS) -DCFLAGS_OPT=\"$(CFLAGS_OPT)\" -lm
|
|
@ln -sf afl-cc ./afl-c++
|
|
@ln -sf afl-cc ./afl-gcc
|
|
@ln -sf afl-cc ./afl-g++
|
|
@ln -sf afl-cc ./afl-clang
|
|
@ln -sf afl-cc ./afl-clang++
|
|
@ln -sf afl-cc ./afl-clang-fast
|
|
@ln -sf afl-cc ./afl-clang-fast++
|
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
@ln -sf afl-cc ./afl-clang-lto
|
|
@ln -sf afl-cc ./afl-clang-lto++
|
|
@ln -sf afl-cc ./afl-lto
|
|
@ln -sf afl-cc ./afl-lto++
|
|
endif
|
|
endif
|
|
|
|
instrumentation/afl-llvm-common.o: instrumentation/afl-llvm-common.cc instrumentation/afl-llvm-common.h
|
|
$(CXX) $(CFLAGS) $(CPPFLAGS) $$($(LLVM_CONFIG) --cxxflags) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@
|
|
|
|
./afl-llvm-pass.so: instrumentation/afl-llvm-pass.so.cc instrumentation/afl-llvm-common.o | 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_CPPFL) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps
|
|
ifeq "$(LLVM_13_OK)" "1"
|
|
-$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o
|
|
endif
|
|
|
|
./afl-llvm-lto-instrumentlist.so: instrumentation/afl-llvm-lto-instrumentlist.so.cc instrumentation/afl-llvm-common.o
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
endif
|
|
|
|
./afl-ld-lto: src/afl-ld-lto.c
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
$(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
|
|
endif
|
|
|
|
./SanitizerCoverageLTO.so: instrumentation/SanitizerCoverageLTO.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
|
|
endif
|
|
|
|
# laf
|
|
./split-switches-pass.so: instrumentation/split-switches-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
./compare-transform-pass.so: instrumentation/compare-transform-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
./split-compares-pass.so: instrumentation/split-compares-pass.so.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
# /laf
|
|
|
|
./cmplog-routines-pass.so: instrumentation/cmplog-routines-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
./cmplog-instructions-pass.so: instrumentation/cmplog-instructions-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
./cmplog-switches-pass.so: instrumentation/cmplog-switches-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
afl-llvm-dict2file.so: instrumentation/afl-llvm-dict2file.so.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
./injection-pass.so: instrumentation/injection-pass.cc instrumentation/afl-llvm-common.o | test_deps
|
|
$(CXX) $(CLANG_CPPFL) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
|
|
|
|
.PHONY: document
|
|
document:
|
|
$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt.o
|
|
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m32 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt-32.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
@$(CLANG_BIN) -D_AFL_DOCUMENT_MUTATIONS $(CFLAGS_SAFE) $(CPPFLAGS) $(CLANG_CFL) -O3 -Wno-unused-result -m64 -fPIC -c instrumentation/afl-compiler-rt.o.c -o ./afl-compiler-rt-64.o 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
|
|
./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c
|
|
$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@
|
|
|
|
./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c
|
|
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
|
|
@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
|
|
./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c
|
|
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
|
|
@$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
|
|
|
|
.PHONY: test_build
|
|
test_build: $(PROGS)
|
|
@echo "[*] Testing the CC wrapper and instrumentation output..."
|
|
unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; ASAN_OPTIONS=detect_leaks=0 AFL_QUIET=1 AFL_PATH=. AFL_LLVM_LAF_ALL=1 ./afl-cc $(CFLAGS) $(CPPFLAGS) ./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!"
|
|
|
|
.PHONY: all_done
|
|
all_done: test_build
|
|
@echo "[+] All done! You can now use './afl-cc' to compile programs."
|
|
|
|
.NOTPARALLEL: clean
|
|
|
|
.PHONY: install
|
|
install: all
|
|
@install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)
|
|
@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); 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); fi
|
|
@if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); fi
|
|
@if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi
|
|
@if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi
|
|
@if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi
|
|
set -e; install -m 644 ./dynamic_list.txt $${DESTDIR}$(HELPER_PATH)
|
|
install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
|
|
|
|
%.8: %
|
|
@echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@
|
|
@echo .SH NAME >> ./$@
|
|
@printf "%s" ".B $* \- " >> ./$@
|
|
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
|
|
@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>, Dominik Maier <domenukk@gmail.com>, Andrea Fioraldi <andreafioraldi@gmail.com> and Heiko \"hexcoder-\" Eissfeldt <heiko.eissfeldt@hexco.de>" >> ./$@
|
|
@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-cc.8 ./afl-c++.8
|
|
@ln -sf afl-cc.8 ./afl-clang-fast.8
|
|
@ln -sf afl-cc.8 ./afl-clang-fast++.8
|
|
ifneq "$(AFL_CLANG_FLTO)" ""
|
|
ifeq "$(LLVM_LTO)" "1"
|
|
@ln -sf afl-cc.8 ./afl-clang-lto.8
|
|
@ln -sf afl-cc.8 ./afl-clang-lto++.8
|
|
@ln -sf afl-cc.8 ./afl-lto.8
|
|
@ln -sf afl-cc.8 ./afl-lto++.8
|
|
endif
|
|
endif
|
|
|
|
.PHONY: clean
|
|
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-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-compiler-rt*.o ./afl-llvm-rt*.o instrumentation/*.o
|