zcashd/zcutil/libfuzzer/zcash-wrapper

124 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# you shouldn't normally be calling this script directly, it should be called
# by build.sh, but only when build.sh is invoked from libfuzzer-build.sh.
set -ex -o pipefail
# logging functions
export green="\e[92m"
export red="\e[95m"
export normal="\e[0m"
export color=$normal
function log {
while read line
do
(echo ; echo -e "${color}${line}${normal}") >> "$LOGFILE" ;
done
}
# command-line parsing
export FINAL_LINK=0 # by default we using -fsanitize=fuzzer-no-link
for arg do
shift
if [ "$arg" = "-fPIE" ] # no more pie
then
set -- "$@" "-fPIC" "-fno-pie"
continue
fi
if [ "$arg" = "-pie" ]
then
set -- "$@" "-no-pie"
continue
fi
if [ "$arg" = "-o" ] # here an output file is being specified
then
if [ "$1" = "zcashd" ] # here zcashd is the output file
then
export FINAL_LINK=1 # we should use -fsanitize=fuzzer because that links libfuzzer
fi
# note no continue, we fall through to default set
fi
set -- "$@" "$arg"
done
# which source dirs to instrument
if [ "$dirs_to_instrument" = "" ]
then
export dirs_to_instrument=("^.*\/src$")
fi
# Store the command line we were given to a file
echo "`hostname`:`pwd` \$" | log
echo -- "original command: $0 $@" | log
# decide on a sanitizer option beyond just fuzzing:
# to link nor not to link libfuzzer we only link on
# the final call, to the linker.
if [ "$LLVM_SANITIZE" = "" ]
then
export LLVM_SANITIZE="address" # you can override this behavior by setting this environment variable first
fi
if [ "$FINAL_LINK" = "1" ]
then
export LLVM_SANITIZE="-fsanitize=fuzzer,$LLVM_SANITIZE"
else
export LLVM_SANITIZE="-fsanitize=fuzzer-no-link,$LLVM_SANITIZE"
fi
# Work out which compiler we were called as
case $0 in
*zcash-wrapper-clang)
COMPILER="clang"
export DEFINES_FLAGS="${CFLAGS} -DZCASH_FUZZ=1 -DFUZZ_WITH_LIBFUZZER=1 -fPIC"
export INSTRUMENT_FLAGS="${DEFINES_FLAGS} ${LLVM_SANITIZE}"
;;
*zcash-wrapper-clang++)
COMPILER="clang++"
export DEFINES_FLAGS="${CXXFLAGS} -DZCASH_FUZZ=1 -DFUZZ_WITH_LIBFUZZER=1 -fPIC"
export INSTRUMENT_FLAGS="${DEFINES_FLAGS} ${LLVM_SANITIZE}"
;;
*zcash-wrapper)
echo -n "Call this script instead of your regular compiler, and if the absolute "
echo -n "path of the CWD the wrapper was called from matches a regex in the "
echo -n "array 'dirs_to_instrument', it will instrument the resulting object. "
echo -n "Otherwise it will exec directly to the original compiler without "
echo "changing arguments."
echo -n "You can also set LLVM_SANITIZE to whatever sanitizers you'd like to use."
echo -n "the default is 'address'. You don't need the -fsanitize=fuzzer part, "
echo "this script handles that"
exit
;;
esac
# Check if we should instrument
for i in "${dirs_to_instrument[@]}"
do
if echo -- "`pwd`" | grep "$i"; then
# We found a match, let's instrument this one.
echo "pwd (`pwd`) matches dirs_to_instrument array element ($i). Adding instrumentation flags..." | log
echo "command with defines and instrumentation added:" | color=$green log
echo -- "$COMPILER" $INSTRUMENT_FLAGS "$@" | log
exec -- "$COMPILER" $INSTRUMENT_FLAGS "$@"
fi
done
# No match, just pass-through.
echo -e -- "${red}command with defines added:${normal}" | color=$red log
echo -- "$COMPILER" $DEFINES_FLAGS "$@" | log
exec -- "$COMPILER" $DEFINES_FLAGS "$@"