summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include2
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.build2
-rw-r--r--scripts/Makefile.clean4
-rw-r--r--scripts/Makefile.gcc-plugins43
-rw-r--r--scripts/Makefile.host55
-rw-r--r--scripts/Makefile.lib9
-rw-r--r--scripts/basic/bin2c.c3
-rwxr-xr-xscripts/checkpatch.pl30
-rwxr-xr-xscripts/coccicheck96
-rw-r--r--scripts/coccinelle/free/devm_free.cocci26
-rw-r--r--scripts/coccinelle/free/ifnullfree.cocci4
-rw-r--r--scripts/coccinelle/free/kfree.cocci18
-rw-r--r--scripts/coccinelle/free/kfreeaddr.cocci6
-rw-r--r--scripts/coccinelle/iterators/device_node_continue.cocci3
-rw-r--r--scripts/coccinelle/misc/noderef.cocci18
-rwxr-xr-xscripts/dtc/dt_to_config1213
-rwxr-xr-xscripts/dtc/dtx_diff2
-rwxr-xr-xscripts/gcc-plugin.sh51
-rw-r--r--scripts/gcc-plugins/Makefile27
-rw-r--r--scripts/gcc-plugins/cyc_complexity_plugin.c73
-rw-r--r--scripts/gcc-plugins/gcc-common.h830
-rw-r--r--scripts/gcc-plugins/gcc-generate-gimple-pass.h175
-rw-r--r--scripts/gcc-plugins/gcc-generate-ipa-pass.h289
-rw-r--r--scripts/gcc-plugins/gcc-generate-rtl-pass.h175
-rw-r--r--scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h175
-rw-r--r--scripts/gcc-plugins/sancov_plugin.c144
-rwxr-xr-xscripts/get_maintainer.pl20
-rwxr-xr-xscripts/link-vmlinux.sh2
-rwxr-xr-xscripts/package/builddeb12
-rwxr-xr-xscripts/setlocalversion2
-rwxr-xr-xscripts/sign-file.c34
32 files changed, 3494 insertions, 51 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 0f82314621f2..15b196fc2f49 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -202,7 +202,7 @@ hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj
# Prefix -I with $(srctree) if it is not an absolute path.
# skip if -I has no parameter
addtree = $(if $(patsubst -I%,%,$(1)), \
-$(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1))
+$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)))
# Find all -I options and call addtree
flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
diff --git a/scripts/Makefile b/scripts/Makefile
index 822ab4a6a4aa..1d80897a9644 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -47,4 +47,4 @@ subdir-$(CONFIG_DTC) += dtc
subdir-$(CONFIG_GDB_SCRIPTS) += gdb
# Let clean descend into subdirs
-subdir- += basic kconfig package
+subdir- += basic kconfig package gcc-plugins
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0d1ca5bf42fb..11602e5efb3b 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -60,7 +60,7 @@ endif
endif
# Do not include host rules unless needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
include scripts/Makefile.host
endif
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 55c96cb8070f..50616ea25131 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,9 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
__clean-files := $(extra-y) $(extra-m) $(extra-) \
$(always) $(targets) $(clean-files) \
$(host-progs) \
- $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+ $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
+ $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \
+ $(hostcxxlibs-y) $(hostcxxlibs-m)
__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
new file mode 100644
index 000000000000..5e22b60589c1
--- /dev/null
+++ b/scripts/Makefile.gcc-plugins
@@ -0,0 +1,43 @@
+ifdef CONFIG_GCC_PLUGINS
+ __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
+ PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
+
+ SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
+
+ gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so
+
+ ifdef CONFIG_GCC_PLUGIN_SANCOV
+ ifeq ($(CFLAGS_KCOV),)
+ # It is needed because of the gcc-plugin.sh and gcc version checks.
+ gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
+
+ ifneq ($(PLUGINCC),)
+ CFLAGS_KCOV := $(SANCOV_PLUGIN)
+ else
+ $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler)
+ endif
+ endif
+ endif
+
+ GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
+
+ export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN
+
+ ifeq ($(PLUGINCC),)
+ ifneq ($(GCC_PLUGINS_CFLAGS),)
+ ifeq ($(call cc-ifversion, -ge, 0405, y), y)
+ PLUGINCC := $(shell $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
+ $(warning warning: your gcc installation does not support plugins, perhaps the necessary headers are missing?)
+ else
+ $(warning warning: your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least)
+ endif
+ endif
+ else
+ # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication.
+ GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS))
+ endif
+
+ KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
+ GCC_PLUGIN := $(gcc-plugin-y)
+
+endif
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 133edfae5b8a..45b5b1aaedbd 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -20,7 +20,15 @@
# Will compile qconf as a C++ program, and menu as a C program.
# They are linked as C++ code to the executable qconf
+# hostcc-option
+# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
+
+hostcc-option = $(call try-run,\
+ $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+
__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
+host-cshlib := $(sort $(hostlibs-y) $(hostlibs-m))
+host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
# C code
# Executables compiled from a single .c file
@@ -42,6 +50,10 @@ host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
# C++ Object (.o) files compiled from .cc files
host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
+# Object (.o) files used by the shared libaries
+host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
+host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs))))
+
# output directory for programs/.o files
# hostprogs-y := tools/build may have been specified.
# Retrieve also directory of .o files from prog-objs or prog-cxxobjs notation
@@ -56,6 +68,10 @@ host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
+host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
+host-cxxshlib := $(addprefix $(obj)/,$(host-cxxshlib))
+host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
+host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
host-objdirs := $(addprefix $(obj)/,$(host-objdirs))
obj-dirs += $(host-objdirs)
@@ -124,5 +140,42 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
+# Compile .c file, create position independent .o file
+# host-cshobjs -> .o
+quiet_cmd_host-cshobjs = HOSTCC -fPIC $@
+ cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
+$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
+ $(call if_changed_dep,host-cshobjs)
+
+# Compile .c file, create position independent .o file
+# Note that plugin capable gcc versions can be either C or C++ based
+# therefore plugin source files have to be compilable in both C and C++ mode.
+# This is why a C++ compiler is invoked on a .c file.
+# host-cxxshobjs -> .o
+quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@
+ cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
+$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
+ $(call if_changed_dep,host-cxxshobjs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cshlib)
+quiet_cmd_host-cshlib = HOSTLLD -shared $@
+ cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cshlib): FORCE
+ $(call if_changed,host-cshlib)
+$(call multi_depend, $(host-cshlib), .so, -objs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cxxshlib)
+quiet_cmd_host-cxxshlib = HOSTLLD -shared $@
+ cmd_host-cxxshlib = $(HOSTCXX) $(HOSTLDFLAGS) -shared -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cxxshlib): FORCE
+ $(call if_changed,host-cxxshlib)
+$(call multi_depend, $(host-cxxshlib), .so, -objs)
+
targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
- $(host-cxxmulti) $(host-cxxobjs)
+ $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs) $(host-cxxshlib) $(host-cxxshobjs)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e7df0f5db7ec..0a07f9014944 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -138,7 +138,7 @@ endif
ifeq ($(CONFIG_KCOV),y)
_c_flags += $(if $(patsubst n%,, \
- $(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)y), \
+ $(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \
$(CFLAGS_KCOV))
endif
@@ -155,9 +155,10 @@ else
# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
# and locates generated .h files
# FIXME: Replace both with specific CFLAGS* statements in the makefiles
-__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags)
-__a_flags = $(call flags,_a_flags)
-__cpp_flags = $(call flags,_cpp_flags)
+__c_flags = $(if $(obj),-I$(srctree)/$(src) -I$(obj)) \
+ $(call flags,_c_flags)
+__a_flags = $(call flags,_a_flags)
+__cpp_flags = $(call flags,_cpp_flags)
endif
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
diff --git a/scripts/basic/bin2c.c b/scripts/basic/bin2c.c
index af187e695345..c3d7eef3ad06 100644
--- a/scripts/basic/bin2c.c
+++ b/scripts/basic/bin2c.c
@@ -29,7 +29,8 @@ int main(int argc, char *argv[])
} while (ch != EOF);
if (argc > 1)
- printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
+ printf("\t;\n\n#include <linux/types.h>\n\nconst size_t %s_size = %d;\n",
+ argv[1], total);
return 0;
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 4904ced676d4..4de3cc42fc50 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -55,6 +55,7 @@ my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $color = 1;
+my $allow_c99_comments = 1;
sub help {
my ($exitcode) = @_;
@@ -227,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {
}
}
+#if no filenames are given, push '-' to read patch from stdin
if ($#ARGV < 0) {
- print "$P: no input files\n";
- exit(1);
+ push(@ARGV, '-');
}
sub hash_save_array_words {
@@ -313,7 +314,6 @@ our $Sparse = qr{
__kernel|
__force|
__iomem|
- __pmem|
__must_check|
__init_refok|
__kprobes|
@@ -1145,6 +1145,11 @@ sub sanitise_line {
$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
}
+ if ($allow_c99_comments && $res =~ m@(//.*$)@) {
+ my $match = $1;
+ $res =~ s/\Q$match\E/"$;" x length($match)/e;
+ }
+
return $res;
}
@@ -2064,6 +2069,7 @@ sub process {
my $is_patch = 0;
my $in_header_lines = $file ? 0 : 1;
my $in_commit_log = 0; #Scanning lines before patch
+ my $has_commit_log = 0; #Encountered lines before patch
my $commit_log_possible_stack_dump = 0;
my $commit_log_long_line = 0;
my $commit_log_has_diff = 0;
@@ -2454,9 +2460,9 @@ sub process {
# Check for git id commit length and improperly formed commit descriptions
if ($in_commit_log && !$commit_log_possible_stack_dump &&
- $line !~ /^\s*(?:Link|Patchwork|http|BugLink):/i &&
+ $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
- ($line =~ /\b[0-9a-f]{12,40}\b/i &&
+ ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
$line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
$line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
my $init_char = "c";
@@ -2561,6 +2567,7 @@ sub process {
$rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {
$in_header_lines = 0;
$in_commit_log = 1;
+ $has_commit_log = 1;
}
# Check if there is UTF-8 in a commit log when a mail header has explicitly
@@ -2764,6 +2771,10 @@ sub process {
$line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
$msg_type = "";
+ # EFI_GUID is another special case
+ } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
+ $msg_type = "";
+
# Otherwise set the alternate message types
# a comment starts before $max_line_length
@@ -3338,7 +3349,7 @@ sub process {
next if ($line =~ /^[^\+]/);
# check for declarations of signed or unsigned without int
- while ($line =~ m{($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
+ while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
my $type = $1;
my $var = $2;
$var = "" if (!defined $var);
@@ -5723,8 +5734,9 @@ sub process {
}
}
-# check for #defines like: 1 << <digit> that could be BIT(digit)
- if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
+# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
+ if ($realfile !~ m@^include/uapi/@ &&
+ $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
my $ull = "";
$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
if (CHK("BIT_MACRO",
@@ -6045,7 +6057,7 @@ sub process {
ERROR("NOT_UNIFIED_DIFF",
"Does not appear to be a unified-diff format patch\n");
}
- if ($is_patch && $filename ne '-' && $chk_signoff && $signoff == 0) {
+ if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
ERROR("MISSING_SIGN_OFF",
"Missing Signed-off-by: line(s)\n");
}
diff --git a/scripts/coccicheck b/scripts/coccicheck
index dd85a455b2ba..c92c1528a54d 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -1,14 +1,24 @@
#!/bin/bash
-
+# Linux kernel coccicheck
+#
+# Read Documentation/coccinelle.txt
#
# This script requires at least spatch
# version 1.0.0-rc11.
-#
+DIR="$(dirname $(readlink -f $0))/.."
SPATCH="`which ${SPATCH:=spatch}`"
-trap kill_running SIGTERM SIGINT
-declare -a SPATCH_PID
+if [ ! -x "$SPATCH" ]; then
+ echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
+ exit 1
+fi
+
+SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}')
+SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh)
+
+USE_JOBS="no"
+$SPATCH --help | grep "\-\-jobs" > /dev/null && USE_JOBS="yes"
# The verbosity may be set by the environmental parameter V=
# as for example with 'make V=1 coccicheck'
@@ -25,7 +35,28 @@ else
NPROC="$J"
fi
-FLAGS="$SPFLAGS --very-quiet"
+FLAGS="--very-quiet"
+
+# You can use SPFLAGS to append extra arguments to coccicheck or override any
+# heuristics done in this file as Coccinelle accepts the last options when
+# options conflict.
+#
+# A good example for use of SPFLAGS is if you want to debug your cocci script,
+# you can for instance use the following:
+#
+# $ export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
+# $ make coccicheck MODE=report DEBUG_FILE="all.err" SPFLAGS="--profile --show-trying" M=./drivers/mfd/arizona-irq.c
+#
+# "--show-trying" should show you what rule is being processed as it goes to
+# stdout, you do not need a debug file for that. The profile output will be
+# be sent to stdout, if you provide a DEBUG_FILE the profiling data can be
+# inspected there.
+#
+# --profile will not output if --very-quiet is used, so avoid it.
+echo $SPFLAGS | egrep -e "--profile|--show-trying" 2>&1 > /dev/null
+if [ $? -eq 0 ]; then
+ FLAGS="--quiet"
+fi
# spatch only allows include directories with the syntax "-I include"
# while gcc also allows "-Iinclude" and "-include include"
@@ -51,9 +82,14 @@ if [ "$KBUILD_EXTMOD" != "" ] ; then
OPTIONS="--patch $srctree $OPTIONS"
fi
-if [ ! -x "$SPATCH" ]; then
- echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
- exit 1
+# You can override by using SPFLAGS
+if [ "$USE_JOBS" = "no" ]; then
+ trap kill_running SIGTERM SIGINT
+ declare -a SPATCH_PID
+elif [ "$NPROC" != "1" ]; then
+ # Using 0 should work as well, refer to _SC_NPROCESSORS_ONLN use on
+ # https://github.com/rdicosmo/parmap/blob/master/setcore_stubs.c
+ OPTIONS="$OPTIONS --jobs $NPROC --chunksize 1"
fi
if [ "$MODE" = "" ] ; then
@@ -72,7 +108,7 @@ if [ "$MODE" = "chain" ] ; then
echo 'All available modes will be tried (in that order): patch, report, context, org'
fi
elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
- FLAGS="$FLAGS --no-show-diff"
+ FLAGS="--no-show-diff $FLAGS"
fi
if [ "$ONLINE" = "0" ] ; then
@@ -82,7 +118,26 @@ if [ "$ONLINE" = "0" ] ; then
echo ''
fi
-run_cmd() {
+run_cmd_parmap() {
+ if [ $VERBOSE -ne 0 ] ; then
+ echo "Running ($NPROC in parallel): $@"
+ fi
+ if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
+ if [ -f $DEBUG_FILE ]; then
+ echo "Debug file $DEBUG_FILE exists, bailing"
+ exit
+ fi
+ else
+ DEBUG_FILE="/dev/null"
+ fi
+ $@ 2>$DEBUG_FILE
+ if [[ $? -ne 0 ]]; then
+ echo "coccicheck failed"
+ exit $?
+ fi
+}
+
+run_cmd_old() {
local i
if [ $VERBOSE -ne 0 ] ; then
echo "Running ($NPROC in parallel): $@"
@@ -97,6 +152,14 @@ run_cmd() {
wait
}
+run_cmd() {
+ if [ "$USE_JOBS" = "yes" ]; then
+ run_cmd_parmap $@
+ else
+ run_cmd_old $@
+ fi
+}
+
kill_running() {
for i in $(seq 0 $(( NPROC - 1 )) ); do
if [ $VERBOSE -eq 2 ] ; then
@@ -106,10 +169,23 @@ kill_running() {
done
}
+# You can override heuristics with SPFLAGS, these must always go last
+OPTIONS="$OPTIONS $SPFLAGS"
+
coccinelle () {
COCCI="$1"
OPT=`grep "Option" $COCCI | cut -d':' -f2`
+ REQ=`grep "Requires" $COCCI | cut -d':' -f2 | sed "s| ||"`
+ REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh)
+ if [ "$REQ_NUM" != "0" ] ; then
+ if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then
+ echo "Skipping coccinele SmPL patch: $COCCI"
+ echo "You have coccinelle: $SPATCH_VERSION"
+ echo "This SmPL patch requires: $REQ"
+ return
+ fi
+ fi
# The option '--parse-cocci' can be used to syntactically check the SmPL files.
#
diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci
index 3d9349012bb3..c990d2c7ee16 100644
--- a/scripts/coccinelle/free/devm_free.cocci
+++ b/scripts/coccinelle/free/devm_free.cocci
@@ -29,8 +29,24 @@ expression x;
@@
(
+ x = devm_kmalloc(...)
+|
+ x = devm_kvasprintf(...)
+|
+ x = devm_kasprintf(...)
+|
x = devm_kzalloc(...)
|
+ x = devm_kmalloc_array(...)
+|
+ x = devm_kcalloc(...)
+|
+ x = devm_kstrdup(...)
+|
+ x = devm_kmemdup(...)
+|
+ x = devm_get_free_pages(...)
+|
x = devm_request_irq(...)
|
x = devm_ioremap(...)
@@ -48,6 +64,16 @@ position p;
(
* kfree@p(x)
|
+* kzfree@p(x)
+|
+* __krealloc@p(x, ...)
+|
+* krealloc@p(x, ...)
+|
+* free_pages@p(x, ...)
+|
+* free_page@p(x)
+|
* free_irq@p(x)
|
* iounmap@p(x)
diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci
index 52bd235286fa..14a4cd98e83b 100644
--- a/scripts/coccinelle/free/ifnullfree.cocci
+++ b/scripts/coccinelle/free/ifnullfree.cocci
@@ -20,6 +20,8 @@ expression E;
(
kfree(E);
|
+ kzfree(E);
+|
debugfs_remove(E);
|
debugfs_remove_recursive(E);
@@ -39,7 +41,7 @@ position p;
@@
* if (E != NULL)
-* \(kfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|
+* \(kfree@p\|kzfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|
* usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\|
* dma_pool_destroy@p\)(E);
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
index 577b78056990..ac438da4fd7b 100644
--- a/scripts/coccinelle/free/kfree.cocci
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -20,7 +20,11 @@ expression E;
position p1;
@@
-kfree@p1(E)
+(
+* kfree@p1(E)
+|
+* kzfree@p1(E)
+)
@print expression@
constant char [] c;
@@ -60,7 +64,11 @@ position ok;
@@
while (1) { ...
- kfree@ok(E)
+(
+* kfree@ok(E)
+|
+* kzfree@ok(E)
+)
... when != break;
when != goto l;
when forall
@@ -74,7 +82,11 @@ statement S;
position free.p1!=loop.ok,p2!={print.p,sz.p};
@@
-kfree@p1(E,...)
+(
+* kfree@p1(E,...)
+|
+* kzfree@p1(E,...)
+)
...
(
iter(...,subE,...) S // no use
diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci
index ce8aacc314cb..d46063b1db8b 100644
--- a/scripts/coccinelle/free/kfreeaddr.cocci
+++ b/scripts/coccinelle/free/kfreeaddr.cocci
@@ -16,7 +16,11 @@ identifier f;
position p;
@@
+(
* kfree@p(&e->f)
+|
+* kzfree@p(&e->f)
+)
@script:python depends on org@
p << r.p;
@@ -28,5 +32,5 @@ cocci.print_main("kfree",p)
p << r.p;
@@
-msg = "ERROR: kfree of structure field"
+msg = "ERROR: invalid free of structure field"
coccilib.report.print_report(p[0],msg)
diff --git a/scripts/coccinelle/iterators/device_node_continue.cocci b/scripts/coccinelle/iterators/device_node_continue.cocci
index 38ab744a4037..a36c16db171b 100644
--- a/scripts/coccinelle/iterators/device_node_continue.cocci
+++ b/scripts/coccinelle/iterators/device_node_continue.cocci
@@ -5,8 +5,11 @@
// Copyright: (C) 2015 Julia Lawall, Inria. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Options: --no-includes --include-headers
+// Requires: 1.0.4
// Keywords: for_each_child_of_node, etc.
+// This uses a conjunction, which requires at least coccinelle >= 1.0.4
+
virtual patch
virtual context
virtual org
diff --git a/scripts/coccinelle/misc/noderef.cocci b/scripts/coccinelle/misc/noderef.cocci
index 80a831c91161..007f0de0c715 100644
--- a/scripts/coccinelle/misc/noderef.cocci
+++ b/scripts/coccinelle/misc/noderef.cocci
@@ -16,6 +16,7 @@ virtual patch
@depends on patch@
expression *x;
expression f;
+expression i;
type T;
@@
@@ -30,15 +31,26 @@ f(...,(T)(x),...,sizeof(
+ *x
),...)
|
-f(...,sizeof(x),...,(T)(
+f(...,sizeof(
+- x
++ *x
+ ),...,(T)(x),...)
+|
+f(...,(T)(x),...,i*sizeof(
- x
+ *x
),...)
+|
+f(...,i*sizeof(
+- x
++ *x
+ ),...,(T)(x),...)
)
@r depends on !patch@
expression *x;
expression f;
+expression i;
position p;
type T;
@@
@@ -49,6 +61,10 @@ type T;
*f(...,(T)(x),...,sizeof@p(x),...)
|
*f(...,sizeof@p(x),...,(T)(x),...)
+|
+*f(...,(T)(x),...,i*sizeof@p(x),...)
+|
+*f(...,i*sizeof@p(x),...,(T)(x),...)
)
@script:python depends on org@
diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config
new file mode 100755
index 000000000000..9a248b505c58
--- /dev/null
+++ b/scripts/dtc/dt_to_config
@@ -0,0 +1,1213 @@
+#!/usr/bin/perl
+
+# Copyright 2016 by Frank Rowand
+# Copyright 2016 by Gaurav Minocha
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License v2.
+
+use strict 'refs';
+use strict subs;
+
+use Getopt::Long;
+
+$VUFX = "160610a";
+
+$script_name = $0;
+$script_name =~ s|^.*/||;
+
+
+# ----- constants for print_flags()
+
+# Position in string $pr_flags. Range of 0..($num_pr_flags - 1).
+$pr_flag_pos_mcompatible = 0;
+$pr_flag_pos_driver = 1;
+$pr_flag_pos_mdriver = 2;
+$pr_flag_pos_config = 3;
+$pr_flag_pos_mconfig = 4;
+$pr_flag_pos_node_not_enabled = 5;
+$pr_flag_pos_white_list = 6;
+$pr_flag_pos_hard_coded = 7;
+$pr_flag_pos_config_hard_coded = 8;
+$pr_flag_pos_config_none = 9;
+$pr_flag_pos_config_m = 10;
+$pr_flag_pos_config_y = 11;
+$pr_flag_pos_config_test_fail = 12;
+
+$num_pr_flags = $pr_flag_pos_config_test_fail + 1;
+
+# flags in @pr_flag_value must be unique values to allow simple regular
+# expessions to work for --include_flags and --exclude_flags.
+# Convention: use upper case letters for potential issues or problems.
+
+@pr_flag_value = ('M', 'd', 'D', 'c', 'C', 'E', 'W', 'H', 'x', 'n', 'm', 'y', 'F');
+
+@pr_flag_help = (
+ "multiple compatibles found for this node",
+ "driver found for this compatible",
+ "multiple drivers found for this compatible",
+ "kernel config found for this driver",
+ "multiple config options found for this driver",
+ "node is not enabled",
+ "compatible is white listed",
+ "matching driver and/or kernel config is hard coded",
+ "kernel config hard coded in Makefile",
+ "one or more kernel config file options is not set",
+ "one or more kernel config file options is set to 'm'",
+ "one or more kernel config file options is set to 'y'",
+ "one of more kernel config file options fails to have correct value"
+);
+
+
+# -----
+
+%driver_config = (); # driver config array, indexed by driver source file
+%driver_count = (); # driver_cnt, indexed by compatible
+%compat_driver = (); # compatible driver array, indexed by compatible
+%existing_config = (); # existing config symbols present in given config file
+ # expected values are: "y", "m", a decimal number, a
+ # hex number, or a string
+
+# ----- magic compatibles, do not have a driver
+#
+# Will not search for drivers for these compatibles.
+
+%compat_white_list = (
+ 'none' => '1',
+ 'pci' => '1',
+ 'simple-bus' => '1',
+);
+
+# Will not search for drivers for these compatibles.
+#
+# These compatibles have a very large number of false positives.
+#
+# 'hardcoded_no_driver' is a magic value. Other code knows this
+# magic value. Do not use 'no_driver' here!
+#
+# Revisit each 'hardcoded_no_driver' to see how the compatible
+# is used. Are there drivers that can be provided?
+
+%driver_hard_code_list = (
+ 'cache' => ['hardcoded_no_driver'],
+ 'eeprom' => ['hardcoded_no_driver'],
+ 'gpio' => ['hardcoded_no_driver'],
+ 'gpio-keys' => ['drivers/input/keyboard/gpio_keys.c'],
+ 'i2c-gpio' => ['drivers/i2c/busses/i2c-gpio.c'],
+ 'isa' => ['arch/mips/mti-malta/malta-dt.c',
+ 'arch/x86/kernel/devicetree.c'],
+ 'led' => ['hardcoded_no_driver'],
+ 'm25p32' => ['hardcoded_no_driver'],
+ 'm25p64' => ['hardcoded_no_driver'],
+ 'm25p80' => ['hardcoded_no_driver'],
+ 'mtd-ram' => ['drivers/mtd/maps/physmap_of.c'],
+ 'pwm-backlight' => ['drivers/video/backlight/pwm_bl.c'],
+ 'spidev' => ['hardcoded_no_driver'],
+ 'syscon' => ['drivers/mfd/syscon.c'],
+ 'tlv320aic23' => ['hardcoded_no_driver'],
+ 'wm8731' => ['hardcoded_no_driver'],
+);
+
+# Use these config options instead of searching makefiles
+
+%driver_config_hard_code_list = (
+
+ # this one needed even if %driver_hard_code_list is empty
+ 'no_driver' => ['no_config'],
+ 'hardcoded_no_driver' => ['no_config'],
+
+ # drivers/usb/host/ehci-ppc-of.c
+ # drivers/usb/host/ehci-xilinx-of.c
+ # are included from:
+ # drivers/usb/host/ehci-hcd.c
+ # thus the search of Makefile for the included .c files is incorrect
+ # ehci-hcd.c wraps the includes with ifdef CONFIG_USB_EHCI_HCD_..._OF
+ #
+ # similar model for ohci-hcd.c (but no ohci-xilinx-of.c)
+ #
+ # similarly, uhci-hcd.c includes uhci-platform.c
+
+ 'drivers/usb/host/ehci-ppc-of.c' => ['CONFIG_USB_EHCI_HCD',
+ 'CONFIG_USB_EHCI_HCD_PPC_OF'],
+ 'drivers/usb/host/ohci-ppc-of.c' => ['CONFIG_USB_OHCI_HCD',
+ 'CONFIG_USB_OHCI_HCD_PPC_OF'],
+
+ 'drivers/usb/host/ehci-xilinx-of.c' => ['CONFIG_USB_EHCI_HCD',
+ 'CONFIG_USB_EHCI_HCD_XILINX'],
+
+ 'drivers/usb/host/uhci-platform.c' => ['CONFIG_USB_UHCI_HCD',
+ 'CONFIG_USB_UHCI_PLATFORM'],
+
+ # scan_makefile will find only one of these config options:
+ # ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
+ 'arch/arm/mach-imx/platsmp.c' => ['CONFIG_SOC_IMX6 && CONFIG_SMP',
+ 'CONFIG_SOC_LS1021A && CONFIG_SMP'],
+);
+
+
+# 'virt/kvm/arm/.*' are controlled by makefiles in other directories,
+# using relative paths, such as 'KVM := ../../../virt/kvm'. Do not
+# add complexity to find_kconfig() to deal with this. There is a long
+# term intent to change the kvm related makefiles to the normal kernel
+# style. After that is done, this entry can be removed from the
+# black_list_driver.
+
+@black_list_driver = (
+ # kvm no longer a problem after commit 503a62862e8f in 4.7-rc1
+ # 'virt/kvm/arm/.*',
+);
+
+
+sub usage()
+{
+ print
+"
+Usage: $script_name [options] device-tree...
+
+ device_tree is: dts_file | dtb_file | proc_device-tree
+
+
+Valid options:
+ -c FILE Read kernel config options from FILE
+ --config FILE synonym for 'c'
+ --config-format config file friendly output format
+ --exclude-flag FLAG exclude entries with a matching flag
+ -h Display this message and exit
+ --help synonym for 'h'
+ --black-list-driver use driver black list
+ --white-list-config use config white list
+ --white-list-driver use driver white list
+ --include-flag FLAG include only entries with a matching flag
+ --include-suspect include only entries with an uppercase flag
+ --short-name do not show the path portion of the node name
+ --show-lists report of white and black lists
+ --version Display program version and exit
+
+
+ Report driver source files that match the compatibles in the device
+ tree file and the kernel config options that enable the driver source
+ files.
+
+ This program must be run in the root directory of a Linux kernel
+ source tree.
+
+ The default format is a report that is intended to be easily human
+ scannable.
+
+ An alternate format can be selected by --config-format. This will
+ create output that can easily be edited to create a fragment that can
+ be appended to the existing kernel config file. Each entry consists of
+ multiple lines. The first line reports flags, the node path, compatible
+ value, driver file matching the compatible, configuration options, and
+ current values of the configuration options. For each configuration
+ option, the following lines report the current value and the value that
+ is required for the driver file to be included in the kernel.
+
+ If a large number of drivers or config options is listed for a node,
+ and the '$pr_flag_value[$pr_flag_pos_hard_coded]' flag is set consider using --white-list-config and/or
+ --white-list-driver. If the white list option suppresses the correct
+ entry please report that as a bug.
+
+ CAUTION:
+ This program uses heuristics to guess which driver(s) support each
+ compatible string and which config option(s) enables the driver(s).
+ Do not believe that the reported information is fully correct.
+ This program is intended to aid the process of determining the
+ proper kernel configuration for a device tree, but this is not
+ a fully automated process -- human involvement may still be
+ required!
+
+ The driver match heuristic used is to search for source files
+ containing the compatible string enclosed in quotes.
+
+ This program might not be able to find all drivers matching a
+ compatible string.
+
+ Some makefiles are overly clever. This program was not made
+ complex enough to handle them. If no config option is listed
+ for a driver, look at the makefile for the driver source file.
+ Even if a config option is listed for a driver, some other
+ available config options may not be listed.
+
+ FLAG values:
+";
+
+ for ($k = 0; $k < $num_pr_flags; $k++) {
+ printf " %s %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
+ }
+
+ print
+"
+ Upper case letters indicate potential issues or problems.
+
+ The flag:
+
+";
+
+ $k = $pr_flag_pos_hard_coded;
+ printf " %s %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
+
+ print
+"
+ will be set if the config or driver is in the white lists, even if
+ --white-list-config and --white-list-driver are not specified.
+ This is a hint that 1) many of these reported lines are likely to
+ be incorrect, and 2) using those options will reduce the number of
+ drivers and/or config options reported.
+
+ --white-list-config and --white-list-driver may not be accurate if this
+ program is not well maintained. Use them with appropriate skepticism.
+ Use the --show-lists option to report the values in the list.
+
+ Return value:
+ 0 if no error
+ 1 error processing command line
+ 2 unable to open or read kernel config file
+ 3 unable to open or process input device tree file(s)
+
+ EXAMPLES:
+
+ dt_to_config arch/arm/boot/dts/my_dts_file.dts
+
+ Basic report.
+
+ dt_to_config \\
+ --config \${KBUILD_OUTPUT}/.config \\
+ arch/\${ARCH}/boot/dts/my_dts_file.dts
+
+ Full report, with config file issues noted.
+
+ dt_to_config --include-suspect \\
+ --config \${KBUILD_OUTPUT}/.config \\
+ arch/\${ARCH}/boot/dts/my_dts_file.dts
+
+ Report of node / compatible string / driver tuples that should
+ be further investigated. A node may have multiple compatible
+ strings. A compatible string may be matched by multiple drivers.
+ A driver may have config file issues noted. The compatible string
+ and/or driver may be in the white lists.
+
+ dt_to_config --include-suspect --config-format \\
+ --config ${KBUILD_OUTPUT}/.config \\
+ arch/\${ARCH}/boot/dts/my_dts_file.dts
+
+ Report of node / compatible string / driver tuples that should
+ be further investigated. The report can be edited to uncomment
+ the config options to select the desired tuple for a given node.
+ A node may have multiple compatible strings. A compatible string
+ may be matched by multiple drivers. A driver may have config file
+ issues noted. The compatible string and/or driver may be in the
+ white lists.
+
+";
+}
+
+sub set_flag()
+{
+ # pr_flags_ref is a reference to $pr_flags
+
+ my $pr_flags_ref = shift;
+ my $pos = shift;
+
+ substr $$pr_flags_ref, $pos, 1, $pr_flag_value[$pos];
+
+ return $pr_flags;
+}
+
+sub print_flags()
+{
+ # return 1 if anything printed, else 0
+
+ # some fields of pn_arg_ref might not be used in this function, but
+ # extract all of them anyway.
+ my $pn_arg_ref = shift;
+
+ my $compat = $pn_arg_ref->{compat};
+ my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
+ my $config = $pn_arg_ref->{config};
+ my $config_cnt = $pn_arg_ref->{config_cnt};
+ my $driver = $pn_arg_ref->{driver};
+ my $driver_cnt = $pn_arg_ref->{driver_cnt};
+ my $full_node = $pn_arg_ref->{full_node};
+ my $node = $pn_arg_ref->{node};
+ my $node_enabled = $pn_arg_ref->{node_enabled};
+ my $white_list = $pn_arg_ref->{white_list};
+
+ my $pr_flags = '-' x $num_pr_flags;
+
+
+ # ----- set flags in $pr_flags
+
+ if ($compatible_cnt > 1) {
+ &set_flag(\$pr_flags, $pr_flag_pos_mcompatible);
+ }
+
+ if ($config_cnt > 1) {
+ &set_flag(\$pr_flags, $pr_flag_pos_mconfig);
+ }
+
+ if ($driver_cnt >= 1) {
+ &set_flag(\$pr_flags, $pr_flag_pos_driver);
+ }
+
+ if ($driver_cnt > 1) {
+ &set_flag(\$pr_flags, $pr_flag_pos_mdriver);
+ }
+
+ # These strings are the same way the linux kernel tests.
+ # The ePapr lists of values is slightly different.
+ if (!(
+ ($node_enabled eq "") ||
+ ($node_enabled eq "ok") ||
+ ($node_enabled eq "okay")
+ )) {
+ &set_flag(\$pr_flags, $pr_flag_pos_node_not_enabled);
+ }
+
+ if ($white_list) {
+ &set_flag(\$pr_flags, $pr_flag_pos_white_list);
+ }
+
+ if (exists($driver_hard_code_list{$compat}) ||
+ (exists($driver_config_hard_code_list{$driver}) &&
+ ($driver ne "no_driver"))) {
+ &set_flag(\$pr_flags, $pr_flag_pos_hard_coded);
+ }
+
+ my @configs = split(' && ', $config);
+ for $configs (@configs) {
+ $not = $configs =~ /^!/;
+ $configs =~ s/^!//;
+
+ if (($configs ne "no_config") && ($configs ne "no_makefile")) {
+ &set_flag(\$pr_flags, $pr_flag_pos_config);
+ }
+
+ if (($config_cnt >= 1) &&
+ ($configs !~ /CONFIG_/) &&
+ (($configs ne "no_config") && ($configs ne "no_makefile"))) {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_hard_coded);
+ }
+
+ my $existing_config = $existing_config{$configs};
+ if ($existing_config eq "m") {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_m);
+ # Possible fail, depends on whether built in or
+ # module is desired.
+ &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
+ } elsif ($existing_config eq "y") {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_y);
+ if ($not) {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
+ }
+ } elsif (($config_file) && ($configs =~ /CONFIG_/)) {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_none);
+ if (!$not) {
+ &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
+ }
+ }
+ }
+
+ # ----- include / exclude filters
+
+ if ($include_flag_pattern && ($pr_flags !~ m/$include_flag_pattern/)) {
+ return 0;
+ }
+
+ if ($exclude_flag_pattern && ($pr_flags =~ m/$exclude_flag_pattern/)) {
+ return 0;
+ }
+
+ if ($config_format) {
+ print "# ";
+ }
+ print "$pr_flags : ";
+
+ return 1;
+}
+
+
+sub print_node()
+{
+ # return number of lines printed
+
+ # some fields of pn_arg_ref might not be used in this function, but
+ # extract all of them anyway.
+ my $pn_arg_ref = shift;
+
+ my $compat = $pn_arg_ref->{compat};
+ my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
+ my $config = $pn_arg_ref->{config};
+ my $config_cnt = $pn_arg_ref->{config_cnt};
+ my $driver = $pn_arg_ref->{driver};
+ my $driver_cnt = $pn_arg_ref->{driver_cnt};
+ my $full_node = $pn_arg_ref->{full_node};
+ my $node = $pn_arg_ref->{node};
+ my $node_enabled = $pn_arg_ref->{node_enabled};
+ my $white_list = $pn_arg_ref->{white_list};
+
+ my $separator;
+
+ if (! &print_flags($pn_arg_ref)) {
+ return 0;
+ }
+
+
+ if ($short_name) {
+ print "$node";
+ } else {
+ print "$full_node";
+ }
+ print " : $compat : $driver : $config : ";
+
+ my @configs = split(' && ', $config);
+
+ if ($config_file) {
+ for $configs (@configs) {
+ $configs =~ s/^!//;
+ my $existing_config = $existing_config{$configs};
+ if (!$existing_config) {
+ # check for /-m/, /-y/, or /-objs/
+ if ($configs !~ /CONFIG_/) {
+ $existing_config = "x";
+ };
+ };
+ if ($existing_config) {
+ print "$separator", "$existing_config";
+ $separator = ", ";
+ } else {
+ print "$separator", "n";
+ $separator = ", ";
+ }
+ }
+ } else {
+ print "none";
+ }
+
+ print "\n";
+
+ if ($config_format) {
+ for $configs (@configs) {
+ $not = $configs =~ /^!/;
+ $configs =~ s/^!//;
+ my $existing_config = $existing_config{$configs};
+
+ if ($not) {
+ if ($configs !~ /CONFIG_/) {
+ print "# $configs\n";
+ } elsif ($existing_config eq "m") {
+ print "# $configs is m\n";
+ print "# $configs=n\n";
+ } elsif ($existing_config eq "y") {
+ print "# $configs is set\n";
+ print "# $configs=n\n";
+ } else {
+ print "# $configs is not set\n";
+ print "# $configs=n\n";
+ }
+
+ } else {
+ if ($configs !~ /CONFIG_/) {
+ print "# $configs\n";
+ } elsif ($existing_config eq "m") {
+ print "# $configs is m\n";
+ print "# $configs=y\n";
+ } elsif ($existing_config eq "y") {
+ print "# $configs is set\n";
+ print "# $configs=y\n";
+ } else {
+ print "# $configs is not set\n";
+ print "# $configs=y\n";
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+sub scan_makefile
+{
+ my $pn_arg_ref = shift;
+ my $driver = shift;
+
+ # ----- Find Kconfig symbols that enable driver
+
+ my ($dir, $base) = $driver =~ m{(.*)/(.*).c};
+
+ my $makefile = $dir . "/Makefile";
+ if (! -r $makefile) {
+ $makefile = $dir . "/Kbuild";
+ }
+ if (! -r $makefile) {
+ my $config;
+
+ $config = 'no_makefile';
+ push @{ $driver_config{$driver} }, $config;
+ return;
+ }
+
+ if (!open(MAKEFILE_FILE, "<", "$makefile")) {
+ return;
+ }
+
+ my $line;
+ my @config;
+ my @if_config;
+ my @make_var;
+
+ NEXT_LINE:
+ while ($next_line = <MAKEFILE_FILE>) {
+ my $config;
+ my $if_config;
+ my $ifdef;
+ my $ifeq;
+ my $ifndef;
+ my $ifneq;
+ my $ifdef_config;
+ my $ifeq_config;
+ my $ifndef_config;
+ my $ifneq_config;
+
+ chomp($next_line);
+ $line = $line . $next_line;
+ if ($next_line =~ /\\$/) {
+ $line =~ s/\\$/ /;
+ next NEXT_LINE;
+ }
+ if ($line =~ /^\s*#/) {
+ $line = "";
+ next NEXT_LINE;
+ }
+
+ # ----- condition ... else ... endif
+
+ if ($line =~ /^([ ]\s*|)else\b/) {
+ $if_config = "!" . pop @if_config;
+ $if_config =~ s/^!!//;
+ push @if_config, $if_config;
+ $line =~ s/^([ ]\s*|)else\b//;
+ }
+
+ ($null, $ifeq_config, $ifeq_config_val ) = $line =~ /^([ ]\s*|)ifeq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
+ ($null, $ifneq_config, $ifneq_config_val) = $line =~ /^([ ]\s*|)ifneq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
+ ($null, $ifdef_config) = $line =~ /^([ ]\s*|)ifdef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
+ ($null, $ifndef_config) = $line =~ /^([ ]\s*|)ifndef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
+
+ ($null, $ifeq) = $line =~ /^([ ]\s*|)ifeq\b\s*(.*)/;
+ ($null, $ifneq) = $line =~ /^([ ]\s*|)ifneq\b\s*(.*)/;
+ ($null, $ifdef) = $line =~ /^([ ]\s*|)ifdef\b\s*(.*)/;
+ ($null, $ifndef) = $line =~ /^([ ]\s*|)ifndef\b\s*(.*)/;
+
+ # Order of tests is important. Prefer "CONFIG_*" regex match over
+ # less specific regex match.
+ if ($ifdef_config) {
+ $if_config = $ifdef_config;
+ } elsif ($ifeq_config) {
+ if ($ifeq_config_val =~ /y/) {
+ $if_config = $ifeq_config;
+ } else {
+ $if_config = "!" . $ifeq_config;
+ }
+ } elsif ($ifndef_config) {
+ $if_config = "!" . $ifndef_config;
+ } elsif ($ifneq_config) {
+ if ($ifneq_config_val =~ /y/) {
+ $if_config = "!" . $ifneq_config;
+ } else {
+ $if_config = $ifneq_config;
+ }
+ } elsif ($ifdef) {
+ $if_config = $ifdef;
+ } elsif ($ifeq) {
+ $if_config = $ifeq;
+ } elsif ($ifndef) {
+ $if_config = "!" . $ifndef;
+ } elsif ($ifneq) {
+ $if_config = "!" . $ifneq;
+ } else {
+ $if_config = "";
+ }
+ $if_config =~ s/^!!//;
+
+ if ($if_config) {
+ push @if_config, $if_config;
+ $line = "";
+ next NEXT_LINE;
+ }
+
+ if ($line =~ /^([ ]\s*|)endif\b/) {
+ pop @if_config;
+ $line = "";
+ next NEXT_LINE;
+ }
+
+ # ----- simple CONFIG_* = *.[co] or xxx [+:?]*= *.[co]
+ # Most makefiles select on *.o, but
+ # arch/powerpc/boot/Makefile selects on *.c
+
+ ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$base.[co]\b/;
+
+ # ----- match a make variable instead of *.[co]
+ # Recursively expanded variables are not handled.
+
+ if (!$config) {
+ my $make_var;
+ ($make_var) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$base.[co]\b/;
+ if ($make_var) {
+ if ($make_var =~ /[a-zA-Z0-9]+-[ym]/) {
+ $config = $make_var;
+ } elsif ($make_var =~ /[a-zA-Z0-9]+-objs/) {
+ $config = $make_var;
+ } else {
+ push @make_var, $make_var;
+ }
+ }
+ }
+
+ if (!$config) {
+ for $make_var (@make_var) {
+ ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$make_var\b/;
+ last if ($config);
+ }
+ }
+
+ if (!$config) {
+ for $make_var (@make_var) {
+ ($config) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$make_var\b/;
+ last if ($config);
+ }
+ }
+
+ # ----- next if no config found
+
+ if (!$config) {
+ $line = "";
+ next NEXT_LINE;
+ }
+
+ for $if_config (@if_config) {
+ $config = $if_config . " && " . $config;
+ }
+
+ push @{ $driver_config{$driver} }, $config;
+
+ $line = "";
+ }
+
+ close(MAKEFILE_FILE);
+
+}
+
+
+sub find_kconfig
+{
+ my $pn_arg_ref = shift;
+ my $driver = shift;
+
+ my $lines_printed = 0;
+ my @configs;
+
+ if (!@{ $driver_config{$driver} }) {
+ &scan_makefile($pn_arg_ref, $driver);
+ if (!@{ $driver_config{$driver} }) {
+ push @{ $driver_config{$driver} }, "no_config";
+ }
+ }
+
+ @configs = @{ $driver_config{$driver} };
+
+ $$pn_arg_ref{config_cnt} = $#configs + 1;
+ for my $config (@configs) {
+ $$pn_arg_ref{config} = $config;
+ $lines_printed += &print_node($pn_arg_ref);
+ }
+
+ return $lines_printed;
+}
+
+
+sub handle_compatible()
+{
+ my $full_node = shift;
+ my $node = shift;
+ my $compatible = shift;
+ my $node_enabled = shift;
+
+ my $compat;
+ my $lines_printed = 0;
+ my %pn_arg = ();
+
+ return if (!$node or !$compatible);
+
+ # Do not process compatible property of root node,
+ # it is used to match board, not to bind a driver.
+ return if ($node eq "/");
+
+ $pn_arg{full_node} = $full_node;
+ $pn_arg{node} = $node;
+ $pn_arg{node_enabled} = $node_enabled;
+
+ my @compatibles = split('", "', $compatible);
+
+ $compatibles[0] =~ s/^"//;
+ $compatibles[$#compatibles] =~ s/"$//;
+
+ $pn_arg{compatible_cnt} = $#compatibles + 1;
+
+ COMPAT:
+ for $compat (@compatibles) {
+
+ $pn_arg{compat} = $compat;
+ $pn_arg{driver_cnt} = 0;
+ $pn_arg{white_list} = 0;
+
+ if (exists($compat_white_list{$compat})) {
+ $pn_arg{white_list} = 1;
+ $pn_arg{driver} = "no_driver";
+ $pn_arg{config_cnt} = 1;
+ $pn_arg{config} = "no_config";
+ $lines_printed += &print_node(\%pn_arg);
+ next COMPAT;
+ }
+
+ # ----- if compat previously seen, use cached info
+
+ if (exists($compat_driver{$compat})) {
+ for my $driver (@{ $compat_driver{$compat} }) {
+ $pn_arg{driver} = $driver;
+ $pn_arg{driver_cnt} = $driver_count{$compat};
+ $pn_arg{config_cnt} = $#{ $driver_config{$driver}} + 1;
+
+ for my $config (@{ $driver_config{$driver} }) {
+ $pn_arg{config} = $config;
+ $lines_printed += &print_node(\%pn_arg);
+ }
+
+ if (!@{ $driver_config{$driver} }) {
+ # no config cached yet
+ # $driver in %driver_hard_code_list
+ # but not %driver_config_hard_code_list
+ $lines_printed += &find_kconfig(\%pn_arg, $driver);
+ }
+ }
+ next COMPAT;
+ }
+
+
+ # ----- Find drivers (source files that contain compatible)
+
+ # this will miss arch/sparc/include/asm/parport.h
+ # It is better to move the compatible out of the .h
+ # than to add *.h. to the files list, because *.h generates
+ # a lot of false negatives.
+ my $files = '"*.c"';
+ my $drivers = `git grep -l '"$compat"' -- $files`;
+ chomp($drivers);
+ if ($drivers eq "") {
+ $pn_arg{driver} = "no_driver";
+ $pn_arg{config_cnt} = 1;
+ $pn_arg{config} = "no_config";
+ push @{ $compat_driver{$compat} }, "no_driver";
+ $lines_printed += &print_node(\%pn_arg);
+ next COMPAT;
+ }
+
+ my @drivers = split("\n", $drivers);
+ $driver_count{$compat} = $#drivers + 1;
+ $pn_arg{driver_cnt} = $#drivers + 1;
+
+ DRIVER:
+ for my $driver (@drivers) {
+ push @{ $compat_driver{$compat} }, $driver;
+ $pn_arg{driver} = $driver;
+
+ # ----- if driver previously seen, use cached info
+
+ $pn_arg{config_cnt} = $#{ $driver_config{$driver} } + 1;
+ for my $config (@{ $driver_config{$driver} }) {
+ $pn_arg{config} = $config;
+ $lines_printed += &print_node(\%pn_arg);
+ }
+ if (@{ $driver_config{$driver} }) {
+ next DRIVER;
+ }
+
+ if ($black_list_driver) {
+ for $black (@black_list_driver) {
+ next DRIVER if ($driver =~ /^$black$/);
+ }
+ }
+
+
+ # ----- Find Kconfig symbols that enable driver
+
+ $lines_printed += &find_kconfig(\%pn_arg, $driver);
+
+ }
+ }
+
+ # White space (line) between nodes for readability.
+ # Each node may report several compatibles.
+ # For each compatible, multiple drivers may be reported.
+ # For each driver, multiple CONFIG_ options may be reported.
+ if ($lines_printed) {
+ print "\n";
+ }
+}
+
+sub read_dts()
+{
+ my $file = shift;
+
+ my $compatible = "";
+ my $line;
+ my $node = "";
+ my $node_enabled = "";
+
+ if (! -r $file) {
+ print STDERR "file '$file' is not readable or does not exist\n";
+ exit 3;
+ }
+
+ if (!open(DT_FILE, "-|", "$dtx_diff $file")) {
+ print STDERR "\n";
+ print STDERR "shell command failed:\n";
+ print STDERR " $dtx_diff $file\n";
+ print STDERR "\n";
+ exit 3;
+ }
+
+ FILE:
+ while ($line = <DT_FILE>) {
+ chomp($line);
+
+ if ($line =~ /{/) {
+
+ &handle_compatible($full_node, $node, $compatible,
+ $node_enabled);
+
+ while ($end_node_count-- > 0) {
+ pop @full_node;
+ };
+ $end_node_count = 0;
+ $full_node = @full_node[-1];
+
+ $node = $line;
+ $node =~ s/^\s*(.*)\s+\{.*/$1/;
+ $node =~ s/.*: //;
+ if ($node eq '/' ) {
+ $full_node = '/';
+ } elsif ($full_node ne '/') {
+ $full_node = $full_node . '/' . $node;
+ } else {
+ $full_node = '/' . $node;
+ }
+ push @full_node, $full_node;
+
+ $compatible = "";
+ $node_enabled = "";
+ next FILE;
+ }
+
+ if ($line =~ /}/) {
+ $end_node_count++;
+ }
+
+ if ($line =~ /(\s+|^)status =/) {
+ $node_enabled = $line;
+ $node_enabled =~ s/^\t*//;
+ $node_enabled =~ s/^status = "//;
+ $node_enabled =~ s/";$//;
+ next FILE;
+ }
+
+ if ($line =~ /(\s+|^)compatible =/) {
+ # Extract all compatible entries for this device
+ # White space matching here and in handle_compatible() is
+ # precise, because input format is the output of dtc,
+ # which is invoked by dtx_diff.
+ $compatible = $line;
+ $compatible =~ s/^\t*//;
+ $compatible =~ s/^compatible = //;
+ $compatible =~ s/;$//;
+ }
+ }
+
+ &handle_compatible($full_node, $node, $compatible, $node_enabled);
+
+ close(DT_FILE);
+}
+
+
+sub read_config_file()
+{
+ if (! -r $config_file) {
+ print STDERR "file '$config_file' is not readable or does not exist\n";
+ exit 2;
+ }
+
+ if (!open(CONFIG_FILE, "<", "$config_file")) {
+ print STDERR "open $config_file failed\n";
+ exit 2;
+ }
+
+ my @line;
+
+ LINE:
+ while ($line = <CONFIG_FILE>) {
+ chomp($line);
+ next LINE if ($line =~ /^\s*#/);
+ next LINE if ($line =~ /^\s*$/);
+ @line = split /=/, $line;
+ $existing_config{@line[0]} = @line[1];
+ }
+
+ close(CONFIG_FILE);
+}
+
+
+sub cmd_line_err()
+{
+ my $msg = shift;
+
+ print STDERR "\n";
+ print STDERR " ERROR processing command line options\n";
+ print STDERR " $msg\n" if ($msg ne "");
+ print STDERR "\n";
+ print STDERR " For help, type '$script_name --help'\n";
+ print STDERR "\n";
+}
+
+
+# -----------------------------------------------------------------------------
+# program entry point
+
+Getopt::Long::Configure("no_ignore_case", "bundling");
+
+if (!GetOptions(
+ "c=s" => \$config_file,
+ "config=s" => \$config_file,
+ "config-format" => \$config_format,
+ "exclude-flag=s" => \@exclude_flag,
+ "h" => \$help,
+ "help" => \$help,
+ "black-list-driver" => \$black_list_driver,
+ "white-list-config" => \$white_list_config,
+ "white-list-driver" => \$white_list_driver,
+ "include-flag=s" => \@include_flag,
+ "include-suspect" => \$include_suspect,
+ "short-name" => \$short_name,
+ "show-lists" => \$show_lists,
+ "version" => \$version,
+ )) {
+
+ &cmd_line_err();
+
+ exit 1;
+}
+
+
+my $exit_after_messages = 0;
+
+if ($version) {
+ print STDERR "\n$script_name $VUFX\n\n";
+ $exit_after_messages = 1;
+}
+
+
+if ($help) {
+ &usage;
+ $exit_after_messages = 1;
+}
+
+
+if ($show_lists) {
+
+ print "\n";
+ print "These compatibles are hard coded to have no driver.\n";
+ print "\n";
+ for my $compat (sort keys %compat_white_list) {
+ print " $compat\n";
+ }
+
+
+ print "\n\n";
+ print "The driver for these compatibles is hard coded (white list).\n";
+ print "\n";
+ my $max_compat_len = 0;
+ for my $compat (sort keys %driver_hard_code_list) {
+ if (length $compat > $max_compat_len) {
+ $max_compat_len = length $compat;
+ }
+ }
+ for my $compat (sort keys %driver_hard_code_list) {
+ if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
+ my $first = 1;
+ for my $driver (@{ $driver_hard_code_list{$compat} }) {
+ if ($first) {
+ print " $compat";
+ print " " x ($max_compat_len - length $compat);
+ $first = 0;
+ } else {
+ print " ", " " x $max_compat_len;
+ }
+ print " $driver\n";
+ }
+ }
+ }
+
+
+ print "\n\n";
+ print "The configuration option for these drivers is hard coded (white list).\n";
+ print "\n";
+ my $max_driver_len = 0;
+ for my $driver (sort keys %driver_config_hard_code_list) {
+ if (length $driver > $max_driver_len) {
+ $max_driver_len = length $driver;
+ }
+ }
+ for my $driver (sort keys %driver_config_hard_code_list) {
+ if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
+ my $first = 1;
+ for my $config (@{ $driver_config_hard_code_list{$driver} }) {
+ if ($first) {
+ print " $driver";
+ print " " x ($max_driver_len - length $driver);
+ $first = 0;
+ } else {
+ print " ", " " x $max_driver_len;
+ }
+ print " $config\n";
+ }
+ }
+ }
+
+
+ print "\n\n";
+ print "These drivers are black listed.\n";
+ print "\n";
+ for my $driver (@black_list_driver) {
+ print " $driver\n";
+ }
+
+ print "\n";
+
+ $exit_after_messages = 1;
+}
+
+
+if ($exit_after_messages) {
+ exit 0;
+}
+
+
+$exclude_flag_pattern = "[";
+for my $exclude_flag (@exclude_flag) {
+ $exclude_flag_pattern = $exclude_flag_pattern . $exclude_flag;
+}
+$exclude_flag_pattern = $exclude_flag_pattern . "]";
+# clean up if empty
+$exclude_flag_pattern =~ s/^\[\]$//;
+
+
+$include_flag_pattern = "[";
+for my $include_flag (@include_flag) {
+ $include_flag_pattern = $include_flag_pattern . $include_flag;
+}
+$include_flag_pattern = $include_flag_pattern . "]";
+# clean up if empty
+$include_flag_pattern =~ s/^\[\]$//;
+
+
+if ($exclude_flag_pattern) {
+ my $found = 0;
+ for $pr_flag_value (@pr_flag_value) {
+ if ($exclude_flag_pattern =~ m/$pr_flag_value/) {
+ $found = 1;
+ }
+ }
+ if (!$found) {
+ &cmd_line_err("invalid value for FLAG in --exclude-flag\n");
+ exit 1
+ }
+}
+
+if ($include_flag_pattern) {
+ my $found = 0;
+ for $pr_flag_value (@pr_flag_value) {
+ if ($include_flag_pattern =~ m/$pr_flag_value/) {
+ $found = 1;
+ }
+ }
+ if (!$found) {
+ &cmd_line_err("invalid value for FLAG in --include-flag\n");
+ exit 1
+ }
+}
+
+if ($include_suspect) {
+ $include_flag_pattern =~ s/\[//;
+ $include_flag_pattern =~ s/\]//;
+ $include_flag_pattern = "[" . $include_flag_pattern . "A-Z]";
+}
+
+if ($exclude_flag_pattern =~ m/$include_flag_pattern/) {
+ &cmd_line_err("the same flag appears in both --exclude-flag and --include-flag or --include-suspect\n");
+ exit 1
+}
+
+
+# ($#ARGV < 0) is valid for --help, --version
+if ($#ARGV < 0) {
+ &cmd_line_err("device-tree... is required");
+ exit 1
+}
+
+
+if ($config_file) {
+ &read_config_file();
+}
+
+
+# avoid pushing duplicates for this value
+$driver = "hardcoded_no_driver";
+for $config ( @{ $driver_config_hard_code_list{$driver} } ) {
+ push @{ $driver_config{$driver} }, $config;
+}
+
+if ($white_list_driver) {
+ for my $compat (keys %driver_hard_code_list) {
+ for my $driver (@{ $driver_hard_code_list{$compat} }) {
+ push @{ $compat_driver{$compat} }, $driver;
+ if ($driver ne "hardcoded_no_driver") {
+ $driver_count{$compat} = scalar @{ $compat_driver{$compat} };
+ }
+ }
+ }
+}
+
+if ($white_list_config) {
+ for my $driver (keys %driver_config_hard_code_list) {
+ if ($driver ne "hardcoded_no_driver") {
+ for $config ( @{ $driver_config_hard_code_list{$driver} } ) {
+ push @{ $driver_config{$driver} }, $config;
+ }
+ }
+ }
+}
+
+if (-x "scripts/dtc/dtx_diff") {
+ $dtx_diff = "scripts/dtc/dtx_diff";
+} else {
+
+ print STDERR "\n";
+ print STDERR "$script_name must be run from the root directory of a Linux kernel tree\n";
+ print STDERR "\n";
+ exit 3;
+}
+
+for $file (@ARGV) {
+ &read_dts($file);
+}
diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff
index 959ab2646d38..ec47f95991a3 100755
--- a/scripts/dtc/dtx_diff
+++ b/scripts/dtc/dtx_diff
@@ -266,7 +266,7 @@ DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc"
if [ ! -x ${DTC} ] ; then
__DTC="dtc"
- if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config ; then
+ if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then
make_command='
make scripts'
else
diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh
new file mode 100755
index 000000000000..fb9207565471
--- /dev/null
+++ b/scripts/gcc-plugin.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+srctree=$(dirname "$0")
+gccplugins_dir=$($3 -print-file-name=plugin)
+plugincc=$($1 -E -x c++ - -o /dev/null -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF
+#include "gcc-common.h"
+#if BUILDING_GCC_VERSION >= 4008 || defined(ENABLE_BUILD_WITH_CXX)
+#warning $2 CXX
+#else
+#warning $1 CC
+#endif
+EOF
+)
+
+if [ $? -ne 0 ]
+then
+ exit 1
+fi
+
+case "$plugincc" in
+ *"$1 CC"*)
+ echo "$1"
+ exit 0
+ ;;
+
+ *"$2 CXX"*)
+ # the c++ compiler needs another test, see below
+ ;;
+
+ *)
+ exit 1
+ ;;
+esac
+
+# we need a c++ compiler that supports the designated initializer GNU extension
+plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/gcc-plugins -I"${gccplugins_dir}"/include 2>&1 <<EOF
+#include "gcc-common.h"
+class test {
+public:
+ int test;
+} test = {
+ .test = 1
+};
+EOF
+)
+
+if [ $? -eq 0 ]
+then
+ echo "$2"
+ exit 0
+fi
+exit 1
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
new file mode 100644
index 000000000000..88c8ec47232b
--- /dev/null
+++ b/scripts/gcc-plugins/Makefile
@@ -0,0 +1,27 @@
+GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
+
+ifeq ($(PLUGINCC),$(HOSTCC))
+ HOSTLIBS := hostlibs
+ HOST_EXTRACFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu99 -ggdb
+ export HOST_EXTRACFLAGS
+else
+ HOSTLIBS := hostcxxlibs
+ HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti
+ HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb
+ HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable
+ export HOST_EXTRACXXFLAGS
+endif
+
+export GCCPLUGINS_DIR HOSTLIBS
+
+ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
+ GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
+endif
+
+$(HOSTLIBS)-y := $(GCC_PLUGIN)
+always := $($(HOSTLIBS)-y)
+
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
+sancov_plugin-objs := sancov_plugin.o
+
+clean-files += *.so
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 000000000000..34df974c6ba3
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ * E = the number of edges of the graph
+ * N = the number of nodes of the graph
+ * P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+ .version = "20160225",
+ .help = "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+ int complexity;
+ expanded_location xloc;
+
+ /* M = E - N + 2P */
+ complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+ xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+ fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+ xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+ return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
+{
+ const char * const plugin_name = plugin_info->base_name;
+ struct register_pass_info cyc_complexity_pass_info;
+
+ cyc_complexity_pass_info.pass = make_cyc_complexity_pass();
+ cyc_complexity_pass_info.reference_pass_name = "ssa";
+ cyc_complexity_pass_info.ref_pass_instance_number = 1;
+ cyc_complexity_pass_info.pos_op = PASS_POS_INSERT_AFTER;
+
+ if (!plugin_default_version_check(version, &gcc_version)) {
+ error(G_("incompatible gcc/plugin versions"));
+ return 1;
+ }
+
+ register_callback(plugin_name, PLUGIN_INFO, NULL,
+ &cyc_complexity_plugin_info);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+ &cyc_complexity_pass_info);
+
+ return 0;
+}
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
new file mode 100644
index 000000000000..172850bcd0d9
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -0,0 +1,830 @@
+#ifndef GCC_COMMON_H_INCLUDED
+#define GCC_COMMON_H_INCLUDED
+
+#include "bversion.h"
+#if BUILDING_GCC_VERSION >= 6000
+#include "gcc-plugin.h"
+#else
+#include "plugin.h"
+#endif
+#include "plugin-version.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "line-map.h"
+#include "input.h"
+#include "tree.h"
+
+#include "tree-inline.h"
+#include "version.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "hard-reg-set.h"
+#include "output.h"
+#include "except.h"
+#include "function.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "intl.h"
+#include "ggc.h"
+#include "timevar.h"
+
+#include "params.h"
+
+#if BUILDING_GCC_VERSION <= 4009
+#include "pointer-set.h"
+#else
+#include "hash-map.h"
+#endif
+
+#include "emit-rtl.h"
+#include "debug.h"
+#include "target.h"
+#include "langhooks.h"
+#include "cfgloop.h"
+#include "cgraph.h"
+#include "opts.h"
+
+#if BUILDING_GCC_VERSION == 4005
+#include <sys/mman.h>
+#endif
+
+#if BUILDING_GCC_VERSION >= 4007
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
+#endif
+
+#if BUILDING_GCC_VERSION >= 4006
+#include "c-family/c-common.h"
+#else
+#include "c-common.h"
+#endif
+
+#if BUILDING_GCC_VERSION <= 4008
+#include "tree-flow.h"
+#else
+#include "tree-cfgcleanup.h"
+#include "tree-ssa-operands.h"
+#include "tree-into-ssa.h"
+#endif
+
+#if BUILDING_GCC_VERSION >= 4008
+#include "is-a.h"
+#endif
+
+#include "diagnostic.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "predict.h"
+#include "ipa-utils.h"
+
+#if BUILDING_GCC_VERSION >= 4009
+#include "attribs.h"
+#include "varasm.h"
+#include "stor-layout.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "gimple-fold.h"
+#include "context.h"
+#include "tree-ssa-alias.h"
+#include "tree-ssa.h"
+#include "stringpool.h"
+#include "tree-ssanames.h"
+#include "print-tree.h"
+#include "tree-eh.h"
+#include "stmt.h"
+#include "gimplify.h"
+#endif
+
+#include "gimple.h"
+
+#if BUILDING_GCC_VERSION >= 4009
+#include "tree-ssa-operands.h"
+#include "tree-phinodes.h"
+#include "tree-cfg.h"
+#include "gimple-iterator.h"
+#include "gimple-ssa.h"
+#include "ssa-iterators.h"
+#endif
+
+#if BUILDING_GCC_VERSION >= 5000
+#include "builtins.h"
+#endif
+
+/* #include "expr.h" where are you... */
+extern rtx emit_move_insn(rtx x, rtx y);
+
+/* missing from basic_block.h... */
+extern void debug_dominance_info(enum cdi_direction dir);
+extern void debug_dominance_tree(enum cdi_direction dir, basic_block root);
+
+#if BUILDING_GCC_VERSION == 4006
+extern void debug_gimple_stmt(gimple);
+extern void debug_gimple_seq(gimple_seq);
+extern void print_gimple_seq(FILE *, gimple_seq, int, int);
+extern void print_gimple_stmt(FILE *, gimple, int, int);
+extern void print_gimple_expr(FILE *, gimple, int, int);
+extern void dump_gimple_stmt(pretty_printer *, gimple, int, int);
+#endif
+
+#define __unused __attribute__((__unused__))
+
+#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node))
+#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node))
+#define TYPE_NAME_POINTER(node) IDENTIFIER_POINTER(TYPE_NAME(node))
+#define TYPE_NAME_LENGTH(node) IDENTIFIER_LENGTH(TYPE_NAME(node))
+
+/* should come from c-tree.h if only it were installed for gcc 4.5... */
+#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE)
+
+#if BUILDING_GCC_VERSION == 4005
+#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
+ for (tree vars = (FUN)->local_decls, (I) = 0; \
+ vars && ((D) = TREE_VALUE(vars)); \
+ vars = TREE_CHAIN(vars), (I)++)
+#define DECL_CHAIN(NODE) (TREE_CHAIN(DECL_MINIMAL_CHECK(NODE)))
+#define FOR_EACH_VEC_ELT(T, V, I, P) \
+ for (I = 0; VEC_iterate(T, (V), (I), (P)); ++(I))
+#define TODO_rebuild_cgraph_edges 0
+#define SCOPE_FILE_SCOPE_P(EXP) (!(EXP))
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+typedef struct varpool_node *varpool_node_ptr;
+
+static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function code)
+{
+ tree fndecl;
+
+ if (!is_gimple_call(stmt))
+ return false;
+ fndecl = gimple_call_fndecl(stmt);
+ if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL)
+ return false;
+ return DECL_FUNCTION_CODE(fndecl) == code;
+}
+
+static inline bool is_simple_builtin(tree decl)
+{
+ if (decl && DECL_BUILT_IN_CLASS(decl) != BUILT_IN_NORMAL)
+ return false;
+
+ switch (DECL_FUNCTION_CODE(decl)) {
+ /* Builtins that expand to constants. */
+ case BUILT_IN_CONSTANT_P:
+ case BUILT_IN_EXPECT:
+ case BUILT_IN_OBJECT_SIZE:
+ case BUILT_IN_UNREACHABLE:
+ /* Simple register moves or loads from stack. */
+ case BUILT_IN_RETURN_ADDRESS:
+ case BUILT_IN_EXTRACT_RETURN_ADDR:
+ case BUILT_IN_FROB_RETURN_ADDR:
+ case BUILT_IN_RETURN:
+ case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
+ case BUILT_IN_FRAME_ADDRESS:
+ case BUILT_IN_VA_END:
+ case BUILT_IN_STACK_SAVE:
+ case BUILT_IN_STACK_RESTORE:
+ /* Exception state returns or moves registers around. */
+ case BUILT_IN_EH_FILTER:
+ case BUILT_IN_EH_POINTER:
+ case BUILT_IN_EH_COPY_VALUES:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline void add_local_decl(struct function *fun, tree d)
+{
+ gcc_assert(TREE_CODE(d) == VAR_DECL);
+ fun->local_decls = tree_cons(NULL_TREE, d, fun->local_decls);
+}
+#endif
+
+#if BUILDING_GCC_VERSION <= 4006
+#define ANY_RETURN_P(rtx) (GET_CODE(rtx) == RETURN)
+#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4(EXP)
+#define EDGE_PRESERVE 0ULL
+#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x"
+#define flag_fat_lto_objects true
+
+#define get_random_seed(noinit) ({ \
+ unsigned HOST_WIDE_INT seed; \
+ sscanf(get_random_seed(noinit), "%" HOST_WIDE_INT_PRINT "x", &seed); \
+ seed * seed; })
+
+#define int_const_binop(code, arg1, arg2) \
+ int_const_binop((code), (arg1), (arg2), 0)
+
+static inline bool gimple_clobber_p(gimple s __unused)
+{
+ return false;
+}
+
+static inline bool gimple_asm_clobbers_memory_p(const_gimple stmt)
+{
+ unsigned i;
+
+ for (i = 0; i < gimple_asm_nclobbers(stmt); i++) {
+ tree op = gimple_asm_clobber_op(stmt, i);
+
+ if (!strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "memory"))
+ return true;
+ }
+
+ return false;
+}
+
+static inline tree builtin_decl_implicit(enum built_in_function fncode)
+{
+ return implicit_built_in_decls[fncode];
+}
+
+static inline int ipa_reverse_postorder(struct cgraph_node **order)
+{
+ return cgraph_postorder(order);
+}
+
+static inline struct cgraph_node *cgraph_create_node(tree decl)
+{
+ return cgraph_node(decl);
+}
+
+static inline struct cgraph_node *cgraph_get_create_node(tree decl)
+{
+ struct cgraph_node *node = cgraph_get_node(decl);
+
+ return node ? node : cgraph_node(decl);
+}
+
+static inline bool cgraph_function_with_gimple_body_p(struct cgraph_node *node)
+{
+ return node->analyzed && !node->thunk.thunk_p && !node->alias;
+}
+
+static inline struct cgraph_node *cgraph_first_function_with_gimple_body(void)
+{
+ struct cgraph_node *node;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ if (cgraph_function_with_gimple_body_p(node))
+ return node;
+ return NULL;
+}
+
+static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct cgraph_node *node)
+{
+ for (node = node->next; node; node = node->next)
+ if (cgraph_function_with_gimple_body_p(node))
+ return node;
+ return NULL;
+}
+
+#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
+ for ((node) = cgraph_first_function_with_gimple_body(); (node); \
+ (node) = cgraph_next_function_with_gimple_body(node))
+
+static inline void varpool_add_new_variable(tree decl)
+{
+ varpool_finalize_decl(decl);
+}
+#endif
+
+#if BUILDING_GCC_VERSION <= 4007
+#define FOR_EACH_FUNCTION(node) \
+ for (node = cgraph_nodes; node; node = node->next)
+#define FOR_EACH_VARIABLE(node) \
+ for (node = varpool_nodes; node; node = node->next)
+#define PROP_loops 0
+#define NODE_SYMBOL(node) (node)
+#define NODE_DECL(node) (node)->decl
+#define INSN_LOCATION(INSN) RTL_LOCATION(INSN)
+#define vNULL NULL
+
+static inline int bb_loop_depth(const_basic_block bb)
+{
+ return bb->loop_father ? loop_depth(bb->loop_father) : 0;
+}
+
+static inline bool gimple_store_p(gimple gs)
+{
+ tree lhs = gimple_get_lhs(gs);
+
+ return lhs && !is_gimple_reg(lhs);
+}
+
+static inline void gimple_init_singleton(gimple g __unused)
+{
+}
+#endif
+
+#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008
+static inline struct cgraph_node *cgraph_alias_target(struct cgraph_node *n)
+{
+ return cgraph_alias_aliased_node(n);
+}
+#endif
+
+#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION <= 4009
+#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \
+ cgraph_create_edge((caller), (callee), (call_stmt), (count), (freq))
+#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \
+ cgraph_create_edge_including_clones((caller), (callee), (old_call_stmt), (call_stmt), (count), (freq), (reason))
+#endif
+
+#if BUILDING_GCC_VERSION <= 4008
+#define ENTRY_BLOCK_PTR_FOR_FN(FN) ENTRY_BLOCK_PTR_FOR_FUNCTION(FN)
+#define EXIT_BLOCK_PTR_FOR_FN(FN) EXIT_BLOCK_PTR_FOR_FUNCTION(FN)
+#define basic_block_info_for_fn(FN) ((FN)->cfg->x_basic_block_info)
+#define n_basic_blocks_for_fn(FN) ((FN)->cfg->x_n_basic_blocks)
+#define n_edges_for_fn(FN) ((FN)->cfg->x_n_edges)
+#define last_basic_block_for_fn(FN) ((FN)->cfg->x_last_basic_block)
+#define label_to_block_map_for_fn(FN) ((FN)->cfg->x_label_to_block_map)
+#define profile_status_for_fn(FN) ((FN)->cfg->x_profile_status)
+#define BASIC_BLOCK_FOR_FN(FN, N) BASIC_BLOCK_FOR_FUNCTION((FN), (N))
+#define NODE_IMPLICIT_ALIAS(node) (node)->same_body_alias
+#define VAR_P(NODE) (TREE_CODE(NODE) == VAR_DECL)
+
+static inline bool tree_fits_shwi_p(const_tree t)
+{
+ if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST)
+ return false;
+
+ if (TREE_INT_CST_HIGH(t) == 0 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) >= 0)
+ return true;
+
+ if (TREE_INT_CST_HIGH(t) == -1 && (HOST_WIDE_INT)TREE_INT_CST_LOW(t) < 0 && !TYPE_UNSIGNED(TREE_TYPE(t)))
+ return true;
+
+ return false;
+}
+
+static inline bool tree_fits_uhwi_p(const_tree t)
+{
+ if (t == NULL_TREE || TREE_CODE(t) != INTEGER_CST)
+ return false;
+
+ return TREE_INT_CST_HIGH(t) == 0;
+}
+
+static inline HOST_WIDE_INT tree_to_shwi(const_tree t)
+{
+ gcc_assert(tree_fits_shwi_p(t));
+ return TREE_INT_CST_LOW(t);
+}
+
+static inline unsigned HOST_WIDE_INT tree_to_uhwi(const_tree t)
+{
+ gcc_assert(tree_fits_uhwi_p(t));
+ return TREE_INT_CST_LOW(t);
+}
+
+static inline const char *get_tree_code_name(enum tree_code code)
+{
+ gcc_assert(code < MAX_TREE_CODES);
+ return tree_code_name[code];
+}
+
+#define ipa_remove_stmt_references(cnode, stmt)
+
+typedef union gimple_statement_d gasm;
+typedef union gimple_statement_d gassign;
+typedef union gimple_statement_d gcall;
+typedef union gimple_statement_d gcond;
+typedef union gimple_statement_d gdebug;
+typedef union gimple_statement_d gphi;
+typedef union gimple_statement_d greturn;
+
+static inline gasm *as_a_gasm(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gasm *as_a_const_gasm(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gassign *as_a_gassign(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gassign *as_a_const_gassign(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gcall *as_a_gcall(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gcall *as_a_const_gcall(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gcond *as_a_gcond(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gcond *as_a_const_gcond(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gdebug *as_a_gdebug(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gdebug *as_a_const_gdebug(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gphi *as_a_gphi(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gphi *as_a_const_gphi(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline greturn *as_a_greturn(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const greturn *as_a_const_greturn(const_gimple stmt)
+{
+ return stmt;
+}
+#endif
+
+#if BUILDING_GCC_VERSION == 4008
+#define NODE_SYMBOL(node) (&(node)->symbol)
+#define NODE_DECL(node) (node)->symbol.decl
+#endif
+
+#if BUILDING_GCC_VERSION >= 4008
+#define add_referenced_var(var)
+#define mark_sym_for_renaming(var)
+#define varpool_mark_needed_node(node)
+#define create_var_ann(var)
+#define TODO_dump_func 0
+#define TODO_dump_cgraph 0
+#endif
+
+#if BUILDING_GCC_VERSION <= 4009
+#define TODO_verify_il 0
+#define AVAIL_INTERPOSABLE AVAIL_OVERWRITABLE
+
+#define section_name_prefix LTO_SECTION_NAME_PREFIX
+#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__)
+
+typedef struct rtx_def rtx_insn;
+
+static inline void set_decl_section_name(tree node, const char *value)
+{
+ if (value)
+ DECL_SECTION_NAME(node) = build_string(strlen(value) + 1, value);
+ else
+ DECL_SECTION_NAME(node) = NULL;
+}
+#endif
+
+#if BUILDING_GCC_VERSION == 4009
+typedef struct gimple_statement_asm gasm;
+typedef struct gimple_statement_base gassign;
+typedef struct gimple_statement_call gcall;
+typedef struct gimple_statement_base gcond;
+typedef struct gimple_statement_base gdebug;
+typedef struct gimple_statement_phi gphi;
+typedef struct gimple_statement_base greturn;
+
+static inline gasm *as_a_gasm(gimple stmt)
+{
+ return as_a<gasm>(stmt);
+}
+
+static inline const gasm *as_a_const_gasm(const_gimple stmt)
+{
+ return as_a<const gasm>(stmt);
+}
+
+static inline gassign *as_a_gassign(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gassign *as_a_const_gassign(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gcall *as_a_gcall(gimple stmt)
+{
+ return as_a<gcall>(stmt);
+}
+
+static inline const gcall *as_a_const_gcall(const_gimple stmt)
+{
+ return as_a<const gcall>(stmt);
+}
+
+static inline gcond *as_a_gcond(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gcond *as_a_const_gcond(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gdebug *as_a_gdebug(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const gdebug *as_a_const_gdebug(const_gimple stmt)
+{
+ return stmt;
+}
+
+static inline gphi *as_a_gphi(gimple stmt)
+{
+ return as_a<gphi>(stmt);
+}
+
+static inline const gphi *as_a_const_gphi(const_gimple stmt)
+{
+ return as_a<const gphi>(stmt);
+}
+
+static inline greturn *as_a_greturn(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const greturn *as_a_const_greturn(const_gimple stmt)
+{
+ return stmt;
+}
+#endif
+
+#if BUILDING_GCC_VERSION >= 4009
+#define TODO_ggc_collect 0
+#define NODE_SYMBOL(node) (node)
+#define NODE_DECL(node) (node)->decl
+#define cgraph_node_name(node) (node)->name()
+#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias
+#endif
+
+#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000
+/* gimple related */
+template <>
+template <>
+inline bool is_a_helper<const gassign *>::test(const_gimple gs)
+{
+ return gs->code == GIMPLE_ASSIGN;
+}
+#endif
+
+#if BUILDING_GCC_VERSION >= 5000
+#define TODO_verify_ssa TODO_verify_il
+#define TODO_verify_flow TODO_verify_il
+#define TODO_verify_stmts TODO_verify_il
+#define TODO_verify_rtl_sharing TODO_verify_il
+
+#define INSN_DELETED_P(insn) (insn)->deleted()
+
+/* symtab/cgraph related */
+#define debug_cgraph_node(node) (node)->debug()
+#define cgraph_get_node(decl) cgraph_node::get(decl)
+#define cgraph_get_create_node(decl) cgraph_node::get_create(decl)
+#define cgraph_create_node(decl) cgraph_node::create(decl)
+#define cgraph_n_nodes symtab->cgraph_count
+#define cgraph_max_uid symtab->cgraph_max_uid
+#define varpool_get_node(decl) varpool_node::get(decl)
+
+#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \
+ (caller)->create_edge((callee), (call_stmt), (count), (freq))
+#define cgraph_create_edge_including_clones(caller, callee, old_call_stmt, call_stmt, count, freq, nest, reason) \
+ (caller)->create_edge_including_clones((callee), (old_call_stmt), (call_stmt), (count), (freq), (reason))
+
+typedef struct cgraph_node *cgraph_node_ptr;
+typedef struct cgraph_edge *cgraph_edge_p;
+typedef struct varpool_node *varpool_node_ptr;
+
+static inline void change_decl_assembler_name(tree decl, tree name)
+{
+ symtab->change_decl_assembler_name(decl, name);
+}
+
+static inline void varpool_finalize_decl(tree decl)
+{
+ varpool_node::finalize_decl(decl);
+}
+
+static inline void varpool_add_new_variable(tree decl)
+{
+ varpool_node::add(decl);
+}
+
+static inline unsigned int rebuild_cgraph_edges(void)
+{
+ return cgraph_edge::rebuild_edges();
+}
+
+static inline cgraph_node_ptr cgraph_function_node(cgraph_node_ptr node, enum availability *availability)
+{
+ return node->function_symbol(availability);
+}
+
+static inline cgraph_node_ptr cgraph_function_or_thunk_node(cgraph_node_ptr node, enum availability *availability = NULL)
+{
+ return node->ultimate_alias_target(availability);
+}
+
+static inline bool cgraph_only_called_directly_p(cgraph_node_ptr node)
+{
+ return node->only_called_directly_p();
+}
+
+static inline enum availability cgraph_function_body_availability(cgraph_node_ptr node)
+{
+ return node->get_availability();
+}
+
+static inline cgraph_node_ptr cgraph_alias_target(cgraph_node_ptr node)
+{
+ return node->get_alias_target();
+}
+
+static inline struct cgraph_node_hook_list *cgraph_add_function_insertion_hook(cgraph_node_hook hook, void *data)
+{
+ return symtab->add_cgraph_insertion_hook(hook, data);
+}
+
+static inline void cgraph_remove_function_insertion_hook(struct cgraph_node_hook_list *entry)
+{
+ symtab->remove_cgraph_insertion_hook(entry);
+}
+
+static inline struct cgraph_node_hook_list *cgraph_add_node_removal_hook(cgraph_node_hook hook, void *data)
+{
+ return symtab->add_cgraph_removal_hook(hook, data);
+}
+
+static inline void cgraph_remove_node_removal_hook(struct cgraph_node_hook_list *entry)
+{
+ symtab->remove_cgraph_removal_hook(entry);
+}
+
+static inline struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook(cgraph_2node_hook hook, void *data)
+{
+ return symtab->add_cgraph_duplication_hook(hook, data);
+}
+
+static inline void cgraph_remove_node_duplication_hook(struct cgraph_2node_hook_list *entry)
+{
+ symtab->remove_cgraph_duplication_hook(entry);
+}
+
+static inline void cgraph_call_node_duplication_hooks(cgraph_node_ptr node, cgraph_node_ptr node2)
+{
+ symtab->call_cgraph_duplication_hooks(node, node2);
+}
+
+static inline void cgraph_call_edge_duplication_hooks(cgraph_edge *cs1, cgraph_edge *cs2)
+{
+ symtab->call_edge_duplication_hooks(cs1, cs2);
+}
+
+#if BUILDING_GCC_VERSION >= 6000
+typedef gimple *gimple_ptr;
+typedef const gimple *const_gimple_ptr;
+#define gimple gimple_ptr
+#define const_gimple const_gimple_ptr
+#undef CONST_CAST_GIMPLE
+#define CONST_CAST_GIMPLE(X) CONST_CAST(gimple, (X))
+#endif
+
+/* gimple related */
+static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree lhs, tree op1, tree op2 MEM_STAT_DECL)
+{
+ return gimple_build_assign(lhs, subcode, op1, op2 PASS_MEM_STAT);
+}
+
+template <>
+template <>
+inline bool is_a_helper<const greturn *>::test(const_gimple gs)
+{
+ return gs->code == GIMPLE_RETURN;
+}
+
+static inline gasm *as_a_gasm(gimple stmt)
+{
+ return as_a<gasm *>(stmt);
+}
+
+static inline const gasm *as_a_const_gasm(const_gimple stmt)
+{
+ return as_a<const gasm *>(stmt);
+}
+
+static inline gassign *as_a_gassign(gimple stmt)
+{
+ return as_a<gassign *>(stmt);
+}
+
+static inline const gassign *as_a_const_gassign(const_gimple stmt)
+{
+ return as_a<const gassign *>(stmt);
+}
+
+static inline gcall *as_a_gcall(gimple stmt)
+{
+ return as_a<gcall *>(stmt);
+}
+
+static inline const gcall *as_a_const_gcall(const_gimple stmt)
+{
+ return as_a<const gcall *>(stmt);
+}
+
+static inline gphi *as_a_gphi(gimple stmt)
+{
+ return as_a<gphi *>(stmt);
+}
+
+static inline const gphi *as_a_const_gphi(const_gimple stmt)
+{
+ return as_a<const gphi *>(stmt);
+}
+
+static inline greturn *as_a_greturn(gimple stmt)
+{
+ return as_a<greturn *>(stmt);
+}
+
+static inline const greturn *as_a_const_greturn(const_gimple stmt)
+{
+ return as_a<const greturn *>(stmt);
+}
+
+/* IPA/LTO related */
+#define ipa_ref_list_referring_iterate(L, I, P) \
+ (L)->referring.iterate((I), &(P))
+#define ipa_ref_list_reference_iterate(L, I, P) \
+ (L)->reference.iterate((I), &(P))
+
+static inline cgraph_node_ptr ipa_ref_referring_node(struct ipa_ref *ref)
+{
+ return dyn_cast<cgraph_node_ptr>(ref->referring);
+}
+
+static inline void ipa_remove_stmt_references(symtab_node *referring_node, gimple stmt)
+{
+ referring_node->remove_stmt_references(stmt);
+}
+#endif
+
+#if BUILDING_GCC_VERSION < 6000
+#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
+ get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, pvolatilep, keep_aligning)
+#define gen_rtx_set(ARG0, ARG1) gen_rtx_SET(VOIDmode, (ARG0), (ARG1))
+#endif
+
+#if BUILDING_GCC_VERSION >= 6000
+#define gen_rtx_set(ARG0, ARG1) gen_rtx_SET((ARG0), (ARG1))
+#endif
+
+#ifdef __cplusplus
+static inline void debug_tree(const_tree t)
+{
+ debug_tree(CONST_CAST_TREE(t));
+}
+
+static inline void debug_gimple_stmt(const_gimple s)
+{
+ debug_gimple_stmt(CONST_CAST_GIMPLE(s));
+}
+#else
+#define debug_tree(t) debug_tree(CONST_CAST_TREE(t))
+#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
+#endif
+
+#endif
diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h
new file mode 100644
index 000000000000..526c3c79b68e
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h
@@ -0,0 +1,175 @@
+/*
+ * Generator for GIMPLE pass related boilerplate code/data
+ *
+ * Supports gcc 4.5-6
+ *
+ * Usage:
+ *
+ * 1. before inclusion define PASS_NAME
+ * 2. before inclusion define NO_* for unimplemented callbacks
+ * NO_GATE
+ * NO_EXECUTE
+ * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
+ * the default 0 values
+ * 4. for convenience, all the above will be undefined after inclusion!
+ * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
+ */
+
+#ifndef PASS_NAME
+#error at least PASS_NAME must be defined
+#else
+#define __GCC_PLUGIN_STRINGIFY(n) #n
+#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
+#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
+#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
+
+#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
+#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
+
+#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
+#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
+
+#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
+
+#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
+#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
+
+#ifdef NO_GATE
+#define _GATE NULL
+#define _HAS_GATE false
+#else
+#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
+#define _GATE __GATE(PASS_NAME)
+#define _HAS_GATE true
+#endif
+
+#ifdef NO_EXECUTE
+#define _EXECUTE NULL
+#define _HAS_EXECUTE false
+#else
+#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
+#define _EXECUTE __EXECUTE(PASS_NAME)
+#define _HAS_EXECUTE true
+#endif
+
+#ifndef PROPERTIES_REQUIRED
+#define PROPERTIES_REQUIRED 0
+#endif
+
+#ifndef PROPERTIES_PROVIDED
+#define PROPERTIES_PROVIDED 0
+#endif
+
+#ifndef PROPERTIES_DESTROYED
+#define PROPERTIES_DESTROYED 0
+#endif
+
+#ifndef TODO_FLAGS_START
+#define TODO_FLAGS_START 0
+#endif
+
+#ifndef TODO_FLAGS_FINISH
+#define TODO_FLAGS_FINISH 0
+#endif
+
+#if BUILDING_GCC_VERSION >= 4009
+namespace {
+static const pass_data _PASS_NAME_PASS_DATA = {
+#else
+static struct gimple_opt_pass _PASS_NAME_PASS = {
+ .pass = {
+#endif
+ .type = GIMPLE_PASS,
+ .name = _PASS_NAME_NAME,
+#if BUILDING_GCC_VERSION >= 4008
+ .optinfo_flags = OPTGROUP_NONE,
+#endif
+#if BUILDING_GCC_VERSION >= 5000
+#elif BUILDING_GCC_VERSION == 4009
+ .has_gate = _HAS_GATE,
+ .has_execute = _HAS_EXECUTE,
+#else
+ .gate = _GATE,
+ .execute = _EXECUTE,
+ .sub = NULL,
+ .next = NULL,
+ .static_pass_number = 0,
+#endif
+ .tv_id = TV_NONE,
+ .properties_required = PROPERTIES_REQUIRED,
+ .properties_provided = PROPERTIES_PROVIDED,
+ .properties_destroyed = PROPERTIES_DESTROYED,
+ .todo_flags_start = TODO_FLAGS_START,
+ .todo_flags_finish = TODO_FLAGS_FINISH,
+#if BUILDING_GCC_VERSION < 4009
+ }
+#endif
+};
+
+#if BUILDING_GCC_VERSION >= 4009
+class _PASS_NAME_PASS : public gimple_opt_pass {
+public:
+ _PASS_NAME_PASS() : gimple_opt_pass(_PASS_NAME_PASS_DATA, g) {}
+
+#ifndef NO_GATE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual bool gate(function *) { return _GATE(); }
+#else
+ virtual bool gate(void) { return _GATE(); }
+#endif
+#endif
+
+ virtual opt_pass * clone () { return new _PASS_NAME_PASS(); }
+
+#ifndef NO_EXECUTE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual unsigned int execute(function *) { return _EXECUTE(); }
+#else
+ virtual unsigned int execute(void) { return _EXECUTE(); }
+#endif
+#endif
+};
+}
+
+opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return new _PASS_NAME_PASS();
+}
+#else
+struct opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return &_PASS_NAME_PASS.pass;
+}
+#endif
+
+/* clean up user provided defines */
+#undef PASS_NAME
+#undef NO_GATE
+#undef NO_EXECUTE
+
+#undef PROPERTIES_DESTROYED
+#undef PROPERTIES_PROVIDED
+#undef PROPERTIES_REQUIRED
+#undef TODO_FLAGS_FINISH
+#undef TODO_FLAGS_START
+
+/* clean up generated defines */
+#undef _EXECUTE
+#undef __EXECUTE
+#undef _GATE
+#undef __GATE
+#undef _GCC_PLUGIN_CONCAT2
+#undef _GCC_PLUGIN_CONCAT3
+#undef _GCC_PLUGIN_STRINGIFY
+#undef __GCC_PLUGIN_STRINGIFY
+#undef _HAS_EXECUTE
+#undef _HAS_GATE
+#undef _MAKE_PASS_NAME_PASS
+#undef __MAKE_PASS_NAME_PASS
+#undef _PASS_NAME_NAME
+#undef _PASS_NAME_PASS
+#undef __PASS_NAME_PASS
+#undef _PASS_NAME_PASS_DATA
+#undef __PASS_NAME_PASS_DATA
+
+#endif /* PASS_NAME */
diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
new file mode 100644
index 000000000000..9bd926e072f0
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
@@ -0,0 +1,289 @@
+/*
+ * Generator for IPA pass related boilerplate code/data
+ *
+ * Supports gcc 4.5-6
+ *
+ * Usage:
+ *
+ * 1. before inclusion define PASS_NAME
+ * 2. before inclusion define NO_* for unimplemented callbacks
+ * NO_GENERATE_SUMMARY
+ * NO_READ_SUMMARY
+ * NO_WRITE_SUMMARY
+ * NO_READ_OPTIMIZATION_SUMMARY
+ * NO_WRITE_OPTIMIZATION_SUMMARY
+ * NO_STMT_FIXUP
+ * NO_FUNCTION_TRANSFORM
+ * NO_VARIABLE_TRANSFORM
+ * NO_GATE
+ * NO_EXECUTE
+ * 3. before inclusion define PROPERTIES_* and *TODO_FLAGS_* to override
+ * the default 0 values
+ * 4. for convenience, all the above will be undefined after inclusion!
+ * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
+ */
+
+#ifndef PASS_NAME
+#error at least PASS_NAME must be defined
+#else
+#define __GCC_PLUGIN_STRINGIFY(n) #n
+#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
+#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
+#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
+
+#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
+#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
+
+#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
+#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
+
+#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
+
+#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
+#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
+
+#ifdef NO_GENERATE_SUMMARY
+#define _GENERATE_SUMMARY NULL
+#else
+#define __GENERATE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _generate_summary)
+#define _GENERATE_SUMMARY __GENERATE_SUMMARY(PASS_NAME)
+#endif
+
+#ifdef NO_READ_SUMMARY
+#define _READ_SUMMARY NULL
+#else
+#define __READ_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_summary)
+#define _READ_SUMMARY __READ_SUMMARY(PASS_NAME)
+#endif
+
+#ifdef NO_WRITE_SUMMARY
+#define _WRITE_SUMMARY NULL
+#else
+#define __WRITE_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_summary)
+#define _WRITE_SUMMARY __WRITE_SUMMARY(PASS_NAME)
+#endif
+
+#ifdef NO_READ_OPTIMIZATION_SUMMARY
+#define _READ_OPTIMIZATION_SUMMARY NULL
+#else
+#define __READ_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _read_optimization_summary)
+#define _READ_OPTIMIZATION_SUMMARY __READ_OPTIMIZATION_SUMMARY(PASS_NAME)
+#endif
+
+#ifdef NO_WRITE_OPTIMIZATION_SUMMARY
+#define _WRITE_OPTIMIZATION_SUMMARY NULL
+#else
+#define __WRITE_OPTIMIZATION_SUMMARY(n) _GCC_PLUGIN_CONCAT2(n, _write_optimization_summary)
+#define _WRITE_OPTIMIZATION_SUMMARY __WRITE_OPTIMIZATION_SUMMARY(PASS_NAME)
+#endif
+
+#ifdef NO_STMT_FIXUP
+#define _STMT_FIXUP NULL
+#else
+#define __STMT_FIXUP(n) _GCC_PLUGIN_CONCAT2(n, _stmt_fixup)
+#define _STMT_FIXUP __STMT_FIXUP(PASS_NAME)
+#endif
+
+#ifdef NO_FUNCTION_TRANSFORM
+#define _FUNCTION_TRANSFORM NULL
+#else
+#define __FUNCTION_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _function_transform)
+#define _FUNCTION_TRANSFORM __FUNCTION_TRANSFORM(PASS_NAME)
+#endif
+
+#ifdef NO_VARIABLE_TRANSFORM
+#define _VARIABLE_TRANSFORM NULL
+#else
+#define __VARIABLE_TRANSFORM(n) _GCC_PLUGIN_CONCAT2(n, _variable_transform)
+#define _VARIABLE_TRANSFORM __VARIABLE_TRANSFORM(PASS_NAME)
+#endif
+
+#ifdef NO_GATE
+#define _GATE NULL
+#define _HAS_GATE false
+#else
+#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
+#define _GATE __GATE(PASS_NAME)
+#define _HAS_GATE true
+#endif
+
+#ifdef NO_EXECUTE
+#define _EXECUTE NULL
+#define _HAS_EXECUTE false
+#else
+#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
+#define _EXECUTE __EXECUTE(PASS_NAME)
+#define _HAS_EXECUTE true
+#endif
+
+#ifndef PROPERTIES_REQUIRED
+#define PROPERTIES_REQUIRED 0
+#endif
+
+#ifndef PROPERTIES_PROVIDED
+#define PROPERTIES_PROVIDED 0
+#endif
+
+#ifndef PROPERTIES_DESTROYED
+#define PROPERTIES_DESTROYED 0
+#endif
+
+#ifndef TODO_FLAGS_START
+#define TODO_FLAGS_START 0
+#endif
+
+#ifndef TODO_FLAGS_FINISH
+#define TODO_FLAGS_FINISH 0
+#endif
+
+#ifndef FUNCTION_TRANSFORM_TODO_FLAGS_START
+#define FUNCTION_TRANSFORM_TODO_FLAGS_START 0
+#endif
+
+#if BUILDING_GCC_VERSION >= 4009
+namespace {
+static const pass_data _PASS_NAME_PASS_DATA = {
+#else
+static struct ipa_opt_pass_d _PASS_NAME_PASS = {
+ .pass = {
+#endif
+ .type = IPA_PASS,
+ .name = _PASS_NAME_NAME,
+#if BUILDING_GCC_VERSION >= 4008
+ .optinfo_flags = OPTGROUP_NONE,
+#endif
+#if BUILDING_GCC_VERSION >= 5000
+#elif BUILDING_GCC_VERSION == 4009
+ .has_gate = _HAS_GATE,
+ .has_execute = _HAS_EXECUTE,
+#else
+ .gate = _GATE,
+ .execute = _EXECUTE,
+ .sub = NULL,
+ .next = NULL,
+ .static_pass_number = 0,
+#endif
+ .tv_id = TV_NONE,
+ .properties_required = PROPERTIES_REQUIRED,
+ .properties_provided = PROPERTIES_PROVIDED,
+ .properties_destroyed = PROPERTIES_DESTROYED,
+ .todo_flags_start = TODO_FLAGS_START,
+ .todo_flags_finish = TODO_FLAGS_FINISH,
+#if BUILDING_GCC_VERSION < 4009
+ },
+ .generate_summary = _GENERATE_SUMMARY,
+ .write_summary = _WRITE_SUMMARY,
+ .read_summary = _READ_SUMMARY,
+#if BUILDING_GCC_VERSION >= 4006
+ .write_optimization_summary = _WRITE_OPTIMIZATION_SUMMARY,
+ .read_optimization_summary = _READ_OPTIMIZATION_SUMMARY,
+#endif
+ .stmt_fixup = _STMT_FIXUP,
+ .function_transform_todo_flags_start = FUNCTION_TRANSFORM_TODO_FLAGS_START,
+ .function_transform = _FUNCTION_TRANSFORM,
+ .variable_transform = _VARIABLE_TRANSFORM,
+#endif
+};
+
+#if BUILDING_GCC_VERSION >= 4009
+class _PASS_NAME_PASS : public ipa_opt_pass_d {
+public:
+ _PASS_NAME_PASS() : ipa_opt_pass_d(_PASS_NAME_PASS_DATA,
+ g,
+ _GENERATE_SUMMARY,
+ _WRITE_SUMMARY,
+ _READ_SUMMARY,
+ _WRITE_OPTIMIZATION_SUMMARY,
+ _READ_OPTIMIZATION_SUMMARY,
+ _STMT_FIXUP,
+ FUNCTION_TRANSFORM_TODO_FLAGS_START,
+ _FUNCTION_TRANSFORM,
+ _VARIABLE_TRANSFORM) {}
+
+#ifndef NO_GATE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual bool gate(function *) { return _GATE(); }
+#else
+ virtual bool gate(void) { return _GATE(); }
+#endif
+#endif
+
+ virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
+
+#ifndef NO_EXECUTE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual unsigned int execute(function *) { return _EXECUTE(); }
+#else
+ virtual unsigned int execute(void) { return _EXECUTE(); }
+#endif
+#endif
+};
+}
+
+opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return new _PASS_NAME_PASS();
+}
+#else
+struct opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return &_PASS_NAME_PASS.pass;
+}
+#endif
+
+/* clean up user provided defines */
+#undef PASS_NAME
+#undef NO_GENERATE_SUMMARY
+#undef NO_WRITE_SUMMARY
+#undef NO_READ_SUMMARY
+#undef NO_WRITE_OPTIMIZATION_SUMMARY
+#undef NO_READ_OPTIMIZATION_SUMMARY
+#undef NO_STMT_FIXUP
+#undef NO_FUNCTION_TRANSFORM
+#undef NO_VARIABLE_TRANSFORM
+#undef NO_GATE
+#undef NO_EXECUTE
+
+#undef FUNCTION_TRANSFORM_TODO_FLAGS_START
+#undef PROPERTIES_DESTROYED
+#undef PROPERTIES_PROVIDED
+#undef PROPERTIES_REQUIRED
+#undef TODO_FLAGS_FINISH
+#undef TODO_FLAGS_START
+
+/* clean up generated defines */
+#undef _EXECUTE
+#undef __EXECUTE
+#undef _FUNCTION_TRANSFORM
+#undef __FUNCTION_TRANSFORM
+#undef _GATE
+#undef __GATE
+#undef _GCC_PLUGIN_CONCAT2
+#undef _GCC_PLUGIN_CONCAT3
+#undef _GCC_PLUGIN_STRINGIFY
+#undef __GCC_PLUGIN_STRINGIFY
+#undef _GENERATE_SUMMARY
+#undef __GENERATE_SUMMARY
+#undef _HAS_EXECUTE
+#undef _HAS_GATE
+#undef _MAKE_PASS_NAME_PASS
+#undef __MAKE_PASS_NAME_PASS
+#undef _PASS_NAME_NAME
+#undef _PASS_NAME_PASS
+#undef __PASS_NAME_PASS
+#undef _PASS_NAME_PASS_DATA
+#undef __PASS_NAME_PASS_DATA
+#undef _READ_OPTIMIZATION_SUMMARY
+#undef __READ_OPTIMIZATION_SUMMARY
+#undef _READ_SUMMARY
+#undef __READ_SUMMARY
+#undef _STMT_FIXUP
+#undef __STMT_FIXUP
+#undef _VARIABLE_TRANSFORM
+#undef __VARIABLE_TRANSFORM
+#undef _WRITE_OPTIMIZATION_SUMMARY
+#undef __WRITE_OPTIMIZATION_SUMMARY
+#undef _WRITE_SUMMARY
+#undef __WRITE_SUMMARY
+
+#endif /* PASS_NAME */
diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h
new file mode 100644
index 000000000000..1dc67a5aeadf
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h
@@ -0,0 +1,175 @@
+/*
+ * Generator for RTL pass related boilerplate code/data
+ *
+ * Supports gcc 4.5-6
+ *
+ * Usage:
+ *
+ * 1. before inclusion define PASS_NAME
+ * 2. before inclusion define NO_* for unimplemented callbacks
+ * NO_GATE
+ * NO_EXECUTE
+ * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
+ * the default 0 values
+ * 4. for convenience, all the above will be undefined after inclusion!
+ * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
+ */
+
+#ifndef PASS_NAME
+#error at least PASS_NAME must be defined
+#else
+#define __GCC_PLUGIN_STRINGIFY(n) #n
+#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
+#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
+#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
+
+#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
+#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
+
+#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
+#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
+
+#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
+
+#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
+#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
+
+#ifdef NO_GATE
+#define _GATE NULL
+#define _HAS_GATE false
+#else
+#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
+#define _GATE __GATE(PASS_NAME)
+#define _HAS_GATE true
+#endif
+
+#ifdef NO_EXECUTE
+#define _EXECUTE NULL
+#define _HAS_EXECUTE false
+#else
+#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
+#define _EXECUTE __EXECUTE(PASS_NAME)
+#define _HAS_EXECUTE true
+#endif
+
+#ifndef PROPERTIES_REQUIRED
+#define PROPERTIES_REQUIRED 0
+#endif
+
+#ifndef PROPERTIES_PROVIDED
+#define PROPERTIES_PROVIDED 0
+#endif
+
+#ifndef PROPERTIES_DESTROYED
+#define PROPERTIES_DESTROYED 0
+#endif
+
+#ifndef TODO_FLAGS_START
+#define TODO_FLAGS_START 0
+#endif
+
+#ifndef TODO_FLAGS_FINISH
+#define TODO_FLAGS_FINISH 0
+#endif
+
+#if BUILDING_GCC_VERSION >= 4009
+namespace {
+static const pass_data _PASS_NAME_PASS_DATA = {
+#else
+static struct rtl_opt_pass _PASS_NAME_PASS = {
+ .pass = {
+#endif
+ .type = RTL_PASS,
+ .name = _PASS_NAME_NAME,
+#if BUILDING_GCC_VERSION >= 4008
+ .optinfo_flags = OPTGROUP_NONE,
+#endif
+#if BUILDING_GCC_VERSION >= 5000
+#elif BUILDING_GCC_VERSION == 4009
+ .has_gate = _HAS_GATE,
+ .has_execute = _HAS_EXECUTE,
+#else
+ .gate = _GATE,
+ .execute = _EXECUTE,
+ .sub = NULL,
+ .next = NULL,
+ .static_pass_number = 0,
+#endif
+ .tv_id = TV_NONE,
+ .properties_required = PROPERTIES_REQUIRED,
+ .properties_provided = PROPERTIES_PROVIDED,
+ .properties_destroyed = PROPERTIES_DESTROYED,
+ .todo_flags_start = TODO_FLAGS_START,
+ .todo_flags_finish = TODO_FLAGS_FINISH,
+#if BUILDING_GCC_VERSION < 4009
+ }
+#endif
+};
+
+#if BUILDING_GCC_VERSION >= 4009
+class _PASS_NAME_PASS : public rtl_opt_pass {
+public:
+ _PASS_NAME_PASS() : rtl_opt_pass(_PASS_NAME_PASS_DATA, g) {}
+
+#ifndef NO_GATE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual bool gate(function *) { return _GATE(); }
+#else
+ virtual bool gate(void) { return _GATE(); }
+#endif
+#endif
+
+ virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
+
+#ifndef NO_EXECUTE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual unsigned int execute(function *) { return _EXECUTE(); }
+#else
+ virtual unsigned int execute(void) { return _EXECUTE(); }
+#endif
+#endif
+};
+}
+
+opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return new _PASS_NAME_PASS();
+}
+#else
+struct opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return &_PASS_NAME_PASS.pass;
+}
+#endif
+
+/* clean up user provided defines */
+#undef PASS_NAME
+#undef NO_GATE
+#undef NO_EXECUTE
+
+#undef PROPERTIES_DESTROYED
+#undef PROPERTIES_PROVIDED
+#undef PROPERTIES_REQUIRED
+#undef TODO_FLAGS_FINISH
+#undef TODO_FLAGS_START
+
+/* clean up generated defines */
+#undef _EXECUTE
+#undef __EXECUTE
+#undef _GATE
+#undef __GATE
+#undef _GCC_PLUGIN_CONCAT2
+#undef _GCC_PLUGIN_CONCAT3
+#undef _GCC_PLUGIN_STRINGIFY
+#undef __GCC_PLUGIN_STRINGIFY
+#undef _HAS_EXECUTE
+#undef _HAS_GATE
+#undef _MAKE_PASS_NAME_PASS
+#undef __MAKE_PASS_NAME_PASS
+#undef _PASS_NAME_NAME
+#undef _PASS_NAME_PASS
+#undef __PASS_NAME_PASS
+#undef _PASS_NAME_PASS_DATA
+#undef __PASS_NAME_PASS_DATA
+
+#endif /* PASS_NAME */
diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
new file mode 100644
index 000000000000..a27e2b36afaa
--- /dev/null
+++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
@@ -0,0 +1,175 @@
+/*
+ * Generator for SIMPLE_IPA pass related boilerplate code/data
+ *
+ * Supports gcc 4.5-6
+ *
+ * Usage:
+ *
+ * 1. before inclusion define PASS_NAME
+ * 2. before inclusion define NO_* for unimplemented callbacks
+ * NO_GATE
+ * NO_EXECUTE
+ * 3. before inclusion define PROPERTIES_* and TODO_FLAGS_* to override
+ * the default 0 values
+ * 4. for convenience, all the above will be undefined after inclusion!
+ * 5. the only exported name is make_PASS_NAME_pass() to register with gcc
+ */
+
+#ifndef PASS_NAME
+#error at least PASS_NAME must be defined
+#else
+#define __GCC_PLUGIN_STRINGIFY(n) #n
+#define _GCC_PLUGIN_STRINGIFY(n) __GCC_PLUGIN_STRINGIFY(n)
+#define _GCC_PLUGIN_CONCAT2(x, y) x ## y
+#define _GCC_PLUGIN_CONCAT3(x, y, z) x ## y ## z
+
+#define __PASS_NAME_PASS_DATA(n) _GCC_PLUGIN_CONCAT2(n, _pass_data)
+#define _PASS_NAME_PASS_DATA __PASS_NAME_PASS_DATA(PASS_NAME)
+
+#define __PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT2(n, _pass)
+#define _PASS_NAME_PASS __PASS_NAME_PASS(PASS_NAME)
+
+#define _PASS_NAME_NAME _GCC_PLUGIN_STRINGIFY(PASS_NAME)
+
+#define __MAKE_PASS_NAME_PASS(n) _GCC_PLUGIN_CONCAT3(make_, n, _pass)
+#define _MAKE_PASS_NAME_PASS __MAKE_PASS_NAME_PASS(PASS_NAME)
+
+#ifdef NO_GATE
+#define _GATE NULL
+#define _HAS_GATE false
+#else
+#define __GATE(n) _GCC_PLUGIN_CONCAT2(n, _gate)
+#define _GATE __GATE(PASS_NAME)
+#define _HAS_GATE true
+#endif
+
+#ifdef NO_EXECUTE
+#define _EXECUTE NULL
+#define _HAS_EXECUTE false
+#else
+#define __EXECUTE(n) _GCC_PLUGIN_CONCAT2(n, _execute)
+#define _EXECUTE __EXECUTE(PASS_NAME)
+#define _HAS_EXECUTE true
+#endif
+
+#ifndef PROPERTIES_REQUIRED
+#define PROPERTIES_REQUIRED 0
+#endif
+
+#ifndef PROPERTIES_PROVIDED
+#define PROPERTIES_PROVIDED 0
+#endif
+
+#ifndef PROPERTIES_DESTROYED
+#define PROPERTIES_DESTROYED 0
+#endif
+
+#ifndef TODO_FLAGS_START
+#define TODO_FLAGS_START 0
+#endif
+
+#ifndef TODO_FLAGS_FINISH
+#define TODO_FLAGS_FINISH 0
+#endif
+
+#if BUILDING_GCC_VERSION >= 4009
+namespace {
+static const pass_data _PASS_NAME_PASS_DATA = {
+#else
+static struct simple_ipa_opt_pass _PASS_NAME_PASS = {
+ .pass = {
+#endif
+ .type = SIMPLE_IPA_PASS,
+ .name = _PASS_NAME_NAME,
+#if BUILDING_GCC_VERSION >= 4008
+ .optinfo_flags = OPTGROUP_NONE,
+#endif
+#if BUILDING_GCC_VERSION >= 5000
+#elif BUILDING_GCC_VERSION == 4009
+ .has_gate = _HAS_GATE,
+ .has_execute = _HAS_EXECUTE,
+#else
+ .gate = _GATE,
+ .execute = _EXECUTE,
+ .sub = NULL,
+ .next = NULL,
+ .static_pass_number = 0,
+#endif
+ .tv_id = TV_NONE,
+ .properties_required = PROPERTIES_REQUIRED,
+ .properties_provided = PROPERTIES_PROVIDED,
+ .properties_destroyed = PROPERTIES_DESTROYED,
+ .todo_flags_start = TODO_FLAGS_START,
+ .todo_flags_finish = TODO_FLAGS_FINISH,
+#if BUILDING_GCC_VERSION < 4009
+ }
+#endif
+};
+
+#if BUILDING_GCC_VERSION >= 4009
+class _PASS_NAME_PASS : public simple_ipa_opt_pass {
+public:
+ _PASS_NAME_PASS() : simple_ipa_opt_pass(_PASS_NAME_PASS_DATA, g) {}
+
+#ifndef NO_GATE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual bool gate(function *) { return _GATE(); }
+#else
+ virtual bool gate(void) { return _GATE(); }
+#endif
+#endif
+
+ virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
+
+#ifndef NO_EXECUTE
+#if BUILDING_GCC_VERSION >= 5000
+ virtual unsigned int execute(function *) { return _EXECUTE(); }
+#else
+ virtual unsigned int execute(void) { return _EXECUTE(); }
+#endif
+#endif
+};
+}
+
+opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return new _PASS_NAME_PASS();
+}
+#else
+struct opt_pass *_MAKE_PASS_NAME_PASS(void)
+{
+ return &_PASS_NAME_PASS.pass;
+}
+#endif
+
+/* clean up user provided defines */
+#undef PASS_NAME
+#undef NO_GATE
+#undef NO_EXECUTE
+
+#undef PROPERTIES_DESTROYED
+#undef PROPERTIES_PROVIDED
+#undef PROPERTIES_REQUIRED
+#undef TODO_FLAGS_FINISH
+#undef TODO_FLAGS_START
+
+/* clean up generated defines */
+#undef _EXECUTE
+#undef __EXECUTE
+#undef _GATE
+#undef __GATE
+#undef _GCC_PLUGIN_CONCAT2
+#undef _GCC_PLUGIN_CONCAT3
+#undef _GCC_PLUGIN_STRINGIFY
+#undef __GCC_PLUGIN_STRINGIFY
+#undef _HAS_EXECUTE
+#undef _HAS_GATE
+#undef _MAKE_PASS_NAME_PASS
+#undef __MAKE_PASS_NAME_PASS
+#undef _PASS_NAME_NAME
+#undef _PASS_NAME_PASS
+#undef __PASS_NAME_PASS
+#undef _PASS_NAME_PASS_DATA
+#undef __PASS_NAME_PASS_DATA
+
+#endif /* PASS_NAME */
diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c
new file mode 100644
index 000000000000..aedd6113cb73
--- /dev/null
+++ b/scripts/gcc-plugins/sancov_plugin.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/sancov
+ *
+ * This plugin inserts a __sanitizer_cov_trace_pc() call at the start of basic blocks.
+ * It supports all gcc versions with plugin support (from gcc-4.5 on).
+ * It is based on the commit "Add fuzzing coverage support" by Dmitry Vyukov <dvyukov@google.com>.
+ *
+ * You can read about it more here:
+ * https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296
+ * http://lwn.net/Articles/674854/
+ * https://github.com/google/syzkaller
+ * https://lwn.net/Articles/677764/
+ *
+ * Usage:
+ * make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+tree sancov_fndecl;
+
+static struct plugin_info sancov_plugin_info = {
+ .version = "20160402",
+ .help = "sancov plugin\n",
+};
+
+static unsigned int sancov_execute(void)
+{
+ basic_block bb;
+
+ /* Remove this line when this plugin and kcov will be in the kernel.
+ if (!strcmp(DECL_NAME_POINTER(current_function_decl), DECL_NAME_POINTER(sancov_fndecl)))
+ return 0;
+ */
+
+ FOR_EACH_BB_FN(bb, cfun) {
+ const_gimple stmt;
+ gcall *gcall;
+ gimple_stmt_iterator gsi = gsi_after_labels(bb);
+
+ if (gsi_end_p(gsi))
+ continue;
+
+ stmt = gsi_stmt(gsi);
+ gcall = as_a_gcall(gimple_build_call(sancov_fndecl, 0));
+ gimple_set_location(gcall, gimple_location(stmt));
+ gsi_insert_before(&gsi, gcall, GSI_SAME_STMT);
+ }
+ return 0;
+}
+
+#define PASS_NAME sancov
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func | TODO_verify_stmts | TODO_update_ssa_no_phi | TODO_verify_flow
+
+#include "gcc-generate-gimple-pass.h"
+
+static void sancov_start_unit(void __unused *gcc_data, void __unused *user_data)
+{
+ tree leaf_attr, nothrow_attr;
+ tree BT_FN_VOID = build_function_type_list(void_type_node, NULL_TREE);
+
+ sancov_fndecl = build_fn_decl("__sanitizer_cov_trace_pc", BT_FN_VOID);
+
+ DECL_ASSEMBLER_NAME(sancov_fndecl);
+ TREE_PUBLIC(sancov_fndecl) = 1;
+ DECL_EXTERNAL(sancov_fndecl) = 1;
+ DECL_ARTIFICIAL(sancov_fndecl) = 1;
+ DECL_PRESERVE_P(sancov_fndecl) = 1;
+ DECL_UNINLINABLE(sancov_fndecl) = 1;
+ TREE_USED(sancov_fndecl) = 1;
+
+ nothrow_attr = tree_cons(get_identifier("nothrow"), NULL, NULL);
+ decl_attributes(&sancov_fndecl, nothrow_attr, 0);
+ gcc_assert(TREE_NOTHROW(sancov_fndecl));
+#if BUILDING_GCC_VERSION > 4005
+ leaf_attr = tree_cons(get_identifier("leaf"), NULL, NULL);
+ decl_attributes(&sancov_fndecl, leaf_attr, 0);
+#endif
+}
+
+int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
+{
+ int i;
+ struct register_pass_info sancov_plugin_pass_info;
+ const char * const plugin_name = plugin_info->base_name;
+ const int argc = plugin_info->argc;
+ const struct plugin_argument * const argv = plugin_info->argv;
+ bool enable = true;
+
+ static const struct ggc_root_tab gt_ggc_r_gt_sancov[] = {
+ {
+ .base = &sancov_fndecl,
+ .nelt = 1,
+ .stride = sizeof(sancov_fndecl),
+ .cb = &gt_ggc_mx_tree_node,
+ .pchw = &gt_pch_nx_tree_node
+ },
+ LAST_GGC_ROOT_TAB
+ };
+
+ /* BBs can be split afterwards?? */
+ sancov_plugin_pass_info.pass = make_sancov_pass();
+#if BUILDING_GCC_VERSION >= 4009
+ sancov_plugin_pass_info.reference_pass_name = "asan";
+#else
+ sancov_plugin_pass_info.reference_pass_name = "nrv";
+#endif
+ sancov_plugin_pass_info.ref_pass_instance_number = 0;
+ sancov_plugin_pass_info.pos_op = PASS_POS_INSERT_BEFORE;
+
+ if (!plugin_default_version_check(version, &gcc_version)) {
+ error(G_("incompatible gcc/plugin versions"));
+ return 1;
+ }
+
+ for (i = 0; i < argc; ++i) {
+ if (!strcmp(argv[i].key, "no-sancov")) {
+ enable = false;
+ continue;
+ }
+ error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
+ }
+
+ register_callback(plugin_name, PLUGIN_INFO, NULL, &sancov_plugin_info);
+
+ if (!enable)
+ return 0;
+
+#if BUILDING_GCC_VERSION < 6000
+ register_callback(plugin_name, PLUGIN_START_UNIT, &sancov_start_unit, NULL);
+ register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)&gt_ggc_r_gt_sancov);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &sancov_plugin_pass_info);
+#endif
+
+ return 0;
+}
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 1873421f2305..122fcdaf42c8 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -133,6 +133,7 @@ my %VCS_cmds_git = (
"author_pattern" => "^GitAuthor: (.*)",
"subject_pattern" => "^GitSubject: (.*)",
"stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$",
+ "file_exists_cmd" => "git ls-files \$file",
);
my %VCS_cmds_hg = (
@@ -161,6 +162,7 @@ my %VCS_cmds_hg = (
"author_pattern" => "^HgAuthor: (.*)",
"subject_pattern" => "^HgSubject: (.*)",
"stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$",
+ "file_exists_cmd" => "hg files \$file",
);
my $conf = which_conf(".get_maintainer.conf");
@@ -430,7 +432,7 @@ foreach my $file (@ARGV) {
die "$P: file '${file}' not found\n";
}
}
- if ($from_filename) {
+ if ($from_filename || vcs_file_exists($file)) {
$file =~ s/^\Q${cur_path}\E//; #strip any absolute path
$file =~ s/^\Q${lk_path}\E//; #or the path to the lk tree
push(@files, $file);
@@ -2124,6 +2126,22 @@ sub vcs_file_blame {
}
}
+sub vcs_file_exists {
+ my ($file) = @_;
+
+ my $exists;
+
+ my $vcs_used = vcs_exists();
+ return 0 if (!$vcs_used);
+
+ my $cmd = $VCS_cmds{"file_exists_cmd"};
+ $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd
+
+ $exists = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+ return $exists;
+}
+
sub uniq {
my (@parms) = @_;
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index f0f6d9d75435..4f727eb5ec43 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -180,7 +180,7 @@ else
fi;
# final build of init/
-${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
+${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init GCC_PLUGINS_CFLAGS="${GCC_PLUGINS_CFLAGS}"
kallsymso=""
kallsyms_vmlinux=""
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 86e56fef7473..e1c09e2f9be7 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -26,6 +26,8 @@ create_package() {
# Fix ownership and permissions
chown -R root:root "$pdir"
chmod -R go-w "$pdir"
+ # in case we are in a restrictive umask environment like 0077
+ chmod -R a+rX "$pdir"
# Create the package
dpkg-gencontrol $forcearch -Vkernel:debarch="${debarch}" -p$pname -P"$pdir"
@@ -238,7 +240,8 @@ maintainer="$name <$email>"
# Try to determine distribution
if [ -n "$KDEB_CHANGELOG_DIST" ]; then
distribution=$KDEB_CHANGELOG_DIST
-elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ]; then
+# In some cases lsb_release returns the codename as n/a, which breaks dpkg-parsechangelog
+elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ] && [ "$distribution" != "n/a" ]; then
: # nothing to do in this case
else
distribution="unstable"
@@ -322,13 +325,14 @@ fi
# Build kernel header package
(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
-if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
- (cd $srctree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrsrcfiles"
-fi
(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
+if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
+ (cd $objtree; find tools/objtool -type f -executable) >> "$objtree/debian/hdrobjfiles"
+fi
(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles"
+(cd $objtree; find scripts/gcc-plugins -name \*.so -o -name gcc-common.h) >> "$objtree/debian/hdrobjfiles"
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 63d91e22ed7c..966dd3924ea9 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -143,7 +143,7 @@ fi
if test -e include/config/auto.conf; then
. include/config/auto.conf
else
- echo "Error: kernelrelease not valid - run 'make prepare' to update it"
+ echo "Error: kernelrelease not valid - run 'make prepare' to update it" >&2
exit 1
fi
diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index d912d5a56a5e..53af6dc3e6c1 100755
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -1,6 +1,6 @@
/* Sign a module file using the given key.
*
- * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
+ * Copyright © 2014-2016 Red Hat, Inc. All Rights Reserved.
* Copyright © 2015 Intel Corporation.
* Copyright © 2016 Hewlett Packard Enterprise Development LP
*
@@ -167,19 +167,37 @@ static EVP_PKEY *read_private_key(const char *private_key_name)
static X509 *read_x509(const char *x509_name)
{
+ unsigned char buf[2];
X509 *x509;
BIO *b;
+ int n;
b = BIO_new_file(x509_name, "rb");
ERR(!b, "%s", x509_name);
- x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
- if (!x509) {
- ERR(BIO_reset(b) != 1, "%s", x509_name);
- x509 = PEM_read_bio_X509(b, NULL, NULL,
- NULL); /* PEM encoded X.509 */
- if (x509)
- drain_openssl_errors();
+
+ /* Look at the first two bytes of the file to determine the encoding */
+ n = BIO_read(b, buf, 2);
+ if (n != 2) {
+ if (BIO_should_retry(b)) {
+ fprintf(stderr, "%s: Read wanted retry\n", x509_name);
+ exit(1);
+ }
+ if (n >= 0) {
+ fprintf(stderr, "%s: Short read\n", x509_name);
+ exit(1);
+ }
+ ERR(1, "%s", x509_name);
}
+
+ ERR(BIO_reset(b) != 0, "%s", x509_name);
+
+ if (buf[0] == 0x30 && buf[1] >= 0x81 && buf[1] <= 0x84)
+ /* Assume raw DER encoded X.509 */
+ x509 = d2i_X509_bio(b, NULL);
+ else
+ /* Assume PEM encoded X.509 */
+ x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
+
BIO_free(b);
ERR(!x509, "%s", x509_name);