summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Kbuild.include26
-rwxr-xr-xscripts/Lindent1
-rw-r--r--scripts/Makefile11
-rw-r--r--scripts/Makefile.asm-generic7
-rw-r--r--scripts/Makefile.build38
-rw-r--r--scripts/Makefile.clean1
-rw-r--r--scripts/Makefile.dtbinst11
-rw-r--r--scripts/Makefile.extrawarn2
-rw-r--r--scripts/Makefile.fwinst70
-rw-r--r--scripts/Makefile.gcc-plugins6
-rw-r--r--scripts/Makefile.headersinst38
-rw-r--r--scripts/Makefile.host7
-rw-r--r--scripts/Makefile.kasan1
-rw-r--r--scripts/Makefile.lib23
-rw-r--r--scripts/Makefile.modbuiltin1
-rw-r--r--scripts/Makefile.modinst1
-rw-r--r--scripts/Makefile.modpost2
-rw-r--r--scripts/Makefile.modsign1
-rw-r--r--scripts/Makefile.ubsan1
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/fixdep.c6
-rwxr-xr-xscripts/bootgraph.pl2
-rw-r--r--scripts/check-lc_ctype.c11
-rwxr-xr-xscripts/check_00index.sh1
-rwxr-xr-xscripts/check_extable.sh1
-rwxr-xr-xscripts/checkincludes.pl3
-rwxr-xr-xscripts/checkpatch.pl199
-rwxr-xr-xscripts/checkstack.pl3
-rwxr-xr-xscripts/checksyscalls.sh12
-rwxr-xr-xscripts/checkversion.pl3
-rwxr-xr-xscripts/cleanfile4
-rwxr-xr-xscripts/cleanpatch4
-rwxr-xr-xscripts/coccicheck1
-rw-r--r--scripts/coccinelle/api/d_find_alias.cocci1
-rw-r--r--scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci1
-rw-r--r--scripts/coccinelle/api/drm-get-put.cocci1
-rw-r--r--scripts/coccinelle/api/simple_open.cocci1
-rw-r--r--scripts/coccinelle/api/vma_pages.cocci1
-rw-r--r--scripts/coccinelle/misc/boolreturn.cocci1
-rw-r--r--scripts/coccinelle/misc/irqf_oneshot.cocci1
-rw-r--r--scripts/coccinelle/misc/of_table.cocci1
-rwxr-xr-xscripts/config1
-rwxr-xr-xscripts/decode_stacktrace.sh1
-rwxr-xr-xscripts/decodecode1
-rwxr-xr-xscripts/depmod.sh1
-rwxr-xr-xscripts/diffconfig1
-rw-r--r--scripts/docproc.c681
-rwxr-xr-xscripts/documentation-file-ref-check15
-rw-r--r--scripts/dtc/Makefile1
-rw-r--r--scripts/dtc/checks.c291
-rwxr-xr-xscripts/dtc/dt_to_config2
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped10
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped430
-rw-r--r--scripts/dtc/dtc-parser.y20
-rw-r--r--scripts/dtc/dtc.c2
-rw-r--r--scripts/dtc/dtc.h3
-rwxr-xr-xscripts/dtc/dtx_diff26
-rw-r--r--scripts/dtc/fdtdump.c1
-rw-r--r--scripts/dtc/libfdt/fdt_addresses.c96
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c1
-rw-r--r--scripts/dtc/libfdt/fdt_overlay.c861
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c4
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c24
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c16
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c4
-rw-r--r--scripts/dtc/libfdt/libfdt.h47
-rw-r--r--scripts/dtc/livetree.c31
-rwxr-xr-xscripts/dtc/update-dtc-source.sh5
-rw-r--r--scripts/dtc/version_gen.h2
-rwxr-xr-xscripts/export_report.pl3
-rwxr-xr-xscripts/extract-module-sig.pl4
-rwxr-xr-xscripts/extract-sys-certs.pl4
-rwxr-xr-xscripts/extract_xc3028.pl2
-rwxr-xr-xscripts/faddr2line6
-rwxr-xr-xscripts/find-unused-docs.sh62
-rwxr-xr-xscripts/gcc-goto.sh1
-rwxr-xr-xscripts/gcc-ld1
-rwxr-xr-xscripts/gcc-plugin.sh1
-rw-r--r--scripts/gcc-plugins/.gitignore1
-rw-r--r--scripts/gcc-plugins/Makefile9
-rw-r--r--scripts/gcc-plugins/gcc-common.h13
-rw-r--r--scripts/gcc-plugins/gcc-generate-gimple-pass.h1
-rw-r--r--scripts/gcc-plugins/gcc-generate-ipa-pass.h1
-rw-r--r--scripts/gcc-plugins/gcc-generate-rtl-pass.h1
-rw-r--r--scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h1
-rw-r--r--scripts/gcc-plugins/gen-random-seed.sh9
-rw-r--r--scripts/gcc-plugins/randomize_layout_plugin.c1025
-rw-r--r--scripts/gcc-plugins/structleak_plugin.c13
-rwxr-xr-xscripts/gcc-version.sh1
-rwxr-xr-xscripts/gcc-x86_32-has-stack-protector.sh1
-rwxr-xr-xscripts/gcc-x86_64-has-stack-protector.sh1
-rw-r--r--scripts/gdb/linux/Makefile3
-rw-r--r--scripts/gdb/linux/constants.py.in7
-rw-r--r--scripts/gdb/linux/dmesg.py15
-rw-r--r--scripts/gdb/linux/proc.py73
-rwxr-xr-xscripts/gen_initramfs_list.sh4
-rw-r--r--scripts/genksyms/Makefile5
-rw-r--r--scripts/genksyms/genksyms.h2
-rw-r--r--scripts/genksyms/keywords.c74
-rw-r--r--scripts/genksyms/keywords.gperf61
-rw-r--r--scripts/genksyms/keywords.hash.c_shipped230
-rw-r--r--scripts/genksyms/lex.l10
-rw-r--r--scripts/genksyms/lex.lex.c_shipped10
-rwxr-xr-xscripts/get_dvb_firmware2
-rwxr-xr-xscripts/get_maintainer.pl94
-rwxr-xr-xscripts/headerdep.pl3
-rwxr-xr-xscripts/headers.sh1
-rwxr-xr-xscripts/headers_check.pl4
-rwxr-xr-xscripts/headers_install.sh3
-rw-r--r--scripts/kallsyms.c2
-rw-r--r--scripts/kconfig/.gitignore1
-rw-r--r--scripts/kconfig/Makefile7
-rwxr-xr-xscripts/kconfig/check.sh1
-rw-r--r--scripts/kconfig/kconf_id.c54
-rw-r--r--scripts/kconfig/list.h1
-rw-r--r--scripts/kconfig/lkc.h2
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rwxr-xr-xscripts/kconfig/lxdialog/check-lxdialog.sh1
-rw-r--r--scripts/kconfig/nconf.c12
-rw-r--r--scripts/kconfig/nconf.gui.c4
-rwxr-xr-xscripts/kconfig/streamline_config.pl3
-rw-r--r--scripts/kconfig/zconf.gperf50
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped297
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped10
-rw-r--r--scripts/kconfig/zconf.y10
-rwxr-xr-xscripts/kernel-doc26
-rwxr-xr-xscripts/kernel-doc-xml-ref198
-rwxr-xr-xscripts/ld-version.sh1
-rwxr-xr-xscripts/leaking_addresses.pl305
-rwxr-xr-xscripts/link-vmlinux.sh48
-rwxr-xr-xscripts/makelst1
-rwxr-xr-xscripts/markup_oops.pl2
-rwxr-xr-xscripts/mkcompile_h3
-rwxr-xr-xscripts/mkmakefile1
-rwxr-xr-xscripts/mkuboot.sh1
-rw-r--r--scripts/mkversion6
-rw-r--r--scripts/mod/Makefile1
-rw-r--r--scripts/mod/devicetable-offsets.c1
-rw-r--r--scripts/mod/mk_elfconfig.c1
-rw-r--r--scripts/mod/modpost.c59
-rw-r--r--scripts/mod/modpost.h1
-rwxr-xr-xscripts/namespace.pl4
-rw-r--r--scripts/package/Makefile5
-rwxr-xr-xscripts/package/builddeb22
-rwxr-xr-xscripts/package/buildtar37
-rwxr-xr-xscripts/package/mkspec14
-rw-r--r--scripts/parse-maintainers.pl129
-rwxr-xr-xscripts/patch-kernel1
-rwxr-xr-xscripts/profile2linkerlist.pl3
-rwxr-xr-xscripts/prune-kernel1
-rwxr-xr-xscripts/recordmcount.pl3
-rw-r--r--scripts/selinux/README2
-rw-r--r--scripts/selinux/genheaders/Makefile1
-rw-r--r--scripts/selinux/genheaders/genheaders.c8
-rwxr-xr-xscripts/selinux/install_policy.sh1
-rw-r--r--scripts/selinux/mdp/Makefile1
-rwxr-xr-xscripts/setlocalversion1
-rw-r--r--scripts/spelling.txt64
-rwxr-xr-xscripts/sphinx-pre-install608
-rwxr-xr-xscripts/stackdelta3
-rwxr-xr-xscripts/stackusage1
-rwxr-xr-xscripts/tags.sh1
-rwxr-xr-xscripts/tracing/ftrace-bisect.sh1
-rwxr-xr-xscripts/ver_linux1
-rw-r--r--scripts/xen-hypercalls.sh1
166 files changed, 4674 insertions, 2199 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index e063daa3ec4a..0442c06eefcb 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -7,7 +7,6 @@ pnmtologo
unifdef
ihex2fw
recordmcount
-docproc
check-lc_ctype
sortextable
asn1_compiler
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 61f87a99bf0a..9ffd3dda3889 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -85,8 +85,8 @@ TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
# try-run
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
-# Exit code chooses option. "$$TMP" is can be used as temporary file and
-# is automatically cleaned up.
+# Exit code chooses option. "$$TMP" serves as a temporary file and is
+# automatically cleaned up.
try-run = $(shell set -e; \
TMP="$(TMPOUT).$$$$.tmp"; \
TMPO="$(TMPOUT).$$$$.o"; \
@@ -108,6 +108,11 @@ as-option = $(call try-run,\
as-instr = $(call try-run,\
printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
+# __cc-option
+# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586)
+__cc-option = $(call try-run,\
+ $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4))
+
# Do not attempt to build with gcc plugins during cc-option tests.
# (And this uses delayed resolution so the flags will be up to date.)
CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
@@ -115,19 +120,19 @@ CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
-cc-option = $(call try-run,\
- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+cc-option = $(call __cc-option, $(CC),\
+ $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2))
+
+# hostcc-option
+# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
+hostcc-option = $(call __cc-option, $(HOSTCC),\
+ $(HOSTCFLAGS) $(HOST_EXTRACFLAGS),$(1),$(2))
# cc-option-yn
# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
cc-option-yn = $(call try-run,\
$(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
-# cc-option-align
-# Prefix align with either -falign or -malign
-cc-option-align = $(subst -functions=0,,\
- $(call cc-option,-falign-functions=0,-malign-functions=0))
-
# cc-disable-warning
# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
cc-disable-warning = $(call try-run,\
@@ -256,7 +261,6 @@ make-cmd = $(call escsq,$(subst \#,\\\#,$(subst $$,$$$$,$(cmd_$(1)))))
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
# Execute command if command has changed or prerequisite(s) are updated.
-#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
@@ -310,7 +314,7 @@ if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
$(rule_$(1)), @:)
###
-# why - tell why a a target got build
+# why - tell why a target got built
# enabled by make V=2
# Output (listed in the order they are checked):
# (1) - due to target is PHONY
diff --git a/scripts/Lindent b/scripts/Lindent
index 57b564c24d61..1688c44c2df6 100755
--- a/scripts/Lindent
+++ b/scripts/Lindent
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
PARAM="-npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1"
diff --git a/scripts/Makefile b/scripts/Makefile
index 1d80897a9644..25ab143cbe14 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
###
# scripts contains sources for various helper programs used throughout
# the kernel for the build process.
@@ -6,8 +7,6 @@
# pnmttologo: Convert pnm files to logo files
# conmakehash: Create chartable
# conmakehash: Create arrays for initializing the kernel console tables
-# docproc: Used in Documentation/DocBook
-# check-lc_ctype: Used in Documentation/DocBook
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
@@ -29,16 +28,12 @@ HOSTLOADLIBES_extract-cert = -lcrypto
always := $(hostprogs-y) $(hostprogs-m)
# The following hostprogs-y programs are only build on demand
-hostprogs-y += unifdef docproc check-lc_ctype
+hostprogs-y += unifdef
# These targets are used internally to avoid "is up to date" messages
-PHONY += build_unifdef build_docproc build_check-lc_ctype
+PHONY += build_unifdef
build_unifdef: $(obj)/unifdef
@:
-build_docproc: $(obj)/docproc
- @:
-build_check-lc_ctype: $(obj)/check-lc_ctype
- @:
subdir-$(CONFIG_MODVERSIONS) += genksyms
subdir-y += mod
diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic
index e4d017d53819..524eeedc8d25 100644
--- a/scripts/Makefile.asm-generic
+++ b/scripts/Makefile.asm-generic
@@ -1,9 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
# include/asm-generic contains a lot of files that are used
# verbatim by several architectures.
#
-# This Makefile reads the file arch/$(SRCARCH)/include/asm/Kbuild
+# This Makefile reads the file arch/$(SRCARCH)/include/$(src)/Kbuild
# and for each file listed in this file with generic-y creates
-# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/asm)
+# a small wrapper file in $(obj) (arch/$(SRCARCH)/include/generated/$(src))
kbuild-file := $(srctree)/arch/$(SRCARCH)/include/$(src)/Kbuild
-include $(kbuild-file)
@@ -15,7 +16,7 @@ _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
# Stale wrappers when the corresponding files are removed from generic-y
# need removing.
-generated-y := $(generic-y) $(genhdr-y) $(generated-y)
+generated-y := $(generic-y) $(generated-y)
all-files := $(patsubst %, $(obj)/%, $(generated-y))
old-headers := $(wildcard $(obj)/*.h)
unwanted := $(filter-out $(all-files),$(old-headers))
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 733e044fff8b..e63af4e19382 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Building
# ==========================================================================
@@ -229,8 +230,8 @@ ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
endif
# Due to recursion, we must skip empty.o.
# The empty.o file is created in the make process in order to determine
-# the target endianness and word size. It is made before all other C
-# files, including recordmcount.
+# the target endianness and word size. It is made before all other C
+# files, including recordmcount.
sub_cmd_record_mcount = \
if [ $(@) != "scripts/mod/empty.o" ]; then \
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
@@ -245,23 +246,29 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH
"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
"$(if $(part-of-module),1,0)" "$(@)";
recordmcount_source := $(srctree)/scripts/recordmcount.pl
-endif
+endif # BUILD_C_RECORDMCOUNT
cmd_record_mcount = \
if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \
"$(CC_FLAGS_FTRACE)" ]; then \
$(sub_cmd_record_mcount) \
fi;
-endif
+endif # CONFIG_FTRACE_MCOUNT_RECORD
ifdef CONFIG_STACK_VALIDATION
ifneq ($(SKIP_STACK_VALIDATION),1)
__objtool_obj := $(objtree)/tools/objtool/objtool
-objtool_args = check
+objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check)
+
ifndef CONFIG_FRAME_POINTER
objtool_args += --no-fp
endif
+ifdef CONFIG_GCOV_KERNEL
+objtool_args += --no-unreachable
+else
+objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
+endif
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
@@ -276,6 +283,11 @@ objtool_obj = $(if $(patsubst y%,, \
endif # SKIP_STACK_VALIDATION
endif # CONFIG_STACK_VALIDATION
+# Rebuild all objects when objtool changes, or is enabled/disabled.
+objtool_dep = $(objtool_obj) \
+ $(wildcard include/config/orc/unwinder.h \
+ include/config/stack/validation.h)
+
define rule_cc_o_c
$(call echo-cmd,checksrc) $(cmd_checksrc) \
$(call cmd_and_fixdep,cc_o_c) \
@@ -298,13 +310,13 @@ cmd_undef_syms = echo
endif
# Built-in and composite module parts
-$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE
+$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
# Single-part modules are special since we need to mark them in $(MODVERDIR)
-$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE
+$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
@{ echo $(@:.o=.ko); echo $@; \
@@ -399,7 +411,7 @@ cmd_modversions_S = \
endif
endif
-$(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE
+$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
$(call if_changed_rule,as_o_S)
targets += $(real-objs-y) $(real-objs-m) $(lib-y)
@@ -408,7 +420,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(always)
# Linker scripts preprocessor (.lds.S -> .lds)
# ---------------------------------------------------------------------------
quiet_cmd_cpp_lds_S = LDS $@
- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
+ cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
$(obj)/%.lds: $(src)/%.lds.S FORCE
@@ -437,8 +449,8 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
ifdef builtin-target
ifdef CONFIG_THIN_ARCHIVES
- cmd_make_builtin = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS)
- cmd_make_empty_builtin = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS)
+ cmd_make_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS)
+ cmd_make_empty_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS)
quiet_cmd_link_o_target = AR $@
else
cmd_make_builtin = $(LD) $(ld_flags) -r -o
@@ -478,7 +490,7 @@ ifdef lib-target
quiet_cmd_link_l_target = AR $@
ifdef CONFIG_THIN_ARCHIVES
- cmd_link_l_target = rm -f $@; $(AR) rcsT$(KBUILD_ARFLAGS) $@ $(lib-y)
+ cmd_link_l_target = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(lib-y)
else
cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y)
endif
@@ -531,7 +543,7 @@ cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secana
ifdef CONFIG_THIN_ARCHIVES
quiet_cmd_link_multi-y = AR $@
- cmd_link_multi-y = rm -f $@; $(AR) rcST$(KBUILD_ARFLAGS) $@ $(link_multi_deps)
+ cmd_link_multi-y = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(link_multi_deps)
else
quiet_cmd_link_multi-y = LD $@
cmd_link_multi-y = $(cmd_link_multi-link)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 50616ea25131..808d09f27ad4 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Cleaning up
# ==========================================================================
diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst
index 34614a48b717..7301ab5e2e06 100644
--- a/scripts/Makefile.dtbinst
+++ b/scripts/Makefile.dtbinst
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Installing dtb files
#
@@ -5,8 +6,6 @@
# INSTALL_DTBS_PATH directory or the default location:
#
# $INSTALL_PATH/dtbs/$KERNELRELEASE
-#
-# Traverse through subdirectories listed in $(dts-dirs).
# ==========================================================================
src := $(obj)
@@ -14,20 +13,20 @@ src := $(obj)
PHONY := __dtbs_install
__dtbs_install:
-export dtbinst-root ?= $(obj)
+export dtbinst_root ?= $(obj)
include include/config/auto.conf
include scripts/Kbuild.include
include $(src)/Makefile
-dtbinst-files := $(dtb-y)
-dtbinst-dirs := $(dts-dirs)
+dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-)))
+dtbinst-dirs := $(subdir-y) $(subdir-m)
# Helper targets for Installing DTBs into the boot directory
quiet_cmd_dtb_install = INSTALL $<
cmd_dtb_install = mkdir -p $(2); cp $< $(2)
-install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj))
+install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj))
$(dtbinst-files): %.dtb: $(obj)/%.dtb
$(call cmd,dtb_install,$(install-dir))
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index fb3522fd8702..c6ebf4239e64 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
#
# make W=... settings
@@ -37,6 +38,7 @@ warning-2 += $(call cc-option, -Wlogical-op)
warning-2 += $(call cc-option, -Wmissing-field-initializers)
warning-2 += $(call cc-option, -Wsign-compare)
warning-2 += $(call cc-option, -Wmaybe-uninitialized)
+warning-2 += $(call cc-option, -Wunused-macros)
warning-3 := -Wbad-function-cast
warning-3 += -Wcast-qual
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst
deleted file mode 100644
index b27290035253..000000000000
--- a/scripts/Makefile.fwinst
+++ /dev/null
@@ -1,70 +0,0 @@
-# ==========================================================================
-# Installing firmware
-#
-# We don't include the .config, so all firmware files are in $(fw-shipped-)
-# rather than in $(fw-shipped-y) or $(fw-shipped-m).
-# ==========================================================================
-
-INSTALL := install
-src := $(obj)
-
-# For modules_install installing firmware, we want to see .config
-# But for firmware_install, we don't care, but don't want to require it.
--include $(objtree)/.config
-
-include scripts/Kbuild.include
-include $(src)/Makefile
-
-include scripts/Makefile.host
-
-mod-fw := $(fw-shipped-m)
-# If CONFIG_FIRMWARE_IN_KERNEL isn't set, then install the
-# firmware for in-kernel drivers too.
-ifndef CONFIG_FIRMWARE_IN_KERNEL
-mod-fw += $(fw-shipped-y)
-endif
-
-ifneq ($(KBUILD_SRC),)
-# Create output directory if not already present
-_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
-
-firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all))))
-# Create directories for firmware in subdirectories
-_dummy := $(foreach d,$(firmware-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
-endif
-
-installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw))
-
-installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all))
-
-quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
- cmd_install = mkdir -p $(@D); $(INSTALL) -m0644 $< $@
-
-$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/%
- $(call cmd,install)
-
-PHONY += __fw_install __fw_modinst FORCE
-
-.PHONY: $(PHONY)
-
-__fw_install: $(installed-fw)
-
-__fw_modinst: $(installed-mod-fw)
- @:
-
-__fw_modbuild: $(addprefix $(obj)/,$(mod-fw))
- @:
-
-FORCE:
-
-# Read all saved command lines and dependencies for the $(targets) we
-# may be building using $(if_changed{,_dep}). As an optimization, we
-# don't need to read them if the target does not exist; we will rebuild
-# anyway in that case.
-
-targets := $(wildcard $(sort $(targets)))
-cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
-
-ifneq ($(cmd_files),)
- include $(cmd_files)
-endif
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 82335533620e..b2a95af7df18 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
ifdef CONFIG_GCC_PLUGINS
__PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
@@ -27,8 +28,13 @@ ifdef CONFIG_GCC_PLUGINS
gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose
+ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN
+ gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
+ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN
+ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode
+
GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index ce753a408c56..99967948d764 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Installing headers
#
@@ -14,16 +15,21 @@ __headers:
include scripts/Kbuild.include
srcdir := $(srctree)/$(obj)
-subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
-# caller may set destination dir (when installing to asm/)
-_dst := $(if $(dst),$(dst),$(obj))
+
+# When make is run under a fakechroot environment, the function
+# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular
+# files. So, we are using a combination of sort/dir/wildcard which works
+# with fakechroot.
+subdirs := $(patsubst $(srcdir)/%/,%,\
+ $(filter-out $(srcdir)/,\
+ $(sort $(dir $(wildcard $(srcdir)/*/)))))
# Recursion
__headers: $(subdirs)
.PHONY: $(subdirs)
$(subdirs):
- $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
+ $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(dst)/$@
# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi.
# We have only sub-directories there.
@@ -31,21 +37,12 @@ skip-inst := $(if $(filter %/uapi,$(obj)),1)
ifeq ($(skip-inst),)
-# generated header directory
-gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
-
# Kbuild file is optional
kbuild-file := $(srctree)/$(obj)/Kbuild
-include $(kbuild-file)
-old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
-ifneq ($(wildcard $(old-kbuild-file)),)
-include $(old-kbuild-file)
-endif
-
-installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
-
-gendir := $(objtree)/$(gen)
+installdir := $(INSTALL_HDR_PATH)/$(dst)
+gendir := $(objtree)/$(subst include/,include/generated/,$(obj))
header-files := $(notdir $(wildcard $(srcdir)/*.h))
header-files += $(notdir $(wildcard $(srcdir)/*.agh))
header-files := $(filter-out $(no-export-headers), $(header-files))
@@ -56,14 +53,8 @@ genhdr-files := $(filter-out $(header-files), $(genhdr-files))
install-file := $(installdir)/.install
check-file := $(installdir)/.check
-# generic-y list all files an architecture uses from asm-generic
-# Use this to build a list of headers which require a wrapper
-generic-files := $(notdir $(wildcard $(srctree)/include/uapi/asm-generic/*.h))
-wrapper-files := $(filter $(generic-files), $(generic-y))
-wrapper-files := $(filter-out $(header-files), $(wrapper-files))
-
# all headers files for this dir
-all-files := $(header-files) $(genhdr-files) $(wrapper-files)
+all-files := $(header-files) $(genhdr-files)
output-files := $(addprefix $(installdir)/, $(all-files))
ifneq ($(mandatory-y),)
@@ -87,9 +78,6 @@ quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
cmd_install = \
$(CONFIG_SHELL) $< $(installdir) $(srcdir) $(header-files); \
$(CONFIG_SHELL) $< $(installdir) $(gendir) $(genhdr-files); \
- for F in $(wrapper-files); do \
- echo "\#include <asm-generic/$$F>" > $(installdir)/$$F; \
- done; \
touch $@
quiet_cmd_remove = REMOVE $(unwanted)
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 45b5b1aaedbd..10e5c3cb89dc 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Building binaries on the host system
# Binaries are used during the compilation of the kernel, for example
@@ -20,12 +21,6 @@
# 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))
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 9576775a86f6..1ce7115aa499 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
ifdef CONFIG_KASAN
ifdef CONFIG_KASAN_INLINE
call_threshold := 10000
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 58c05e5d9870..2278405cbc80 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Backward compatibility
asflags-y += $(EXTRA_AFLAGS)
ccflags-y += $(EXTRA_CFLAGS)
@@ -69,6 +70,11 @@ obj-dirs := $(dir $(multi-objs) $(obj-y))
real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m)))
+# DTB
+# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
+extra-y += $(dtb-y)
+extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
+
# Add subdir path
extra-y := $(addprefix $(obj)/,$(extra-y))
@@ -173,10 +179,10 @@ cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
ld_flags = $(LDFLAGS) $(ldflags-y)
+DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes
+
dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
- -I$(srctree)/arch/$(SRCARCH)/boot/dts \
- -I$(srctree)/scripts/dtc/include-prefixes \
- -I$(srctree)/drivers/of/testcase-data \
+ $(addprefix -I,$(DTC_INCLUDE)) \
-undef -D__DTS__
# Finds the multi-part object the current object will be linked into
@@ -194,15 +200,6 @@ endef
ifdef REGENERATE_PARSERS
-# GPERF
-# ---------------------------------------------------------------------------
-quiet_cmd_gperf = GPERF $@
- cmd_gperf = gperf -t --output-file $@ -a -C -E -g -k 1,3,$$ -p -t $<
-
-.PRECIOUS: $(src)/%.hash.c_shipped
-$(src)/%.hash.c_shipped: $(src)/%.gperf
- $(call cmd,gperf)
-
# LEX
# ---------------------------------------------------------------------------
LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy)
@@ -317,7 +314,7 @@ quiet_cmd_dtc = DTC $@
cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
$(DTC) -O dtb -o $@ -b 0 \
- -i $(dir $<) $(DTC_FLAGS) \
+ $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin
index 1adb974e6950..a763b4775d06 100644
--- a/scripts/Makefile.modbuiltin
+++ b/scripts/Makefile.modbuiltin
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Generating modules.builtin
# ==========================================================================
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 07650eeaaf06..51ca0244fc8a 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Installing modules
# ==========================================================================
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 16923ba4b5b1..991db7d6e4df 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ===========================================================================
# Module versions
# ===========================================================================
@@ -97,7 +98,6 @@ vmlinux.o: FORCE
$(call cmd,kernel-mod)
# Declare generated files as targets for modpost
-$(symverfile): __modpost ;
$(modules:.ko=.mod.c): __modpost ;
diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign
index b6ac7084da79..171483bc0538 100644
--- a/scripts/Makefile.modsign
+++ b/scripts/Makefile.modsign
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Signing modules
# ==========================================================================
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 3b1b13818d59..8fd4d44fbcd1 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
ifdef CONFIG_UBSAN
CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index ec10d9345bc2..0372b33febe5 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -1,5 +1,5 @@
###
-# Makefile.basic lists the most basic programs used during the build process.
+# This Makefile lists the most basic programs used during the build process.
# The programs listed herein are what are needed to do the basic stuff,
# such as fix file dependencies.
# This initial step is needed to avoid files to be recompiled
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index fff818b92acb..bbf62cb1f819 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -25,7 +25,7 @@
*
* So we play the same trick that "mkdep" played before. We replace
* the dependency on autoconf.h by a dependency on every config
- * option which is mentioned in any of the listed prequisites.
+ * option which is mentioned in any of the listed prerequisites.
*
* kconfig populates a tree in include/config/ with an empty file
* for each config symbol and when the configuration is updated
@@ -34,7 +34,7 @@
* the config symbols are rebuilt.
*
* So if the user changes his CONFIG_HIS_DRIVER option, only the objects
- * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * which depend on "include/config/his/driver.h" will be rebuilt,
* so most likely only his driver ;-)
*
* The idea above dates, by the way, back to Michael E Chastain, AFAIK.
@@ -75,7 +75,7 @@
* and then basically copies the .<target>.d file to stdout, in the
* process filtering out the dependency on autoconf.h and adding
* dependencies on include/config/my/option.h for every
- * CONFIG_MY_OPTION encountered in any of the prequisites.
+ * CONFIG_MY_OPTION encountered in any of the prerequisites.
*
* It will also filter out all the dependencies on *.ver. We need
* to make sure that the generated version checksum are globally up
diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
index 9ca667bcaee9..594c55541b16 100755
--- a/scripts/bootgraph.pl
+++ b/scripts/bootgraph.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright 2008, Intel Corporation
#
diff --git a/scripts/check-lc_ctype.c b/scripts/check-lc_ctype.c
deleted file mode 100644
index 9097ff5449fb..000000000000
--- a/scripts/check-lc_ctype.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Check that a specified locale works as LC_CTYPE. Used by the
- * DocBook build system to probe for C.UTF-8 support.
- */
-
-#include <locale.h>
-
-int main(void)
-{
- return !setlocale(LC_CTYPE, "");
-}
diff --git a/scripts/check_00index.sh b/scripts/check_00index.sh
index 6ac9527aeddb..aa47f5926c80 100755
--- a/scripts/check_00index.sh
+++ b/scripts/check_00index.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
cd Documentation/
diff --git a/scripts/check_extable.sh b/scripts/check_extable.sh
index 0fb6b1c97c27..93af93c7b346 100755
--- a/scripts/check_extable.sh
+++ b/scripts/check_extable.sh
@@ -1,4 +1,5 @@
#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
# (c) 2015, Quentin Casasnovas <quentin.casasnovas@oracle.com>
obj=$1
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl
index 381c018a4612..b514a956d550 100755
--- a/scripts/checkincludes.pl
+++ b/scripts/checkincludes.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# checkincludes: find/remove files included more than once
#
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 4b9569fa931b..8b80bac055e4 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# (c) 2001, Dave Jones. (the file handling bit)
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
@@ -6,6 +6,7 @@
# Licensed under the terms of the GNU GPL License version 2
use strict;
+use warnings;
use POSIX;
use File::Basename;
use Cwd 'abs_path';
@@ -56,7 +57,7 @@ my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $conststructsfile = "$D/const_structs.checkpatch";
my $typedefsfile = "";
-my $color = 1;
+my $color = "auto";
my $allow_c99_comments = 1;
sub help {
@@ -115,7 +116,8 @@ Options:
(default:/usr/share/codespell/dictionary.txt)
--codespellfile Use this codespell dictionary
--typedefsfile Read additional types from this file
- --color Use colors when output is STDOUT (default: on)
+ --color[=WHEN] Use colors 'always', 'never', or only when output
+ is a terminal ('auto'). Default is 'auto'.
-h, --help, --version display this help and exit
When FILE is - read standard input.
@@ -143,7 +145,8 @@ sub list_types {
close($script);
my @types = ();
- for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) {
+ # Also catch when type or level is passed through a variable
+ for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
push (@types, $_);
}
@types = sort(uniq(@types));
@@ -181,6 +184,14 @@ if (-f $conf) {
unshift(@ARGV, @conf_args) if @conf_args;
}
+# Perl's Getopt::Long allows options to take optional arguments after a space.
+# Prevent --color by itself from consuming other arguments
+foreach (@ARGV) {
+ if ($_ eq "--color" || $_ eq "-color") {
+ $_ = "--color=$color";
+ }
+}
+
GetOptions(
'q|quiet+' => \$quiet,
'tree!' => \$tree,
@@ -211,7 +222,9 @@ GetOptions(
'codespell!' => \$codespell,
'codespellfile=s' => \$codespellfile,
'typedefsfile=s' => \$typedefsfile,
- 'color!' => \$color,
+ 'color=s' => \$color,
+ 'no-color' => \$color, #keep old behaviors of -nocolor
+ 'nocolor' => \$color, #keep old behaviors of -nocolor
'h|help' => \$help,
'version' => \$help
) or help(1);
@@ -237,6 +250,18 @@ if ($#ARGV < 0) {
push(@ARGV, '-');
}
+if ($color =~ /^[01]$/) {
+ $color = !$color;
+} elsif ($color =~ /^always$/i) {
+ $color = 1;
+} elsif ($color =~ /^never$/i) {
+ $color = 0;
+} elsif ($color =~ /^auto$/i) {
+ $color = (-t STDOUT);
+} else {
+ die "Invalid color mode: $color\n";
+}
+
sub hash_save_array_words {
my ($hashRef, $arrayRef) = @_;
@@ -732,7 +757,7 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
our $declaration_macros = qr{(?x:
(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
- (?:$Storage\s+)?LIST_HEAD\s*\(|
+ (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
)};
@@ -866,6 +891,7 @@ sub git_commit_info {
# echo "commit $(cut -c 1-12,41-)"
# done
} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
+ $id = undef;
} else {
$id = substr($lines[0], 0, 12);
$desc = substr($lines[0], 41);
@@ -1881,7 +1907,7 @@ sub report {
return 0;
}
my $output = '';
- if (-t STDOUT && $color) {
+ if ($color) {
if ($level eq 'ERROR') {
$output .= RED;
} elsif ($level eq 'WARNING') {
@@ -1892,10 +1918,10 @@ sub report {
}
$output .= $prefix . $level . ':';
if ($show_types) {
- $output .= BLUE if (-t STDOUT && $color);
+ $output .= BLUE if ($color);
$output .= "$type:";
}
- $output .= RESET if (-t STDOUT && $color);
+ $output .= RESET if ($color);
$output .= ' ' . $msg . "\n";
if ($showfile) {
@@ -2605,7 +2631,8 @@ sub process {
($id, $description) = git_commit_info($orig_commit,
$id, $orig_desc);
- if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) {
+ if (defined($id) &&
+ ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
ERROR("GIT_COMMIT_ID",
"Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
}
@@ -2689,10 +2716,10 @@ sub process {
my $typo_fix = $spelling_fix{lc($typo)};
$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
- my $msg_type = \&WARN;
- $msg_type = \&CHK if ($file);
- if (&{$msg_type}("TYPO_SPELLING",
- "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
+ my $msg_level = \&WARN;
+ $msg_level = \&CHK if ($file);
+ if (&{$msg_level}("TYPO_SPELLING",
+ "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
$fix) {
$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
}
@@ -2727,10 +2754,10 @@ sub process {
$rawline =~ /\b59\s+Temple\s+Pl/i ||
$rawline =~ /\b51\s+Franklin\s+St/i) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- my $msg_type = \&ERROR;
- $msg_type = \&CHK if ($file);
- &{$msg_type}("FSF_MAILING_ADDRESS",
- "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
+ my $msg_level = \&ERROR;
+ $msg_level = \&CHK if ($file);
+ &{$msg_level}("FSF_MAILING_ADDRESS",
+ "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
}
# check for Kconfig help text having a real description
@@ -2775,6 +2802,17 @@ sub process {
#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
}
+# check for MAINTAINERS entries that don't have the right form
+ if ($realfile =~ /^MAINTAINERS$/ &&
+ $rawline =~ /^\+[A-Z]:/ &&
+ $rawline !~ /^\+[A-Z]:\t\S/) {
+ if (WARN("MAINTAINERS_STYLE",
+ "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
+ }
+ }
+
# discourage the use of boolean for type definition attributes of Kconfig options
if ($realfile =~ /Kconfig/ &&
$line =~ /^\+\s*\bboolean\b/) {
@@ -2838,7 +2876,7 @@ sub process {
# #defines that are a single string
#
# There are 3 different line length message types:
-# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength
+# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
# LONG_LINE all other lines longer than $max_line_length
#
@@ -2956,7 +2994,7 @@ sub process {
# check multi-line statement indentation matches previous line
if ($^V && $^V ge 5.10.0 &&
- $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
+ $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
$prevline =~ /^\+(\t*)(.*)$/;
my $oldindent = $1;
my $rest = $2;
@@ -3207,7 +3245,7 @@ sub process {
my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
$realline_next);
#print "LINE<$line>\n";
- if ($linenr >= $suppress_statement &&
+ if ($linenr > $suppress_statement &&
$realcnt && $sline =~ /.\s*\S/) {
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
ctx_statement_block($linenr, $realcnt, 0);
@@ -3541,7 +3579,7 @@ sub process {
$fixedline =~ s/\s*=\s*$/ = {/;
fix_insert_line($fixlinenr, $fixedline);
$fixedline = $line;
- $fixedline =~ s/^(.\s*){\s*/$1/;
+ $fixedline =~ s/^(.\s*)\{\s*/$1/;
fix_insert_line($fixlinenr, $fixedline);
}
}
@@ -3773,10 +3811,10 @@ sub process {
# avoid BUG() or BUG_ON()
if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
- my $msg_type = \&WARN;
- $msg_type = \&CHK if ($file);
- &{$msg_type}("AVOID_BUG",
- "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
+ my $msg_level = \&WARN;
+ $msg_level = \&CHK if ($file);
+ &{$msg_level}("AVOID_BUG",
+ "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
}
# avoid LINUX_VERSION_CODE
@@ -3882,7 +3920,7 @@ sub process {
my $fixedline = rtrim($prevrawline) . " {";
fix_insert_line($fixlinenr, $fixedline);
$fixedline = $rawline;
- $fixedline =~ s/^(.\s*){\s*/$1\t/;
+ $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
if ($fixedline !~ /^\+\s*$/) {
fix_insert_line($fixlinenr, $fixedline);
}
@@ -4302,11 +4340,11 @@ sub process {
# messages are ERROR, but ?: are CHK
if ($ok == 0) {
- my $msg_type = \&ERROR;
- $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
+ my $msg_level = \&ERROR;
+ $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
- if (&{$msg_type}("SPACING",
- "spaces required around that '$op' $at\n" . $hereptr)) {
+ if (&{$msg_level}("SPACING",
+ "spaces required around that '$op' $at\n" . $hereptr)) {
$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
if (defined $fix_elements[$n + 2]) {
$fix_elements[$n + 2] =~ s/^\s+//;
@@ -4371,7 +4409,7 @@ sub process {
if (ERROR("SPACING",
"space required before the open brace '{'\n" . $herecurr) &&
$fix) {
- $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/;
+ $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
}
}
@@ -4459,6 +4497,30 @@ sub process {
}
}
+# check for unnecessary parentheses around comparisons in if uses
+ if ($^V && $^V ge 5.10.0 && defined($stat) &&
+ $stat =~ /(^.\s*if\s*($balanced_parens))/) {
+ my $if_stat = $1;
+ my $test = substr($2, 1, -1);
+ my $herectx;
+ while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
+ my $match = $1;
+ # avoid parentheses around potential macro args
+ next if ($match =~ /^\s*\w+\s*$/);
+ if (!defined($herectx)) {
+ $herectx = $here . "\n";
+ my $cnt = statement_rawlines($if_stat);
+ for (my $n = 0; $n < $cnt; $n++) {
+ my $rl = raw_line($linenr, $n);
+ $herectx .= $rl . "\n";
+ last if $rl =~ /^[ \+].*\{/;
+ }
+ }
+ CHK("UNNECESSARY_PARENTHESES",
+ "Unnecessary parentheses around '$match'\n" . $herectx);
+ }
+ }
+
#goto labels aren't indented, allow a single space however
if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
!($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
@@ -4903,17 +4965,17 @@ sub process {
foreach my $arg (@def_args) {
next if ($arg =~ /\.\.\./);
next if ($arg =~ /^type$/i);
- my $tmp = $define_stmt;
- $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
- $tmp =~ s/\#+\s*$arg\b//g;
- $tmp =~ s/\b$arg\s*\#\#//g;
- my $use_cnt = $tmp =~ s/\b$arg\b//g;
+ my $tmp_stmt = $define_stmt;
+ $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
+ $tmp_stmt =~ s/\#+\s*$arg\b//g;
+ $tmp_stmt =~ s/\b$arg\s*\#\#//g;
+ my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g;
if ($use_cnt > 1) {
CHK("MACRO_ARG_REUSE",
"Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
}
# check if any macro arguments may have other precedence issues
- if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
+ if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
((defined($1) && $1 ne ',') ||
(defined($2) && $2 ne ','))) {
CHK("MACRO_ARG_PRECEDENCE",
@@ -5310,7 +5372,7 @@ sub process {
my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
- if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) {
+ if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
WARN("OOM_MESSAGE",
"Possible unnecessary 'out of memory' message\n" . $hereprev);
}
@@ -5533,33 +5595,24 @@ sub process {
}
}
-# Check for expedited grace periods that interrupt non-idle non-nohz
-# online CPUs. These expedited can therefore degrade real-time response
-# if used carelessly, and should be avoided where not absolutely
-# needed. It is always OK to use synchronize_rcu_expedited() and
-# synchronize_sched_expedited() at boot time (before real-time applications
-# start) and in error situations where real-time response is compromised in
-# any case. Note that synchronize_srcu_expedited() does -not- interrupt
-# other CPUs, so don't warn on uses of synchronize_srcu_expedited().
-# Of course, nothing comes for free, and srcu_read_lock() and
-# srcu_read_unlock() do contain full memory barriers in payment for
-# synchronize_srcu_expedited() non-interruption properties.
- if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) {
- WARN("EXPEDITED_RCU_GRACE_PERIOD",
- "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr);
-
- }
-
# check of hardware specific defines
if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
CHK("ARCH_DEFINES",
"architecture specific defines should be avoided\n" . $herecurr);
}
+# check that the storage class is not after a type
+ if ($line =~ /\b($Type)\s+($Storage)\b/) {
+ WARN("STORAGE_CLASS",
+ "storage class '$2' should be located before type '$1'\n" . $herecurr);
+ }
# Check that the storage class is at the beginning of a declaration
- if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
+ if ($line =~ /\b$Storage\b/ &&
+ $line !~ /^.\s*$Storage/ &&
+ $line =~ /^.\s*(.+?)\$Storage\s/ &&
+ $1 !~ /[\,\)]\s*$/) {
WARN("STORAGE_CLASS",
- "storage class should be at the beginning of the declaration\n" . $herecurr)
+ "storage class should be at the beginning of the declaration\n" . $herecurr);
}
# check the location of the inline attribute, that it is between
@@ -5709,7 +5762,7 @@ sub process {
for (my $count = $linenr; $count <= $lc; $count++) {
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
$fmt =~ s/%%//g;
- if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) {
+ if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
$bad_extension = $1;
last;
}
@@ -5902,7 +5955,8 @@ sub process {
"externs should be avoided in .c files\n" . $herecurr);
}
- if ($realfile =~ /\.[ch]$/ && defined $stat &&
+# check for function declarations that have arguments without identifier names
+ if (defined $stat &&
$stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
$1 ne "void") {
my $args = trim($1);
@@ -5915,6 +5969,29 @@ sub process {
}
}
+# check for function definitions
+ if ($^V && $^V ge 5.10.0 &&
+ defined $stat &&
+ $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
+ $context_function = $1;
+
+# check for multiline function definition with misplaced open brace
+ my $ok = 0;
+ my $cnt = statement_rawlines($stat);
+ my $herectx = $here . "\n";
+ for (my $n = 0; $n < $cnt; $n++) {
+ my $rl = raw_line($linenr, $n);
+ $herectx .= $rl . "\n";
+ $ok = 1 if ($rl =~ /^[ \+]\{/);
+ $ok = 1 if ($rl =~ /\{/ && $n == 0);
+ last if $rl =~ /^[ \+].*\{/;
+ }
+ if (!$ok) {
+ ERROR("OPEN_BRACE",
+ "open brace '{' following function definitions go on the next line\n" . $herectx);
+ }
+ }
+
# checks for new __setup's
if ($rawline =~ /\b__setup\("([^"]*)"/) {
my $name = $1;
@@ -6313,7 +6390,7 @@ sub process {
exit(0);
}
- if (!$is_patch && $file !~ /cover-letter\.patch$/) {
+ if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
ERROR("NOT_UNIFIED_DIFF",
"Does not appear to be a unified-diff format patch\n");
}
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 9d37aa4faf5c..cb993801e4b2 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
# Check the stack usage of functions
#
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
index 116b7735ee9f..ee3dfb5be6cd 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# Check if current architecture are missing any function calls compared
# to i386.
@@ -202,15 +203,12 @@ EOF
}
syscall_list() {
- grep '^[0-9]' "$1" | sort -n | (
+ grep '^[0-9]' "$1" | sort -n |
while read nr abi name entry ; do
- cat <<EOF
-#if !defined(__NR_${name}) && !defined(__IGNORE_${name})
-#warning syscall ${name} not implemented
-#endif
-EOF
+ echo "#if !defined(__NR_${name}) && !defined(__IGNORE_${name})"
+ echo "#warning syscall ${name} not implemented"
+ echo "#endif"
done
- )
}
(ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
index 5e490a8ceca5..f67b125c5269 100755
--- a/scripts/checkversion.pl
+++ b/scripts/checkversion.pl
@@ -1,4 +1,5 @@
-#! /usr/bin/perl
+#! /usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# checkversion find uses of LINUX_VERSION_CODE or KERNEL_VERSION
# without including <linux/version.h>, or cases of
diff --git a/scripts/cleanfile b/scripts/cleanfile
index cefd29e52298..c00c69b9171a 100755
--- a/scripts/cleanfile
+++ b/scripts/cleanfile
@@ -1,9 +1,11 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# Clean a text file -- or directory of text files -- of stealth whitespace.
# WARNING: this can be a highly destructive operation. Use with caution.
#
+use warnings;
use bytes;
use File::Basename;
diff --git a/scripts/cleanpatch b/scripts/cleanpatch
index 9680d03ad2b8..9f1755271516 100755
--- a/scripts/cleanpatch
+++ b/scripts/cleanpatch
@@ -1,9 +1,11 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# Clean a patch file -- or directory of patch files -- of stealth whitespace.
# WARNING: this can be a highly destructive operation. Use with caution.
#
+use warnings;
use bytes;
use File::Basename;
diff --git a/scripts/coccicheck b/scripts/coccicheck
index ec487b8e7051..28ad1feff9e1 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
# Linux kernel coccicheck
#
# Read Documentation/dev-tools/coccinelle.rst
diff --git a/scripts/coccinelle/api/d_find_alias.cocci b/scripts/coccinelle/api/d_find_alias.cocci
index 9594c9f7eb8d..47e050166f20 100644
--- a/scripts/coccinelle/api/d_find_alias.cocci
+++ b/scripts/coccinelle/api/d_find_alias.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Make sure calls to d_find_alias() have a corresponding call to dput().
//
// Keywords: d_find_alias, dput
diff --git a/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci b/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
index 85cf5408d378..7c312310547c 100644
--- a/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
+++ b/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE
/// for debugfs files.
///
diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci
index 0c7a9265c07e..bf1313274f0b 100644
--- a/scripts/coccinelle/api/drm-get-put.cocci
+++ b/scripts/coccinelle/api/drm-get-put.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
///
/// Use drm_*_get() and drm_*_put() helpers instead of drm_*_reference() and
/// drm_*_unreference() helpers.
diff --git a/scripts/coccinelle/api/simple_open.cocci b/scripts/coccinelle/api/simple_open.cocci
index bd1a2a4ee106..c121876d54ec 100644
--- a/scripts/coccinelle/api/simple_open.cocci
+++ b/scripts/coccinelle/api/simple_open.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Remove an open coded simple_open() function
/// and replace file operations references to the function
/// with simple_open() instead.
diff --git a/scripts/coccinelle/api/vma_pages.cocci b/scripts/coccinelle/api/vma_pages.cocci
index 3e52e11ea1dc..10511b9bf35e 100644
--- a/scripts/coccinelle/api/vma_pages.cocci
+++ b/scripts/coccinelle/api/vma_pages.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
///
/// Use vma_pages function on vma object instead of explicit computation.
///
diff --git a/scripts/coccinelle/misc/boolreturn.cocci b/scripts/coccinelle/misc/boolreturn.cocci
index a43c7b0c36ef..29d2bf41e95d 100644
--- a/scripts/coccinelle/misc/boolreturn.cocci
+++ b/scripts/coccinelle/misc/boolreturn.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Return statements in functions returning bool should use
/// true/false instead of 1/0.
//
diff --git a/scripts/coccinelle/misc/irqf_oneshot.cocci b/scripts/coccinelle/misc/irqf_oneshot.cocci
index f698d6d0f5d7..7b48287b3dc1 100644
--- a/scripts/coccinelle/misc/irqf_oneshot.cocci
+++ b/scripts/coccinelle/misc/irqf_oneshot.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Since commit 1c6c69525b40 ("genirq: Reject bogus threaded irq requests")
/// threaded IRQs without a primary handler need to be requested with
/// IRQF_ONESHOT, otherwise the request will fail.
diff --git a/scripts/coccinelle/misc/of_table.cocci b/scripts/coccinelle/misc/of_table.cocci
index 2294915a19bc..4693ea744753 100644
--- a/scripts/coccinelle/misc/of_table.cocci
+++ b/scripts/coccinelle/misc/of_table.cocci
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/// Make sure (of/i2c/platform)_device_id tables are NULL terminated
//
// Keywords: of_table i2c_table platform_table
diff --git a/scripts/config b/scripts/config
index 026aeb4f32ee..e0e39826dae9 100755
--- a/scripts/config
+++ b/scripts/config
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
# Manipulate options in a .config file from the command line
myname=${0##*/}
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index 5206d99ddeb8..64220e36ce3b 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
# (c) 2014, Sasha Levin <sasha.levin@oracle.com>
#set -x
diff --git a/scripts/decodecode b/scripts/decodecode
index d8824f37acce..438120da1361 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Disassemble the Code: line in Linux oopses
# usage: decodecode < oops.file
#
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index 122599b1c13b..9831cca31240 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# A depmod wrapper used by the toplevel Makefile
diff --git a/scripts/diffconfig b/scripts/diffconfig
index 0db267d0adc9..89abf777f197 100755
--- a/scripts/diffconfig
+++ b/scripts/diffconfig
@@ -1,4 +1,5 @@
#!/usr/bin/python
+# SPDX-License-Identifier: GPL-2.0
#
# diffconfig - a tool to compare .config files.
#
diff --git a/scripts/docproc.c b/scripts/docproc.c
deleted file mode 100644
index 0a12593b9041..000000000000
--- a/scripts/docproc.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * docproc is a simple preprocessor for the template files
- * used as placeholders for the kernel internal documentation.
- * docproc is used for documentation-frontend and
- * dependency-generator.
- * The two usages have in common that they require
- * some knowledge of the .tmpl syntax, therefore they
- * are kept together.
- *
- * documentation-frontend
- * Scans the template file and call kernel-doc for
- * all occurrences of ![EIF]file
- * Beforehand each referenced file is scanned for
- * any symbols that are exported via these macros:
- * EXPORT_SYMBOL(), EXPORT_SYMBOL_GPL(), &
- * EXPORT_SYMBOL_GPL_FUTURE()
- * This is used to create proper -function and
- * -nofunction arguments in calls to kernel-doc.
- * Usage: docproc doc file.tmpl
- *
- * dependency-generator:
- * Scans the template file and list all files
- * referenced in a format recognized by make.
- * Usage: docproc depend file.tmpl
- * Writes dependency information to stdout
- * in the following format:
- * file.tmpl src.c src2.c
- * The filenames are obtained from the following constructs:
- * !Efilename
- * !Ifilename
- * !Dfilename
- * !Ffilename
- * !Pfilename
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <time.h>
-
-/* exitstatus is used to keep track of any failing calls to kernel-doc,
- * but execution continues. */
-int exitstatus = 0;
-
-typedef void DFL(char *);
-DFL *defaultline;
-
-typedef void FILEONLY(char * file);
-FILEONLY *internalfunctions;
-FILEONLY *externalfunctions;
-FILEONLY *symbolsonly;
-FILEONLY *findall;
-
-typedef void FILELINE(char * file, char * line);
-FILELINE * singlefunctions;
-FILELINE * entity_system;
-FILELINE * docsection;
-
-#define MAXLINESZ 2048
-#define MAXFILES 250
-#define KERNELDOCPATH "scripts/"
-#define KERNELDOC "kernel-doc"
-#define DOCBOOK "-docbook"
-#define RST "-rst"
-#define LIST "-list"
-#define FUNCTION "-function"
-#define NOFUNCTION "-nofunction"
-#define NODOCSECTIONS "-no-doc-sections"
-#define SHOWNOTFOUND "-show-not-found"
-
-enum file_format {
- FORMAT_AUTO,
- FORMAT_DOCBOOK,
- FORMAT_RST,
-};
-
-static enum file_format file_format = FORMAT_AUTO;
-
-#define KERNELDOC_FORMAT (file_format == FORMAT_RST ? RST : DOCBOOK)
-
-static char *srctree, *kernsrctree;
-
-static char **all_list = NULL;
-static int all_list_len = 0;
-
-static void consume_symbol(const char *sym)
-{
- int i;
-
- for (i = 0; i < all_list_len; i++) {
- if (!all_list[i])
- continue;
- if (strcmp(sym, all_list[i]))
- continue;
- all_list[i] = NULL;
- break;
- }
-}
-
-static void usage (void)
-{
- fprintf(stderr, "Usage: docproc [{--docbook|--rst}] {doc|depend} file\n");
- fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
- fprintf(stderr, "doc: frontend when generating kernel documentation\n");
- fprintf(stderr, "depend: generate list of files referenced within file\n");
- fprintf(stderr, "Environment variable SRCTREE: absolute path to sources.\n");
- fprintf(stderr, " KBUILD_SRC: absolute path to kernel source tree.\n");
-}
-
-/*
- * Execute kernel-doc with parameters given in svec
- */
-static void exec_kernel_doc(char **svec)
-{
- pid_t pid;
- int ret;
- char real_filename[PATH_MAX + 1];
- /* Make sure output generated so far are flushed */
- fflush(stdout);
- switch (pid=fork()) {
- case -1:
- perror("fork");
- exit(1);
- case 0:
- memset(real_filename, 0, sizeof(real_filename));
- strncat(real_filename, kernsrctree, PATH_MAX);
- strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
- PATH_MAX - strlen(real_filename));
- execvp(real_filename, svec);
- fprintf(stderr, "exec ");
- perror(real_filename);
- exit(1);
- default:
- waitpid(pid, &ret ,0);
- }
- if (WIFEXITED(ret))
- exitstatus |= WEXITSTATUS(ret);
- else
- exitstatus = 0xff;
-}
-
-/* Types used to create list of all exported symbols in a number of files */
-struct symbols
-{
- char *name;
-};
-
-struct symfile
-{
- char *filename;
- struct symbols *symbollist;
- int symbolcnt;
-};
-
-struct symfile symfilelist[MAXFILES];
-int symfilecnt = 0;
-
-static void add_new_symbol(struct symfile *sym, char * symname)
-{
- sym->symbollist =
- realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
- sym->symbollist[sym->symbolcnt++].name = strdup(symname);
-}
-
-/* Add a filename to the list */
-static struct symfile * add_new_file(char * filename)
-{
- symfilelist[symfilecnt++].filename = strdup(filename);
- return &symfilelist[symfilecnt - 1];
-}
-
-/* Check if file already are present in the list */
-static struct symfile * filename_exist(char * filename)
-{
- int i;
- for (i=0; i < symfilecnt; i++)
- if (strcmp(symfilelist[i].filename, filename) == 0)
- return &symfilelist[i];
- return NULL;
-}
-
-/*
- * List all files referenced within the template file.
- * Files are separated by tabs.
- */
-static void adddep(char * file) { printf("\t%s", file); }
-static void adddep2(char * file, char * line) { line = line; adddep(file); }
-static void noaction(char * line) { line = line; }
-static void noaction2(char * file, char * line) { file = file; line = line; }
-
-/* Echo the line without further action */
-static void printline(char * line) { printf("%s", line); }
-
-/*
- * Find all symbols in filename that are exported with EXPORT_SYMBOL &
- * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly).
- * All symbols located are stored in symfilelist.
- */
-static void find_export_symbols(char * filename)
-{
- FILE * fp;
- struct symfile *sym;
- char line[MAXLINESZ];
- if (filename_exist(filename) == NULL) {
- char real_filename[PATH_MAX + 1];
- memset(real_filename, 0, sizeof(real_filename));
- strncat(real_filename, srctree, PATH_MAX);
- strncat(real_filename, "/", PATH_MAX - strlen(real_filename));
- strncat(real_filename, filename,
- PATH_MAX - strlen(real_filename));
- sym = add_new_file(filename);
- fp = fopen(real_filename, "r");
- if (fp == NULL) {
- fprintf(stderr, "docproc: ");
- perror(real_filename);
- exit(1);
- }
- while (fgets(line, MAXLINESZ, fp)) {
- char *p;
- char *e;
- if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != NULL) ||
- ((p = strstr(line, "EXPORT_SYMBOL")) != NULL)) {
- /* Skip EXPORT_SYMBOL{_GPL} */
- while (isalnum(*p) || *p == '_')
- p++;
- /* Remove parentheses & additional whitespace */
- while (isspace(*p))
- p++;
- if (*p != '(')
- continue; /* Syntax error? */
- else
- p++;
- while (isspace(*p))
- p++;
- e = p;
- while (isalnum(*e) || *e == '_')
- e++;
- *e = '\0';
- add_new_symbol(sym, p);
- }
- }
- fclose(fp);
- }
-}
-
-/*
- * Document all external or internal functions in a file.
- * Call kernel-doc with following parameters:
- * kernel-doc [-docbook|-rst] -nofunction function_name1 filename
- * Function names are obtained from all the src files
- * by find_export_symbols.
- * intfunc uses -nofunction
- * extfunc uses -function
- */
-static void docfunctions(char * filename, char * type)
-{
- int i,j;
- int symcnt = 0;
- int idx = 0;
- char **vec;
-
- for (i=0; i <= symfilecnt; i++)
- symcnt += symfilelist[i].symbolcnt;
- vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *));
- if (vec == NULL) {
- perror("docproc: ");
- exit(1);
- }
- vec[idx++] = KERNELDOC;
- vec[idx++] = KERNELDOC_FORMAT;
- vec[idx++] = NODOCSECTIONS;
- for (i=0; i < symfilecnt; i++) {
- struct symfile * sym = &symfilelist[i];
- for (j=0; j < sym->symbolcnt; j++) {
- vec[idx++] = type;
- consume_symbol(sym->symbollist[j].name);
- vec[idx++] = sym->symbollist[j].name;
- }
- }
- vec[idx++] = filename;
- vec[idx] = NULL;
- if (file_format == FORMAT_RST)
- printf(".. %s\n", filename);
- else
- printf("<!-- %s -->\n", filename);
- exec_kernel_doc(vec);
- fflush(stdout);
- free(vec);
-}
-static void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
-static void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
-
-/*
- * Document specific function(s) in a file.
- * Call kernel-doc with the following parameters:
- * kernel-doc -docbook -function function1 [-function function2]
- */
-static void singfunc(char * filename, char * line)
-{
- char *vec[200]; /* Enough for specific functions */
- int i, idx = 0;
- int startofsym = 1;
- vec[idx++] = KERNELDOC;
- vec[idx++] = KERNELDOC_FORMAT;
- vec[idx++] = SHOWNOTFOUND;
-
- /* Split line up in individual parameters preceded by FUNCTION */
- for (i=0; line[i]; i++) {
- if (isspace(line[i])) {
- line[i] = '\0';
- startofsym = 1;
- continue;
- }
- if (startofsym) {
- startofsym = 0;
- vec[idx++] = FUNCTION;
- vec[idx++] = &line[i];
- }
- }
- for (i = 0; i < idx; i++) {
- if (strcmp(vec[i], FUNCTION))
- continue;
- consume_symbol(vec[i + 1]);
- }
- vec[idx++] = filename;
- vec[idx] = NULL;
- exec_kernel_doc(vec);
-}
-
-/*
- * Insert specific documentation section from a file.
- * Call kernel-doc with the following parameters:
- * kernel-doc -docbook -function "doc section" filename
- */
-static void docsect(char *filename, char *line)
-{
- /* kerneldoc -docbook -show-not-found -function "section" file NULL */
- char *vec[7];
- char *s;
-
- for (s = line; *s; s++)
- if (*s == '\n')
- *s = '\0';
-
- if (asprintf(&s, "DOC: %s", line) < 0) {
- perror("asprintf");
- exit(1);
- }
- consume_symbol(s);
- free(s);
-
- vec[0] = KERNELDOC;
- vec[1] = KERNELDOC_FORMAT;
- vec[2] = SHOWNOTFOUND;
- vec[3] = FUNCTION;
- vec[4] = line;
- vec[5] = filename;
- vec[6] = NULL;
- exec_kernel_doc(vec);
-}
-
-static void find_all_symbols(char *filename)
-{
- char *vec[4]; /* kerneldoc -list file NULL */
- pid_t pid;
- int ret, i, count, start;
- char real_filename[PATH_MAX + 1];
- int pipefd[2];
- char *data, *str;
- size_t data_len = 0;
-
- vec[0] = KERNELDOC;
- vec[1] = LIST;
- vec[2] = filename;
- vec[3] = NULL;
-
- if (pipe(pipefd)) {
- perror("pipe");
- exit(1);
- }
-
- switch (pid=fork()) {
- case -1:
- perror("fork");
- exit(1);
- case 0:
- close(pipefd[0]);
- dup2(pipefd[1], 1);
- memset(real_filename, 0, sizeof(real_filename));
- strncat(real_filename, kernsrctree, PATH_MAX);
- strncat(real_filename, "/" KERNELDOCPATH KERNELDOC,
- PATH_MAX - strlen(real_filename));
- execvp(real_filename, vec);
- fprintf(stderr, "exec ");
- perror(real_filename);
- exit(1);
- default:
- close(pipefd[1]);
- data = malloc(4096);
- do {
- while ((ret = read(pipefd[0],
- data + data_len,
- 4096)) > 0) {
- data_len += ret;
- data = realloc(data, data_len + 4096);
- }
- } while (ret == -EAGAIN);
- if (ret != 0) {
- perror("read");
- exit(1);
- }
- waitpid(pid, &ret ,0);
- }
- if (WIFEXITED(ret))
- exitstatus |= WEXITSTATUS(ret);
- else
- exitstatus = 0xff;
-
- count = 0;
- /* poor man's strtok, but with counting */
- for (i = 0; i < data_len; i++) {
- if (data[i] == '\n') {
- count++;
- data[i] = '\0';
- }
- }
- start = all_list_len;
- all_list_len += count;
- all_list = realloc(all_list, sizeof(char *) * all_list_len);
- str = data;
- for (i = 0; i < data_len && start != all_list_len; i++) {
- if (data[i] == '\0') {
- all_list[start] = str;
- str = data + i + 1;
- start++;
- }
- }
-}
-
-/*
- * Terminate s at first space, if any. If there was a space, return pointer to
- * the character after that. Otherwise, return pointer to the terminating NUL.
- */
-static char *chomp(char *s)
-{
- while (*s && !isspace(*s))
- s++;
-
- if (*s)
- *s++ = '\0';
-
- return s;
-}
-
-/* Return pointer to directive content, or NULL if not a directive. */
-static char *is_directive(char *line)
-{
- if (file_format == FORMAT_DOCBOOK && line[0] == '!')
- return line + 1;
- else if (file_format == FORMAT_RST && !strncmp(line, ".. !", 4))
- return line + 4;
-
- return NULL;
-}
-
-/*
- * Parse file, calling action specific functions for:
- * 1) Lines containing !E
- * 2) Lines containing !I
- * 3) Lines containing !D
- * 4) Lines containing !F
- * 5) Lines containing !P
- * 6) Lines containing !C
- * 7) Default lines - lines not matching the above
- */
-static void parse_file(FILE *infile)
-{
- char line[MAXLINESZ];
- char *p, *s;
- while (fgets(line, MAXLINESZ, infile)) {
- p = is_directive(line);
- if (!p) {
- defaultline(line);
- continue;
- }
-
- switch (*p++) {
- case 'E':
- chomp(p);
- externalfunctions(p);
- break;
- case 'I':
- chomp(p);
- internalfunctions(p);
- break;
- case 'D':
- chomp(p);
- symbolsonly(p);
- break;
- case 'F':
- /* filename */
- s = chomp(p);
- /* function names */
- while (isspace(*s))
- s++;
- singlefunctions(p, s);
- break;
- case 'P':
- /* filename */
- s = chomp(p);
- /* DOC: section name */
- while (isspace(*s))
- s++;
- docsection(p, s);
- break;
- case 'C':
- chomp(p);
- if (findall)
- findall(p);
- break;
- default:
- defaultline(line);
- }
- }
- fflush(stdout);
-}
-
-/*
- * Is this a RestructuredText template? Answer the question by seeing if its
- * name ends in ".rst".
- */
-static int is_rst(const char *file)
-{
- char *dot = strrchr(file, '.');
-
- return dot && !strcmp(dot + 1, "rst");
-}
-
-enum opts {
- OPT_DOCBOOK,
- OPT_RST,
- OPT_HELP,
-};
-
-int main(int argc, char *argv[])
-{
- const char *subcommand, *filename;
- FILE * infile;
- int i;
-
- srctree = getenv("SRCTREE");
- if (!srctree)
- srctree = getcwd(NULL, 0);
- kernsrctree = getenv("KBUILD_SRC");
- if (!kernsrctree || !*kernsrctree)
- kernsrctree = srctree;
-
- for (;;) {
- int c;
- struct option opts[] = {
- { "docbook", no_argument, NULL, OPT_DOCBOOK },
- { "rst", no_argument, NULL, OPT_RST },
- { "help", no_argument, NULL, OPT_HELP },
- {}
- };
-
- c = getopt_long_only(argc, argv, "", opts, NULL);
- if (c == -1)
- break;
-
- switch (c) {
- case OPT_DOCBOOK:
- file_format = FORMAT_DOCBOOK;
- break;
- case OPT_RST:
- file_format = FORMAT_RST;
- break;
- case OPT_HELP:
- usage();
- return 0;
- default:
- case '?':
- usage();
- return 1;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc != 2) {
- usage();
- exit(1);
- }
-
- subcommand = argv[0];
- filename = argv[1];
-
- if (file_format == FORMAT_AUTO)
- file_format = is_rst(filename) ? FORMAT_RST : FORMAT_DOCBOOK;
-
- /* Open file, exit on error */
- infile = fopen(filename, "r");
- if (infile == NULL) {
- fprintf(stderr, "docproc: ");
- perror(filename);
- exit(2);
- }
-
- if (strcmp("doc", subcommand) == 0) {
- if (file_format == FORMAT_RST) {
- time_t t = time(NULL);
- printf(".. generated from %s by docproc %s\n",
- filename, ctime(&t));
- }
-
- /* Need to do this in two passes.
- * First pass is used to collect all symbols exported
- * in the various files;
- * Second pass generate the documentation.
- * This is required because some functions are declared
- * and exported in different files :-((
- */
- /* Collect symbols */
- defaultline = noaction;
- internalfunctions = find_export_symbols;
- externalfunctions = find_export_symbols;
- symbolsonly = find_export_symbols;
- singlefunctions = noaction2;
- docsection = noaction2;
- findall = find_all_symbols;
- parse_file(infile);
-
- /* Rewind to start from beginning of file again */
- fseek(infile, 0, SEEK_SET);
- defaultline = printline;
- internalfunctions = intfunc;
- externalfunctions = extfunc;
- symbolsonly = printline;
- singlefunctions = singfunc;
- docsection = docsect;
- findall = NULL;
-
- parse_file(infile);
-
- for (i = 0; i < all_list_len; i++) {
- if (!all_list[i])
- continue;
- fprintf(stderr, "Warning: didn't use docs for %s\n",
- all_list[i]);
- }
- } else if (strcmp("depend", subcommand) == 0) {
- /* Create first part of dependency chain
- * file.tmpl */
- printf("%s\t", filename);
- defaultline = noaction;
- internalfunctions = adddep;
- externalfunctions = adddep;
- symbolsonly = adddep;
- singlefunctions = adddep2;
- docsection = adddep2;
- findall = adddep;
- parse_file(infile);
- printf("\n");
- } else {
- fprintf(stderr, "Unknown option: %s\n", subcommand);
- exit(1);
- }
- fclose(infile);
- fflush(stdout);
- return exitstatus;
-}
diff --git a/scripts/documentation-file-ref-check b/scripts/documentation-file-ref-check
new file mode 100755
index 000000000000..bc1659900e89
--- /dev/null
+++ b/scripts/documentation-file-ref-check
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Treewide grep for references to files under Documentation, and report
+# non-existing files in stderr.
+
+for f in $(git ls-files); do
+ for ref in $(grep -ho "Documentation/[A-Za-z0-9_.,~/*+-]*" "$f"); do
+ # presume trailing . and , are not part of the name
+ ref=${ref%%[.,]}
+
+ # use ls to handle wildcards
+ if ! ls $ref >/dev/null 2>&1; then
+ echo "$f: $ref" >&2
+ fi
+ done
+done
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 2a48022c41e7..0dc922bb7aea 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# scripts/dtc makefile
hostprogs-y := dtc
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 4b72b530c84f..e66138449886 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
while (size--)
reg = (reg << 32) | fdt32_to_cpu(*(cells++));
- snprintf(unit_addr, sizeof(unit_addr), "%zx", reg);
+ snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
if (!streq(unitname, unit_addr))
FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
node->fullpath, unit_addr);
@@ -956,6 +956,274 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
WARNING(obsolete_chosen_interrupt_controller,
check_obsolete_chosen_interrupt_controller, NULL);
+struct provider {
+ const char *prop_name;
+ const char *cell_name;
+ bool optional;
+};
+
+static void check_property_phandle_args(struct check *c,
+ struct dt_info *dti,
+ struct node *node,
+ struct property *prop,
+ const struct provider *provider)
+{
+ struct node *root = dti->dt;
+ int cell, cellsize = 0;
+
+ if (prop->val.len % sizeof(cell_t)) {
+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+ prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
+ return;
+ }
+
+ for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
+ struct node *provider_node;
+ struct property *cellprop;
+ int phandle;
+
+ phandle = propval_cell_n(prop, cell);
+ /*
+ * Some bindings use a cell value 0 or -1 to skip over optional
+ * entries when each index position has a specific definition.
+ */
+ if (phandle == 0 || phandle == -1) {
+ /* Give up if this is an overlay with external references */
+ if (dti->dtsflags & DTSF_PLUGIN)
+ break;
+
+ cellsize = 0;
+ continue;
+ }
+
+ /* If we have markers, verify the current cell is a phandle */
+ if (prop->val.markers) {
+ struct marker *m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ if (m->offset == (cell * sizeof(cell_t)))
+ break;
+ }
+ if (!m)
+ FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
+ prop->name, cell, node->fullpath);
+ }
+
+ provider_node = get_node_by_phandle(root, phandle);
+ if (!provider_node) {
+ FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
+ node->fullpath, prop->name, cell);
+ break;
+ }
+
+ cellprop = get_property(provider_node, provider->cell_name);
+ if (cellprop) {
+ cellsize = propval_cell(cellprop);
+ } else if (provider->optional) {
+ cellsize = 0;
+ } else {
+ FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
+ provider->cell_name,
+ provider_node->fullpath,
+ node->fullpath, prop->name, cell);
+ break;
+ }
+
+ if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
+ FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
+ prop->name, prop->val.len, cellsize, node->fullpath);
+ }
+ }
+}
+
+static void check_provider_cells_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct provider *provider = c->data;
+ struct property *prop;
+
+ prop = get_property(node, provider->prop_name);
+ if (!prop)
+ return;
+
+ check_property_phandle_args(c, dti, node, prop, provider);
+}
+#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
+ static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
+
+WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
+WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
+
+static bool prop_is_gpio(struct property *prop)
+{
+ char *str;
+
+ /*
+ * *-gpios and *-gpio can appear in property names,
+ * so skip over any false matches (only one known ATM)
+ */
+ if (strstr(prop->name, "nr-gpio"))
+ return false;
+
+ str = strrchr(prop->name, '-');
+ if (str)
+ str++;
+ else
+ str = prop->name;
+ if (!(streq(str, "gpios") || streq(str, "gpio")))
+ return false;
+
+ return true;
+}
+
+static void check_gpios_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ /* Skip GPIO hog nodes which have 'gpios' property */
+ if (get_property(node, "gpio-hog"))
+ return;
+
+ for_each_property(node, prop) {
+ struct provider provider;
+
+ if (!prop_is_gpio(prop))
+ continue;
+
+ provider.prop_name = prop->name;
+ provider.cell_name = "#gpio-cells";
+ provider.optional = false;
+ check_property_phandle_args(c, dti, node, prop, &provider);
+ }
+
+}
+WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
+
+static void check_deprecated_gpio_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ char *str;
+
+ if (!prop_is_gpio(prop))
+ continue;
+
+ str = strstr(prop->name, "gpio");
+ if (!streq(str, "gpio"))
+ continue;
+
+ FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
+ node->fullpath, prop->name);
+ }
+
+}
+CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
+
+static bool node_is_interrupt_provider(struct node *node)
+{
+ struct property *prop;
+
+ prop = get_property(node, "interrupt-controller");
+ if (prop)
+ return true;
+
+ prop = get_property(node, "interrupt-map");
+ if (prop)
+ return true;
+
+ return false;
+}
+static void check_interrupts_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct node *root = dti->dt;
+ struct node *irq_node = NULL, *parent = node;
+ struct property *irq_prop, *prop = NULL;
+ int irq_cells, phandle;
+
+ irq_prop = get_property(node, "interrupts");
+ if (!irq_prop)
+ return;
+
+ if (irq_prop->val.len % sizeof(cell_t))
+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+ irq_prop->name, irq_prop->val.len, sizeof(cell_t),
+ node->fullpath);
+
+ while (parent && !prop) {
+ if (parent != node && node_is_interrupt_provider(parent)) {
+ irq_node = parent;
+ break;
+ }
+
+ prop = get_property(parent, "interrupt-parent");
+ if (prop) {
+ phandle = propval_cell(prop);
+ /* Give up if this is an overlay with external references */
+ if ((phandle == 0 || phandle == -1) &&
+ (dti->dtsflags & DTSF_PLUGIN))
+ return;
+
+ irq_node = get_node_by_phandle(root, phandle);
+ if (!irq_node) {
+ FAIL(c, dti, "Bad interrupt-parent phandle for %s",
+ node->fullpath);
+ return;
+ }
+ if (!node_is_interrupt_provider(irq_node))
+ FAIL(c, dti,
+ "Missing interrupt-controller or interrupt-map property in %s",
+ irq_node->fullpath);
+
+ break;
+ }
+
+ parent = parent->parent;
+ }
+
+ if (!irq_node) {
+ FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
+ return;
+ }
+
+ prop = get_property(irq_node, "#interrupt-cells");
+ if (!prop) {
+ FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
+ irq_node->fullpath);
+ return;
+ }
+
+ irq_cells = propval_cell(prop);
+ if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
+ FAIL(c, dti,
+ "interrupts size is (%d), expected multiple of %d in %s",
+ irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
+ node->fullpath);
+ }
+}
+WARNING(interrupts_property, check_interrupts_property, &phandle_references);
+
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
&node_name_chars, &node_name_format, &property_name_chars,
@@ -987,6 +1255,27 @@ static struct check *check_table[] = {
&avoid_default_addr_size,
&obsolete_chosen_interrupt_controller,
+ &clocks_property,
+ &cooling_device_property,
+ &dmas_property,
+ &hwlocks_property,
+ &interrupts_extended_property,
+ &io_channels_property,
+ &iommus_property,
+ &mboxes_property,
+ &msi_parent_property,
+ &mux_controls_property,
+ &phys_property,
+ &power_domains_property,
+ &pwms_property,
+ &resets_property,
+ &sound_dais_property,
+ &thermal_sensors_property,
+
+ &deprecated_gpio_property,
+ &gpios_property,
+ &interrupts_property,
+
&always_fail,
};
diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config
index 9a248b505c58..5dfd1bff351f 100755
--- a/scripts/dtc/dt_to_config
+++ b/scripts/dtc/dt_to_config
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright 2016 by Frank Rowand
# Copyright 2016 by Gaurav Minocha
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 64c243772398..011bb9632ff2 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -1397,7 +1397,7 @@ static int yy_get_next_buffer (void)
{
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = (yytext_ptr);
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -1426,7 +1426,7 @@ static int yy_get_next_buffer (void)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1508,7 +1508,7 @@ static int yy_get_next_buffer (void)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
@@ -1987,10 +1987,10 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = (yy_size_t) _yybytes_len + 2;
+ n = (yy_size_t) (_yybytes_len + 2);
buf = (char *) yyalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index 0a7a5ed86f04..aea514fa6928 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -448,7 +448,7 @@ union yyalloc
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 30
/* YYNRULES -- Number of rules. */
-#define YYNRULES 84
+#define YYNRULES 85
/* YYNSTATES -- Number of states. */
#define YYNSTATES 149
@@ -499,14 +499,14 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint16 yyrline[] =
{
0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
- 153, 161, 165, 170, 181, 191, 206, 214, 217, 224,
- 228, 232, 236, 244, 248, 252, 256, 260, 276, 286,
- 294, 297, 301, 308, 324, 329, 348, 362, 369, 370,
- 371, 378, 382, 383, 387, 388, 392, 393, 397, 398,
- 402, 403, 407, 408, 412, 413, 414, 418, 419, 420,
- 421, 422, 426, 427, 428, 432, 433, 434, 438, 439,
- 448, 457, 461, 462, 463, 464, 469, 472, 476, 484,
- 487, 491, 499, 503, 507
+ 153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
+ 238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
+ 300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
+ 384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
+ 412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
+ 434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
+ 453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
+ 498, 501, 505, 513, 517, 521
};
#endif
@@ -582,20 +582,20 @@ static const yytype_int8 yypact[] =
static const yytype_uint8 yydefact[] =
{
0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
- 0, 7, 0, 38, 39, 0, 0, 10, 0, 2,
- 8, 4, 0, 0, 0, 72, 0, 41, 42, 44,
- 46, 48, 50, 52, 54, 57, 64, 67, 71, 0,
- 17, 11, 0, 0, 0, 0, 73, 74, 75, 40,
+ 16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
+ 8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
+ 47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
+ 18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
- 79, 0, 0, 14, 12, 45, 0, 47, 49, 51,
- 53, 55, 56, 60, 61, 59, 58, 62, 63, 65,
- 66, 69, 68, 70, 0, 0, 0, 0, 18, 0,
- 79, 15, 13, 0, 0, 0, 20, 30, 82, 22,
- 84, 0, 81, 80, 43, 21, 83, 0, 0, 16,
- 29, 19, 31, 0, 23, 32, 26, 0, 76, 34,
- 0, 0, 0, 0, 37, 36, 24, 35, 33, 0,
- 77, 78, 25, 0, 28, 0, 0, 0, 27
+ 80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
+ 54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
+ 67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
+ 80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
+ 85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
+ 30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
+ 0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
+ 78, 79, 26, 0, 29, 0, 0, 0, 28
};
/* YYPGOTO[NTERM-NUM]. */
@@ -678,28 +678,28 @@ static const yytype_uint8 yystos[] =
static const yytype_uint8 yyr1[] =
{
0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
- 53, 54, 54, 54, 54, 54, 55, 56, 56, 57,
- 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
- 59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
- 61, 62, 63, 63, 64, 64, 65, 65, 66, 66,
- 67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
- 70, 70, 71, 71, 71, 72, 72, 72, 73, 73,
- 73, 73, 74, 74, 74, 74, 75, 75, 75, 76,
- 76, 76, 77, 77, 77
+ 53, 54, 54, 54, 54, 54, 54, 55, 56, 56,
+ 57, 57, 57, 57, 58, 58, 58, 58, 58, 58,
+ 58, 59, 59, 59, 60, 60, 60, 60, 60, 61,
+ 61, 61, 62, 63, 63, 64, 64, 65, 65, 66,
+ 66, 67, 67, 68, 68, 69, 69, 69, 70, 70,
+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 73,
+ 73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
+ 76, 76, 76, 77, 77, 77
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
- 2, 2, 3, 4, 3, 4, 5, 0, 2, 4,
- 2, 3, 2, 2, 3, 4, 2, 9, 5, 2,
- 0, 2, 2, 3, 1, 2, 2, 2, 1, 1,
- 3, 1, 1, 5, 1, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 3, 3, 1, 3, 3,
- 3, 3, 3, 3, 1, 3, 3, 1, 3, 3,
- 3, 1, 1, 2, 2, 2, 0, 2, 2, 0,
- 2, 2, 2, 3, 2
+ 2, 2, 3, 4, 3, 4, 0, 5, 0, 2,
+ 4, 2, 3, 2, 2, 3, 4, 2, 9, 5,
+ 2, 0, 2, 2, 3, 1, 2, 2, 2, 1,
+ 1, 3, 1, 1, 5, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
+ 3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
+ 3, 3, 1, 1, 2, 2, 2, 0, 2, 2,
+ 0, 2, 2, 2, 3, 2
};
@@ -1572,17 +1572,26 @@ yyreduce:
{
struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
- if (target)
+ if (target) {
merge_nodes(target, (yyvsp[0].node));
- else
- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ } else {
+ /*
+ * We rely on the rule being always:
+ * versioninfo plugindecl memreserves devicetree
+ * so $-1 is what we want (plugindecl)
+ */
+ if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
+ add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
+ else
+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ }
(yyval.node) = (yyvsp[-2].node);
}
-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 15:
-#line 192 "dtc-parser.y" /* yacc.c:1646 */
+#line 201 "dtc-parser.y" /* yacc.c:1646 */
{
struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
@@ -1594,100 +1603,109 @@ yyreduce:
(yyval.node) = (yyvsp[-3].node);
}
-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 16:
-#line 207 "dtc-parser.y" /* yacc.c:1646 */
+#line 213 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
+ /* build empty node */
+ (yyval.node) = name_node(build_node(NULL, NULL), "");
}
-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 17:
-#line 214 "dtc-parser.y" /* yacc.c:1646 */
+#line 221 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.proplist) = NULL;
+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
}
-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 18:
-#line 218 "dtc-parser.y" /* yacc.c:1646 */
+#line 228 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
+ (yyval.proplist) = NULL;
}
-#line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 19:
-#line 225 "dtc-parser.y" /* yacc.c:1646 */
+#line 232 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
}
-#line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 20:
-#line 229 "dtc-parser.y" /* yacc.c:1646 */
+#line 239 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
}
-#line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 21:
-#line 233 "dtc-parser.y" /* yacc.c:1646 */
+#line 243 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
}
-#line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 22:
-#line 237 "dtc-parser.y" /* yacc.c:1646 */
+#line 247 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ }
+#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 251 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
(yyval.prop) = (yyvsp[0].prop);
}
-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 23:
-#line 245 "dtc-parser.y" /* yacc.c:1646 */
+ case 24:
+#line 259 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
}
-#line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 24:
-#line 249 "dtc-parser.y" /* yacc.c:1646 */
+ case 25:
+#line 263 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
}
-#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 25:
-#line 253 "dtc-parser.y" /* yacc.c:1646 */
+ case 26:
+#line 267 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
}
-#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 26:
-#line 257 "dtc-parser.y" /* yacc.c:1646 */
+ case 27:
+#line 271 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
}
-#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 27:
-#line 261 "dtc-parser.y" /* yacc.c:1646 */
+ case 28:
+#line 275 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
struct data d;
@@ -1703,11 +1721,11 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-8].data), d);
fclose(f);
}
-#line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 28:
-#line 277 "dtc-parser.y" /* yacc.c:1646 */
+ case 29:
+#line 291 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
struct data d = empty_data;
@@ -1717,43 +1735,43 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-4].data), d);
fclose(f);
}
-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 29:
-#line 287 "dtc-parser.y" /* yacc.c:1646 */
+ case 30:
+#line 301 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 30:
-#line 294 "dtc-parser.y" /* yacc.c:1646 */
+ case 31:
+#line 308 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
-#line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 31:
-#line 298 "dtc-parser.y" /* yacc.c:1646 */
+ case 32:
+#line 312 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = (yyvsp[-1].data);
}
-#line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 32:
-#line 302 "dtc-parser.y" /* yacc.c:1646 */
+ case 33:
+#line 316 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 33:
-#line 309 "dtc-parser.y" /* yacc.c:1646 */
+ case 34:
+#line 323 "dtc-parser.y" /* yacc.c:1646 */
{
unsigned long long bits;
@@ -1769,20 +1787,20 @@ yyreduce:
(yyval.array).data = empty_data;
(yyval.array).bits = bits;
}
-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 34:
-#line 325 "dtc-parser.y" /* yacc.c:1646 */
+ case 35:
+#line 339 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = empty_data;
(yyval.array).bits = 32;
}
-#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 35:
-#line 330 "dtc-parser.y" /* yacc.c:1646 */
+ case 36:
+#line 344 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[-1].array).bits < 64) {
uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1801,11 +1819,11 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
}
-#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 36:
-#line 349 "dtc-parser.y" /* yacc.c:1646 */
+ case 37:
+#line 363 "dtc-parser.y" /* yacc.c:1646 */
{
uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
@@ -1819,129 +1837,129 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
}
-#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 37:
-#line 363 "dtc-parser.y" /* yacc.c:1646 */
+ case 38:
+#line 377 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
}
-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 40:
-#line 372 "dtc-parser.y" /* yacc.c:1646 */
+ case 41:
+#line 386 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.integer) = (yyvsp[-1].integer);
}
-#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 43:
-#line 383 "dtc-parser.y" /* yacc.c:1646 */
+ case 44:
+#line 397 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 45:
-#line 388 "dtc-parser.y" /* yacc.c:1646 */
+ case 46:
+#line 402 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 47:
-#line 393 "dtc-parser.y" /* yacc.c:1646 */
+ case 48:
+#line 407 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 49:
-#line 398 "dtc-parser.y" /* yacc.c:1646 */
+ case 50:
+#line 412 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 51:
-#line 403 "dtc-parser.y" /* yacc.c:1646 */
+ case 52:
+#line 417 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 53:
-#line 408 "dtc-parser.y" /* yacc.c:1646 */
+ case 54:
+#line 422 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 55:
-#line 413 "dtc-parser.y" /* yacc.c:1646 */
+ case 56:
+#line 427 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 56:
-#line 414 "dtc-parser.y" /* yacc.c:1646 */
+ case 57:
+#line 428 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 58:
-#line 419 "dtc-parser.y" /* yacc.c:1646 */
+ case 59:
+#line 433 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 59:
-#line 420 "dtc-parser.y" /* yacc.c:1646 */
+ case 60:
+#line 434 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 60:
-#line 421 "dtc-parser.y" /* yacc.c:1646 */
+ case 61:
+#line 435 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 61:
-#line 422 "dtc-parser.y" /* yacc.c:1646 */
+ case 62:
+#line 436 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 62:
-#line 426 "dtc-parser.y" /* yacc.c:1646 */
+ case 63:
+#line 440 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 63:
-#line 427 "dtc-parser.y" /* yacc.c:1646 */
+ case 64:
+#line 441 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 65:
-#line 432 "dtc-parser.y" /* yacc.c:1646 */
+ case 66:
+#line 446 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 66:
-#line 433 "dtc-parser.y" /* yacc.c:1646 */
+ case 67:
+#line 447 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 68:
-#line 438 "dtc-parser.y" /* yacc.c:1646 */
+ case 69:
+#line 452 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 69:
-#line 440 "dtc-parser.y" /* yacc.c:1646 */
+ case 70:
+#line 454 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1950,11 +1968,11 @@ yyreduce:
(yyval.integer) = 0;
}
}
-#line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 70:
-#line 449 "dtc-parser.y" /* yacc.c:1646 */
+ case 71:
+#line 463 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1963,103 +1981,103 @@ yyreduce:
(yyval.integer) = 0;
}
}
-#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 73:
-#line 462 "dtc-parser.y" /* yacc.c:1646 */
+ case 74:
+#line 476 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = -(yyvsp[0].integer); }
-#line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 74:
-#line 463 "dtc-parser.y" /* yacc.c:1646 */
+ case 75:
+#line 477 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 75:
-#line 464 "dtc-parser.y" /* yacc.c:1646 */
+ case 76:
+#line 478 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = !(yyvsp[0].integer); }
-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 76:
-#line 469 "dtc-parser.y" /* yacc.c:1646 */
+ case 77:
+#line 483 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 77:
-#line 473 "dtc-parser.y" /* yacc.c:1646 */
+ case 78:
+#line 487 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
}
-#line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 78:
-#line 477 "dtc-parser.y" /* yacc.c:1646 */
+ case 79:
+#line 491 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 79:
-#line 484 "dtc-parser.y" /* yacc.c:1646 */
+ case 80:
+#line 498 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = NULL;
}
-#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 80:
-#line 488 "dtc-parser.y" /* yacc.c:1646 */
+ case 81:
+#line 502 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
}
-#line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 81:
-#line 492 "dtc-parser.y" /* yacc.c:1646 */
+ case 82:
+#line 506 "dtc-parser.y" /* yacc.c:1646 */
{
ERROR(&(yylsp[0]), "Properties must precede subnodes");
YYERROR;
}
-#line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 82:
-#line 500 "dtc-parser.y" /* yacc.c:1646 */
+ case 83:
+#line 514 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
}
-#line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 83:
-#line 504 "dtc-parser.y" /* yacc.c:1646 */
+ case 84:
+#line 518 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
}
-#line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 84:
-#line 508 "dtc-parser.y" /* yacc.c:1646 */
+ case 85:
+#line 522 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
(yyval.node) = (yyvsp[0].node);
}
-#line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
-#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -2294,7 +2312,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 514 "dtc-parser.y" /* yacc.c:1906 */
+#line 528 "dtc-parser.y" /* yacc.c:1906 */
void yyerror(char const *s)
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index ca3f5003427c..affc81a8f9ab 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -182,10 +182,19 @@ devicetree:
{
struct node *target = get_node_by_ref($1, $2);
- if (target)
+ if (target) {
merge_nodes(target, $3);
- else
- ERROR(&@2, "Label or path %s not found", $2);
+ } else {
+ /*
+ * We rely on the rule being always:
+ * versioninfo plugindecl memreserves devicetree
+ * so $-1 is what we want (plugindecl)
+ */
+ if ($<flags>-1 & DTSF_PLUGIN)
+ add_orphan_node($1, $3, $2);
+ else
+ ERROR(&@2, "Label or path %s not found", $2);
+ }
$$ = $1;
}
| devicetree DT_DEL_NODE DT_REF ';'
@@ -200,6 +209,11 @@ devicetree:
$$ = $1;
}
+ | /* empty */
+ {
+ /* build empty node */
+ $$ = name_node(build_node(NULL, NULL), "");
+ }
;
nodedef:
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index f5eed9d72c02..5ed873c72ad1 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -31,7 +31,7 @@ int reservenum; /* Number of memory reservation slots */
int minsize; /* Minimum blob size */
int padsize; /* Additional padding to blob */
int alignsize; /* Additional padding to blob accroding to the alignsize */
-int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
+int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */
int auto_label_aliases; /* auto generate labels -> aliases */
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index fc24e17510fd..35cf926cc14a 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -31,6 +31,7 @@
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
+#include <inttypes.h>
#include <libfdt_env.h>
#include <fdt.h>
@@ -202,6 +203,7 @@ struct node *build_node_delete(void);
struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
struct node *merge_nodes(struct node *old_node, struct node *new_node);
+void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
void add_property(struct node *node, struct property *prop);
void delete_property_by_name(struct node *node, char *name);
@@ -215,6 +217,7 @@ void append_to_property(struct node *node,
const char *get_unitname(struct node *node);
struct property *get_property(struct node *node, const char *propname);
cell_t propval_cell(struct property *prop);
+cell_t propval_cell_n(struct property *prop, int n);
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node);
struct marker *get_marker_label(struct node *tree, const char *label,
diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff
index ec47f95991a3..8c4fbad2055e 100755
--- a/scripts/dtc/dtx_diff
+++ b/scripts/dtc/dtx_diff
@@ -86,6 +86,7 @@ eod
compile_to_dts() {
dtx="$1"
+ dtc_include="$2"
if [ -d "${dtx}" ] ; then
@@ -113,7 +114,7 @@ compile_to_dts() {
# ----- input is DTS (source)
if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \
- | ${DTC} -I dts ) ; then
+ | ${DTC} ${dtc_include} -I dts ) ; then
return
fi
@@ -320,30 +321,25 @@ fi
cpp_flags="\
-nostdinc \
- -I${srctree}/arch/${ARCH}/boot/dts \
- -I${srctree}/arch/${ARCH}/boot/dts/include \
- -I${srctree}/drivers/of/testcase-data \
+ -I${srctree}/scripts/dtc/include-prefixes \
-undef -D__DTS__"
-dtc_flags="\
- -i ${srctree}/arch/${ARCH}/boot/dts/ \
- -i ${srctree}/kernel/dts \
- ${dtx_path_1_dtc_include} \
- ${dtx_path_2_dtc_include}"
-
-DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -"
+DTC="\
+ ${DTC} \
+ -i ${srctree}/scripts/dtc/include-prefixes \
+ -O dts -qq -f ${dtc_sort} -o -"
# ----- do the diff or decompile
if (( ${cmd_diff} )) ; then
- diff ${diff_flags} \
- <(compile_to_dts "${dtx_file_1}") \
- <(compile_to_dts "${dtx_file_2}")
+ diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \
+ <(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \
+ <(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}")
else
- compile_to_dts "${dtx_file_1}"
+ compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}"
fi
diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c
index 207a46d64864..7d460a50b513 100644
--- a/scripts/dtc/fdtdump.c
+++ b/scripts/dtc/fdtdump.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
*/
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
new file mode 100644
index 000000000000..eff4dbcc729d
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -0,0 +1,96 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+ const fdt32_t *ac;
+ int val;
+ int len;
+
+ ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
+ if (!ac)
+ return 2;
+
+ if (len != sizeof(*ac))
+ return -FDT_ERR_BADNCELLS;
+
+ val = fdt32_to_cpu(*ac);
+ if ((val <= 0) || (val > FDT_MAX_NCELLS))
+ return -FDT_ERR_BADNCELLS;
+
+ return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+ const fdt32_t *sc;
+ int val;
+ int len;
+
+ sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
+ if (!sc)
+ return 2;
+
+ if (len != sizeof(*sc))
+ return -FDT_ERR_BADNCELLS;
+
+ val = fdt32_to_cpu(*sc);
+ if ((val < 0) || (val > FDT_MAX_NCELLS))
+ return -FDT_ERR_BADNCELLS;
+
+ return val;
+}
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
index f72d13b1d19c..f2ae9b77c285 100644
--- a/scripts/dtc/libfdt/fdt_empty_tree.c
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize)
return fdt_open_into(buf, buf, bufsize);
}
-
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
new file mode 100644
index 000000000000..bd81241e6658
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -0,0 +1,861 @@
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+/**
+ * overlay_get_target_phandle - retrieves the target phandle of a fragment
+ * @fdto: pointer to the device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ *
+ * overlay_get_target_phandle() retrieves the target phandle of an
+ * overlay fragment when that fragment uses a phandle (target
+ * property) instead of a path (target-path property).
+ *
+ * returns:
+ * the phandle pointed by the target property
+ * 0, if the phandle was not found
+ * -1, if the phandle was malformed
+ */
+static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
+{
+ const fdt32_t *val;
+ int len;
+
+ val = fdt_getprop(fdto, fragment, "target", &len);
+ if (!val)
+ return 0;
+
+ if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
+ return (uint32_t)-1;
+
+ return fdt32_to_cpu(*val);
+}
+
+/**
+ * overlay_get_target - retrieves the offset of a fragment's target
+ * @fdt: Base device tree blob
+ * @fdto: Device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
+ *
+ * overlay_get_target() retrieves the target offset in the base
+ * device tree of a fragment, no matter how the actual targetting is
+ * done (through a phandle or a path)
+ *
+ * returns:
+ * the targetted node offset in the base device tree
+ * Negative error code on error
+ */
+static int overlay_get_target(const void *fdt, const void *fdto,
+ int fragment, char const **pathp)
+{
+ uint32_t phandle;
+ const char *path = NULL;
+ int path_len = 0, ret;
+
+ /* Try first to do a phandle based lookup */
+ phandle = overlay_get_target_phandle(fdto, fragment);
+ if (phandle == (uint32_t)-1)
+ return -FDT_ERR_BADPHANDLE;
+
+ /* no phandle, try path */
+ if (!phandle) {
+ /* And then a path based lookup */
+ path = fdt_getprop(fdto, fragment, "target-path", &path_len);
+ if (path)
+ ret = fdt_path_offset(fdt, path);
+ else
+ ret = path_len;
+ } else
+ ret = fdt_node_offset_by_phandle(fdt, phandle);
+
+ /*
+ * If we haven't found either a target or a
+ * target-path property in a node that contains a
+ * __overlay__ subnode (we wouldn't be called
+ * otherwise), consider it a improperly written
+ * overlay
+ */
+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
+ ret = -FDT_ERR_BADOVERLAY;
+
+ /* return on error */
+ if (ret < 0)
+ return ret;
+
+ /* return pointer to path (if available) */
+ if (pathp)
+ *pathp = path ? path : NULL;
+
+ return ret;
+}
+
+/**
+ * overlay_phandle_add_offset - Increases a phandle by an offset
+ * @fdt: Base device tree blob
+ * @node: Device tree overlay blob
+ * @name: Name of the property to modify (phandle or linux,phandle)
+ * @delta: offset to apply
+ *
+ * overlay_phandle_add_offset() increments a node phandle by a given
+ * offset.
+ *
+ * returns:
+ * 0 on success.
+ * Negative error code on error
+ */
+static int overlay_phandle_add_offset(void *fdt, int node,
+ const char *name, uint32_t delta)
+{
+ const fdt32_t *val;
+ uint32_t adj_val;
+ int len;
+
+ val = fdt_getprop(fdt, node, name, &len);
+ if (!val)
+ return len;
+
+ if (len != sizeof(*val))
+ return -FDT_ERR_BADPHANDLE;
+
+ adj_val = fdt32_to_cpu(*val);
+ if ((adj_val + delta) < adj_val)
+ return -FDT_ERR_NOPHANDLES;
+
+ adj_val += delta;
+ if (adj_val == (uint32_t)-1)
+ return -FDT_ERR_NOPHANDLES;
+
+ return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
+}
+
+/**
+ * overlay_adjust_node_phandles - Offsets the phandles of a node
+ * @fdto: Device tree overlay blob
+ * @node: Offset of the node we want to adjust
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_node_phandles() adds a constant to all the phandles
+ * of a given node. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_adjust_node_phandles(void *fdto, int node,
+ uint32_t delta)
+{
+ int child;
+ int ret;
+
+ ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ return ret;
+
+ ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ return ret;
+
+ fdt_for_each_subnode(child, fdto, node) {
+ ret = overlay_adjust_node_phandles(fdto, child, delta);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_local_phandles() adds a constant to all the
+ * phandles of an overlay. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
+{
+ /*
+ * Start adjusting the phandles from the overlay root
+ */
+ return overlay_adjust_node_phandles(fdto, 0, delta);
+}
+
+/**
+ * overlay_update_local_node_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @tree_node: Node offset of the node to operate on
+ * @fixup_node: Node offset of the matching local fixups node
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_nodes_references() update the phandles
+ * pointing to a node within the device tree overlay by adding a
+ * constant delta.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_update_local_node_references(void *fdto,
+ int tree_node,
+ int fixup_node,
+ uint32_t delta)
+{
+ int fixup_prop;
+ int fixup_child;
+ int ret;
+
+ fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
+ const fdt32_t *fixup_val;
+ const char *tree_val;
+ const char *name;
+ int fixup_len;
+ int tree_len;
+ int i;
+
+ fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
+ &name, &fixup_len);
+ if (!fixup_val)
+ return fixup_len;
+
+ if (fixup_len % sizeof(uint32_t))
+ return -FDT_ERR_BADOVERLAY;
+
+ tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
+ if (!tree_val) {
+ if (tree_len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+
+ return tree_len;
+ }
+
+ for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
+ fdt32_t adj_val;
+ uint32_t poffset;
+
+ poffset = fdt32_to_cpu(fixup_val[i]);
+
+ /*
+ * phandles to fixup can be unaligned.
+ *
+ * Use a memcpy for the architectures that do
+ * not support unaligned accesses.
+ */
+ memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
+
+ adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
+
+ ret = fdt_setprop_inplace_namelen_partial(fdto,
+ tree_node,
+ name,
+ strlen(name),
+ poffset,
+ &adj_val,
+ sizeof(adj_val));
+ if (ret == -FDT_ERR_NOSPACE)
+ return -FDT_ERR_BADOVERLAY;
+
+ if (ret)
+ return ret;
+ }
+ }
+
+ fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
+ const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
+ NULL);
+ int tree_child;
+
+ tree_child = fdt_subnode_offset(fdto, tree_node,
+ fixup_child_name);
+ if (tree_child == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+ if (tree_child < 0)
+ return tree_child;
+
+ ret = overlay_update_local_node_references(fdto,
+ tree_child,
+ fixup_child,
+ delta);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_update_local_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_references() update all the phandles pointing
+ * to a node within the device tree overlay by adding a constant
+ * delta to not conflict with the base overlay.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_update_local_references(void *fdto, uint32_t delta)
+{
+ int fixups;
+
+ fixups = fdt_path_offset(fdto, "/__local_fixups__");
+ if (fixups < 0) {
+ /* There's no local phandles to adjust, bail out */
+ if (fixups == -FDT_ERR_NOTFOUND)
+ return 0;
+
+ return fixups;
+ }
+
+ /*
+ * Update our local references from the root of the tree
+ */
+ return overlay_update_local_node_references(fdto, 0, fixups,
+ delta);
+}
+
+/**
+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @path: Path to a node holding a phandle in the overlay
+ * @path_len: number of path characters to consider
+ * @name: Name of the property holding the phandle reference in the overlay
+ * @name_len: number of name characters to consider
+ * @poffset: Offset within the overlay property where the phandle is stored
+ * @label: Label of the node referenced by the phandle
+ *
+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
+ * a node in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_one_phandle(void *fdt, void *fdto,
+ int symbols_off,
+ const char *path, uint32_t path_len,
+ const char *name, uint32_t name_len,
+ int poffset, const char *label)
+{
+ const char *symbol_path;
+ uint32_t phandle;
+ fdt32_t phandle_prop;
+ int symbol_off, fixup_off;
+ int prop_len;
+
+ if (symbols_off < 0)
+ return symbols_off;
+
+ symbol_path = fdt_getprop(fdt, symbols_off, label,
+ &prop_len);
+ if (!symbol_path)
+ return prop_len;
+
+ symbol_off = fdt_path_offset(fdt, symbol_path);
+ if (symbol_off < 0)
+ return symbol_off;
+
+ phandle = fdt_get_phandle(fdt, symbol_off);
+ if (!phandle)
+ return -FDT_ERR_NOTFOUND;
+
+ fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
+ if (fixup_off == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+ if (fixup_off < 0)
+ return fixup_off;
+
+ phandle_prop = cpu_to_fdt32(phandle);
+ return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
+ name, name_len, poffset,
+ &phandle_prop,
+ sizeof(phandle_prop));
+};
+
+/**
+ * overlay_fixup_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @property: Property offset in the overlay holding the list of fixups
+ *
+ * overlay_fixup_phandle() resolves all the overlay phandles pointed
+ * to in a __fixups__ property, and updates them to match the phandles
+ * in use in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
+ int property)
+{
+ const char *value;
+ const char *label;
+ int len;
+
+ value = fdt_getprop_by_offset(fdto, property,
+ &label, &len);
+ if (!value) {
+ if (len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+
+ return len;
+ }
+
+ do {
+ const char *path, *name, *fixup_end;
+ const char *fixup_str = value;
+ uint32_t path_len, name_len;
+ uint32_t fixup_len;
+ char *sep, *endptr;
+ int poffset, ret;
+
+ fixup_end = memchr(value, '\0', len);
+ if (!fixup_end)
+ return -FDT_ERR_BADOVERLAY;
+ fixup_len = fixup_end - fixup_str;
+
+ len -= fixup_len + 1;
+ value += fixup_len + 1;
+
+ path = fixup_str;
+ sep = memchr(fixup_str, ':', fixup_len);
+ if (!sep || *sep != ':')
+ return -FDT_ERR_BADOVERLAY;
+
+ path_len = sep - path;
+ if (path_len == (fixup_len - 1))
+ return -FDT_ERR_BADOVERLAY;
+
+ fixup_len -= path_len + 1;
+ name = sep + 1;
+ sep = memchr(name, ':', fixup_len);
+ if (!sep || *sep != ':')
+ return -FDT_ERR_BADOVERLAY;
+
+ name_len = sep - name;
+ if (!name_len)
+ return -FDT_ERR_BADOVERLAY;
+
+ poffset = strtoul(sep + 1, &endptr, 10);
+ if ((*endptr != '\0') || (endptr <= (sep + 1)))
+ return -FDT_ERR_BADOVERLAY;
+
+ ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
+ path, path_len, name, name_len,
+ poffset, label);
+ if (ret)
+ return ret;
+ } while (len > 0);
+
+ return 0;
+}
+
+/**
+ * overlay_fixup_phandles - Resolve the overlay phandles to the base
+ * device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_fixup_phandles() resolves all the overlay phandles pointing
+ * to nodes in the base device tree.
+ *
+ * This is one of the steps of the device tree overlay application
+ * process, when you want all the phandles in the overlay to point to
+ * the actual base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_phandles(void *fdt, void *fdto)
+{
+ int fixups_off, symbols_off;
+ int property;
+
+ /* We can have overlays without any fixups */
+ fixups_off = fdt_path_offset(fdto, "/__fixups__");
+ if (fixups_off == -FDT_ERR_NOTFOUND)
+ return 0; /* nothing to do */
+ if (fixups_off < 0)
+ return fixups_off;
+
+ /* And base DTs without symbols */
+ symbols_off = fdt_path_offset(fdt, "/__symbols__");
+ if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
+ return symbols_off;
+
+ fdt_for_each_property_offset(property, fdto, fixups_off) {
+ int ret;
+
+ ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_apply_node - Merges a node into the base device tree
+ * @fdt: Base Device Tree blob
+ * @target: Node offset in the base device tree to apply the fragment to
+ * @fdto: Device tree overlay blob
+ * @node: Node offset in the overlay holding the changes to merge
+ *
+ * overlay_apply_node() merges a node into a target base device tree
+ * node pointed.
+ *
+ * This is part of the final step in the device tree overlay
+ * application process, when all the phandles have been adjusted and
+ * resolved and you just have to merge overlay into the base device
+ * tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_apply_node(void *fdt, int target,
+ void *fdto, int node)
+{
+ int property;
+ int subnode;
+
+ fdt_for_each_property_offset(property, fdto, node) {
+ const char *name;
+ const void *prop;
+ int prop_len;
+ int ret;
+
+ prop = fdt_getprop_by_offset(fdto, property, &name,
+ &prop_len);
+ if (prop_len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ if (prop_len < 0)
+ return prop_len;
+
+ ret = fdt_setprop(fdt, target, name, prop, prop_len);
+ if (ret)
+ return ret;
+ }
+
+ fdt_for_each_subnode(subnode, fdto, node) {
+ const char *name = fdt_get_name(fdto, subnode, NULL);
+ int nnode;
+ int ret;
+
+ nnode = fdt_add_subnode(fdt, target, name);
+ if (nnode == -FDT_ERR_EXISTS) {
+ nnode = fdt_subnode_offset(fdt, target, name);
+ if (nnode == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ }
+
+ if (nnode < 0)
+ return nnode;
+
+ ret = overlay_apply_node(fdt, nnode, fdto, subnode);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_merge - Merge an overlay into its base device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_merge() merges an overlay into its base device tree.
+ *
+ * This is the next to last step in the device tree overlay application
+ * process, when all the phandles have been adjusted and resolved and
+ * you just have to merge overlay into the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_merge(void *fdt, void *fdto)
+{
+ int fragment;
+
+ fdt_for_each_subnode(fragment, fdto, 0) {
+ int overlay;
+ int target;
+ int ret;
+
+ /*
+ * Each fragments will have an __overlay__ node. If
+ * they don't, it's not supposed to be merged
+ */
+ overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (overlay == -FDT_ERR_NOTFOUND)
+ continue;
+
+ if (overlay < 0)
+ return overlay;
+
+ target = overlay_get_target(fdt, fdto, fragment, NULL);
+ if (target < 0)
+ return target;
+
+ ret = overlay_apply_node(fdt, target, fdto, overlay);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int get_path_len(const void *fdt, int nodeoffset)
+{
+ int len = 0, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (;;) {
+ name = fdt_get_name(fdt, nodeoffset, &namelen);
+ if (!name)
+ return namelen;
+
+ /* root? we're done */
+ if (namelen == 0)
+ break;
+
+ nodeoffset = fdt_parent_offset(fdt, nodeoffset);
+ if (nodeoffset < 0)
+ return nodeoffset;
+ len += namelen + 1;
+ }
+
+ /* in case of root pretend it's "/" */
+ if (len == 0)
+ len++;
+ return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_symbol_update(void *fdt, void *fdto)
+{
+ int root_sym, ov_sym, prop, path_len, fragment, target;
+ int len, frag_name_len, ret, rel_path_len;
+ const char *s, *e;
+ const char *path;
+ const char *name;
+ const char *frag_name;
+ const char *rel_path;
+ const char *target_path;
+ char *buf;
+ void *p;
+
+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
+
+ /* if no overlay symbols exist no problem */
+ if (ov_sym < 0)
+ return 0;
+
+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
+
+ /* it no root symbols exist we should create them */
+ if (root_sym == -FDT_ERR_NOTFOUND)
+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
+
+ /* any error is fatal now */
+ if (root_sym < 0)
+ return root_sym;
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset(prop, fdto, ov_sym) {
+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
+ if (!path)
+ return path_len;
+
+ /* verify it's a string property (terminated by a single \0) */
+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
+ return -FDT_ERR_BADVALUE;
+
+ /* keep end marker to avoid strlen() */
+ e = path + path_len;
+
+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+ if (*path != '/')
+ return -FDT_ERR_BADVALUE;
+
+ /* get fragment name first */
+ s = strchr(path + 1, '/');
+ if (!s)
+ return -FDT_ERR_BADOVERLAY;
+
+ frag_name = path + 1;
+ frag_name_len = s - path - 1;
+
+ /* verify format; safe since "s" lies in \0 terminated prop */
+ len = sizeof("/__overlay__/") - 1;
+ if ((e - s) < len || memcmp(s, "/__overlay__/", len))
+ return -FDT_ERR_BADOVERLAY;
+
+ rel_path = s + len;
+ rel_path_len = e - rel_path;
+
+ /* find the fragment index in which the symbol lies */
+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
+ frag_name_len);
+ /* not found? */
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+ fragment = ret;
+
+ /* an __overlay__ subnode must exist */
+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+
+ /* get the target of the fragment */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+
+ /* if we have a target path use */
+ if (!target_path) {
+ ret = get_path_len(fdt, target);
+ if (ret < 0)
+ return ret;
+ len = ret;
+ } else {
+ len = strlen(target_path);
+ }
+
+ ret = fdt_setprop_placeholder(fdt, root_sym, name,
+ len + (len > 1) + rel_path_len + 1, &p);
+ if (ret < 0)
+ return ret;
+
+ if (!target_path) {
+ /* again in case setprop_placeholder changed it */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+ }
+
+ buf = p;
+ if (len > 1) { /* target is not root */
+ if (!target_path) {
+ ret = fdt_get_path(fdt, target, buf, len + 1);
+ if (ret < 0)
+ return ret;
+ } else
+ memcpy(buf, target_path, len + 1);
+
+ } else
+ len--;
+
+ buf[len] = '/';
+ memcpy(buf + len + 1, rel_path, rel_path_len);
+ buf[len + 1 + rel_path_len] = '\0';
+ }
+
+ return 0;
+}
+
+int fdt_overlay_apply(void *fdt, void *fdto)
+{
+ uint32_t delta = fdt_get_max_phandle(fdt);
+ int ret;
+
+ FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER(fdto);
+
+ ret = overlay_adjust_local_phandles(fdto, delta);
+ if (ret)
+ goto err;
+
+ ret = overlay_update_local_references(fdto, delta);
+ if (ret)
+ goto err;
+
+ ret = overlay_fixup_phandles(fdt, fdto);
+ if (ret)
+ goto err;
+
+ ret = overlay_merge(fdt, fdto);
+ if (ret)
+ goto err;
+
+ ret = overlay_symbol_update(fdt, fdto);
+ if (ret)
+ goto err;
+
+ /*
+ * The overlay has been damaged, erase its magic.
+ */
+ fdt_set_magic(fdto, ~0);
+
+ return 0;
+
+err:
+ /*
+ * The overlay might have been damaged, erase its magic.
+ */
+ fdt_set_magic(fdto, ~0);
+
+ /*
+ * The base device tree might have been damaged, erase its
+ * magic.
+ */
+ fdt_set_magic(fdt, ~0);
+
+ return ret;
+}
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 3d00d2eee0e3..08de2cce674d 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset,
{
const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
- if (! p)
+ if (!p)
/* short match */
return 0;
@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
const struct fdt_property *prop;
prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (! prop)
+ if (!prop)
return NULL;
return prop->data;
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 3fd5847377c9..5c3a2bb0bc6b 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
int err;
*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (! (*prop))
+ if (!*prop)
return oldlen;
if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
@@ -269,8 +269,8 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data)
{
struct fdt_property *prop;
int err;
@@ -283,8 +283,22 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
if (err)
return err;
+ *prop_data = prop->data;
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *prop_data;
+ int err;
+
+ err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
+ if (err)
+ return err;
+
if (len)
- memcpy(prop->data, val, len);
+ memcpy(prop_data, val, len);
return 0;
}
@@ -323,7 +337,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
FDT_RW_CHECK_HEADER(fdt);
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
+ if (!prop)
return len;
proplen = sizeof(*prop) + FDT_TAGALIGN(len);
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 6a804859fd0c..2bd15e7aef87 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
return offset;
}
-int fdt_property(void *fdt, const char *name, const void *val, int len)
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
{
struct fdt_property *prop;
int nameoff;
@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
prop->tag = cpu_to_fdt32(FDT_PROP);
prop->nameoff = cpu_to_fdt32(nameoff);
prop->len = cpu_to_fdt32(len);
- memcpy(prop->data, val, len);
+ *valp = prop->data;
+ return 0;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ void *ptr;
+ int ret;
+
+ ret = fdt_property_placeholder(fdt, name, len, &ptr);
+ if (ret)
+ return ret;
+ memcpy(ptr, val, len);
return 0;
}
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 6aaab399929c..5e859198622b 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
int proplen;
propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
- if (! propval)
+ if (!propval)
return proplen;
if (proplen != len)
@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
int len;
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
+ if (!prop)
return len;
_fdt_nop_region(prop, len + sizeof(*prop));
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index ba86caa73d01..7f83023ee109 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1314,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
{
return fdt_property_u32(fdt, name, val);
}
+
+/**
+ * fdt_property_placeholder - add a new property and return a ptr to its value
+ *
+ * @fdt: pointer to the device tree blob
+ * @name: name of property to add
+ * @len: length of property value in bytes
+ * @valp: returns a pointer to where where the value should be placed
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_NOSPACE, standard meanings
+ */
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
+
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
int fdt_end_node(void *fdt);
@@ -1433,6 +1449,37 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
const void *val, int len);
/**
+ * fdt_setprop _placeholder - allocate space for a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @len: length of the property value
+ * @prop_data: return pointer to property data
+ *
+ * fdt_setprop_placeholer() allocates the named property in the given node.
+ * If the property exists it is resized. In either case a pointer to the
+ * property data is returned.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data);
+
+/**
* fdt_setprop_u32 - set a property to a 32-bit integer
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 3673de07e4e5..6846ad2fd6d2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
return old_node;
}
+void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
+{
+ static unsigned int next_orphan_fragment = 0;
+ struct node *node;
+ struct property *p;
+ struct data d = empty_data;
+ char *name;
+
+ d = data_add_marker(d, REF_PHANDLE, ref);
+ d = data_append_integer(d, 0xffffffff, 32);
+
+ p = build_property("target", d);
+
+ xasprintf(&name, "fragment@%u",
+ next_orphan_fragment++);
+ name_node(new_node, "__overlay__");
+ node = build_node(p, new_node);
+ name_node(node, name);
+
+ add_child(dt, node);
+}
+
struct node *chain_node(struct node *first, struct node *list)
{
assert(first->next_sibling == NULL);
@@ -396,6 +418,12 @@ cell_t propval_cell(struct property *prop)
return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
}
+cell_t propval_cell_n(struct property *prop, int n)
+{
+ assert(prop->val.len / sizeof(cell_t) >= n);
+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
+}
+
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node)
{
@@ -478,7 +506,8 @@ struct node *get_node_by_path(struct node *tree, const char *path)
p = strchr(path, '/');
for_each_child(tree, child) {
- if (p && strneq(path, child->name, p-path))
+ if (p && (strlen(child->name) == p-path) &&
+ strneq(path, child->name, p-path))
return get_node_by_path(child, p+1);
else if (!p && streq(path, child->name))
return child;
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index b8ebcc6722d2..fe8926bb3b54 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Simple script to update the version of DTC carried by the Linux kernel
#
# This script assumes that the dtc and the linux git trees are in the
@@ -34,7 +35,9 @@ DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c
srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
dtc-lexer.l dtc-parser.y"
DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
-LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_empty_tree.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
+LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
+ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
+ fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
get_last_dtc_version() {
git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/'
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 1229e07b4912..6a4e84798966 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.4-g756ffc4f"
+#define DTC_VERSION "DTC 1.4.5-gc1e55a55"
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index 8f79b701de87..68ff426b347c 100755
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# (C) Copyright IBM Corporation 2006.
# Released under GPL v2.
@@ -7,6 +7,7 @@
# Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c
#
+use warnings;
use Getopt::Std;
use strict;
diff --git a/scripts/extract-module-sig.pl b/scripts/extract-module-sig.pl
index faac6f2e377f..36a2f59c4e41 100755
--- a/scripts/extract-module-sig.pl
+++ b/scripts/extract-module-sig.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# extract-mod-sig <part> <module-file>
#
@@ -12,6 +13,7 @@
# -k: Just the key ID
# -s: Just the crypto signature or PKCS#7 message
#
+use warnings;
use strict;
die "Format: $0 -[0adnks] module-file >out\n"
diff --git a/scripts/extract-sys-certs.pl b/scripts/extract-sys-certs.pl
index 8227ca10a494..fa8ab15118cc 100755
--- a/scripts/extract-sys-certs.pl
+++ b/scripts/extract-sys-certs.pl
@@ -1,5 +1,7 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
+use warnings;
use strict;
use Math::BigInt;
use Fcntl "SEEK_SET";
diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl
index 47877deae6d7..61d9b256c658 100755
--- a/scripts/extract_xc3028.pl
+++ b/scripts/extract_xc3028.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) Mauro Carvalho Chehab <mchehab@infradead.org>
# Released under GPLv2
diff --git a/scripts/faddr2line b/scripts/faddr2line
index 29df825d375c..1f5ce959f596 100755
--- a/scripts/faddr2line
+++ b/scripts/faddr2line
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
#
# Translate stack dump function offsets.
#
@@ -103,11 +104,12 @@ __faddr2line() {
# Go through each of the object's symbols which match the func name.
# In rare cases there might be duplicates.
+ file_end=$(size -Ax $objfile | awk '$1 == ".text" {print $2}')
while read symbol; do
local fields=($symbol)
local sym_base=0x${fields[0]}
local sym_type=${fields[1]}
- local sym_end=0x${fields[3]}
+ local sym_end=${fields[3]}
# calculate the size
local sym_size=$(($sym_end - $sym_base))
@@ -157,7 +159,7 @@ __faddr2line() {
addr2line -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;"
DONE=1
- done < <(nm -n $objfile | awk -v fn=$func '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, $1 }')
+ done < <(nm -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }')
}
[[ $# -lt 2 ]] && usage
diff --git a/scripts/find-unused-docs.sh b/scripts/find-unused-docs.sh
new file mode 100755
index 000000000000..3f46f8977dc4
--- /dev/null
+++ b/scripts/find-unused-docs.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# (c) 2017, Jonathan Corbet <corbet@lwn.net>
+# sayli karnik <karniksayli1995@gmail.com>
+#
+# This script detects files with kernel-doc comments for exported functions
+# that are not included in documentation.
+#
+# usage: Run 'scripts/find-unused-docs.sh directory' from top level of kernel
+# tree.
+#
+# example: $scripts/find-unused-docs.sh drivers/scsi
+#
+# Licensed under the terms of the GNU GPL License
+
+if ! [ -d "Documentation" ]; then
+ echo "Run from top level of kernel tree"
+ exit 1
+fi
+
+if [ "$#" -ne 1 ]; then
+ echo "Usage: scripts/find-unused-docs.sh directory"
+ exit 1
+fi
+
+if ! [ -d "$1" ]; then
+ echo "Directory $1 doesn't exist"
+ exit 1
+fi
+
+cd "$( dirname "${BASH_SOURCE[0]}" )"
+cd ..
+
+cd Documentation/
+
+echo "The following files contain kerneldoc comments for exported functions \
+that are not used in the formatted documentation"
+
+# FILES INCLUDED
+
+files_included=($(grep -rHR ".. kernel-doc" --include \*.rst | cut -d " " -f 3))
+
+declare -A FILES_INCLUDED
+
+for each in "${files_included[@]}"; do
+ FILES_INCLUDED[$each]="$each"
+ done
+
+cd ..
+
+# FILES NOT INCLUDED
+
+for file in `find $1 -name '*.c'`; do
+
+ if [[ ${FILES_INCLUDED[$file]+_} ]]; then
+ continue;
+ fi
+ str=$(scripts/kernel-doc -text -export "$file" 2>/dev/null)
+ if [[ -n "$str" ]]; then
+ echo "$file"
+ fi
+ done
+
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh
index c9469d34ecc6..083c526073ef 100755
--- a/scripts/gcc-goto.sh
+++ b/scripts/gcc-goto.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Test for gcc 'asm goto' support
# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
diff --git a/scripts/gcc-ld b/scripts/gcc-ld
index cadab9a13ed7..997b818c3962 100755
--- a/scripts/gcc-ld
+++ b/scripts/gcc-ld
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# run gcc with ld options
# used as a wrapper to execute link time optimizations
# yes virginia, this is not pretty
diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh
index b65224bfb847..d3caefe53eab 100755
--- a/scripts/gcc-plugin.sh
+++ b/scripts/gcc-plugin.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
srctree=$(dirname "$0")
SHOW_ERROR=
diff --git a/scripts/gcc-plugins/.gitignore b/scripts/gcc-plugins/.gitignore
new file mode 100644
index 000000000000..de92ed9e3d83
--- /dev/null
+++ b/scripts/gcc-plugins/.gitignore
@@ -0,0 +1 @@
+randomize_layout_seed.h
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 8b29dc17c73c..e2ff425f4c7e 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
ifeq ($(PLUGINCC),$(HOSTCC))
@@ -18,6 +19,14 @@ endif
export HOSTLIBS
+$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
+quiet_cmd_create_randomize_layout_seed = GENSEED $@
+cmd_create_randomize_layout_seed = \
+ $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
+$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
+ $(call if_changed,create_randomize_layout_seed)
+targets = randomize_layout_seed.h randomize_layout_hash.h
+
$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
always := $($(HOSTLIBS)-y)
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index b232ab15624c..ffd1dfaa1cc1 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GCC_COMMON_H_INCLUDED
#define GCC_COMMON_H_INCLUDED
@@ -63,6 +64,13 @@
#endif
#if BUILDING_GCC_VERSION >= 4006
+/*
+ * The c-family headers were moved into a subdirectory in GCC version
+ * 4.7, but most plugin-building users of GCC 4.6 are using the Debian
+ * or Ubuntu package, which has an out-of-tree patch to move this to the
+ * same location as found in 4.7 and later:
+ * https://sources.debian.net/src/gcc-4.6/4.6.3-14/debian/patches/pr45078.diff/
+ */
#include "c-family/c-common.h"
#else
#include "c-common.h"
@@ -946,4 +954,9 @@ static inline void debug_gimple_stmt(const_gimple s)
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
#endif
+#if BUILDING_GCC_VERSION < 7000
+#define SET_DECL_ALIGN(decl, align) DECL_ALIGN(decl) = (align)
+#define SET_DECL_MODE(decl, mode) DECL_MODE(decl) = (mode)
+#endif
+
#endif
diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h
index 526c3c79b68e..f20797e80b6d 100644
--- a/scripts/gcc-plugins/gcc-generate-gimple-pass.h
+++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Generator for GIMPLE pass related boilerplate code/data
*
diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
index 9bd926e072f0..92bb4f3a87a4 100644
--- a/scripts/gcc-plugins/gcc-generate-ipa-pass.h
+++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Generator for IPA pass related boilerplate code/data
*
diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h
index 1dc67a5aeadf..d69cd80b6c10 100644
--- a/scripts/gcc-plugins/gcc-generate-rtl-pass.h
+++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Generator for RTL pass related boilerplate code/data
*
diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
index a27e2b36afaa..06800bc477e0 100644
--- a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
+++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Generator for SIMPLE_IPA pass related boilerplate code/data
*
diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh
new file mode 100644
index 000000000000..68af5cc20a64
--- /dev/null
+++ b/scripts/gcc-plugins/gen-random-seed.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+if [ ! -f "$1" ]; then
+ SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
+ echo "const char *randstruct_seed = \"$SEED\";" > "$1"
+ HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
+ echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
+fi
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
new file mode 100644
index 000000000000..0073af326449
--- /dev/null
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -0,0 +1,1025 @@
+/*
+ * Copyright 2014-2016 by Open Source Security, Inc., Brad Spengler <spender@grsecurity.net>
+ * and PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
+ *
+ * Note: the choice of the license means that the compilation process is
+ * NOT 'eligible' as defined by gcc's library exception to the GPL v3,
+ * but for the kernel it doesn't matter since it doesn't link against
+ * any of the gcc libraries
+ *
+ * Usage:
+ * $ # for 4.5/4.6/C based 4.7
+ * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
+ * $ # for C++ based 4.7/4.8+
+ * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
+ * $ gcc -fplugin=./randomize_layout_plugin.so test.c -O2
+ */
+
+#include "gcc-common.h"
+#include "randomize_layout_seed.h"
+
+#if BUILDING_GCC_MAJOR < 4 || (BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR < 7)
+#error "The RANDSTRUCT plugin requires GCC 4.7 or newer."
+#endif
+
+#define ORIG_TYPE_NAME(node) \
+ (TYPE_NAME(TYPE_MAIN_VARIANT(node)) != NULL_TREE ? ((const unsigned char *)IDENTIFIER_POINTER(TYPE_NAME(TYPE_MAIN_VARIANT(node)))) : (const unsigned char *)"anonymous")
+
+#define INFORM(loc, msg, ...) inform(loc, "randstruct: " msg, ##__VA_ARGS__)
+#define MISMATCH(loc, how, ...) INFORM(loc, "casting between randomized structure pointer types (" how "): %qT and %qT\n", __VA_ARGS__)
+
+__visible int plugin_is_GPL_compatible;
+
+static int performance_mode;
+
+static struct plugin_info randomize_layout_plugin_info = {
+ .version = "201402201816vanilla",
+ .help = "disable\t\t\tdo not activate plugin\n"
+ "performance-mode\tenable cacheline-aware layout randomization\n"
+};
+
+struct whitelist_entry {
+ const char *pathname;
+ const char *lhs;
+ const char *rhs;
+};
+
+static const struct whitelist_entry whitelist[] = {
+ /* NIU overloads mapping with page struct */
+ { "drivers/net/ethernet/sun/niu.c", "page", "address_space" },
+ /* unix_skb_parms via UNIXCB() buffer */
+ { "net/unix/af_unix.c", "unix_skb_parms", "char" },
+ /* big_key payload.data struct splashing */
+ { "security/keys/big_key.c", "path", "void *" },
+ /* walk struct security_hook_heads as an array of struct list_head */
+ { "security/security.c", "list_head", "security_hook_heads" },
+ { }
+};
+
+/* from old Linux dcache.h */
+static inline unsigned long
+partial_name_hash(unsigned long c, unsigned long prevhash)
+{
+ return (prevhash + (c << 4) + (c >> 4)) * 11;
+}
+static inline unsigned int
+name_hash(const unsigned char *name)
+{
+ unsigned long hash = 0;
+ unsigned int len = strlen((const char *)name);
+ while (len--)
+ hash = partial_name_hash(*name++, hash);
+ return (unsigned int)hash;
+}
+
+static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
+{
+ tree type;
+
+ *no_add_attrs = true;
+ if (TREE_CODE(*node) == FUNCTION_DECL) {
+ error("%qE attribute does not apply to functions (%qF)", name, *node);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE(*node) == PARM_DECL) {
+ error("%qE attribute does not apply to function parameters (%qD)", name, *node);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE(*node) == VAR_DECL) {
+ error("%qE attribute does not apply to variables (%qD)", name, *node);
+ return NULL_TREE;
+ }
+
+ if (TYPE_P(*node)) {
+ type = *node;
+ } else {
+ gcc_assert(TREE_CODE(*node) == TYPE_DECL);
+ type = TREE_TYPE(*node);
+ }
+
+ if (TREE_CODE(type) != RECORD_TYPE) {
+ error("%qE attribute used on %qT applies to struct types only", name, type);
+ return NULL_TREE;
+ }
+
+ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) {
+ error("%qE attribute is already applied to the type %qT", name, type);
+ return NULL_TREE;
+ }
+
+ *no_add_attrs = false;
+
+ return NULL_TREE;
+}
+
+/* set on complete types that we don't need to inspect further at all */
+static tree handle_randomize_considered_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
+{
+ *no_add_attrs = false;
+ return NULL_TREE;
+}
+
+/*
+ * set on types that we've performed a shuffle on, to prevent re-shuffling
+ * this does not preclude us from inspecting its fields for potential shuffles
+ */
+static tree handle_randomize_performed_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
+{
+ *no_add_attrs = false;
+ return NULL_TREE;
+}
+
+/*
+ * 64bit variant of Bob Jenkins' public domain PRNG
+ * 256 bits of internal state
+ */
+
+typedef unsigned long long u64;
+
+typedef struct ranctx { u64 a; u64 b; u64 c; u64 d; } ranctx;
+
+#define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
+static u64 ranval(ranctx *x) {
+ u64 e = x->a - rot(x->b, 7);
+ x->a = x->b ^ rot(x->c, 13);
+ x->b = x->c + rot(x->d, 37);
+ x->c = x->d + e;
+ x->d = e + x->a;
+ return x->d;
+}
+
+static void raninit(ranctx *x, u64 *seed) {
+ int i;
+
+ x->a = seed[0];
+ x->b = seed[1];
+ x->c = seed[2];
+ x->d = seed[3];
+
+ for (i=0; i < 30; ++i)
+ (void)ranval(x);
+}
+
+static u64 shuffle_seed[4];
+
+struct partition_group {
+ tree tree_start;
+ unsigned long start;
+ unsigned long length;
+};
+
+static void partition_struct(tree *fields, unsigned long length, struct partition_group *size_groups, unsigned long *num_groups)
+{
+ unsigned long i;
+ unsigned long accum_size = 0;
+ unsigned long accum_length = 0;
+ unsigned long group_idx = 0;
+
+ gcc_assert(length < INT_MAX);
+
+ memset(size_groups, 0, sizeof(struct partition_group) * length);
+
+ for (i = 0; i < length; i++) {
+ if (size_groups[group_idx].tree_start == NULL_TREE) {
+ size_groups[group_idx].tree_start = fields[i];
+ size_groups[group_idx].start = i;
+ accum_length = 0;
+ accum_size = 0;
+ }
+ accum_size += (unsigned long)int_size_in_bytes(TREE_TYPE(fields[i]));
+ accum_length++;
+ if (accum_size >= 64) {
+ size_groups[group_idx].length = accum_length;
+ accum_length = 0;
+ group_idx++;
+ }
+ }
+
+ if (size_groups[group_idx].tree_start != NULL_TREE &&
+ !size_groups[group_idx].length) {
+ size_groups[group_idx].length = accum_length;
+ group_idx++;
+ }
+
+ *num_groups = group_idx;
+}
+
+static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
+{
+ unsigned long i, x;
+ struct partition_group size_group[length];
+ unsigned long num_groups = 0;
+ unsigned long randnum;
+
+ partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups);
+ for (i = num_groups - 1; i > 0; i--) {
+ struct partition_group tmp;
+ randnum = ranval(prng_state) % (i + 1);
+ tmp = size_group[i];
+ size_group[i] = size_group[randnum];
+ size_group[randnum] = tmp;
+ }
+
+ for (x = 0; x < num_groups; x++) {
+ for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) {
+ tree tmp;
+ if (DECL_BIT_FIELD_TYPE(newtree[i]))
+ continue;
+ randnum = ranval(prng_state) % (i + 1);
+ // we could handle this case differently if desired
+ if (DECL_BIT_FIELD_TYPE(newtree[randnum]))
+ continue;
+ tmp = newtree[i];
+ newtree[i] = newtree[randnum];
+ newtree[randnum] = tmp;
+ }
+ }
+}
+
+static void full_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
+{
+ unsigned long i, randnum;
+
+ for (i = length - 1; i > 0; i--) {
+ tree tmp;
+ randnum = ranval(prng_state) % (i + 1);
+ tmp = newtree[i];
+ newtree[i] = newtree[randnum];
+ newtree[randnum] = tmp;
+ }
+}
+
+/* modern in-place Fisher-Yates shuffle */
+static void shuffle(const_tree type, tree *newtree, unsigned long length)
+{
+ unsigned long i;
+ u64 seed[4];
+ ranctx prng_state;
+ const unsigned char *structname;
+
+ if (length == 0)
+ return;
+
+ gcc_assert(TREE_CODE(type) == RECORD_TYPE);
+
+ structname = ORIG_TYPE_NAME(type);
+
+#ifdef __DEBUG_PLUGIN
+ fprintf(stderr, "Shuffling struct %s %p\n", (const char *)structname, type);
+#ifdef __DEBUG_VERBOSE
+ debug_tree((tree)type);
+#endif
+#endif
+
+ for (i = 0; i < 4; i++) {
+ seed[i] = shuffle_seed[i];
+ seed[i] ^= name_hash(structname);
+ }
+
+ raninit(&prng_state, (u64 *)&seed);
+
+ if (performance_mode)
+ performance_shuffle(newtree, length, &prng_state);
+ else
+ full_shuffle(newtree, length, &prng_state);
+}
+
+static bool is_flexible_array(const_tree field)
+{
+ const_tree fieldtype;
+ const_tree typesize;
+ const_tree elemtype;
+ const_tree elemsize;
+
+ fieldtype = TREE_TYPE(field);
+ typesize = TYPE_SIZE(fieldtype);
+
+ if (TREE_CODE(fieldtype) != ARRAY_TYPE)
+ return false;
+
+ elemtype = TREE_TYPE(fieldtype);
+ elemsize = TYPE_SIZE(elemtype);
+
+ /* size of type is represented in bits */
+
+ if (typesize == NULL_TREE && TYPE_DOMAIN(fieldtype) != NULL_TREE &&
+ TYPE_MAX_VALUE(TYPE_DOMAIN(fieldtype)) == NULL_TREE)
+ return true;
+
+ if (typesize != NULL_TREE &&
+ (TREE_CONSTANT(typesize) && (!tree_to_uhwi(typesize) ||
+ tree_to_uhwi(typesize) == tree_to_uhwi(elemsize))))
+ return true;
+
+ return false;
+}
+
+static int relayout_struct(tree type)
+{
+ unsigned long num_fields = (unsigned long)list_length(TYPE_FIELDS(type));
+ unsigned long shuffle_length = num_fields;
+ tree field;
+ tree newtree[num_fields];
+ unsigned long i;
+ tree list;
+ tree variant;
+ tree main_variant;
+ expanded_location xloc;
+ bool has_flexarray = false;
+
+ if (TYPE_FIELDS(type) == NULL_TREE)
+ return 0;
+
+ if (num_fields < 2)
+ return 0;
+
+ gcc_assert(TREE_CODE(type) == RECORD_TYPE);
+
+ gcc_assert(num_fields < INT_MAX);
+
+ if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type)) ||
+ lookup_attribute("no_randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))))
+ return 0;
+
+ /* Workaround for 3rd-party VirtualBox source that we can't modify ourselves */
+ if (!strcmp((const char *)ORIG_TYPE_NAME(type), "INTNETTRUNKFACTORY") ||
+ !strcmp((const char *)ORIG_TYPE_NAME(type), "RAWPCIFACTORY"))
+ return 0;
+
+ /* throw out any structs in uapi */
+ xloc = expand_location(DECL_SOURCE_LOCATION(TYPE_FIELDS(type)));
+
+ if (strstr(xloc.file, "/uapi/"))
+ error(G_("attempted to randomize userland API struct %s"), ORIG_TYPE_NAME(type));
+
+ for (field = TYPE_FIELDS(type), i = 0; field; field = TREE_CHAIN(field), i++) {
+ gcc_assert(TREE_CODE(field) == FIELD_DECL);
+ newtree[i] = field;
+ }
+
+ /*
+ * enforce that we don't randomize the layout of the last
+ * element of a struct if it's a 0 or 1-length array
+ * or a proper flexible array
+ */
+ if (is_flexible_array(newtree[num_fields - 1])) {
+ has_flexarray = true;
+ shuffle_length--;
+ }
+
+ shuffle(type, (tree *)newtree, shuffle_length);
+
+ /*
+ * set up a bogus anonymous struct field designed to error out on unnamed struct initializers
+ * as gcc provides no other way to detect such code
+ */
+ list = make_node(FIELD_DECL);
+ TREE_CHAIN(list) = newtree[0];
+ TREE_TYPE(list) = void_type_node;
+ DECL_SIZE(list) = bitsize_zero_node;
+ DECL_NONADDRESSABLE_P(list) = 1;
+ DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node;
+ DECL_SIZE_UNIT(list) = size_zero_node;
+ DECL_FIELD_OFFSET(list) = size_zero_node;
+ DECL_CONTEXT(list) = type;
+ // to satisfy the constify plugin
+ TREE_READONLY(list) = 1;
+
+ for (i = 0; i < num_fields - 1; i++)
+ TREE_CHAIN(newtree[i]) = newtree[i+1];
+ TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
+
+ main_variant = TYPE_MAIN_VARIANT(type);
+ for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
+ TYPE_FIELDS(variant) = list;
+ TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
+ TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+ TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
+ if (has_flexarray)
+ TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
+ }
+
+ /*
+ * force a re-layout of the main variant
+ * the TYPE_SIZE for all variants will be recomputed
+ * by finalize_type_size()
+ */
+ TYPE_SIZE(main_variant) = NULL_TREE;
+ layout_type(main_variant);
+ gcc_assert(TYPE_SIZE(main_variant) != NULL_TREE);
+
+ return 1;
+}
+
+/* from constify plugin */
+static const_tree get_field_type(const_tree field)
+{
+ return strip_array_types(TREE_TYPE(field));
+}
+
+/* from constify plugin */
+static bool is_fptr(const_tree fieldtype)
+{
+ if (TREE_CODE(fieldtype) != POINTER_TYPE)
+ return false;
+
+ return TREE_CODE(TREE_TYPE(fieldtype)) == FUNCTION_TYPE;
+}
+
+/* derived from constify plugin */
+static int is_pure_ops_struct(const_tree node)
+{
+ const_tree field;
+
+ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
+
+ for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) {
+ const_tree fieldtype = get_field_type(field);
+ enum tree_code code = TREE_CODE(fieldtype);
+
+ if (node == fieldtype)
+ continue;
+
+ if (!is_fptr(fieldtype))
+ return 0;
+
+ if (code != RECORD_TYPE && code != UNION_TYPE)
+ continue;
+
+ if (!is_pure_ops_struct(fieldtype))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void randomize_type(tree type)
+{
+ tree variant;
+
+ gcc_assert(TREE_CODE(type) == RECORD_TYPE);
+
+ if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type)))
+ return;
+
+ if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type))
+ relayout_struct(type);
+
+ for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
+ TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
+ TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
+ }
+#ifdef __DEBUG_PLUGIN
+ fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
+#ifdef __DEBUG_VERBOSE
+ debug_tree(type);
+#endif
+#endif
+}
+
+static void update_decl_size(tree decl)
+{
+ tree lastval, lastidx, field, init, type, flexsize;
+ unsigned HOST_WIDE_INT len;
+
+ type = TREE_TYPE(decl);
+
+ if (!lookup_attribute("has_flexarray", TYPE_ATTRIBUTES(type)))
+ return;
+
+ init = DECL_INITIAL(decl);
+ if (init == NULL_TREE || init == error_mark_node)
+ return;
+
+ if (TREE_CODE(init) != CONSTRUCTOR)
+ return;
+
+ len = CONSTRUCTOR_NELTS(init);
+ if (!len)
+ return;
+
+ lastval = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->value;
+ lastidx = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->index;
+
+ for (field = TYPE_FIELDS(TREE_TYPE(decl)); TREE_CHAIN(field); field = TREE_CHAIN(field))
+ ;
+
+ if (lastidx != field)
+ return;
+
+ if (TREE_CODE(lastval) != STRING_CST) {
+ error("Only string constants are supported as initializers "
+ "for randomized structures with flexible arrays");
+ return;
+ }
+
+ flexsize = bitsize_int(TREE_STRING_LENGTH(lastval) *
+ tree_to_uhwi(TYPE_SIZE(TREE_TYPE(TREE_TYPE(lastval)))));
+
+ DECL_SIZE(decl) = size_binop(PLUS_EXPR, TYPE_SIZE(type), flexsize);
+
+ return;
+}
+
+
+static void randomize_layout_finish_decl(void *event_data, void *data)
+{
+ tree decl = (tree)event_data;
+ tree type;
+
+ if (decl == NULL_TREE || decl == error_mark_node)
+ return;
+
+ type = TREE_TYPE(decl);
+
+ if (TREE_CODE(decl) != VAR_DECL)
+ return;
+
+ if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
+ return;
+
+ if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type)))
+ return;
+
+ DECL_SIZE(decl) = 0;
+ DECL_SIZE_UNIT(decl) = 0;
+ SET_DECL_ALIGN(decl, 0);
+ SET_DECL_MODE (decl, VOIDmode);
+ SET_DECL_RTL(decl, 0);
+ update_decl_size(decl);
+ layout_decl(decl, 0);
+}
+
+static void finish_type(void *event_data, void *data)
+{
+ tree type = (tree)event_data;
+
+ if (type == NULL_TREE || type == error_mark_node)
+ return;
+
+ if (TREE_CODE(type) != RECORD_TYPE)
+ return;
+
+ if (TYPE_FIELDS(type) == NULL_TREE)
+ return;
+
+ if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type)))
+ return;
+
+#ifdef __DEBUG_PLUGIN
+ fprintf(stderr, "Calling randomize_type on %s\n", ORIG_TYPE_NAME(type));
+#endif
+#ifdef __DEBUG_VERBOSE
+ debug_tree(type);
+#endif
+ randomize_type(type);
+
+ return;
+}
+
+static struct attribute_spec randomize_layout_attr = {
+ .name = "randomize_layout",
+ // related to args
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = false,
+ // need type declaration
+ .type_required = true,
+ .function_type_required = false,
+ .handler = handle_randomize_layout_attr,
+#if BUILDING_GCC_VERSION >= 4007
+ .affects_type_identity = true
+#endif
+};
+
+static struct attribute_spec no_randomize_layout_attr = {
+ .name = "no_randomize_layout",
+ // related to args
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = false,
+ // need type declaration
+ .type_required = true,
+ .function_type_required = false,
+ .handler = handle_randomize_layout_attr,
+#if BUILDING_GCC_VERSION >= 4007
+ .affects_type_identity = true
+#endif
+};
+
+static struct attribute_spec randomize_considered_attr = {
+ .name = "randomize_considered",
+ // related to args
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = false,
+ // need type declaration
+ .type_required = true,
+ .function_type_required = false,
+ .handler = handle_randomize_considered_attr,
+#if BUILDING_GCC_VERSION >= 4007
+ .affects_type_identity = false
+#endif
+};
+
+static struct attribute_spec randomize_performed_attr = {
+ .name = "randomize_performed",
+ // related to args
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = false,
+ // need type declaration
+ .type_required = true,
+ .function_type_required = false,
+ .handler = handle_randomize_performed_attr,
+#if BUILDING_GCC_VERSION >= 4007
+ .affects_type_identity = false
+#endif
+};
+
+static void register_attributes(void *event_data, void *data)
+{
+ register_attribute(&randomize_layout_attr);
+ register_attribute(&no_randomize_layout_attr);
+ register_attribute(&randomize_considered_attr);
+ register_attribute(&randomize_performed_attr);
+}
+
+static void check_bad_casts_in_constructor(tree var, tree init)
+{
+ unsigned HOST_WIDE_INT idx;
+ tree field, val;
+ tree field_type, val_type;
+
+ FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(init), idx, field, val) {
+ if (TREE_CODE(val) == CONSTRUCTOR) {
+ check_bad_casts_in_constructor(var, val);
+ continue;
+ }
+
+ /* pipacs' plugin creates franken-arrays that differ from those produced by
+ normal code which all have valid 'field' trees. work around this */
+ if (field == NULL_TREE)
+ continue;
+ field_type = TREE_TYPE(field);
+ val_type = TREE_TYPE(val);
+
+ if (TREE_CODE(field_type) != POINTER_TYPE || TREE_CODE(val_type) != POINTER_TYPE)
+ continue;
+
+ if (field_type == val_type)
+ continue;
+
+ field_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(field_type))));
+ val_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(val_type))));
+
+ if (field_type == void_type_node)
+ continue;
+ if (field_type == val_type)
+ continue;
+ if (TREE_CODE(val_type) != RECORD_TYPE)
+ continue;
+
+ if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(val_type)))
+ continue;
+ MISMATCH(DECL_SOURCE_LOCATION(var), "constructor\n", TYPE_MAIN_VARIANT(field_type), TYPE_MAIN_VARIANT(val_type));
+ }
+}
+
+/* derived from the constify plugin */
+static void check_global_variables(void *event_data, void *data)
+{
+ struct varpool_node *node;
+ tree init;
+
+ FOR_EACH_VARIABLE(node) {
+ tree var = NODE_DECL(node);
+ init = DECL_INITIAL(var);
+ if (init == NULL_TREE)
+ continue;
+
+ if (TREE_CODE(init) != CONSTRUCTOR)
+ continue;
+
+ check_bad_casts_in_constructor(var, init);
+ }
+}
+
+static bool dominated_by_is_err(const_tree rhs, basic_block bb)
+{
+ basic_block dom;
+ gimple dom_stmt;
+ gimple call_stmt;
+ const_tree dom_lhs;
+ const_tree poss_is_err_cond;
+ const_tree poss_is_err_func;
+ const_tree is_err_arg;
+
+ dom = get_immediate_dominator(CDI_DOMINATORS, bb);
+ if (!dom)
+ return false;
+
+ dom_stmt = last_stmt(dom);
+ if (!dom_stmt)
+ return false;
+
+ if (gimple_code(dom_stmt) != GIMPLE_COND)
+ return false;
+
+ if (gimple_cond_code(dom_stmt) != NE_EXPR)
+ return false;
+
+ if (!integer_zerop(gimple_cond_rhs(dom_stmt)))
+ return false;
+
+ poss_is_err_cond = gimple_cond_lhs(dom_stmt);
+
+ if (TREE_CODE(poss_is_err_cond) != SSA_NAME)
+ return false;
+
+ call_stmt = SSA_NAME_DEF_STMT(poss_is_err_cond);
+
+ if (gimple_code(call_stmt) != GIMPLE_CALL)
+ return false;
+
+ dom_lhs = gimple_get_lhs(call_stmt);
+ poss_is_err_func = gimple_call_fndecl(call_stmt);
+ if (!poss_is_err_func)
+ return false;
+ if (dom_lhs != poss_is_err_cond)
+ return false;
+ if (strcmp(DECL_NAME_POINTER(poss_is_err_func), "IS_ERR"))
+ return false;
+
+ is_err_arg = gimple_call_arg(call_stmt, 0);
+ if (!is_err_arg)
+ return false;
+
+ if (is_err_arg != rhs)
+ return false;
+
+ return true;
+}
+
+static void handle_local_var_initializers(void)
+{
+ tree var;
+ unsigned int i;
+
+ FOR_EACH_LOCAL_DECL(cfun, i, var) {
+ tree init = DECL_INITIAL(var);
+ if (!init)
+ continue;
+ if (TREE_CODE(init) != CONSTRUCTOR)
+ continue;
+ check_bad_casts_in_constructor(var, init);
+ }
+}
+
+static bool type_name_eq(gimple stmt, const_tree type_tree, const char *wanted_name)
+{
+ const char *type_name;
+
+ if (type_tree == NULL_TREE)
+ return false;
+
+ switch (TREE_CODE(type_tree)) {
+ case RECORD_TYPE:
+ type_name = TYPE_NAME_POINTER(type_tree);
+ break;
+ case INTEGER_TYPE:
+ if (TYPE_PRECISION(type_tree) == CHAR_TYPE_SIZE)
+ type_name = "char";
+ else {
+ INFORM(gimple_location(stmt), "found non-char INTEGER_TYPE cast comparison: %qT\n", type_tree);
+ debug_tree(type_tree);
+ return false;
+ }
+ break;
+ case POINTER_TYPE:
+ if (TREE_CODE(TREE_TYPE(type_tree)) == VOID_TYPE) {
+ type_name = "void *";
+ break;
+ } else {
+ INFORM(gimple_location(stmt), "found non-void POINTER_TYPE cast comparison %qT\n", type_tree);
+ debug_tree(type_tree);
+ return false;
+ }
+ default:
+ INFORM(gimple_location(stmt), "unhandled cast comparison: %qT\n", type_tree);
+ debug_tree(type_tree);
+ return false;
+ }
+
+ return strcmp(type_name, wanted_name) == 0;
+}
+
+static bool whitelisted_cast(gimple stmt, const_tree lhs_tree, const_tree rhs_tree)
+{
+ const struct whitelist_entry *entry;
+ expanded_location xloc = expand_location(gimple_location(stmt));
+
+ for (entry = whitelist; entry->pathname; entry++) {
+ if (!strstr(xloc.file, entry->pathname))
+ continue;
+
+ if (type_name_eq(stmt, lhs_tree, entry->lhs) && type_name_eq(stmt, rhs_tree, entry->rhs))
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * iterate over all statements to find "bad" casts:
+ * those where the address of the start of a structure is cast
+ * to a pointer of a structure of a different type, or a
+ * structure pointer type is cast to a different structure pointer type
+ */
+static unsigned int find_bad_casts_execute(void)
+{
+ basic_block bb;
+
+ handle_local_var_initializers();
+
+ FOR_EACH_BB_FN(bb, cfun) {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ gimple stmt;
+ const_tree lhs;
+ const_tree lhs_type;
+ const_tree rhs1;
+ const_tree rhs_type;
+ const_tree ptr_lhs_type;
+ const_tree ptr_rhs_type;
+ const_tree op0;
+ const_tree op0_type;
+ enum tree_code rhs_code;
+
+ stmt = gsi_stmt(gsi);
+
+#ifdef __DEBUG_PLUGIN
+#ifdef __DEBUG_VERBOSE
+ debug_gimple_stmt(stmt);
+ debug_tree(gimple_get_lhs(stmt));
+#endif
+#endif
+
+ if (gimple_code(stmt) != GIMPLE_ASSIGN)
+ continue;
+
+#ifdef __DEBUG_PLUGIN
+#ifdef __DEBUG_VERBOSE
+ debug_tree(gimple_assign_rhs1(stmt));
+#endif
+#endif
+
+
+ rhs_code = gimple_assign_rhs_code(stmt);
+
+ if (rhs_code != ADDR_EXPR && rhs_code != SSA_NAME)
+ continue;
+
+ lhs = gimple_get_lhs(stmt);
+ lhs_type = TREE_TYPE(lhs);
+ rhs1 = gimple_assign_rhs1(stmt);
+ rhs_type = TREE_TYPE(rhs1);
+
+ if (TREE_CODE(rhs_type) != POINTER_TYPE ||
+ TREE_CODE(lhs_type) != POINTER_TYPE)
+ continue;
+
+ ptr_lhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(lhs_type))));
+ ptr_rhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(rhs_type))));
+
+ if (ptr_rhs_type == void_type_node)
+ continue;
+
+ if (ptr_lhs_type == void_type_node)
+ continue;
+
+ if (dominated_by_is_err(rhs1, bb))
+ continue;
+
+ if (TREE_CODE(ptr_rhs_type) != RECORD_TYPE) {
+#ifndef __DEBUG_PLUGIN
+ if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_lhs_type)))
+#endif
+ {
+ if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
+ MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type);
+ }
+ continue;
+ }
+
+ if (rhs_code == SSA_NAME && ptr_lhs_type == ptr_rhs_type)
+ continue;
+
+ if (rhs_code == ADDR_EXPR) {
+ op0 = TREE_OPERAND(rhs1, 0);
+
+ if (op0 == NULL_TREE)
+ continue;
+
+ if (TREE_CODE(op0) != VAR_DECL)
+ continue;
+
+ op0_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(op0))));
+ if (op0_type == ptr_lhs_type)
+ continue;
+
+#ifndef __DEBUG_PLUGIN
+ if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(op0_type)))
+#endif
+ {
+ if (!whitelisted_cast(stmt, ptr_lhs_type, op0_type))
+ MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type);
+ }
+ } else {
+ const_tree ssa_name_var = SSA_NAME_VAR(rhs1);
+ /* skip bogus type casts introduced by container_of */
+ if (ssa_name_var != NULL_TREE && DECL_NAME(ssa_name_var) &&
+ !strcmp((const char *)DECL_NAME_POINTER(ssa_name_var), "__mptr"))
+ continue;
+#ifndef __DEBUG_PLUGIN
+ if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_rhs_type)))
+#endif
+ {
+ if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
+ MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type);
+ }
+ }
+
+ }
+ }
+ return 0;
+}
+
+#define PASS_NAME find_bad_casts
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+#include "gcc-generate-gimple-pass.h"
+
+__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
+{
+ int i;
+ 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;
+ int obtained_seed = 0;
+ struct register_pass_info find_bad_casts_pass_info;
+
+ find_bad_casts_pass_info.pass = make_find_bad_casts_pass();
+ find_bad_casts_pass_info.reference_pass_name = "ssa";
+ find_bad_casts_pass_info.ref_pass_instance_number = 1;
+ find_bad_casts_pass_info.pos_op = PASS_POS_INSERT_AFTER;
+
+ if (!plugin_default_version_check(version, &gcc_version)) {
+ error(G_("incompatible gcc/plugin versions"));
+ return 1;
+ }
+
+ if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) {
+ inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name);
+ enable = false;
+ }
+
+ for (i = 0; i < argc; ++i) {
+ if (!strcmp(argv[i].key, "disable")) {
+ enable = false;
+ continue;
+ }
+ if (!strcmp(argv[i].key, "performance-mode")) {
+ performance_mode = 1;
+ continue;
+ }
+ error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
+ }
+
+ if (strlen(randstruct_seed) != 64) {
+ error(G_("invalid seed value supplied for %s plugin"), plugin_name);
+ return 1;
+ }
+ obtained_seed = sscanf(randstruct_seed, "%016llx%016llx%016llx%016llx",
+ &shuffle_seed[0], &shuffle_seed[1], &shuffle_seed[2], &shuffle_seed[3]);
+ if (obtained_seed != 4) {
+ error(G_("Invalid seed supplied for %s plugin"), plugin_name);
+ return 1;
+ }
+
+ register_callback(plugin_name, PLUGIN_INFO, NULL, &randomize_layout_plugin_info);
+ if (enable) {
+ register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL);
+ register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &find_bad_casts_pass_info);
+ register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL);
+ register_callback(plugin_name, PLUGIN_FINISH_DECL, randomize_layout_finish_decl, NULL);
+ }
+ register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
+
+ return 0;
+}
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index fa3d7a4b26f2..3f8dd4868178 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -16,6 +16,7 @@
* Options:
* -fplugin-arg-structleak_plugin-disable
* -fplugin-arg-structleak_plugin-verbose
+ * -fplugin-arg-structleak_plugin-byref-all
*
* Usage:
* $ # for 4.5/4.6/C based 4.7
@@ -42,6 +43,7 @@ static struct plugin_info structleak_plugin_info = {
};
static bool verbose;
+static bool byref_all;
static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
{
@@ -150,7 +152,9 @@ static void initialize(tree var)
/* these aren't the 0days you're looking for */
if (verbose)
inform(DECL_SOURCE_LOCATION(var),
- "userspace variable will be forcibly initialized");
+ "%s variable will be forcibly initialized",
+ (byref_all && TREE_ADDRESSABLE(var)) ? "byref"
+ : "userspace");
/* build the initializer expression */
initializer = build_constructor(TREE_TYPE(var), NULL);
@@ -190,7 +194,8 @@ static unsigned int structleak_execute(void)
continue;
/* if the type is of interest, examine the variable */
- if (TYPE_USERSPACE(type))
+ if (TYPE_USERSPACE(type) ||
+ (byref_all && TREE_ADDRESSABLE(var)))
initialize(var);
}
@@ -232,6 +237,10 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc
verbose = true;
continue;
}
+ if (!strcmp(argv[i].key, "byref-all")) {
+ byref_all = true;
+ continue;
+ }
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
}
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index 7f2126df91f2..11bb909845e7 100755
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# gcc-version [-p] gcc-command
#
diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh
index 12dbd0b11ea4..6b2aeefb9cd3 100755
--- a/scripts/gcc-x86_32-has-stack-protector.sh
+++ b/scripts/gcc-x86_32-has-stack-protector.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
if [ "$?" -eq "0" ] ; then
diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh
index 17867e723a51..4a48bdcd4d6b 100755
--- a/scripts/gcc-x86_64-has-stack-protector.sh
+++ b/scripts/gcc-x86_64-has-stack-protector.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
if [ "$?" -eq "0" ] ; then
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile
index 8b00031f5349..aba23be985e4 100644
--- a/scripts/gdb/linux/Makefile
+++ b/scripts/gdb/linux/Makefile
@@ -1,6 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
always := gdb-scripts
-SRCTREE := $(shell cd $(srctree) && /bin/pwd)
+SRCTREE := $(abspath $(srctree))
$(obj)/gdb-scripts:
ifneq ($(KBUILD_SRC),)
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
index 7986f4e0da12..7aad82406422 100644
--- a/scripts/gdb/linux/constants.py.in
+++ b/scripts/gdb/linux/constants.py.in
@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/mount.h>
+#include <linux/of_fdt.h>
/* We need to stringify expanded macros so that they can be parsed */
@@ -50,3 +51,9 @@ LX_VALUE(MNT_NOEXEC)
LX_VALUE(MNT_NOATIME)
LX_VALUE(MNT_NODIRATIME)
LX_VALUE(MNT_RELATIME)
+
+/* linux/of_fdt.h> */
+LX_VALUE(OF_DT_HEADER)
+
+/* Kernel Configs */
+LX_CONFIG(CONFIG_OF)
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
index 5afd1098e33a..6d2e09a2ad2f 100644
--- a/scripts/gdb/linux/dmesg.py
+++ b/scripts/gdb/linux/dmesg.py
@@ -12,6 +12,7 @@
#
import gdb
+import sys
from linux import utils
@@ -24,7 +25,7 @@ class LxDmesg(gdb.Command):
def invoke(self, arg, from_tty):
log_buf_addr = int(str(gdb.parse_and_eval(
- "'printk.c'::log_buf")).split()[0], 16)
+ "(void *)'printk.c'::log_buf")).split()[0], 16)
log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx"))
log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx"))
log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len"))
@@ -52,13 +53,19 @@ class LxDmesg(gdb.Command):
continue
text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
- text = log_buf[pos + 16:pos + 16 + text_len].decode()
+ text = log_buf[pos + 16:pos + 16 + text_len].decode(
+ encoding='utf8', errors='replace')
time_stamp = utils.read_u64(log_buf[pos:pos + 8])
for line in text.splitlines():
- gdb.write("[{time:12.6f}] {line}\n".format(
+ msg = u"[{time:12.6f}] {line}\n".format(
time=time_stamp / 1000000000.0,
- line=line))
+ line=line)
+ # With python2 gdb.write will attempt to convert unicode to
+ # ascii and might fail so pass an utf8-encoded str instead.
+ if sys.hexversion < 0x03000000:
+ msg = msg.encode(encoding='utf8', errors='replace')
+ gdb.write(msg)
pos += length
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
index 38b1f09d1cd9..086d27223c0c 100644
--- a/scripts/gdb/linux/proc.py
+++ b/scripts/gdb/linux/proc.py
@@ -16,6 +16,7 @@ from linux import constants
from linux import utils
from linux import tasks
from linux import lists
+from struct import *
class LxCmdLine(gdb.Command):
@@ -195,3 +196,75 @@ values of that process namespace"""
info_opts(MNT_INFO, m_flags)))
LxMounts()
+
+
+class LxFdtDump(gdb.Command):
+ """Output Flattened Device Tree header and dump FDT blob to the filename
+ specified as the command argument. Equivalent to
+ 'cat /proc/fdt > fdtdump.dtb' on a running target"""
+
+ def __init__(self):
+ super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA,
+ gdb.COMPLETE_FILENAME)
+
+ def fdthdr_to_cpu(self, fdt_header):
+
+ fdt_header_be = ">IIIIIII"
+ fdt_header_le = "<IIIIIII"
+
+ if utils.get_target_endianness() == 1:
+ output_fmt = fdt_header_le
+ else:
+ output_fmt = fdt_header_be
+
+ return unpack(output_fmt, pack(fdt_header_be,
+ fdt_header['magic'],
+ fdt_header['totalsize'],
+ fdt_header['off_dt_struct'],
+ fdt_header['off_dt_strings'],
+ fdt_header['off_mem_rsvmap'],
+ fdt_header['version'],
+ fdt_header['last_comp_version']))
+
+ def invoke(self, arg, from_tty):
+
+ if not constants.LX_CONFIG_OF:
+ raise gdb.GdbError("Kernel not compiled with CONFIG_OF\n")
+
+ if len(arg) == 0:
+ filename = "fdtdump.dtb"
+ else:
+ filename = arg
+
+ py_fdt_header_ptr = gdb.parse_and_eval(
+ "(const struct fdt_header *) initial_boot_params")
+ py_fdt_header = py_fdt_header_ptr.dereference()
+
+ fdt_header = self.fdthdr_to_cpu(py_fdt_header)
+
+ if fdt_header[0] != constants.LX_OF_DT_HEADER:
+ raise gdb.GdbError("No flattened device tree magic found\n")
+
+ gdb.write("fdt_magic: 0x{:02X}\n".format(fdt_header[0]))
+ gdb.write("fdt_totalsize: 0x{:02X}\n".format(fdt_header[1]))
+ gdb.write("off_dt_struct: 0x{:02X}\n".format(fdt_header[2]))
+ gdb.write("off_dt_strings: 0x{:02X}\n".format(fdt_header[3]))
+ gdb.write("off_mem_rsvmap: 0x{:02X}\n".format(fdt_header[4]))
+ gdb.write("version: {}\n".format(fdt_header[5]))
+ gdb.write("last_comp_version: {}\n".format(fdt_header[6]))
+
+ inf = gdb.inferiors()[0]
+ fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr,
+ fdt_header[1]).tobytes()
+
+ try:
+ f = open(filename, 'wb')
+ except:
+ raise gdb.GdbError("Could not open file to dump fdt")
+
+ f.write(fdt_buf)
+ f.close()
+
+ gdb.write("Dumped fdt blob to " + filename + "\n")
+
+LxFdtDump()
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 0055b07b03b6..86a3c0e5cfbc 100755
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -174,7 +174,7 @@ dir_filelist() {
${dep_list}header "$1"
srcdir=$(echo "$1" | sed -e 's://*:/:g')
- dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n")
+ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | sort)
# If $dirlist is only one line, then the directory is empty
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
@@ -271,10 +271,12 @@ while [ $# -gt 0 ]; do
case "$arg" in
"-u") # map $1 to uid=0 (root)
root_uid="$1"
+ [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
shift
;;
"-g") # map $1 to gid=0 (root)
root_gid="$1"
+ [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
shift
;;
"-d") # display default initramfs list
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
index aca33b98bf63..34d6ab1811a4 100644
--- a/scripts/genksyms/Makefile
+++ b/scripts/genksyms/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
hostprogs-y := genksyms
always := $(hostprogs-y)
@@ -9,6 +10,6 @@ HOSTCFLAGS_parse.tab.o := -I$(src)
HOSTCFLAGS_lex.lex.o := -I$(src)
# dependencies on generated files need to be listed explicitly
-$(obj)/lex.lex.o: $(obj)/keywords.hash.c $(obj)/parse.tab.h
+$(obj)/lex.lex.o: $(obj)/parse.tab.h
-clean-files := keywords.hash.c lex.lex.c parse.tab.c parse.tab.h
+clean-files := lex.lex.c parse.tab.c parse.tab.h
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
index 3bffdcaaa274..b724a0290c75 100644
--- a/scripts/genksyms/genksyms.h
+++ b/scripts/genksyms/genksyms.h
@@ -75,7 +75,7 @@ struct string_list *copy_list_range(struct string_list *start,
int yylex(void);
int yyparse(void);
-void error_with_pos(const char *, ...);
+void error_with_pos(const char *, ...) __attribute__ ((format(printf, 1, 2)));
/*----------------------------------------------------------------------*/
#define xmalloc(size) ({ void *__ptr = malloc(size); \
diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c
new file mode 100644
index 000000000000..9f40bcd17d07
--- /dev/null
+++ b/scripts/genksyms/keywords.c
@@ -0,0 +1,74 @@
+static struct resword {
+ const char *name;
+ int token;
+} keywords[] = {
+ { "EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW },
+ { "EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW },
+ { "EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW },
+ { "EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW },
+ { "EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW },
+ { "__asm", ASM_KEYW },
+ { "__asm__", ASM_KEYW },
+ { "__attribute", ATTRIBUTE_KEYW },
+ { "__attribute__", ATTRIBUTE_KEYW },
+ { "__const", CONST_KEYW },
+ { "__const__", CONST_KEYW },
+ { "__extension__", EXTENSION_KEYW },
+ { "__inline", INLINE_KEYW },
+ { "__inline__", INLINE_KEYW },
+ { "__signed", SIGNED_KEYW },
+ { "__signed__", SIGNED_KEYW },
+ { "__typeof", TYPEOF_KEYW },
+ { "__typeof__", TYPEOF_KEYW },
+ { "__volatile", VOLATILE_KEYW },
+ { "__volatile__", VOLATILE_KEYW },
+ { "__builtin_va_list", VA_LIST_KEYW },
+
+ // According to rth, c99 defines "_Bool", __restrict", __restrict__", "restrict". KAO
+ { "_Bool", BOOL_KEYW },
+ { "_restrict", RESTRICT_KEYW },
+ { "__restrict__", RESTRICT_KEYW },
+ { "restrict", RESTRICT_KEYW },
+ { "asm", ASM_KEYW },
+
+ // attribute commented out in modutils 2.4.2. People are using 'attribute' as a
+ // field name which breaks the genksyms parser. It is not a gcc keyword anyway.
+ // KAO. },
+ // { "attribute", ATTRIBUTE_KEYW },
+
+ { "auto", AUTO_KEYW },
+ { "char", CHAR_KEYW },
+ { "const", CONST_KEYW },
+ { "double", DOUBLE_KEYW },
+ { "enum", ENUM_KEYW },
+ { "extern", EXTERN_KEYW },
+ { "float", FLOAT_KEYW },
+ { "inline", INLINE_KEYW },
+ { "int", INT_KEYW },
+ { "long", LONG_KEYW },
+ { "register", REGISTER_KEYW },
+ { "short", SHORT_KEYW },
+ { "signed", SIGNED_KEYW },
+ { "static", STATIC_KEYW },
+ { "struct", STRUCT_KEYW },
+ { "typedef", TYPEDEF_KEYW },
+ { "typeof", TYPEOF_KEYW },
+ { "union", UNION_KEYW },
+ { "unsigned", UNSIGNED_KEYW },
+ { "void", VOID_KEYW },
+ { "volatile", VOLATILE_KEYW },
+};
+
+#define NR_KEYWORDS (sizeof(keywords)/sizeof(struct resword))
+
+static int is_reserved_word(register const char *str, register unsigned int len)
+{
+ int i;
+ for (i = 0; i < NR_KEYWORDS; i++) {
+ struct resword *r = keywords + i;
+ int l = strlen(r->name);
+ if (len == l && !memcmp(str, r->name, len))
+ return r->token;
+ }
+ return -1;
+}
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
deleted file mode 100644
index bd4c4b235588..000000000000
--- a/scripts/genksyms/keywords.gperf
+++ /dev/null
@@ -1,61 +0,0 @@
-%language=ANSI-C
-%define hash-function-name is_reserved_hash
-%define lookup-function-name is_reserved_word
-%{
-struct resword;
-static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
-%}
-struct resword { const char *name; int token; }
-%%
-EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
-EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
-EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
-EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW
-EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
-__asm, ASM_KEYW
-__asm__, ASM_KEYW
-__attribute, ATTRIBUTE_KEYW
-__attribute__, ATTRIBUTE_KEYW
-__const, CONST_KEYW
-__const__, CONST_KEYW
-__extension__, EXTENSION_KEYW
-__inline, INLINE_KEYW
-__inline__, INLINE_KEYW
-__signed, SIGNED_KEYW
-__signed__, SIGNED_KEYW
-__typeof, TYPEOF_KEYW
-__typeof__, TYPEOF_KEYW
-__volatile, VOLATILE_KEYW
-__volatile__, VOLATILE_KEYW
-__builtin_va_list, VA_LIST_KEYW
-# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict. KAO
-_Bool, BOOL_KEYW
-_restrict, RESTRICT_KEYW
-__restrict__, RESTRICT_KEYW
-restrict, RESTRICT_KEYW
-asm, ASM_KEYW
-# attribute commented out in modutils 2.4.2. People are using 'attribute' as a
-# field name which breaks the genksyms parser. It is not a gcc keyword anyway.
-# KAO.
-# attribute, ATTRIBUTE_KEYW
-auto, AUTO_KEYW
-char, CHAR_KEYW
-const, CONST_KEYW
-double, DOUBLE_KEYW
-enum, ENUM_KEYW
-extern, EXTERN_KEYW
-float, FLOAT_KEYW
-inline, INLINE_KEYW
-int, INT_KEYW
-long, LONG_KEYW
-register, REGISTER_KEYW
-short, SHORT_KEYW
-signed, SIGNED_KEYW
-static, STATIC_KEYW
-struct, STRUCT_KEYW
-typedef, TYPEDEF_KEYW
-typeof, TYPEOF_KEYW
-union, UNION_KEYW
-unsigned, UNSIGNED_KEYW
-void, VOID_KEYW
-volatile, VOLATILE_KEYW
diff --git a/scripts/genksyms/keywords.hash.c_shipped b/scripts/genksyms/keywords.hash.c_shipped
deleted file mode 100644
index 738018ba7375..000000000000
--- a/scripts/genksyms/keywords.hash.c_shipped
+++ /dev/null
@@ -1,230 +0,0 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -t --output-file scripts/genksyms/keywords.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/genksyms/keywords.gperf */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
- && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
-/* The character set is not based on ISO-646. */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
-#endif
-
-#line 4 "scripts/genksyms/keywords.gperf"
-
-struct resword;
-static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
-#line 8 "scripts/genksyms/keywords.gperf"
-struct resword { const char *name; int token; };
-/* maximum key range = 98, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-is_reserved_hash (register const char *str, register unsigned int len)
-{
- static const unsigned char asso_values[] =
- {
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 0,
- 101, 101, 101, 101, 101, 101, 15, 101, 101, 101,
- 0, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 0, 101, 0, 0, 5,
- 25, 20, 55, 30, 101, 15, 101, 101, 10, 0,
- 10, 40, 10, 101, 10, 5, 0, 10, 15, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101
- };
- return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
-}
-
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-const struct resword *
-is_reserved_word (register const char *str, register unsigned int len)
-{
- enum
- {
- TOTAL_KEYWORDS = 47,
- MIN_WORD_LENGTH = 3,
- MAX_WORD_LENGTH = 24,
- MIN_HASH_VALUE = 3,
- MAX_HASH_VALUE = 100
- };
-
- static const struct resword wordlist[] =
- {
- {""}, {""}, {""},
-#line 36 "scripts/genksyms/keywords.gperf"
- {"asm", ASM_KEYW},
- {""},
-#line 15 "scripts/genksyms/keywords.gperf"
- {"__asm", ASM_KEYW},
- {""},
-#line 16 "scripts/genksyms/keywords.gperf"
- {"__asm__", ASM_KEYW},
- {""}, {""},
-#line 27 "scripts/genksyms/keywords.gperf"
- {"__typeof__", TYPEOF_KEYW},
- {""},
-#line 19 "scripts/genksyms/keywords.gperf"
- {"__const", CONST_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
- {"__attribute__", ATTRIBUTE_KEYW},
-#line 20 "scripts/genksyms/keywords.gperf"
- {"__const__", CONST_KEYW},
-#line 25 "scripts/genksyms/keywords.gperf"
- {"__signed__", SIGNED_KEYW},
-#line 54 "scripts/genksyms/keywords.gperf"
- {"static", STATIC_KEYW},
-#line 30 "scripts/genksyms/keywords.gperf"
- {"__builtin_va_list", VA_LIST_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
- {"int", INT_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
- {"char", CHAR_KEYW},
-#line 43 "scripts/genksyms/keywords.gperf"
- {"const", CONST_KEYW},
-#line 55 "scripts/genksyms/keywords.gperf"
- {"struct", STRUCT_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
- {"__restrict__", RESTRICT_KEYW},
-#line 35 "scripts/genksyms/keywords.gperf"
- {"restrict", RESTRICT_KEYW},
-#line 12 "scripts/genksyms/keywords.gperf"
- {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
-#line 23 "scripts/genksyms/keywords.gperf"
- {"__inline__", INLINE_KEYW},
- {""},
-#line 29 "scripts/genksyms/keywords.gperf"
- {"__volatile__", VOLATILE_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
- {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
- {"_restrict", RESTRICT_KEYW},
- {""},
-#line 17 "scripts/genksyms/keywords.gperf"
- {"__attribute", ATTRIBUTE_KEYW},
-#line 11 "scripts/genksyms/keywords.gperf"
- {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
-#line 21 "scripts/genksyms/keywords.gperf"
- {"__extension__", EXTENSION_KEYW},
-#line 45 "scripts/genksyms/keywords.gperf"
- {"enum", ENUM_KEYW},
-#line 13 "scripts/genksyms/keywords.gperf"
- {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW},
-#line 46 "scripts/genksyms/keywords.gperf"
- {"extern", EXTERN_KEYW},
- {""},
-#line 24 "scripts/genksyms/keywords.gperf"
- {"__signed", SIGNED_KEYW},
-#line 14 "scripts/genksyms/keywords.gperf"
- {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
-#line 58 "scripts/genksyms/keywords.gperf"
- {"union", UNION_KEYW},
- {""}, {""},
-#line 22 "scripts/genksyms/keywords.gperf"
- {"__inline", INLINE_KEYW},
-#line 41 "scripts/genksyms/keywords.gperf"
- {"auto", AUTO_KEYW},
-#line 28 "scripts/genksyms/keywords.gperf"
- {"__volatile", VOLATILE_KEYW},
- {""}, {""},
-#line 59 "scripts/genksyms/keywords.gperf"
- {"unsigned", UNSIGNED_KEYW},
- {""},
-#line 52 "scripts/genksyms/keywords.gperf"
- {"short", SHORT_KEYW},
-#line 48 "scripts/genksyms/keywords.gperf"
- {"inline", INLINE_KEYW},
- {""},
-#line 61 "scripts/genksyms/keywords.gperf"
- {"volatile", VOLATILE_KEYW},
-#line 50 "scripts/genksyms/keywords.gperf"
- {"long", LONG_KEYW},
-#line 32 "scripts/genksyms/keywords.gperf"
- {"_Bool", BOOL_KEYW},
- {""}, {""},
-#line 51 "scripts/genksyms/keywords.gperf"
- {"register", REGISTER_KEYW},
-#line 60 "scripts/genksyms/keywords.gperf"
- {"void", VOID_KEYW},
- {""},
-#line 44 "scripts/genksyms/keywords.gperf"
- {"double", DOUBLE_KEYW},
- {""},
-#line 26 "scripts/genksyms/keywords.gperf"
- {"__typeof", TYPEOF_KEYW},
- {""}, {""},
-#line 53 "scripts/genksyms/keywords.gperf"
- {"signed", SIGNED_KEYW},
- {""}, {""}, {""}, {""},
-#line 57 "scripts/genksyms/keywords.gperf"
- {"typeof", TYPEOF_KEYW},
-#line 56 "scripts/genksyms/keywords.gperf"
- {"typedef", TYPEDEF_KEYW},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-#line 47 "scripts/genksyms/keywords.gperf"
- {"float", FLOAT_KEYW}
- };
-
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = is_reserved_hash (str, len);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register const char *s = wordlist[key].name;
-
- if (*str == *s && !strcmp (str + 1, s + 1))
- return &wordlist[key];
- }
- }
- return 0;
-}
diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l
index 5235aa507ba5..d29c774f51b6 100644
--- a/scripts/genksyms/lex.l
+++ b/scripts/genksyms/lex.l
@@ -94,7 +94,7 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
/* Bring in the keyword recognizer. */
-#include "keywords.hash.c"
+#include "keywords.c"
/* Macros to append to our phrase collection list. */
@@ -186,10 +186,10 @@ repeat:
case IDENT:
APP;
{
- const struct resword *r = is_reserved_word(yytext, yyleng);
- if (r)
+ int r = is_reserved_word(yytext, yyleng);
+ if (r >= 0)
{
- switch (token = r->token)
+ switch (token = r)
{
case ATTRIBUTE_KEYW:
lexstate = ST_ATTRIBUTE;
@@ -292,7 +292,7 @@ repeat:
case ST_TYPEOF_1:
if (token == IDENT)
{
- if (is_reserved_word(yytext, yyleng)
+ if (is_reserved_word(yytext, yyleng) >= 0
|| find_symbol(yytext, SYM_TYPEDEF, 1))
{
yyless(0);
diff --git a/scripts/genksyms/lex.lex.c_shipped b/scripts/genksyms/lex.lex.c_shipped
index 985c5541aae4..ba2fda8dfdb2 100644
--- a/scripts/genksyms/lex.lex.c_shipped
+++ b/scripts/genksyms/lex.lex.c_shipped
@@ -1905,7 +1905,7 @@ void yyfree (void * ptr )
/* Bring in the keyword recognizer. */
-#include "keywords.hash.c"
+#include "keywords.c"
/* Macros to append to our phrase collection list. */
@@ -1995,10 +1995,10 @@ repeat:
case IDENT:
APP;
{
- const struct resword *r = is_reserved_word(yytext, yyleng);
- if (r)
+ int r = is_reserved_word(yytext, yyleng);
+ if (r >= 0)
{
- switch (token = r->token)
+ switch (token = r)
{
case ATTRIBUTE_KEYW:
lexstate = ST_ATTRIBUTE;
@@ -2101,7 +2101,7 @@ repeat:
case ST_TYPEOF_1:
if (token == IDENT)
{
- if (is_reserved_word(yytext, yyleng)
+ if (is_reserved_word(yytext, yyleng) >= 0
|| find_symbol(yytext, SYM_TYPEDEF, 1))
{
yyless(0);
diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware
index 1a0a04125f71..f3f230225aba 100755
--- a/scripts/get_dvb_firmware
+++ b/scripts/get_dvb_firmware
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# DVB firmware extractor
#
# (c) 2004 Andrew de Quincey
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 633f2dd3de27..bc443201d3ef 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# (c) 2007, Joe Perches <joe@perches.com>
# created from checkpatch.pl
#
@@ -10,6 +10,7 @@
#
# Licensed under the terms of the GNU GPL License version 2
+use warnings;
use strict;
my $P = $0;
@@ -17,6 +18,7 @@ my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
use Cwd;
+use File::Find;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
@@ -57,6 +59,7 @@ my $from_filename = 0;
my $pattern_depth = 0;
my $version = 0;
my $help = 0;
+my $find_maintainer_files = 0;
my $vcs_used = 0;
@@ -248,6 +251,7 @@ if (!GetOptions(
'sections!' => \$sections,
'fe|file-emails!' => \$file_emails,
'f|file' => \$from_filename,
+ 'find-maintainer-files' => \$find_maintainer_files,
'v|version' => \$version,
'h|help|usage' => \$help,
)) {
@@ -306,36 +310,74 @@ if (!top_of_kernel_tree($lk_path)) {
my @typevalue = ();
my %keyword_hash;
+my @mfiles = ();
-open (my $maint, '<', "${lk_path}MAINTAINERS")
- or die "$P: Can't open MAINTAINERS: $!\n";
-while (<$maint>) {
- my $line = $_;
-
- if ($line =~ m/^([A-Z]):\s*(.*)/) {
- my $type = $1;
- my $value = $2;
-
- ##Filename pattern matching
- if ($type eq "F" || $type eq "X") {
- $value =~ s@\.@\\\.@g; ##Convert . to \.
- $value =~ s/\*/\.\*/g; ##Convert * to .*
- $value =~ s/\?/\./g; ##Convert ? to .
- ##if pattern is a directory and it lacks a trailing slash, add one
- if ((-d $value)) {
- $value =~ s@([^/])$@$1/@;
+sub read_maintainer_file {
+ my ($file) = @_;
+
+ open (my $maint, '<', "$file")
+ or die "$P: Can't open MAINTAINERS file '$file': $!\n";
+ while (<$maint>) {
+ my $line = $_;
+
+ if ($line =~ m/^([A-Z]):\s*(.*)/) {
+ my $type = $1;
+ my $value = $2;
+
+ ##Filename pattern matching
+ if ($type eq "F" || $type eq "X") {
+ $value =~ s@\.@\\\.@g; ##Convert . to \.
+ $value =~ s/\*/\.\*/g; ##Convert * to .*
+ $value =~ s/\?/\./g; ##Convert ? to .
+ ##if pattern is a directory and it lacks a trailing slash, add one
+ if ((-d $value)) {
+ $value =~ s@([^/])$@$1/@;
+ }
+ } elsif ($type eq "K") {
+ $keyword_hash{@typevalue} = $value;
}
- } elsif ($type eq "K") {
- $keyword_hash{@typevalue} = $value;
+ push(@typevalue, "$type:$value");
+ } elsif (!(/^\s*$/ || /^\s*\#/)) {
+ $line =~ s/\n$//g;
+ push(@typevalue, $line);
}
- push(@typevalue, "$type:$value");
- } elsif (!/^(\s)*$/) {
- $line =~ s/\n$//g;
- push(@typevalue, $line);
}
+ close($maint);
+}
+
+sub find_is_maintainer_file {
+ my ($file) = $_;
+ return if ($file !~ m@/MAINTAINERS$@);
+ $file = $File::Find::name;
+ return if (! -f $file);
+ push(@mfiles, $file);
}
-close($maint);
+sub find_ignore_git {
+ return grep { $_ !~ /^\.git$/; } @_;
+}
+
+if (-d "${lk_path}MAINTAINERS") {
+ opendir(DIR, "${lk_path}MAINTAINERS") or die $!;
+ my @files = readdir(DIR);
+ closedir(DIR);
+ foreach my $file (@files) {
+ push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./);
+ }
+}
+
+if ($find_maintainer_files) {
+ find( { wanted => \&find_is_maintainer_file,
+ preprocess => \&find_ignore_git,
+ no_chdir => 1,
+ }, "${lk_path}");
+} else {
+ push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS";
+}
+
+foreach my $file (@mfiles) {
+ read_maintainer_file("$file");
+}
#
# Read mail address map
@@ -872,7 +914,7 @@ sub top_of_kernel_tree {
if ( (-f "${lk_path}COPYING")
&& (-f "${lk_path}CREDITS")
&& (-f "${lk_path}Kbuild")
- && (-f "${lk_path}MAINTAINERS")
+ && (-e "${lk_path}MAINTAINERS")
&& (-f "${lk_path}Makefile")
&& (-f "${lk_path}README")
&& (-d "${lk_path}Documentation")
diff --git a/scripts/headerdep.pl b/scripts/headerdep.pl
index 8dd019bc5a73..ebfcbef4371c 100755
--- a/scripts/headerdep.pl
+++ b/scripts/headerdep.pl
@@ -1,4 +1,5 @@
-#! /usr/bin/perl
+#! /usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# Detect cycles in the header file dependency graph
# Vegard Nossum <vegardno@ifi.uio.no>
diff --git a/scripts/headers.sh b/scripts/headers.sh
index d4dc4de5cea1..e0f883eb39a2 100755
--- a/scripts/headers.sh
+++ b/scripts/headers.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Run headers_$1 command for all suitable architectures
# Stop on error
diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl
index 8b2da054cdc3..b6aec5e4365f 100755
--- a/scripts/headers_check.pl
+++ b/scripts/headers_check.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# headers_check.pl execute a number of trivial consistency checks
#
@@ -18,6 +19,7 @@
#
# 3) Check for leaked CONFIG_ symbols
+use warnings;
use strict;
use File::Basename;
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index fdebd66f8fc1..a18bca720995 100755
--- a/scripts/headers_install.sh
+++ b/scripts/headers_install.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
if [ $# -lt 2 ]
then
@@ -33,7 +34,7 @@ do
sed -r \
-e 's/([ \t(])(__user|__force|__iomem)[ \t]/\1/g' \
-e 's/__attribute_const__([ \t]|$)/\1/g' \
- -e 's@^#include <linux/compiler.h>@@' \
+ -e 's@^#include <linux/compiler(|_types).h>@@' \
-e 's/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g' \
-e 's/(^|[ \t(])(inline|asm|volatile)([ \t(]|$)/\1__\2__\3/g' \
-e 's@#(ifndef|define|endif[ \t]*/[*])[ \t]*_UAPI@#\1 @' \
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 5d554419170b..9ee9bf7fd1a2 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -158,7 +158,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)
else if (str[0] == '$')
return -1;
/* exclude debugging symbols */
- else if (stype == 'N')
+ else if (stype == 'N' || stype == 'n')
return -1;
/* include the type field in the symbol name, so that it gets
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index be603c4fef62..51f1c877b543 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -5,7 +5,6 @@ config*
*.lex.c
*.tab.c
*.tab.h
-zconf.hash.c
*.moc
gconf.glade.h
*.pot
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 90a091b6ae4d..297c1bf35140 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ===========================================================================
# Kernel configuration targets
# These targets are used from top-level makefile
@@ -191,12 +192,12 @@ gconf-objs := gconf.o zconf.tab.o
hostprogs-y := conf nconf mconf kxgettext qconf gconf
clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck
-clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h
+clean-files += zconf.tab.c zconf.lex.c gconf.glade.h
clean-files += config.pot linux.pot
# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
PHONY += $(obj)/dochecklxdialog
-$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
+$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/dochecklxdialog
$(obj)/dochecklxdialog:
$(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOSTLOADLIBES_mconf)
@@ -280,7 +281,7 @@ $(obj)/.tmp_gtkcheck:
fi
endif
-$(obj)/zconf.tab.o: $(obj)/zconf.lex.c $(obj)/zconf.hash.c
+$(obj)/zconf.tab.o: $(obj)/zconf.lex.c
$(obj)/qconf.o: $(obj)/qconf.moc
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
index 55b79ba1ba2a..97f0fee7d173 100755
--- a/scripts/kconfig/check.sh
+++ b/scripts/kconfig/check.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Needed for systems without gettext
$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
#include <libintl.h>
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c
new file mode 100644
index 000000000000..5abbc728fbc4
--- /dev/null
+++ b/scripts/kconfig/kconf_id.c
@@ -0,0 +1,54 @@
+
+static struct kconf_id kconf_id_array[] = {
+ { "mainmenu", T_MAINMENU, TF_COMMAND },
+ { "menu", T_MENU, TF_COMMAND },
+ { "endmenu", T_ENDMENU, TF_COMMAND },
+ { "source", T_SOURCE, TF_COMMAND },
+ { "choice", T_CHOICE, TF_COMMAND },
+ { "endchoice", T_ENDCHOICE, TF_COMMAND },
+ { "comment", T_COMMENT, TF_COMMAND },
+ { "config", T_CONFIG, TF_COMMAND },
+ { "menuconfig", T_MENUCONFIG, TF_COMMAND },
+ { "help", T_HELP, TF_COMMAND },
+ { "---help---", T_HELP, TF_COMMAND },
+ { "if", T_IF, TF_COMMAND|TF_PARAM },
+ { "endif", T_ENDIF, TF_COMMAND },
+ { "depends", T_DEPENDS, TF_COMMAND },
+ { "optional", T_OPTIONAL, TF_COMMAND },
+ { "default", T_DEFAULT, TF_COMMAND, S_UNKNOWN },
+ { "prompt", T_PROMPT, TF_COMMAND },
+ { "tristate", T_TYPE, TF_COMMAND, S_TRISTATE },
+ { "def_tristate", T_DEFAULT, TF_COMMAND, S_TRISTATE },
+ { "bool", T_TYPE, TF_COMMAND, S_BOOLEAN },
+ { "boolean", T_TYPE, TF_COMMAND, S_BOOLEAN },
+ { "def_bool", T_DEFAULT, TF_COMMAND, S_BOOLEAN },
+ { "int", T_TYPE, TF_COMMAND, S_INT },
+ { "hex", T_TYPE, TF_COMMAND, S_HEX },
+ { "string", T_TYPE, TF_COMMAND, S_STRING },
+ { "select", T_SELECT, TF_COMMAND },
+ { "imply", T_IMPLY, TF_COMMAND },
+ { "range", T_RANGE, TF_COMMAND },
+ { "visible", T_VISIBLE, TF_COMMAND },
+ { "option", T_OPTION, TF_COMMAND },
+ { "on", T_ON, TF_PARAM },
+ { "modules", T_OPT_MODULES, TF_OPTION },
+ { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION },
+ { "env", T_OPT_ENV, TF_OPTION },
+ { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION },
+};
+
+#define KCONF_ID_ARRAY_SIZE (sizeof(kconf_id_array)/sizeof(struct kconf_id))
+
+static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len)
+{
+ int i;
+
+ for (i = 0; i < KCONF_ID_ARRAY_SIZE; i++) {
+ struct kconf_id *id = kconf_id_array+i;
+ int l = strlen(id->name);
+
+ if (len == l && !memcmp(str, id->name, len))
+ return id;
+ }
+ return NULL;
+}
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index 2cf23f002d3f..45cb237ab7ef 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LIST_H
#define LIST_H
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 91ca126ea080..cdcbe43e87b3 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -62,7 +62,7 @@ enum conf_def_mode {
#define T_OPT_ALLNOCONFIG_Y 4
struct kconf_id {
- int name;
+ const char *name;
int token;
unsigned int flags;
enum symbol_type stype;
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index d5398718ec2a..5d86e2dfae59 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include <stdarg.h>
/* confdata.c */
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 5075ebf2d3b9..a10bd9d6fafd 100755
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Check ncurses compatibility
# What library to link
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index a9bc5334a478..003114779815 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -271,7 +271,7 @@ static struct mitem k_menu_items[MAX_MENU_ITEMS];
static int items_num;
static int global_exit;
/* the currently selected button */
-const char *current_instructions = menu_instructions;
+static const char *current_instructions = menu_instructions;
static char *dialog_input_result;
static int dialog_input_result_len;
@@ -305,7 +305,7 @@ struct function_keys {
};
static const int function_keys_num = 9;
-struct function_keys function_keys[] = {
+static struct function_keys function_keys[] = {
{
.key_str = "F1",
.func = "Help",
@@ -508,7 +508,7 @@ static int get_mext_match(const char *match_str, match_f flag)
index = (index + items_num) % items_num;
while (true) {
char *str = k_menu_items[index].str;
- if (strcasestr(str, match_str) != 0)
+ if (strcasestr(str, match_str) != NULL)
return index;
if (flag == FIND_NEXT_MATCH_UP ||
flag == MATCH_TINKER_PATTERN_UP)
@@ -1067,7 +1067,7 @@ static int do_match(int key, struct match_state *state, int *ans)
static void conf(struct menu *menu)
{
- struct menu *submenu = 0;
+ struct menu *submenu = NULL;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
int res;
@@ -1234,7 +1234,7 @@ static void show_help(struct menu *menu)
static void conf_choice(struct menu *menu)
{
const char *prompt = _(menu_get_prompt(menu));
- struct menu *child = 0;
+ struct menu *child = NULL;
struct symbol *active;
int selected_index = 0;
int last_top_row = 0;
@@ -1456,7 +1456,7 @@ static void conf_save(void)
}
}
-void setup_windows(void)
+static void setup_windows(void)
{
int lines, columns;
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 4b2f44c20caf..a64b1c31253e 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -129,7 +129,7 @@ static void no_colors_theme(void)
mkattrn(FUNCTION_TEXT, A_REVERSE);
}
-void set_colors()
+void set_colors(void)
{
start_color();
use_default_colors();
@@ -192,7 +192,7 @@ const char *get_line(const char *text, int line_no)
int lines = 0;
if (!text)
- return 0;
+ return NULL;
for (i = 0; text[i] != '\0' && lines < line_no; i++)
if (text[i] == '\n')
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index b8c7b29affc5..a2e83ab17de3 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# Copyright 2005-2009 - Steven Rostedt
# Licensed under the terms of the GNU GPL License version 2
@@ -42,6 +42,7 @@
# mv config_strip .config
# make oldconfig
#
+use warnings;
use strict;
use Getopt::Long;
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
deleted file mode 100644
index ead02edec936..000000000000
--- a/scripts/kconfig/zconf.gperf
+++ /dev/null
@@ -1,50 +0,0 @@
-%language=ANSI-C
-%define hash-function-name kconf_id_hash
-%define lookup-function-name kconf_id_lookup
-%define string-pool-name kconf_id_strings
-%compare-strncmp
-%enum
-%pic
-%struct-type
-
-struct kconf_id;
-
-static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-
-%%
-mainmenu, T_MAINMENU, TF_COMMAND
-menu, T_MENU, TF_COMMAND
-endmenu, T_ENDMENU, TF_COMMAND
-source, T_SOURCE, TF_COMMAND
-choice, T_CHOICE, TF_COMMAND
-endchoice, T_ENDCHOICE, TF_COMMAND
-comment, T_COMMENT, TF_COMMAND
-config, T_CONFIG, TF_COMMAND
-menuconfig, T_MENUCONFIG, TF_COMMAND
-help, T_HELP, TF_COMMAND
----help---, T_HELP, TF_COMMAND
-if, T_IF, TF_COMMAND|TF_PARAM
-endif, T_ENDIF, TF_COMMAND
-depends, T_DEPENDS, TF_COMMAND
-optional, T_OPTIONAL, TF_COMMAND
-default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
-prompt, T_PROMPT, TF_COMMAND
-tristate, T_TYPE, TF_COMMAND, S_TRISTATE
-def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
-bool, T_TYPE, TF_COMMAND, S_BOOLEAN
-boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
-def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
-int, T_TYPE, TF_COMMAND, S_INT
-hex, T_TYPE, TF_COMMAND, S_HEX
-string, T_TYPE, TF_COMMAND, S_STRING
-select, T_SELECT, TF_COMMAND
-imply, T_IMPLY, TF_COMMAND
-range, T_RANGE, TF_COMMAND
-visible, T_VISIBLE, TF_COMMAND
-option, T_OPTION, TF_COMMAND
-on, T_ON, TF_PARAM
-modules, T_OPT_MODULES, TF_OPTION
-defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
-env, T_OPT_ENV, TF_OPTION
-allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION
-%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
deleted file mode 100644
index d51b15de074a..000000000000
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ /dev/null
@@ -1,297 +0,0 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
-/* Command-line: gperf -t --output-file scripts/kconfig/zconf.hash.c_shipped -a -C -E -g -k '1,3,$' -p -t scripts/kconfig/zconf.gperf */
-
-#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
- && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
- && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
- && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
- && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
- && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
- && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
- && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
- && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
- && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
- && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
- && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
- && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
- && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
- && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
- && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
- && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
- && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
- && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
- && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
- && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
- && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
- && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
-/* The character set is not based on ISO-646. */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
-#endif
-
-#line 10 "scripts/kconfig/zconf.gperf"
-struct kconf_id;
-
-static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
-/* maximum key range = 71, duplicates = 0 */
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static unsigned int
-kconf_id_hash (register const char *str, register unsigned int len)
-{
- static const unsigned char asso_values[] =
- {
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 0, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 10, 25, 25,
- 0, 0, 0, 5, 0, 0, 73, 73, 5, 0,
- 10, 5, 45, 73, 20, 20, 0, 15, 15, 73,
- 20, 0, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 73
- };
- register int hval = len;
-
- switch (hval)
- {
- default:
- hval += asso_values[(unsigned char)str[2]];
- /*FALLTHROUGH*/
- case 2:
- case 1:
- hval += asso_values[(unsigned char)str[0]];
- break;
- }
- return hval + asso_values[(unsigned char)str[len - 1]];
-}
-
-struct kconf_id_strings_t
- {
- char kconf_id_strings_str2[sizeof("if")];
- char kconf_id_strings_str3[sizeof("int")];
- char kconf_id_strings_str5[sizeof("endif")];
- char kconf_id_strings_str7[sizeof("default")];
- char kconf_id_strings_str8[sizeof("tristate")];
- char kconf_id_strings_str9[sizeof("endchoice")];
- char kconf_id_strings_str10[sizeof("---help---")];
- char kconf_id_strings_str12[sizeof("def_tristate")];
- char kconf_id_strings_str13[sizeof("def_bool")];
- char kconf_id_strings_str14[sizeof("defconfig_list")];
- char kconf_id_strings_str17[sizeof("on")];
- char kconf_id_strings_str18[sizeof("optional")];
- char kconf_id_strings_str21[sizeof("option")];
- char kconf_id_strings_str22[sizeof("endmenu")];
- char kconf_id_strings_str23[sizeof("mainmenu")];
- char kconf_id_strings_str25[sizeof("menuconfig")];
- char kconf_id_strings_str27[sizeof("modules")];
- char kconf_id_strings_str28[sizeof("allnoconfig_y")];
- char kconf_id_strings_str29[sizeof("menu")];
- char kconf_id_strings_str31[sizeof("select")];
- char kconf_id_strings_str32[sizeof("comment")];
- char kconf_id_strings_str33[sizeof("env")];
- char kconf_id_strings_str35[sizeof("range")];
- char kconf_id_strings_str36[sizeof("choice")];
- char kconf_id_strings_str39[sizeof("bool")];
- char kconf_id_strings_str41[sizeof("source")];
- char kconf_id_strings_str42[sizeof("visible")];
- char kconf_id_strings_str43[sizeof("hex")];
- char kconf_id_strings_str46[sizeof("config")];
- char kconf_id_strings_str47[sizeof("boolean")];
- char kconf_id_strings_str50[sizeof("imply")];
- char kconf_id_strings_str51[sizeof("string")];
- char kconf_id_strings_str54[sizeof("help")];
- char kconf_id_strings_str56[sizeof("prompt")];
- char kconf_id_strings_str72[sizeof("depends")];
- };
-static const struct kconf_id_strings_t kconf_id_strings_contents =
- {
- "if",
- "int",
- "endif",
- "default",
- "tristate",
- "endchoice",
- "---help---",
- "def_tristate",
- "def_bool",
- "defconfig_list",
- "on",
- "optional",
- "option",
- "endmenu",
- "mainmenu",
- "menuconfig",
- "modules",
- "allnoconfig_y",
- "menu",
- "select",
- "comment",
- "env",
- "range",
- "choice",
- "bool",
- "source",
- "visible",
- "hex",
- "config",
- "boolean",
- "imply",
- "string",
- "help",
- "prompt",
- "depends"
- };
-#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
-const struct kconf_id *
-kconf_id_lookup (register const char *str, register unsigned int len)
-{
- enum
- {
- TOTAL_KEYWORDS = 35,
- MIN_WORD_LENGTH = 2,
- MAX_WORD_LENGTH = 14,
- MIN_HASH_VALUE = 2,
- MAX_HASH_VALUE = 72
- };
-
- static const struct kconf_id wordlist[] =
- {
- {-1}, {-1},
-#line 26 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM},
-#line 37 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
- {-1},
-#line 27 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
- {-1},
-#line 30 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
-#line 32 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
-#line 20 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
-#line 25 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_HELP, TF_COMMAND},
- {-1},
-#line 33 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
-#line 36 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
-#line 47 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
- {-1}, {-1},
-#line 45 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_ON, TF_PARAM},
-#line 29 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
- {-1}, {-1},
-#line 44 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_OPTION, TF_COMMAND},
-#line 17 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND},
-#line 15 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_MAINMENU, TF_COMMAND},
- {-1},
-#line 23 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str25, T_MENUCONFIG, TF_COMMAND},
- {-1},
-#line 46 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
-#line 49 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPT_ALLNOCONFIG_Y,TF_OPTION},
-#line 16 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
- {-1},
-#line 40 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
-#line 21 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
-#line 48 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_OPT_ENV, TF_OPTION},
- {-1},
-#line 42 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_RANGE, TF_COMMAND},
-#line 19 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_CHOICE, TF_COMMAND},
- {-1}, {-1},
-#line 34 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1},
-#line 18 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND},
-#line 43 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_VISIBLE, TF_COMMAND},
-#line 38 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_TYPE, TF_COMMAND, S_HEX},
- {-1}, {-1},
-#line 22 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_CONFIG, TF_COMMAND},
-#line 35 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str47, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {-1}, {-1},
-#line 41 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str50, T_IMPLY, TF_COMMAND},
-#line 39 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str51, T_TYPE, TF_COMMAND, S_STRING},
- {-1}, {-1},
-#line 24 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str54, T_HELP, TF_COMMAND},
- {-1},
-#line 31 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str56, T_PROMPT, TF_COMMAND},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
- {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
-#line 28 "scripts/kconfig/zconf.gperf"
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str72, T_DEPENDS, TF_COMMAND}
- };
-
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = kconf_id_hash (str, len);
-
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register int o = wordlist[key].name;
- if (o >= 0)
- {
- register const char *s = o + kconf_id_strings;
-
- if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
- return &wordlist[key];
- }
- }
- }
- return 0;
-}
-#line 50 "scripts/kconfig/zconf.gperf"
-
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index 65b7515a577c..a22b285d759f 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -209,8 +209,8 @@ int zconfparse (void);
/* Copy the second part of user declarations. */
-/* Include zconf.hash.c here so it can see the token constants. */
-#include "zconf.hash.c"
+/* Include kconf_id.c here so it can see the token constants. */
+#include "kconf_id.c"
@@ -1515,7 +1515,7 @@ yyreduce:
case 12:
{
- zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+ zconf_error("unexpected option \"%s\"", (yyvsp[-2].id)->name);
}
break;
@@ -2268,13 +2268,13 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok
{
if (id->token != endtoken) {
zconf_error("unexpected '%s' within %s block",
- kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ id->name, zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconf_error("'%s' in different file than '%s'",
- kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ id->name, zconf_tokenname(starttoken));
fprintf(stderr, "%s:%d: location of the '%s'\n",
current_menu->file->name, current_menu->lineno,
zconf_tokenname(starttoken));
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 001305fa080b..c8f396c3b190 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -101,8 +101,8 @@ static struct menu *current_menu, *current_entry;
} if_entry menu_entry choice_entry
%{
-/* Include zconf.hash.c here so it can see the token constants. */
-#include "zconf.hash.c"
+/* Include zconf_id.c here so it can see the token constants. */
+#include "kconf_id.c"
%}
%%
@@ -119,7 +119,7 @@ stmt_list:
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
| stmt_list option_name error T_EOL
{
- zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
+ zconf_error("unexpected option \"%s\"", $2->name);
}
| stmt_list error T_EOL { zconf_error("invalid statement"); }
;
@@ -551,13 +551,13 @@ static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtok
{
if (id->token != endtoken) {
zconf_error("unexpected '%s' within %s block",
- kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ id->name, zconf_tokenname(starttoken));
zconfnerrs++;
return false;
}
if (current_menu->file != current_file) {
zconf_error("'%s' in different file than '%s'",
- kconf_id_strings + id->name, zconf_tokenname(starttoken));
+ id->name, zconf_tokenname(starttoken));
fprintf(stderr, "%s:%d: location of the '%s'\n",
current_menu->file->name, current_menu->lineno,
zconf_tokenname(starttoken));
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index a26a5f2dce39..67d051edd615 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1,5 +1,6 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
+use warnings;
use strict;
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
@@ -2167,7 +2168,7 @@ sub dump_struct($$) {
my $nested;
if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) {
- #my $decl_type = $1;
+ my $decl_type = $1;
$declaration_name = $2;
my $members = $3;
@@ -2189,9 +2190,11 @@ sub dump_struct($$) {
$members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos;
# replace DECLARE_BITMAP
$members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
+ # replace DECLARE_HASHTABLE
+ $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
create_parameterlist($members, ';', $file);
- check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
+ check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual, $nested);
output_declaration($declaration_name,
'struct',
@@ -2223,6 +2226,9 @@ sub dump_enum($$) {
if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
$declaration_name = $1;
my $members = $2;
+ my %_members;
+
+ $members =~ s/\s+$//;
foreach my $arg (split ',', $members) {
$arg =~ s/^\s*(\w+).*/$1/;
@@ -2232,9 +2238,16 @@ sub dump_enum($$) {
print STDERR "${file}:$.: warning: Enum value '$arg' ".
"not described in enum '$declaration_name'\n";
}
-
+ $_members{$arg} = 1;
}
+ while (my ($k, $v) = each %parameterdescs) {
+ if (!exists($_members{$k})) {
+ print STDERR "${file}:$.: warning: Excess enum value " .
+ "'$k' description in '$declaration_name'\n";
+ }
+ }
+
output_declaration($declaration_name,
'enum',
{'enum' => $declaration_name,
@@ -2502,7 +2515,7 @@ sub check_sections($$$$$$) {
} else {
if ($nested !~ m/\Q$sects[$sx]\E/) {
print STDERR "${file}:$.: warning: " .
- "Excess struct/union/enum/typedef member " .
+ "Excess $decl_type member " .
"'$sects[$sx]' " .
"description in '$decl_name'\n";
++$warnings;
@@ -2763,6 +2776,9 @@ sub process_proto_type($$) {
while (1) {
if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
+ if( length $prototype ) {
+ $prototype .= " "
+ }
$prototype .= $1 . $2;
($2 eq '{') && $brcount++;
($2 eq '}') && $brcount--;
diff --git a/scripts/kernel-doc-xml-ref b/scripts/kernel-doc-xml-ref
deleted file mode 100755
index 104a5a5ba2c8..000000000000
--- a/scripts/kernel-doc-xml-ref
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-
-## Copyright (C) 2015 Intel Corporation ##
-# ##
-## This software falls under the GNU General Public License. ##
-## Please read the COPYING file for more information ##
-#
-#
-# This software reads a XML file and a list of valid interal
-# references to replace Docbook tags with links.
-#
-# The list of "valid internal references" must be one-per-line in the following format:
-# API-struct-foo
-# API-enum-bar
-# API-my-function
-#
-# The software walks over the XML file looking for xml tags representing possible references
-# to the Document. Each reference will be cross checked against the "Valid Internal Reference" list. If
-# the referece is found it replaces its content by a <link> tag.
-#
-# usage:
-# kernel-doc-xml-ref -db filename
-# xml filename > outputfile
-
-# read arguments
-if ($#ARGV != 2) {
- usage();
-}
-
-#Holds the database filename
-my $databasefile;
-my @database;
-
-#holds the inputfile
-my $inputfile;
-my $errors = 0;
-
-my %highlights = (
- "<function>(.*?)</function>",
- "\"<function>\" . convert_function(\$1, \$line) . \"</function>\"",
- "<structname>(.*?)</structname>",
- "\"<structname>\" . convert_struct(\$1) . \"</structname>\"",
- "<funcdef>(.*?)<function>(.*?)</function></funcdef>",
- "\"<funcdef>\" . convert_param(\$1) . \"<function>\$2</function></funcdef>\"",
- "<paramdef>(.*?)<parameter>(.*?)</parameter></paramdef>",
- "\"<paramdef>\" . convert_param(\$1) . \"<parameter>\$2</parameter></paramdef>\"");
-
-while($ARGV[0] =~ m/^-(.*)/) {
- my $cmd = shift @ARGV;
- if ($cmd eq "-db") {
- $databasefile = shift @ARGV
- } else {
- usage();
- }
-}
-$inputfile = shift @ARGV;
-
-sub open_database {
- open (my $handle, '<', $databasefile) or die "Cannot open $databasefile";
- chomp(my @lines = <$handle>);
- close $handle;
-
- @database = @lines;
-}
-
-sub process_file {
- open_database();
-
- my $dohighlight;
- foreach my $pattern (keys %highlights) {
- $dohighlight .= "\$line =~ s:$pattern:$highlights{$pattern}:eg;\n";
- }
-
- open(FILE, $inputfile) or die("Could not open $inputfile") or die ("Cannot open $inputfile");
- foreach my $line (<FILE>) {
- eval $dohighlight;
- print $line;
- }
-}
-
-sub trim($_)
-{
- my $str = $_[0];
- $str =~ s/^\s+|\s+$//g;
- return $str
-}
-
-sub has_key_defined($_)
-{
- if ( grep( /^$_[0]$/, @database)) {
- return 1;
- }
- return 0;
-}
-
-# Gets a <function> content and add it a hyperlink if possible.
-sub convert_function($_)
-{
- my $arg = $_[0];
- my $key = $_[0];
-
- my $line = $_[1];
-
- $key = trim($key);
-
- $key =~ s/[^A-Za-z0-9]/-/g;
- $key = "API-" . $key;
-
- # We shouldn't add links to <funcdef> prototype
- if (!has_key_defined($key) || $line =~ m/\s+<funcdef/i) {
- return $arg;
- }
-
- my $head = $arg;
- my $tail = "";
- if ($arg =~ /(.*?)( ?)$/) {
- $head = $1;
- $tail = $2;
- }
- return "<link linkend=\"$key\">$head</link>$tail";
-}
-
-# Converting a struct text to link
-sub convert_struct($_)
-{
- my $arg = $_[0];
- my $key = $_[0];
- $key =~ s/(struct )?(\w)/$2/g;
- $key =~ s/[^A-Za-z0-9]/-/g;
- $key = "API-struct-" . $key;
-
- if (!has_key_defined($key)) {
- return $arg;
- }
-
- my ($head, $tail) = split_pointer($arg);
- return "<link linkend=\"$key\">$head</link>$tail";
-}
-
-# Identify "object *" elements
-sub split_pointer($_)
-{
- my $arg = $_[0];
- if ($arg =~ /(.*?)( ?\* ?)/) {
- return ($1, $2);
- }
- return ($arg, "");
-}
-
-sub convert_param($_)
-{
- my $type = $_[0];
- my $keyname = convert_key_name($type);
-
- if (!has_key_defined($keyname)) {
- return $type;
- }
-
- my ($head, $tail) = split_pointer($type);
- return "<link linkend=\"$keyname\">$head</link>$tail";
-
-}
-
-# DocBook links are in the API-<TYPE>-<STRUCT-NAME> format
-# This method gets an element and returns a valid DocBook reference for it.
-sub convert_key_name($_)
-{
- #Pattern $2 is optional and might be uninitialized
- no warnings 'uninitialized';
-
- my $str = $_[0];
- $str =~ s/(const|static)? ?(struct)? ?([a-zA-Z0-9_]+) ?(\*|&)?/$2 $3/g ;
-
- # trim
- $str =~ s/^\s+|\s+$//g;
-
- # spaces and _ to -
- $str =~ s/[^A-Za-z0-9]/-/g;
-
- return "API-" . $str;
-}
-
-sub usage {
- print "Usage: $0 -db database filename\n";
- print " xml source file(s) > outputfile\n";
- exit 1;
-}
-
-# starting point
-process_file();
-
-if ($errors) {
- print STDERR "$errors errors\n";
-}
-
-exit($errors);
diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh
index d135882e2c40..f2be0ff9a738 100755
--- a/scripts/ld-version.sh
+++ b/scripts/ld-version.sh
@@ -1,4 +1,5 @@
#!/usr/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
# extract linker version number from stdin and turn into single number
{
gsub(".*\\)", "");
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
new file mode 100755
index 000000000000..2977371b2956
--- /dev/null
+++ b/scripts/leaking_addresses.pl
@@ -0,0 +1,305 @@
+#!/usr/bin/env perl
+#
+# (c) 2017 Tobin C. Harding <me@tobin.cc>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# leaking_addresses.pl: Scan 64 bit kernel for potential leaking addresses.
+# - Scans dmesg output.
+# - Walks directory tree and parses each file (for each directory in @DIRS).
+#
+# You can configure the behaviour of the script;
+#
+# - By adding paths, for directories you do not want to walk;
+# absolute paths: @skip_walk_dirs_abs
+# directory names: @skip_walk_dirs_any
+#
+# - By adding paths, for files you do not want to parse;
+# absolute paths: @skip_parse_files_abs
+# file names: @skip_parse_files_any
+#
+# The use of @skip_xxx_xxx_any causes files to be skipped where ever they occur.
+# For example adding 'fd' to @skip_walk_dirs_any causes the fd/ directory to be
+# skipped for all PID sub-directories of /proc
+#
+# The same thing can be achieved by passing command line options to --dont-walk
+# and --dont-parse. If absolute paths are supplied to these options they are
+# appended to the @skip_xxx_xxx_abs arrays. If file names are supplied to these
+# options, they are appended to the @skip_xxx_xxx_any arrays.
+#
+# Use --debug to output path before parsing, this is useful to find files that
+# cause the script to choke.
+#
+# You may like to set kptr_restrict=2 before running script
+# (see Documentation/sysctl/kernel.txt).
+
+use warnings;
+use strict;
+use POSIX;
+use File::Basename;
+use File::Spec;
+use Cwd 'abs_path';
+use Term::ANSIColor qw(:constants);
+use Getopt::Long qw(:config no_auto_abbrev);
+
+my $P = $0;
+my $V = '0.01';
+
+# Directories to scan.
+my @DIRS = ('/proc', '/sys');
+
+# Command line options.
+my $help = 0;
+my $debug = 0;
+my @dont_walk = ();
+my @dont_parse = ();
+
+# Do not parse these files (absolute path).
+my @skip_parse_files_abs = ('/proc/kmsg',
+ '/proc/kcore',
+ '/proc/fs/ext4/sdb1/mb_groups',
+ '/proc/1/fd/3',
+ '/sys/kernel/debug/tracing/trace_pipe',
+ '/sys/kernel/security/apparmor/revision');
+
+# Do not parse thes files under any subdirectory.
+my @skip_parse_files_any = ('0',
+ '1',
+ '2',
+ 'pagemap',
+ 'events',
+ 'access',
+ 'registers',
+ 'snapshot_raw',
+ 'trace_pipe_raw',
+ 'ptmx',
+ 'trace_pipe');
+
+# Do not walk these directories (absolute path).
+my @skip_walk_dirs_abs = ();
+
+# Do not walk these directories under any subdirectory.
+my @skip_walk_dirs_any = ('self',
+ 'thread-self',
+ 'cwd',
+ 'fd',
+ 'stderr',
+ 'stdin',
+ 'stdout');
+
+sub help
+{
+ my ($exitcode) = @_;
+
+ print << "EOM";
+Usage: $P [OPTIONS]
+Version: $V
+
+Options:
+
+ --dont-walk=<dir> Don't walk tree starting at <dir>.
+ --dont-parse=<file> Don't parse <file>.
+ -d, --debug Display debugging output.
+ -h, --help, --version Display this help and exit.
+
+If an absolute path is passed to --dont_XXX then this path is skipped. If a
+single filename is passed then this file/directory will be skipped when
+appearing under any subdirectory.
+
+Example:
+
+ # Just scan dmesg output.
+ scripts/leaking_addresses.pl --dont_walk_abs /proc --dont_walk_abs /sys
+
+Scans the running (64 bit) kernel for potential leaking addresses.
+
+EOM
+ exit($exitcode);
+}
+
+GetOptions(
+ 'dont-walk=s' => \@dont_walk,
+ 'dont-parse=s' => \@dont_parse,
+ 'd|debug' => \$debug,
+ 'h|help' => \$help,
+ 'version' => \$help
+) or help(1);
+
+help(0) if ($help);
+
+push_to_global();
+
+parse_dmesg();
+walk(@DIRS);
+
+exit 0;
+
+sub debug_arrays
+{
+ print 'dirs_any: ' . join(", ", @skip_walk_dirs_any) . "\n";
+ print 'dirs_abs: ' . join(", ", @skip_walk_dirs_abs) . "\n";
+ print 'parse_any: ' . join(", ", @skip_parse_files_any) . "\n";
+ print 'parse_abs: ' . join(", ", @skip_parse_files_abs) . "\n";
+}
+
+sub dprint
+{
+ printf(STDERR @_) if $debug;
+}
+
+sub push_in_abs_any
+{
+ my ($in, $abs, $any) = @_;
+
+ foreach my $path (@$in) {
+ if (File::Spec->file_name_is_absolute($path)) {
+ push @$abs, $path;
+ } elsif (index($path,'/') == -1) {
+ push @$any, $path;
+ } else {
+ print 'path error: ' . $path;
+ }
+ }
+}
+
+# Push command line options to global arrays.
+sub push_to_global
+{
+ push_in_abs_any(\@dont_walk, \@skip_walk_dirs_abs, \@skip_walk_dirs_any);
+ push_in_abs_any(\@dont_parse, \@skip_parse_files_abs, \@skip_parse_files_any);
+}
+
+sub is_false_positive
+{
+ my ($match) = @_;
+
+ if ($match =~ '\b(0x)?(f|F){16}\b' or
+ $match =~ '\b(0x)?0{16}\b') {
+ return 1;
+ }
+
+ # vsyscall memory region, we should probably check against a range here.
+ if ($match =~ '\bf{10}600000\b' or
+ $match =~ '\bf{10}601000\b') {
+ return 1;
+ }
+
+ return 0;
+}
+
+# True if argument potentially contains a kernel address.
+sub may_leak_address
+{
+ my ($line) = @_;
+ my $address = '\b(0x)?ffff[[:xdigit:]]{12}\b';
+
+ # Signal masks.
+ if ($line =~ '^SigBlk:' or
+ $line =~ '^SigCgt:') {
+ return 0;
+ }
+
+ if ($line =~ '\bKEY=[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b' or
+ $line =~ '\b[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b') {
+ return 0;
+ }
+
+ while (/($address)/g) {
+ if (!is_false_positive($1)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+sub parse_dmesg
+{
+ open my $cmd, '-|', 'dmesg';
+ while (<$cmd>) {
+ if (may_leak_address($_)) {
+ print 'dmesg: ' . $_;
+ }
+ }
+ close $cmd;
+}
+
+# True if we should skip this path.
+sub skip
+{
+ my ($path, $paths_abs, $paths_any) = @_;
+
+ foreach (@$paths_abs) {
+ return 1 if (/^$path$/);
+ }
+
+ my($filename, $dirs, $suffix) = fileparse($path);
+ foreach (@$paths_any) {
+ return 1 if (/^$filename$/);
+ }
+
+ return 0;
+}
+
+sub skip_parse
+{
+ my ($path) = @_;
+ return skip($path, \@skip_parse_files_abs, \@skip_parse_files_any);
+}
+
+sub parse_file
+{
+ my ($file) = @_;
+
+ if (! -R $file) {
+ return;
+ }
+
+ if (skip_parse($file)) {
+ dprint "skipping file: $file\n";
+ return;
+ }
+ dprint "parsing: $file\n";
+
+ open my $fh, "<", $file or return;
+ while ( <$fh> ) {
+ if (may_leak_address($_)) {
+ print $file . ': ' . $_;
+ }
+ }
+ close $fh;
+}
+
+
+# True if we should skip walking this directory.
+sub skip_walk
+{
+ my ($path) = @_;
+ return skip($path, \@skip_walk_dirs_abs, \@skip_walk_dirs_any)
+}
+
+# Recursively walk directory tree.
+sub walk
+{
+ my @dirs = @_;
+ my %seen;
+
+ while (my $pwd = shift @dirs) {
+ next if (skip_walk($pwd));
+ next if (!opendir(DIR, $pwd));
+ my @files = readdir(DIR);
+ closedir(DIR);
+
+ foreach my $file (@files) {
+ next if ($file eq '.' or $file eq '..');
+
+ my $path = "$pwd/$file";
+ next if (-l $path);
+
+ if (-d $path) {
+ push @dirs, $path;
+ } else {
+ parse_file($path);
+ }
+ }
+ }
+}
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index c80291319cb2..e6818b8e7141 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -1,11 +1,15 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# link vmlinux
#
# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and
-# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories
-# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
-# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.
+# $(KBUILD_VMLINUX_MAIN) and $(KBUILD_VMLINUX_LIBS). Most are built-in.o files
+# from top-level directories in the kernel tree, others are specified in
+# arch/$(ARCH)/Makefile. Ordering when linking is important, and
+# $(KBUILD_VMLINUX_INIT) must be first. $(KBUILD_VMLINUX_LIBS) are archives
+# which are linked conditionally (not within --whole-archive), and do not
+# require symbol indexes added.
#
# vmlinux
# ^
@@ -16,6 +20,9 @@
# +--< $(KBUILD_VMLINUX_MAIN)
# | +--< drivers/built-in.o mm/built-in.o + more
# |
+# +--< $(KBUILD_VMLINUX_LIBS)
+# | +--< lib/lib.a + more
+# |
# +-< ${kallsymso} (see description in KALLSYMS section)
#
# vmlinux version (uname -v) cannot be updated during normal
@@ -37,9 +44,10 @@ info()
fi
}
-# Thin archive build here makes a final archive with
-# symbol table and indexes from vmlinux objects, which can be
-# used as input to linker.
+# Thin archive build here makes a final archive with symbol table and indexes
+# from vmlinux objects INIT and MAIN, which can be used as input to linker.
+# KBUILD_VMLINUX_LIBS archives should already have symbol table and indexes
+# added.
#
# Traditional incremental style of link does not require this step
#
@@ -50,7 +58,7 @@ archive_builtin()
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
info AR built-in.o
rm -f built-in.o;
- ${AR} rcsT${KBUILD_ARFLAGS} built-in.o \
+ ${AR} rcsTP${KBUILD_ARFLAGS} built-in.o \
${KBUILD_VMLINUX_INIT} \
${KBUILD_VMLINUX_MAIN}
fi
@@ -63,11 +71,17 @@ modpost_link()
local objects
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="--whole-archive built-in.o"
+ objects="--whole-archive \
+ built-in.o \
+ --no-whole-archive \
+ --start-group \
+ ${KBUILD_VMLINUX_LIBS} \
+ --end-group"
else
objects="${KBUILD_VMLINUX_INIT} \
--start-group \
${KBUILD_VMLINUX_MAIN} \
+ ${KBUILD_VMLINUX_LIBS} \
--end-group"
fi
${LD} ${LDFLAGS} -r -o ${1} ${objects}
@@ -83,11 +97,18 @@ vmlinux_link()
if [ "${SRCARCH}" != "um" ]; then
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="--whole-archive built-in.o ${1}"
+ objects="--whole-archive \
+ built-in.o \
+ --no-whole-archive \
+ --start-group \
+ ${KBUILD_VMLINUX_LIBS} \
+ --end-group \
+ ${1}"
else
objects="${KBUILD_VMLINUX_INIT} \
--start-group \
${KBUILD_VMLINUX_MAIN} \
+ ${KBUILD_VMLINUX_LIBS} \
--end-group \
${1}"
fi
@@ -96,11 +117,18 @@ vmlinux_link()
-T ${lds} ${objects}
else
if [ -n "${CONFIG_THIN_ARCHIVES}" ]; then
- objects="-Wl,--whole-archive built-in.o ${1}"
+ objects="-Wl,--whole-archive \
+ built-in.o \
+ -Wl,--no-whole-archive \
+ -Wl,--start-group \
+ ${KBUILD_VMLINUX_LIBS} \
+ -Wl,--end-group \
+ ${1}"
else
objects="${KBUILD_VMLINUX_INIT} \
-Wl,--start-group \
${KBUILD_VMLINUX_MAIN} \
+ ${KBUILD_VMLINUX_LIBS} \
-Wl,--end-group \
${1}"
fi
diff --git a/scripts/makelst b/scripts/makelst
index e6581496d820..e432af073a65 100755
--- a/scripts/makelst
+++ b/scripts/makelst
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# A script to dump mixed source code & assembly
# with correct relocations from System.map
# Requires the following lines in makefile:
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index c21d16328d3f..70dcfb6b3de1 100755
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
use File::Basename;
use Math::BigInt;
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 6fdc97ef6023..959199c3147e 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
TARGET=$1
ARCH=$2
@@ -76,7 +77,7 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
echo \#define LINUX_COMPILE_BY \"`echo $LINUX_COMPILE_BY | $UTS_TRUNCATE`\"
echo \#define LINUX_COMPILE_HOST \"`echo $LINUX_COMPILE_HOST | $UTS_TRUNCATE`\"
- echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version '`\"
+ echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//'`\"
) > .tmpcompile
# Only replace the real compile.h if the new one is different,
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index 84af27bf0f99..e19d6565f245 100755
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Generates a small Makefile used in the root of the output
# directory, to allow make to be started from there.
# The Makefile also allow for more convinient build of external modules
diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh
index 446739c7843a..4b1fe09e9042 100755
--- a/scripts/mkuboot.sh
+++ b/scripts/mkuboot.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
#
# Build U-Boot image when `mkimage' tool is available.
diff --git a/scripts/mkversion b/scripts/mkversion
deleted file mode 100644
index c12addc9c7ef..000000000000
--- a/scripts/mkversion
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ ! -f .version ]
-then
- echo 1
-else
- expr 0`cat .version` + 1
-fi
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
index b497d9764dcf..42c5d50f2bcc 100644
--- a/scripts/mod/Makefile
+++ b/scripts/mod/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y
hostprogs-y := modpost mk_elfconfig
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index e4d90e50f6fe..6d0193a3c591 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/kbuild.h>
#include <linux/mod_devicetable.h>
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index a4fd71d71d65..680eade89be1 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 30d752a4a6a6..f51cf977c65b 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -47,6 +47,12 @@ enum export {
export_unused_gpl, export_gpl_future, export_unknown
};
+/* In kernel, this size is defined in linux/module.h;
+ * here we use Elf_Addr instead of long for covering cross-compile
+ */
+
+#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
+
#define PRINTF __attribute__ ((format (printf, 1, 2)))
PRINTF void fatal(const char *fmt, ...)
@@ -261,7 +267,17 @@ static enum export export_no(const char *s)
return export_unknown;
}
-static const char *sec_name(struct elf_info *elf, int secindex);
+static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
+{
+ return (void *)elf->hdr +
+ elf->sechdrs[elf->secindex_strings].sh_offset +
+ sechdr->sh_name;
+}
+
+static const char *sec_name(struct elf_info *elf, int secindex)
+{
+ return sech_name(elf, &elf->sechdrs[secindex]);
+}
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
@@ -775,21 +791,6 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
return "(unknown)";
}
-static const char *sec_name(struct elf_info *elf, int secindex)
-{
- Elf_Shdr *sechdrs = elf->sechdrs;
- return (void *)elf->hdr +
- elf->sechdrs[elf->secindex_strings].sh_offset +
- sechdrs[secindex].sh_name;
-}
-
-static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
-{
- return (void *)elf->hdr +
- elf->sechdrs[elf->secindex_strings].sh_offset +
- sechdr->sh_name;
-}
-
/* The pattern is an array of simple patterns.
* "foo" will match an exact string equal to "foo"
* "*foo" will match a string that ends with "foo"
@@ -1962,7 +1963,7 @@ static void read_symbols(char *modname)
}
license = get_modinfo(info.modinfo, info.modinfo_len, "license");
- if (info.modinfo && !license && !is_vmlinux(modname))
+ if (!license && !is_vmlinux(modname))
warn("modpost: missing MODULE_LICENSE() in %s\n"
"see include/linux/module.h for "
"more information\n", modname);
@@ -2116,6 +2117,23 @@ static void check_exports(struct module *mod)
}
}
+static int check_modname_len(struct module *mod)
+{
+ const char *mod_name;
+
+ mod_name = strrchr(mod->name, '/');
+ if (mod_name == NULL)
+ mod_name = mod->name;
+ else
+ mod_name++;
+ if (strlen(mod_name) >= MODULE_NAME_LEN) {
+ merror("module name is too long [%s.ko]\n", mod->name);
+ return 1;
+ }
+
+ return 0;
+}
+
/**
* Header for the generated file
**/
@@ -2126,6 +2144,7 @@ static void add_header(struct buffer *b, struct module *mod)
buf_printf(b, "#include <linux/compiler.h>\n");
buf_printf(b, "\n");
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
+ buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
buf_printf(b, "\n");
buf_printf(b, "__visible struct module __this_module\n");
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
@@ -2154,11 +2173,6 @@ static void add_staging_flag(struct buffer *b, const char *name)
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
}
-/* In kernel, this size is defined in linux/module.h;
- * here we use Elf_Addr instead of long for covering cross-compile
- */
-#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
-
/**
* Record CRCs for unresolved symbols
**/
@@ -2489,6 +2503,7 @@ int main(int argc, char **argv)
buf.pos = 0;
+ err |= check_modname_len(mod);
add_header(&buf, mod);
add_intree_flag(&buf, !external_module);
add_staging_flag(&buf, mod->name);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 6a5e1515123b..8453d6ac2f77 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
index 9f3c9d47a4a5..729c547fc9e1 100755
--- a/scripts/namespace.pl
+++ b/scripts/namespace.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# namespace.pl. Mon Aug 30 2004
#
@@ -62,7 +62,7 @@
# result.
#
-require 5; # at least perl 5
+use warnings;
use strict;
use File::Find;
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 71b4a8af9d4d..73f9f3192b9f 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -50,8 +50,6 @@ rpm-pkg rpm: FORCE
$(MAKE) clean
$(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
- $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
- mv -f $(objtree)/.tmp_version $(objtree)/.version
rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
rm $(KERNELPATH).tar.gz kernel.spec
@@ -60,9 +58,6 @@ rpm-pkg rpm: FORCE
binrpm-pkg: FORCE
$(MAKE) KBUILD_SRC=
$(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec
- $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
- mv -f $(objtree)/.tmp_version $(objtree)/.version
-
rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
$(UTS_MACHINE) -bb $(objtree)/binkernel.spec
rm binkernel.spec
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index aad67000e4dd..0bc87473f68f 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -92,12 +92,10 @@ else
fi
sourcename=$KDEB_SOURCENAME
tmpdir="$objtree/debian/tmp"
-fwdir="$objtree/debian/fwtmp"
kernel_headers_dir="$objtree/debian/hdrtmp"
libc_headers_dir="$objtree/debian/headertmp"
dbg_dir="$objtree/debian/dbgtmp"
packagename=linux-image-$version
-fwpackagename=linux-firmware-image-$version
kernel_headers_packagename=linux-headers-$version
libc_headers_packagename=linux-libc-dev
dbg_packagename=$packagename-dbg
@@ -126,10 +124,9 @@ esac
BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
# Setup the directory structure
-rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
+rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
mkdir -m 755 -p "$tmpdir/DEBIAN"
mkdir -p "$tmpdir/lib" "$tmpdir/boot"
-mkdir -p "$fwdir/lib/firmware/$version/"
mkdir -p "$kernel_headers_dir/lib/modules/$version/"
# Build and install the kernel
@@ -306,7 +303,6 @@ else
cat <<EOF >> debian/control
Package: $packagename
-Suggests: $fwpackagename
Architecture: any
Description: Linux kernel, version $version
This package contains the Linux kernel, modules and corresponding other
@@ -345,22 +341,6 @@ Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch}
This is useful for people who need to build external modules
EOF
-# Do we have firmware? Move it out of the way and build it into a package.
-if [ -e "$tmpdir/lib/firmware" ]; then
- mv "$tmpdir/lib/firmware"/* "$fwdir/lib/firmware/$version/"
- rmdir "$tmpdir/lib/firmware"
-
- cat <<EOF >> debian/control
-
-Package: $fwpackagename
-Architecture: all
-Description: Linux kernel firmware, version $version
- This package contains firmware from the Linux kernel, version $version.
-EOF
-
- create_package "$fwpackagename" "$fwdir"
-fi
-
cat <<EOF >> debian/control
Package: $libc_headers_packagename
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index e046bff33589..e8cc72a51b32 100755
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# buildtar 0.0.4
@@ -24,20 +25,19 @@ tarball="${objtree}/linux-${KERNELRELEASE}-${ARCH}.tar"
#
case "${1}" in
tar-pkg)
- compress="cat"
- file_ext=""
+ opts=
;;
targz-pkg)
- compress="gzip"
- file_ext=".gz"
+ opts=--gzip
+ tarball=${tarball}.gz
;;
tarbz2-pkg)
- compress="bzip2"
- file_ext=".bz2"
+ opts=--bzip2
+ tarball=${tarball}.bz2
;;
tarxz-pkg)
- compress="xz"
- file_ext=".xz"
+ opts=--xz
+ tarball=${tarball}.xz
;;
*)
echo "Unknown tarball target \"${1}\" requested, please add it to ${0}." >&2
@@ -51,13 +51,14 @@ esac
#
rm -rf -- "${tmpdir}"
mkdir -p -- "${tmpdir}/boot"
-
+dirs=boot
#
# Try to install modules
#
-if grep -q '^CONFIG_MODULES=y' "${objtree}/.config"; then
+if grep -q '^CONFIG_MODULES=y' "${KCONFIG_CONFIG}"; then
make ARCH="${ARCH}" O="${objtree}" KBUILD_SRC= INSTALL_MOD_PATH="${tmpdir}" modules_install
+ dirs="$dirs lib"
fi
@@ -65,7 +66,7 @@ fi
# Install basic kernel files
#
cp -v -- "${objtree}/System.map" "${tmpdir}/boot/System.map-${KERNELRELEASE}"
-cp -v -- "${objtree}/.config" "${tmpdir}/boot/config-${KERNELRELEASE}"
+cp -v -- "${KCONFIG_CONFIG}" "${tmpdir}/boot/config-${KERNELRELEASE}"
cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
@@ -124,14 +125,12 @@ esac
#
# Create the tarball
#
-(
- opts=
- if tar --owner=root --group=root --help >/dev/null 2>&1; then
- opts="--owner=root --group=root"
- fi
- tar cf - -C "$tmpdir" boot/ lib/ $opts | ${compress} > "${tarball}${file_ext}"
-)
+if tar --owner=root --group=root --help >/dev/null 2>&1; then
+ opts="$opts --owner=root --group=root"
+fi
+
+tar cf $tarball -C $tmpdir $opts $dirs
-echo "Tarball successfully created in ${tarball}${file_ext}"
+echo "Tarball successfully created in $tarball"
exit 0
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index bb43f153fd8e..f47f17aae135 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -27,9 +27,7 @@ __KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"`
echo "Name: kernel"
echo "Summary: The Linux Kernel"
echo "Version: $__KERNELRELEASE"
-# we need to determine the NEXT version number so that uname and
-# rpm -q will agree
-echo "Release: `. $srctree/scripts/mkversion`"
+echo "Release: $(cat .version 2>/dev/null || echo 1)"
echo "License: GPL"
echo "Group: System Environment/Kernel"
echo "Vendor: The Linux Community"
@@ -77,7 +75,7 @@ fi
echo "%build"
if ! $PREBUILT; then
-echo "make clean && make %{?_smp_mflags}"
+echo "make clean && make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}"
echo ""
fi
@@ -88,11 +86,8 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules'
echo "%else"
echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
echo "%endif"
-echo 'mkdir -p $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
-echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= mod-fw= modules_install'
-echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
-echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
+echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install'
echo "%ifarch ia64"
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
@@ -119,7 +114,7 @@ if ! $PREBUILT; then
echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/build"
echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/source"
echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE"
-echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude=firmware --exclude .config.old --exclude .missing-syscalls.d\""
+echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude .config.old --exclude .missing-syscalls.d\""
echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)"
echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE"
echo "ln -sf /usr/src/kernels/$KERNELRELEASE build"
@@ -154,7 +149,6 @@ echo '%defattr (-, root, root)'
echo "/lib/modules/$KERNELRELEASE"
echo "%exclude /lib/modules/$KERNELRELEASE/build"
echo "%exclude /lib/modules/$KERNELRELEASE/source"
-echo "/lib/firmware/$KERNELRELEASE"
echo "/boot/*"
echo ""
echo "%files headers"
diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl
new file mode 100644
index 000000000000..5dbd2faa2449
--- /dev/null
+++ b/scripts/parse-maintainers.pl
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -w
+# SPDX-License-Identifier: GPL-2.0
+
+use strict;
+
+my $P = $0;
+
+# sort comparison functions
+sub by_category($$) {
+ my ($a, $b) = @_;
+
+ $a = uc $a;
+ $b = uc $b;
+
+ # This always sorts last
+ $a =~ s/THE REST/ZZZZZZ/g;
+ $b =~ s/THE REST/ZZZZZZ/g;
+
+ return $a cmp $b;
+}
+
+sub by_pattern($$) {
+ my ($a, $b) = @_;
+ my $preferred_order = 'MRPLSWTQBCFXNK';
+
+ my $a1 = uc(substr($a, 0, 1));
+ my $b1 = uc(substr($b, 0, 1));
+
+ my $a_index = index($preferred_order, $a1);
+ my $b_index = index($preferred_order, $b1);
+
+ $a_index = 1000 if ($a_index == -1);
+ $b_index = 1000 if ($b_index == -1);
+
+ if (($a1 =~ /^F$/ && $b1 =~ /^F$/) ||
+ ($a1 =~ /^X$/ && $b1 =~ /^X$/)) {
+ return $a cmp $b;
+ }
+
+ if ($a_index < $b_index) {
+ return -1;
+ } elsif ($a_index == $b_index) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+sub trim {
+ my $s = shift;
+ $s =~ s/\s+$//;
+ $s =~ s/^\s+//;
+ return $s;
+}
+
+sub alpha_output {
+ my ($hashref, $filename) = (@_);
+
+ open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n";
+ foreach my $key (sort by_category keys %$hashref) {
+ if ($key eq " ") {
+ chomp $$hashref{$key};
+ print $file $$hashref{$key};
+ } else {
+ print $file "\n" . $key . "\n";
+ foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) {
+ print $file ($pattern . "\n");
+ }
+ }
+ }
+ close($file);
+}
+
+sub file_input {
+ my ($hashref, $filename) = (@_);
+
+ my $lastline = "";
+ my $case = " ";
+ $$hashref{$case} = "";
+
+ open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n";
+
+ while (<$file>) {
+ my $line = $_;
+
+ # Pattern line?
+ if ($line =~ m/^([A-Z]):\s*(.*)/) {
+ $line = $1 . ":\t" . trim($2) . "\n";
+ if ($lastline eq "") {
+ $$hashref{$case} = $$hashref{$case} . $line;
+ next;
+ }
+ $case = trim($lastline);
+ exists $$hashref{$case} and die "Header '$case' already exists";
+ $$hashref{$case} = $line;
+ $lastline = "";
+ next;
+ }
+
+ if ($case eq " ") {
+ $$hashref{$case} = $$hashref{$case} . $lastline;
+ $lastline = $line;
+ next;
+ }
+ trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'");
+ $lastline = $line;
+ }
+ $$hashref{$case} = $$hashref{$case} . $lastline;
+ close($file);
+}
+
+my %hash;
+my %new_hash;
+
+file_input(\%hash, "MAINTAINERS");
+
+foreach my $type (@ARGV) {
+ foreach my $key (keys %hash) {
+ if ($key =~ /$type/ || $hash{$key} =~ /$type/) {
+ $new_hash{$key} = $hash{$key};
+ delete $hash{$key};
+ }
+ }
+}
+
+alpha_output(\%hash, "MAINTAINERS.new");
+alpha_output(\%new_hash, "SECTION.new");
+
+exit(0);
diff --git a/scripts/patch-kernel b/scripts/patch-kernel
index 49b4241e814a..033d5916797d 100755
--- a/scripts/patch-kernel
+++ b/scripts/patch-kernel
@@ -1,4 +1,5 @@
#! /bin/sh
+# SPDX-License-Identifier: GPL-2.0
# Script to apply kernel patches.
# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
# The source directory defaults to /usr/src/linux, and the patch
diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl
index 6943fa7cc95b..316e71918ac8 100755
--- a/scripts/profile2linkerlist.pl
+++ b/scripts/profile2linkerlist.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
#
# Takes a (sorted) output of readprofile and turns it into a list suitable for
diff --git a/scripts/prune-kernel b/scripts/prune-kernel
index ab5034e1d081..e8aa940bc0a9 100755
--- a/scripts/prune-kernel
+++ b/scripts/prune-kernel
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
# because I use CONFIG_LOCALVERSION_AUTO, not the same version again and
# again, /boot and /lib/modules/ eventually fill up.
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index 1633c3e6c0b9..2033af758173 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# (c) 2008, Steven Rostedt <srostedt@redhat.com>
# Licensed under the terms of the GNU GPL License version 2
#
@@ -106,6 +106,7 @@
# 9) Move the result back to the original object.
#
+use warnings;
use strict;
my $P = $0;
diff --git a/scripts/selinux/README b/scripts/selinux/README
index 4d020ecb7524..5ba679c5be18 100644
--- a/scripts/selinux/README
+++ b/scripts/selinux/README
@@ -1,2 +1,2 @@
-Please see Documentation/security/SELinux.txt for information on
+Please see Documentation/admin-guide/LSM/SELinux.rst for information on
installing a dummy SELinux policy.
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
index 6fc2b8789a0b..e8c533140981 100644
--- a/scripts/selinux/genheaders/Makefile
+++ b/scripts/selinux/genheaders/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
hostprogs-y := genheaders
HOST_EXTRACFLAGS += \
-I$(srctree)/include/uapi -I$(srctree)/include \
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
index 6a24569c3578..fa48fabcb330 100644
--- a/scripts/selinux/genheaders/genheaders.c
+++ b/scripts/selinux/genheaders/genheaders.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* NOTE: we really do want to use the kernel headers here */
#define __EXPORTED_HEADERS__
@@ -129,11 +130,16 @@ int main(int argc, char *argv[])
for (i = 0; secclass_map[i].name; i++) {
struct security_class_mapping *map = &secclass_map[i];
for (j = 0; map->perms[j]; j++) {
+ if (j >= 32) {
+ fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n",
+ map->name, map->perms[j]);
+ exit(5);
+ }
fprintf(fout, "#define %s__%s", map->name,
map->perms[j]);
for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
fprintf(fout, " ");
- fprintf(fout, "0x%08xUL\n", (1<<j));
+ fprintf(fout, "0x%08xU\n", (1<<j));
}
}
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
index f6a0ce71015f..0b86c47baf7d 100755
--- a/scripts/selinux/install_policy.sh
+++ b/scripts/selinux/install_policy.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
if [ `id -u` -ne 0 ]; then
echo "$0: must be root to install the selinux policy"
exit 1
diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile
index d6a83cafe59f..e9c92db7e2a3 100644
--- a/scripts/selinux/mdp/Makefile
+++ b/scripts/selinux/mdp/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
hostprogs-y := mdp
HOST_EXTRACFLAGS += \
-I$(srctree)/include/uapi -I$(srctree)/include \
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 966dd3924ea9..71f39410691b 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
#
# This scripts adds local version information from the version
# control systems git, mercurial (hg) and subversion (svn).
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
index eb38f49d4b75..aa0cc49ad1ad 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -53,7 +53,9 @@ acumulator||accumulator
adapater||adapter
addional||additional
additionaly||additionally
+additonal||additional
addres||address
+adddress||address
addreses||addresses
addresss||address
aditional||additional
@@ -66,6 +68,8 @@ adviced||advised
afecting||affecting
againt||against
agaist||against
+aggreataon||aggregation
+aggreation||aggregation
albumns||albums
alegorical||allegorical
algined||aligned
@@ -79,6 +83,8 @@ aligment||alignment
alignement||alignment
allign||align
alligned||aligned
+alllocate||allocate
+alloated||allocated
allocatote||allocate
allocatrd||allocated
allocte||allocate
@@ -130,6 +136,7 @@ arraival||arrival
artifical||artificial
artillary||artillery
asign||assign
+asser||assert
assertation||assertion
assiged||assigned
assigment||assignment
@@ -149,6 +156,7 @@ atempt||attempt
attachement||attachment
attched||attached
attemps||attempts
+attemping||attempting
attruibutes||attributes
authentification||authentication
automaticaly||automatically
@@ -168,6 +176,7 @@ availale||available
availavility||availability
availble||available
availiable||available
+availible||available
avalable||available
avaliable||available
aysnc||async
@@ -200,14 +209,18 @@ broadcat||broadcast
cacluated||calculated
caculation||calculation
calender||calendar
+calescing||coalescing
calle||called
callibration||calibration
calucate||calculate
calulate||calculate
cancelation||cancellation
+cancle||cancel
capabilites||capabilities
+capabilty||capability
capabitilies||capabilities
capatibilities||capabilities
+capapbilities||capabilities
carefuly||carefully
cariage||carriage
catagory||category
@@ -216,6 +229,7 @@ challange||challenge
challanges||challenges
chanell||channel
changable||changeable
+chanined||chained
channle||channel
channnel||channel
charachter||character
@@ -241,6 +255,7 @@ claread||cleared
clared||cleared
closeing||closing
clustred||clustered
+coexistance||coexistence
collapsable||collapsible
colorfull||colorful
comand||command
@@ -269,6 +284,7 @@ completition||completion
completly||completely
complient||compliant
componnents||components
+compoment||component
compres||compress
compresion||compression
comression||compression
@@ -294,6 +310,7 @@ containts||contains
contaisn||contains
contant||contact
contence||contents
+continious||continuous
continous||continuous
continously||continuously
continueing||continuing
@@ -315,6 +332,7 @@ correponding||corresponding
correponds||corresponds
correspoding||corresponding
cotrol||control
+cound||could
couter||counter
coutner||counter
cryptocraphic||cryptographic
@@ -326,6 +344,7 @@ deafult||default
deamon||daemon
decompres||decompress
decription||description
+dectected||detected
defailt||default
defferred||deferred
definate||definite
@@ -343,6 +362,8 @@ delare||declare
delares||declares
delaring||declaring
delemiter||delimiter
+demodualtor||demodulator
+demension||dimension
dependancies||dependencies
dependancy||dependency
dependant||dependent
@@ -357,11 +378,13 @@ descritptor||descriptor
desctiptor||descriptor
desriptor||descriptor
desriptors||descriptors
+destionation||destination
destory||destroy
destoryed||destroyed
destorys||destroys
destroied||destroyed
detabase||database
+deteced||detected
develope||develop
developement||development
developped||developed
@@ -379,6 +402,7 @@ differrence||difference
diffrent||different
diffrentiate||differentiate
difinition||definition
+dimesions||dimensions
diplay||display
direectly||directly
disassocation||disassociation
@@ -419,9 +443,11 @@ enchanced||enhanced
encorporating||incorporating
encrupted||encrypted
encrypiton||encryption
+encryptio||encryption
endianess||endianness
enhaced||enhanced
enlightnment||enlightenment
+entrys||entries
enocded||encoded
enterily||entirely
enviroiment||environment
@@ -433,12 +459,14 @@ equiped||equipped
equivelant||equivalent
equivilant||equivalent
eror||error
+errorr||error
estbalishment||establishment
etsablishment||establishment
etsbalishment||establishment
excecutable||executable
exceded||exceeded
excellant||excellent
+exeed||exceed
existance||existence
existant||existent
exixt||exist
@@ -464,9 +492,11 @@ failied||failed
faillure||failure
failue||failure
failuer||failure
+failng||failing
faireness||fairness
falied||failed
faliure||failure
+fallbck||fallback
familar||familiar
fatser||faster
feauture||feature
@@ -475,6 +505,7 @@ fetaure||feature
fetaures||features
fileystem||filesystem
fimware||firmware
+firware||firmware
finanize||finalize
findn||find
finilizes||finalizes
@@ -484,6 +515,7 @@ folloing||following
followign||following
followings||following
follwing||following
+fonud||found
forseeable||foreseeable
forse||force
fortan||fortran
@@ -514,6 +546,7 @@ grabing||grabbing
grahical||graphical
grahpical||graphical
grapic||graphic
+grranted||granted
guage||gauge
guarenteed||guaranteed
guarentee||guarantee
@@ -525,6 +558,7 @@ happend||happened
harware||hardware
heirarchically||hierarchically
helpfull||helpful
+hybernate||hibernate
hierachy||hierarchy
hierarchie||hierarchy
howver||however
@@ -547,16 +581,19 @@ implemenation||implementation
implementaiton||implementation
implementated||implemented
implemention||implementation
+implementd||implemented
implemetation||implementation
implemntation||implementation
implentation||implementation
implmentation||implementation
implmenting||implementing
+incative||inactive
incomming||incoming
incompatabilities||incompatibilities
incompatable||incompatible
inconsistant||inconsistent
increas||increase
+incremeted||incremented
incrment||increment
indendation||indentation
indended||intended
@@ -564,6 +601,7 @@ independant||independent
independantly||independently
independed||independent
indiate||indicate
+indicat||indicate
inexpect||inexpected
infomation||information
informatiom||information
@@ -600,6 +638,7 @@ interger||integer
intermittant||intermittent
internel||internal
interoprability||interoperability
+interuupt||interrupt
interrface||interface
interrrupt||interrupt
interrup||interrupt
@@ -619,8 +658,10 @@ intrrupt||interrupt
intterrupt||interrupt
intuative||intuitive
invaid||invalid
+invald||invalid
invalde||invalid
invalide||invalid
+invalidiate||invalidate
invalud||invalid
invididual||individual
invokation||invocation
@@ -682,6 +723,7 @@ messags||messages
messgaes||messages
messsage||message
messsages||messages
+micropone||microphone
microprocesspr||microprocessor
milliseonds||milliseconds
minium||minimum
@@ -693,11 +735,15 @@ misformed||malformed
mispelled||misspelled
mispelt||misspelt
mising||missing
+mismactch||mismatch
+missmanaged||mismanaged
+missmatch||mismatch
miximum||maximum
mmnemonic||mnemonic
mnay||many
modulues||modules
momery||memory
+memomry||memory
monochorome||monochrome
monochromo||monochrome
monocrome||monochrome
@@ -708,6 +754,7 @@ multidimensionnal||multidimensional
multple||multiple
mumber||number
muticast||multicast
+mutilcast||multicast
mutiple||multiple
mutli||multi
nams||names
@@ -798,6 +845,7 @@ permissons||permissions
peroid||period
persistance||persistence
persistant||persistent
+plalform||platform
platfrom||platform
plattform||platform
pleaes||please
@@ -810,6 +858,8 @@ posible||possible
positon||position
possibilites||possibilities
powerfull||powerful
+preample||preamble
+preapre||prepare
preceeded||preceded
preceeding||preceding
preceed||precede
@@ -868,6 +918,7 @@ psuedo||pseudo
psychadelic||psychedelic
pwoer||power
quering||querying
+randomally||randomly
raoming||roaming
reasearcher||researcher
reasearchers||researchers
@@ -895,6 +946,7 @@ refernnce||reference
refrence||reference
registerd||registered
registeresd||registered
+registerred||registered
registes||registers
registraration||registration
regsiter||register
@@ -923,6 +975,7 @@ requried||required
requst||request
reseting||resetting
resizeable||resizable
+resouce||resource
resouces||resources
resoures||resources
responce||response
@@ -938,6 +991,7 @@ reudce||reduce
reuest||request
reuqest||request
reutnred||returned
+revsion||revision
rmeoved||removed
rmeove||remove
rmeoves||removes
@@ -1030,6 +1084,7 @@ sturcture||structure
subdirectoires||subdirectories
suble||subtle
substract||subtract
+submition||submission
succesfully||successfully
succesful||successful
successed||succeeded
@@ -1049,6 +1104,7 @@ suppoted||supported
suppported||supported
suppport||support
supress||suppress
+surpressed||suppressed
surpresses||suppresses
susbsystem||subsystem
suspeneded||suspended
@@ -1062,6 +1118,7 @@ swithced||switched
swithcing||switching
swithed||switched
swithing||switching
+swtich||switch
symetric||symmetric
synax||syntax
synchonized||synchronized
@@ -1082,7 +1139,9 @@ therfore||therefore
thier||their
threds||threads
threshhold||threshold
+thresold||threshold
throught||through
+troughput||throughput
thses||these
tiggered||triggered
tipically||typically
@@ -1091,6 +1150,7 @@ tmis||this
torerable||tolerable
tramsmitted||transmitted
tramsmit||transmit
+tranasction||transaction
tranfer||transfer
transciever||transceiver
transferd||transferred
@@ -1099,10 +1159,12 @@ transfering||transferring
transision||transition
transmittd||transmitted
transormed||transformed
+trasfer||transfer
trasmission||transmission
treshold||threshold
trigerring||triggering
trun||turn
+tunning||tuning
ture||true
tyep||type
udpate||update
@@ -1167,7 +1229,9 @@ virtaul||virtual
virtiual||virtual
visiters||visitors
vitual||virtual
+wakeus||wakeups
wating||waiting
+wiat||wait
wether||whether
whataver||whatever
whcih||which
diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install
new file mode 100755
index 000000000000..067459760a7b
--- /dev/null
+++ b/scripts/sphinx-pre-install
@@ -0,0 +1,608 @@
+#!/usr/bin/perl
+use strict;
+
+# Copyright (c) 2017 Mauro Carvalho Chehab <mchehab@kernel.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+my $virtenv_dir = "sphinx_1.4";
+my $requirement_file = "Documentation/sphinx/requirements.txt";
+
+#
+# Static vars
+#
+
+my %missing;
+my $system_release;
+my $need = 0;
+my $optional = 0;
+my $need_symlink = 0;
+my $need_sphinx = 0;
+my $install = "";
+
+#
+# Command line arguments
+#
+
+my $pdf = 1;
+my $virtualenv = 1;
+
+#
+# List of required texlive packages on Fedora and OpenSuse
+#
+
+my %texlive = (
+ 'amsfonts.sty' => 'texlive-amsfonts',
+ 'amsmath.sty' => 'texlive-amsmath',
+ 'amssymb.sty' => 'texlive-amsfonts',
+ 'amsthm.sty' => 'texlive-amscls',
+ 'anyfontsize.sty' => 'texlive-anyfontsize',
+ 'atbegshi.sty' => 'texlive-oberdiek',
+ 'bm.sty' => 'texlive-tools',
+ 'capt-of.sty' => 'texlive-capt-of',
+ 'cmap.sty' => 'texlive-cmap',
+ 'ecrm1000.tfm' => 'texlive-ec',
+ 'eqparbox.sty' => 'texlive-eqparbox',
+ 'eu1enc.def' => 'texlive-euenc',
+ 'fancybox.sty' => 'texlive-fancybox',
+ 'fancyvrb.sty' => 'texlive-fancyvrb',
+ 'float.sty' => 'texlive-float',
+ 'fncychap.sty' => 'texlive-fncychap',
+ 'footnote.sty' => 'texlive-mdwtools',
+ 'framed.sty' => 'texlive-framed',
+ 'luatex85.sty' => 'texlive-luatex85',
+ 'multirow.sty' => 'texlive-multirow',
+ 'needspace.sty' => 'texlive-needspace',
+ 'palatino.sty' => 'texlive-psnfss',
+ 'parskip.sty' => 'texlive-parskip',
+ 'polyglossia.sty' => 'texlive-polyglossia',
+ 'tabulary.sty' => 'texlive-tabulary',
+ 'threeparttable.sty' => 'texlive-threeparttable',
+ 'titlesec.sty' => 'texlive-titlesec',
+ 'ucs.sty' => 'texlive-ucs',
+ 'upquote.sty' => 'texlive-upquote',
+ 'wrapfig.sty' => 'texlive-wrapfig',
+);
+
+#
+# Subroutines that checks if a feature exists
+#
+
+sub check_missing(%)
+{
+ my %map = %{$_[0]};
+
+ foreach my $prog (sort keys %missing) {
+ my $is_optional = $missing{$prog};
+
+ if ($is_optional) {
+ print "Warning: better to also install \"$prog\".\n";
+ } else {
+ print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
+ }
+ if (defined($map{$prog})) {
+ $install .= " " . $map{$prog};
+ } else {
+ $install .= " " . $prog;
+ }
+ }
+
+ $install =~ s/^\s//;
+}
+
+sub add_package($$)
+{
+ my $package = shift;
+ my $is_optional = shift;
+
+ $missing{$package} = $is_optional;
+ if ($is_optional) {
+ $optional++;
+ } else {
+ $need++;
+ }
+}
+
+sub check_missing_file($$$)
+{
+ my $file = shift;
+ my $package = shift;
+ my $is_optional = shift;
+
+ return if(-e $file);
+
+ add_package($package, $is_optional);
+}
+
+sub findprog($)
+{
+ foreach(split(/:/, $ENV{PATH})) {
+ return "$_/$_[0]" if(-x "$_/$_[0]");
+ }
+}
+
+sub check_program($$)
+{
+ my $prog = shift;
+ my $is_optional = shift;
+
+ return if findprog($prog);
+
+ add_package($prog, $is_optional);
+}
+
+sub check_perl_module($$)
+{
+ my $prog = shift;
+ my $is_optional = shift;
+
+ my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null");
+ return if ($err == 0);
+
+ add_package($prog, $is_optional);
+}
+
+sub check_python_module($$)
+{
+ my $prog = shift;
+ my $is_optional = shift;
+
+ my $err = system("python3 -c 'import $prog' 2>/dev/null /dev/null");
+ return if ($err == 0);
+ my $err = system("python -c 'import $prog' 2>/dev/null /dev/null");
+ return if ($err == 0);
+
+ add_package($prog, $is_optional);
+}
+
+sub check_rpm_missing($$)
+{
+ my @pkgs = @{$_[0]};
+ my $is_optional = $_[1];
+
+ foreach my $prog(@pkgs) {
+ my $err = system("rpm -q '$prog' 2>/dev/null >/dev/null");
+ add_package($prog, $is_optional) if ($err);
+ }
+}
+
+sub check_pacman_missing($$)
+{
+ my @pkgs = @{$_[0]};
+ my $is_optional = $_[1];
+
+ foreach my $prog(@pkgs) {
+ my $err = system("pacman -Q '$prog' 2>/dev/null >/dev/null");
+ add_package($prog, $is_optional) if ($err);
+ }
+}
+
+sub check_missing_tex($)
+{
+ my $is_optional = shift;
+ my $kpsewhich = findprog("kpsewhich");
+
+ foreach my $prog(keys %texlive) {
+ my $package = $texlive{$prog};
+ if (!$kpsewhich) {
+ add_package($package, $is_optional);
+ next;
+ }
+ my $file = qx($kpsewhich $prog);
+ add_package($package, $is_optional) if ($file =~ /^\s*$/);
+ }
+}
+
+sub check_sphinx()
+{
+ return if findprog("sphinx-build");
+
+ if (findprog("sphinx-build-3")) {
+ $need_symlink = 1;
+ return;
+ }
+
+ if ($virtualenv) {
+ my $prog = findprog("virtualenv-3");
+ $prog = findprog("virtualenv-3.5") if (!$prog);
+
+ check_program("virtualenv", 0) if (!$prog);
+ $need_sphinx = 1;
+ } else {
+ add_package("python-sphinx", 0);
+ }
+}
+
+#
+# Ancillary subroutines
+#
+
+sub catcheck($)
+{
+ my $res = "";
+ $res = qx(cat $_[0]) if (-r $_[0]);
+ return $res;
+}
+
+sub which($)
+{
+ my $file = shift;
+ my @path = split ":", $ENV{PATH};
+
+ foreach my $dir(@path) {
+ my $name = $dir.'/'.$file;
+ return $name if (-x $name );
+ }
+ return undef;
+}
+
+#
+# Subroutines that check distro-specific hints
+#
+
+sub give_debian_hints()
+{
+ my %map = (
+ "python-sphinx" => "python3-sphinx",
+ "sphinx_rtd_theme" => "python3-sphinx-rtd-theme",
+ "virtualenv" => "virtualenv",
+ "dot" => "graphviz",
+ "convert" => "imagemagick",
+ "Pod::Usage" => "perl-modules",
+ "xelatex" => "texlive-xetex",
+ "rsvg-convert" => "librsvg2-bin",
+ );
+
+ if ($pdf) {
+ check_missing_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
+ "fonts-dejavu", 1);
+ }
+
+ check_program("dvipng", 1) if ($pdf);
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+ printf("You should run:\n\n\tsudo apt-get install $install\n");
+}
+
+sub give_redhat_hints()
+{
+ my %map = (
+ "python-sphinx" => "python3-sphinx",
+ "sphinx_rtd_theme" => "python3-sphinx_rtd_theme",
+ "virtualenv" => "python3-virtualenv",
+ "dot" => "graphviz",
+ "convert" => "ImageMagick",
+ "Pod::Usage" => "perl-Pod-Usage",
+ "xelatex" => "texlive-xetex-bin",
+ "rsvg-convert" => "librsvg2-tools",
+ );
+
+ my @fedora26_opt_pkgs = (
+ "graphviz-gd", # Fedora 26: needed for PDF support
+ );
+
+ my @fedora_tex_pkgs = (
+ "texlive-collection-fontsrecommended",
+ "texlive-collection-latex",
+ "dejavu-sans-fonts",
+ "dejavu-serif-fonts",
+ "dejavu-sans-mono-fonts",
+ );
+
+ #
+ # Checks valid for RHEL/CentOS version 7.x.
+ #
+ if (! $system_release =~ /Fedora/) {
+ $map{"virtualenv"} = "python-virtualenv";
+ }
+
+ my $release;
+
+ $release = $1 if ($system_release =~ /Fedora\s+release\s+(\d+)/);
+
+ check_rpm_missing(\@fedora26_opt_pkgs, 1) if ($pdf && $release >= 26);
+ check_rpm_missing(\@fedora_tex_pkgs, 1) if ($pdf);
+ check_missing_tex(1) if ($pdf);
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+
+ if ($release >= 18) {
+ # dnf, for Fedora 18+
+ printf("You should run:\n\n\tsudo dnf install -y $install\n");
+ } else {
+ # yum, for RHEL (and clones) or Fedora version < 18
+ printf("You should run:\n\n\tsudo yum install -y $install\n");
+ }
+}
+
+sub give_opensuse_hints()
+{
+ my %map = (
+ "python-sphinx" => "python3-sphinx",
+ "sphinx_rtd_theme" => "python3-sphinx_rtd_theme",
+ "virtualenv" => "python3-virtualenv",
+ "dot" => "graphviz",
+ "convert" => "ImageMagick",
+ "Pod::Usage" => "perl-Pod-Usage",
+ "xelatex" => "texlive-xetex-bin",
+ "rsvg-convert" => "rsvg-view",
+ );
+
+ my @suse_tex_pkgs = (
+ "texlive-babel-english",
+ "texlive-caption",
+ "texlive-colortbl",
+ "texlive-courier",
+ "texlive-dvips",
+ "texlive-helvetic",
+ "texlive-makeindex",
+ "texlive-metafont",
+ "texlive-metapost",
+ "texlive-palatino",
+ "texlive-preview",
+ "texlive-times",
+ "texlive-zapfchan",
+ "texlive-zapfding",
+ );
+
+ check_rpm_missing(\@suse_tex_pkgs, 1) if ($pdf);
+ check_missing_tex(1) if ($pdf);
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+ printf("You should run:\n\n\tsudo zypper install --no-recommends $install\n");
+}
+
+sub give_mageia_hints()
+{
+ my %map = (
+ "python-sphinx" => "python3-sphinx",
+ "sphinx_rtd_theme" => "python3-sphinx_rtd_theme",
+ "virtualenv" => "python3-virtualenv",
+ "dot" => "graphviz",
+ "convert" => "ImageMagick",
+ "Pod::Usage" => "perl-Pod-Usage",
+ "xelatex" => "texlive",
+ "rsvg-convert" => "librsvg2-tools",
+ );
+
+ my @tex_pkgs = (
+ "texlive-fontsextra",
+ );
+
+ check_rpm_missing(\@tex_pkgs, 1) if ($pdf);
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+ printf("You should run:\n\n\tsudo urpmi $install\n");
+}
+
+sub give_arch_linux_hints()
+{
+ my %map = (
+ "sphinx_rtd_theme" => "python-sphinx_rtd_theme",
+ "virtualenv" => "python-virtualenv",
+ "dot" => "graphviz",
+ "convert" => "imagemagick",
+ "xelatex" => "texlive-bin",
+ "rsvg-convert" => "extra/librsvg",
+ );
+
+ my @archlinux_tex_pkgs = (
+ "texlive-core",
+ "texlive-latexextra",
+ "ttf-dejavu",
+ );
+ check_pacman_missing(\@archlinux_tex_pkgs, 1) if ($pdf);
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+ printf("You should run:\n\n\tsudo pacman -S $install\n");
+}
+
+sub give_gentoo_hints()
+{
+ my %map = (
+ "sphinx_rtd_theme" => "dev-python/sphinx_rtd_theme",
+ "virtualenv" => "dev-python/virtualenv",
+ "dot" => "media-gfx/graphviz",
+ "convert" => "media-gfx/imagemagick",
+ "xelatex" => "dev-texlive/texlive-xetex media-fonts/dejavu",
+ "rsvg-convert" => "gnome-base/librsvg",
+ );
+
+ check_missing_file("/usr/share/fonts/dejavu/DejaVuSans.ttf",
+ "media-fonts/dejavu", 1) if ($pdf);
+
+ check_missing(\%map);
+
+ return if (!$need && !$optional);
+
+ printf("You should run:\n\n");
+ printf("\tsudo su -c 'echo \"media-gfx/imagemagick svg png\" > /etc/portage/package.use/imagemagick'\n");
+ printf("\tsudo su -c 'echo \"media-gfx/graphviz cairo pdf\" > /etc/portage/package.use/graphviz'\n");
+ printf("\tsudo emerge --ask $install\n");
+
+}
+
+sub check_distros()
+{
+ # Distro-specific hints
+ if ($system_release =~ /Red Hat Enterprise Linux/) {
+ give_redhat_hints;
+ return;
+ }
+ if ($system_release =~ /CentOS/) {
+ give_redhat_hints;
+ return;
+ }
+ if ($system_release =~ /Scientific Linux/) {
+ give_redhat_hints;
+ return;
+ }
+ if ($system_release =~ /Oracle Linux Server/) {
+ give_redhat_hints;
+ return;
+ }
+ if ($system_release =~ /Fedora/) {
+ give_redhat_hints;
+ return;
+ }
+ if ($system_release =~ /Ubuntu/) {
+ give_debian_hints;
+ return;
+ }
+ if ($system_release =~ /Debian/) {
+ give_debian_hints;
+ return;
+ }
+ if ($system_release =~ /openSUSE/) {
+ give_opensuse_hints;
+ return;
+ }
+ if ($system_release =~ /Mageia/) {
+ give_mageia_hints;
+ return;
+ }
+ if ($system_release =~ /Arch Linux/) {
+ give_arch_linux_hints;
+ return;
+ }
+ if ($system_release =~ /Gentoo/) {
+ give_gentoo_hints;
+ return;
+ }
+
+ #
+ # Fall-back to generic hint code for other distros
+ # That's far from ideal, specially for LaTeX dependencies.
+ #
+ my %map = (
+ "sphinx-build" => "sphinx"
+ );
+ check_missing_tex(1) if ($pdf);
+ check_missing(\%map);
+ print "I don't know distro $system_release.\n";
+ print "So, I can't provide you a hint with the install procedure.\n";
+ print "There are likely missing dependencies.\n";
+}
+
+#
+# Common dependencies
+#
+
+sub check_needs()
+{
+ if ($system_release) {
+ print "Detected OS: $system_release.\n";
+ } else {
+ print "Unknown OS\n";
+ }
+
+ # RHEL 7.x and clones have Sphinx version 1.1.x and incomplete texlive
+ if (($system_release =~ /Red Hat Enterprise Linux/) ||
+ ($system_release =~ /CentOS/) ||
+ ($system_release =~ /Scientific Linux/) ||
+ ($system_release =~ /Oracle Linux Server/)) {
+ $virtualenv = 1;
+ $pdf = 0;
+
+ printf("NOTE: On this distro, Sphinx and TexLive shipped versions are incompatible\n");
+ printf("with doc build. So, use Sphinx via a Python virtual environment.\n\n");
+ printf("This script can't install a TexLive version that would provide PDF.\n");
+ }
+
+ # Check for needed programs/tools
+ check_sphinx();
+ check_perl_module("Pod::Usage", 0);
+ check_program("make", 0);
+ check_program("gcc", 0);
+ check_python_module("sphinx_rtd_theme", 1) if (!$virtualenv);
+ check_program("xelatex", 1) if ($pdf);
+ check_program("dot", 1);
+ check_program("convert", 1);
+ check_program("rsvg-convert", 1) if ($pdf);
+
+ check_distros();
+
+ if ($need_symlink) {
+ printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n",
+ which("sphinx-build-3");
+ }
+ if ($need_sphinx) {
+ my $activate = "$virtenv_dir/bin/activate";
+ if (-e "$ENV{'PWD'}/$activate") {
+ printf "\nNeed to activate virtualenv with:\n";
+ printf "\t. $activate\n";
+ } else {
+ my $virtualenv = findprog("virtualenv-3");
+ $virtualenv = findprog("virtualenv-3.5") if (!$virtualenv);
+ $virtualenv = findprog("virtualenv") if (!$virtualenv);
+ $virtualenv = "virtualenv" if (!$virtualenv);
+
+ printf "\t$virtualenv $virtenv_dir\n";
+ printf "\t. $activate\n";
+ printf "\tpip install -r $requirement_file\n";
+ $need++;
+ }
+ }
+ printf "\n";
+
+ print "All optional dependenties are met.\n" if (!$optional);
+
+ if ($need == 1) {
+ die "Can't build as $need mandatory dependency is missing";
+ } elsif ($need) {
+ die "Can't build as $need mandatory dependencies are missing";
+ }
+
+ print "Needed package dependencies are met.\n";
+}
+
+#
+# Main
+#
+
+while (@ARGV) {
+ my $arg = shift(@ARGV);
+
+ if ($arg eq "--no-virtualenv") {
+ $virtualenv = 0;
+ } elsif ($arg eq "--no-pdf"){
+ $pdf = 0;
+ } else {
+ print "Usage:\n\t$0 <--no-virtualenv> <--no-pdf>\n\n";
+ exit -1;
+ }
+}
+
+#
+# Determine the system type. There's no standard unique way that would
+# work with all distros with a minimal package install. So, several
+# methods are used here.
+#
+# By default, it will use lsb_release function. If not available, it will
+# fail back to reading the known different places where the distro name
+# is stored
+#
+
+$system_release = qx(lsb_release -d) if which("lsb_release");
+$system_release =~ s/Description:\s*// if ($system_release);
+$system_release = catcheck("/etc/system-release") if !$system_release;
+$system_release = catcheck("/etc/redhat-release") if !$system_release;
+$system_release = catcheck("/etc/lsb-release") if !$system_release;
+$system_release = catcheck("/etc/gentoo-release") if !$system_release;
+$system_release = catcheck("/etc/issue") if !$system_release;
+$system_release =~ s/\s+$//;
+
+check_needs;
diff --git a/scripts/stackdelta b/scripts/stackdelta
index 48eabf2f48f8..44d2dfd6216f 100755
--- a/scripts/stackdelta
+++ b/scripts/stackdelta
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
# Read two files produced by the stackusage script, and show the
# delta between them.
diff --git a/scripts/stackusage b/scripts/stackusage
index 8cf26640ef8a..56ef1ab670ac 100755
--- a/scripts/stackusage
+++ b/scripts/stackusage
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
outfile=""
now=`date +%s`
diff --git a/scripts/tags.sh b/scripts/tags.sh
index d661f2f3ef61..d23dcbf17457 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -106,6 +106,7 @@ all_compiled_sources()
case "$i" in
*.[cS])
j=${i/\.[cS]/\.o}
+ j="${j#$tree}"
if [ -e $j ]; then
echo $i
fi
diff --git a/scripts/tracing/ftrace-bisect.sh b/scripts/tracing/ftrace-bisect.sh
index 9ff8ac5fc53c..926701162bc8 100755
--- a/scripts/tracing/ftrace-bisect.sh
+++ b/scripts/tracing/ftrace-bisect.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
#
# Here's how to use this:
#
diff --git a/scripts/ver_linux b/scripts/ver_linux
index b51de8a7e2a3..545ec7388eb7 100755
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -1,4 +1,5 @@
#!/usr/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
# Before running this script please ensure that your PATH is
# typical as you use for compilation/installation. I use
# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
diff --git a/scripts/xen-hypercalls.sh b/scripts/xen-hypercalls.sh
index 676d9226814f..f18b00843df3 100644
--- a/scripts/xen-hypercalls.sh
+++ b/scripts/xen-hypercalls.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
out="$1"
shift
in="$@"