summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include21
-rw-r--r--scripts/Kconfig.include8
-rw-r--r--scripts/Makefile18
-rw-r--r--scripts/Makefile.build15
-rw-r--r--scripts/Makefile.clean13
-rw-r--r--scripts/Makefile.extrawarn2
-rw-r--r--scripts/Makefile.gcc-plugins2
-rw-r--r--scripts/Makefile.host40
-rw-r--r--scripts/Makefile.kasan3
-rw-r--r--scripts/Makefile.kcov4
-rw-r--r--scripts/Makefile.kcsan6
-rw-r--r--scripts/Makefile.lib57
-rw-r--r--scripts/Makefile.modpost3
-rw-r--r--scripts/Makefile.ubsan3
-rwxr-xr-xscripts/atomic/gen-atomic-fallback.sh31
-rw-r--r--scripts/basic/Makefile3
-rwxr-xr-xscripts/bloat-o-meter2
-rwxr-xr-xscripts/bpf_helpers_doc.py21
-rwxr-xr-xscripts/checkkconfigsymbols.py2
-rwxr-xr-xscripts/checkpatch.pl147
-rw-r--r--scripts/coccinelle/api/device_attr_show.cocci55
-rw-r--r--scripts/coccinelle/api/kstrdup.cocci2
-rw-r--r--scripts/coccinelle/api/kzfree.cocci101
-rw-r--r--scripts/coccinelle/api/memdup_user.cocci64
-rw-r--r--scripts/coccinelle/free/devm_free.cocci4
-rw-r--r--scripts/coccinelle/free/ifnullfree.cocci4
-rw-r--r--scripts/coccinelle/free/kfree.cocci6
-rw-r--r--scripts/coccinelle/free/kfreeaddr.cocci2
-rw-r--r--scripts/coccinelle/misc/add_namespace.cocci8
-rw-r--r--scripts/coccinelle/misc/array_size_dup.cocci209
-rw-r--r--scripts/const_structs.checkpatch1
-rwxr-xr-xscripts/decode_stacktrace.sh86
-rw-r--r--scripts/dtc/Makefile5
-rw-r--r--scripts/dtc/checks.c39
-rw-r--r--scripts/dtc/dtc.h31
-rw-r--r--scripts/dtc/flattree.c2
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c2
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c2
-rw-r--r--scripts/dtc/libfdt/libfdt.h8
-rw-r--r--scripts/dtc/treesource.c8
-rw-r--r--scripts/dtc/version_gen.h2
-rw-r--r--scripts/dtc/yamltree.c6
-rw-r--r--scripts/gcc-plugins/Kconfig2
-rw-r--r--scripts/gcc-plugins/Makefile61
-rw-r--r--scripts/gcc-plugins/cyc_complexity_plugin.c2
-rw-r--r--scripts/gcc-plugins/sancov_plugin.c2
-rw-r--r--scripts/gcc-plugins/stackleak_plugin.c248
-rw-r--r--scripts/gcc-plugins/structleak_plugin.c2
-rw-r--r--scripts/gdb/linux/genpd.py12
-rw-r--r--scripts/gdb/linux/rbtree.py4
-rw-r--r--scripts/gdb/linux/symbols.py2
-rw-r--r--scripts/genksyms/Makefile3
-rwxr-xr-xscripts/headers_install.sh4
-rw-r--r--scripts/kallsyms.c1
-rw-r--r--scripts/kconfig/.gitignore2
-rw-r--r--scripts/kconfig/Makefile13
-rw-r--r--scripts/kconfig/images.c30
-rw-r--r--scripts/kconfig/images.h30
-rw-r--r--scripts/kconfig/lexer.l4
-rw-r--r--scripts/kconfig/qconf.cc499
-rw-r--r--scripts/kconfig/qconf.h83
-rw-r--r--scripts/kconfig/symbol.c14
-rwxr-xr-xscripts/kernel-doc30
-rwxr-xr-xscripts/link-vmlinux.sh10
-rw-r--r--scripts/mod/Makefile4
-rw-r--r--scripts/mod/devicetable-offsets.c2
-rw-r--r--scripts/mod/file2alias.c6
-rw-r--r--scripts/mod/modpost.c13
-rw-r--r--scripts/nsdeps2
-rwxr-xr-xscripts/package/buildtar12
-rwxr-xr-xscripts/package/mkdebian2
-rwxr-xr-xscripts/package/mkspec2
-rw-r--r--scripts/recordmcount.c8
-rw-r--r--scripts/recordmcount.h98
-rw-r--r--scripts/selinux/genheaders/Makefile4
-rw-r--r--scripts/selinux/mdp/Makefile3
-rw-r--r--scripts/selinux/mdp/mdp.c23
-rw-r--r--scripts/sorttable.c41
-rw-r--r--scripts/spelling.txt19
-rwxr-xr-xscripts/sphinx-pre-install4
-rwxr-xr-xscripts/tags.sh18
81 files changed, 1729 insertions, 638 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 0c3dc983439b..83a1637417e5 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -86,20 +86,21 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \
$(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
# output directory for tests below
-TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
+TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
# try-run
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
# 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"; \
+ TMP=$(TMPOUT)/tmp; \
+ TMPO=$(TMPOUT)/tmp.o; \
+ mkdir -p $(TMPOUT); \
+ trap "rm -rf $(TMPOUT)" EXIT; \
if ($(1)) >/dev/null 2>&1; \
then echo "$(2)"; \
else echo "$(3)"; \
- fi; \
- rm -f "$$TMP" "$$TMPO")
+ fi)
# as-option
# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
@@ -118,25 +119,21 @@ as-instr = $(call try-run,\
__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))
-
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
cc-option = $(call __cc-option, $(CC),\
- $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2))
+ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(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) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
# cc-disable-warning
# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
cc-disable-warning = $(call try-run,\
- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+ $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
# cc-ifversion
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index c264da2b9b30..a5fe72c504ff 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -25,18 +25,12 @@ failure = $(if-success,$(1),n,y)
# $(cc-option,<flag>)
# Return y if the compiler supports <flag>, n otherwise
-cc-option = $(success,$(CC) -Werror $(CLANG_FLAGS) $(1) -S -x c /dev/null -o /dev/null)
+cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o)
# $(ld-option,<flag>)
# Return y if the linker supports <flag>, n otherwise
ld-option = $(success,$(LD) -v $(1))
-# $(as-option,<flag>)
-# /dev/zero is used as output instead of /dev/null as some assembler cribs when
-# both input and output are same. Also both of them have same write behaviour so
-# can be easily substituted.
-as-option = $(success, $(CC) $(CLANG_FLAGS) $(1) -c -x assembler /dev/null -o /dev/zero)
-
# $(as-instr,<instr>)
# Return y if the assembler supports <instr>, n otherwise
as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)
diff --git a/scripts/Makefile b/scripts/Makefile
index 95ecf970c74c..bc018e4b733e 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -3,14 +3,14 @@
# scripts contains sources for various helper programs used throughout
# the kernel for the build process.
-always-$(CONFIG_BUILD_BIN2C) += bin2c
-always-$(CONFIG_KALLSYMS) += kallsyms
-always-$(BUILD_C_RECORDMCOUNT) += recordmcount
-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
-always-$(CONFIG_ASN1) += asn1_compiler
-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
+hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c
+hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms
+hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount
+hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
+hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
+hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
+hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
+hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
@@ -26,8 +26,6 @@ HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
HOSTLDLIBS_sorttable = -lpthread
endif
-hostprogs := $(always-y) $(always-m)
-
# The following programs are only built on demand
hostprogs += unifdef
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 2e8810b7e5ed..a467b9323442 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -45,12 +45,15 @@ include $(kbuild-file)
include scripts/Makefile.lib
-# Do not include host rules unless needed
-ifneq ($(hostprogs)$(hostcxxlibs-y)$(hostcxxlibs-m),)
+# Do not include hostprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
+hostprogs := $(sort $(hostprogs))
+ifneq ($(hostprogs),)
include scripts/Makefile.host
endif
# Do not include userprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
userprogs := $(sort $(userprogs))
ifneq ($(userprogs),)
include scripts/Makefile.userprogs
@@ -252,9 +255,9 @@ cmd_gen_ksymdeps = \
endif
define rule_cc_o_c
- $(call cmd,checksrc)
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,gen_ksymdeps)
+ $(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,objtool)
$(call cmd,modversions_c)
@@ -277,8 +280,8 @@ endif
# Built-in and composite module parts
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
- $(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
+ $(call cmd,force_checksrc)
cmd_mod = { \
echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \
@@ -515,15 +518,13 @@ existing-targets := $(wildcard $(sort $(targets)))
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
-ifdef building_out_of_srctree
# Create directories for object files if they do not exist
-obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets))))
+obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets))))
# If targets exist, their directories apparently exist. Skip mkdir.
existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets))))
obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs)))
ifneq ($(obj-dirs),)
$(shell mkdir -p $(obj-dirs))
endif
-endif
.PHONY: $(PHONY)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index e2c76122319d..d9e0ceace6a6 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -27,10 +27,15 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
# build a list of files to remove, usually relative to the current
# directory
-__clean-files := $(extra-y) $(extra-m) $(extra-) \
- $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files) \
- $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) \
- $(hostcxxlibs-y) $(hostcxxlibs-m)
+__clean-files := \
+ $(clean-files) $(targets) $(hostprogs) $(userprogs) \
+ $(extra-y) $(extra-m) $(extra-) \
+ $(always-y) $(always-m) $(always-) \
+ $(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \
+ $(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-)
+
+# deprecated
+__clean-files += $(always) $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 4aea7cf71d11..62c275685b75 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -35,6 +35,7 @@ KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation)
# The following turn off the warnings enabled by -Wextra
KBUILD_CFLAGS += -Wno-missing-field-initializers
KBUILD_CFLAGS += -Wno-sign-compare
+KBUILD_CFLAGS += -Wno-type-limits
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
@@ -66,6 +67,7 @@ KBUILD_CFLAGS += -Wshadow
KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
KBUILD_CFLAGS += -Wmissing-field-initializers
KBUILD_CFLAGS += -Wsign-compare
+KBUILD_CFLAGS += -Wtype-limits
KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized)
KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 5f7df50cfe7a..952e46876329 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -33,6 +33,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+= -DSTACKLEAK_PLUGIN
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+= -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE)
+gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \
+ += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH)
ifdef CONFIG_GCC_PLUGIN_STACKLEAK
DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable
endif
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index c8a4a033dc3e..278b4d6ac945 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -38,39 +38,31 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
# Will compile qconf as a C++ program, and menu as a C program.
# They are linked as C++ code to the executable qconf
-__hostprogs := $(sort $(hostprogs))
-host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
-
# C code
# Executables compiled from a single .c file
-host-csingle := $(foreach m,$(__hostprogs), \
+host-csingle := $(foreach m,$(hostprogs), \
$(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
# C executables linked based on several .o files
-host-cmulti := $(foreach m,$(__hostprogs),\
+host-cmulti := $(foreach m,$(hostprogs),\
$(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
# Object (.o) files compiled from .c files
-host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
+host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
# C++ code
# C++ executables compiled from at least one .cc file
# and zero or more .c files
-host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
+host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m)))
# C++ Object (.o) files compiled from .cc files
host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
-# Object (.o) files used by the shared libaries
-host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs))))
-
host-csingle := $(addprefix $(obj)/,$(host-csingle))
host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
-host-cxxshlib := $(addprefix $(obj)/,$(host-cxxshlib))
-host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
#####
# Handle options to gcc. Support building with separate output directory
@@ -136,25 +128,5 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
-# Compile .c file, create position independent .o file
-# Note that plugin capable gcc versions can be either C or C++ based
-# therefore plugin source files have to be compilable in both C and C++ mode.
-# This is why a C++ compiler is invoked on a .c file.
-# host-cxxshobjs -> .o
-quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@
- cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
-$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
- $(call if_changed_dep,host-cxxshobjs)
-
-# Link a shared library, based on position independent .o files
-# *.o -> .so shared library (host-cxxshlib)
-quiet_cmd_host-cxxshlib = HOSTLLD -shared $@
- cmd_host-cxxshlib = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \
- $(addprefix $(obj)/, $($(target-stem)-objs)) \
- $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so)
-$(host-cxxshlib): FORCE
- $(call if_changed,host-cxxshlib)
-$(call multi_depend, $(host-cxxshlib), .so, -objs)
-
-targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
- $(host-cxxmulti) $(host-cxxobjs) $(host-cxxshlib) $(host-cxxshobjs)
+targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
+ $(host-cxxmulti) $(host-cxxobjs)
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 03757cc60e06..f4beee1b0013 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -44,7 +44,8 @@ else
endif
CFLAGS_KASAN := -fsanitize=kernel-hwaddress \
- -mllvm -hwasan-instrument-stack=0 \
+ -mllvm -hwasan-instrument-stack=$(CONFIG_KASAN_STACK) \
+ -mllvm -hwasan-use-short-granules=0 \
$(instrumentation_flags)
endif # CONFIG_KASAN_SW_TAGS
diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov
index 52b113302443..67e8cfe3474b 100644
--- a/scripts/Makefile.kcov
+++ b/scripts/Makefile.kcov
@@ -1,10 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-ifdef CONFIG_KCOV
-
kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc
kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp
kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
export CFLAGS_KCOV := $(kcov-flags-y)
-
-endif
diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan
index bd4da1af5953..c50f27b3ac56 100644
--- a/scripts/Makefile.kcsan
+++ b/scripts/Makefile.kcsan
@@ -1,12 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
-ifdef CONFIG_KCSAN
-
# GCC and Clang accept backend options differently. Do not wrap in cc-option,
# because Clang accepts "--param" even if it is unused.
ifdef CONFIG_CC_IS_CLANG
cc-param = -mllvm -$(1)
else
-cc-param = --param -$(1)
+cc-param = --param $(1)
endif
# Keep most options here optional, to allow enabling more compilers if absence
@@ -15,5 +13,3 @@ CFLAGS_KCSAN := -fsanitize=thread \
$(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0) -fno-optimize-sibling-calls) \
$(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1)) \
$(call cc-param,tsan-distinguish-volatile=1)
-
-endif # CONFIG_KCSAN
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 99ac59c59826..3d599716940c 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -68,6 +68,17 @@ real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))
always-y += $(always-m)
+# hostprogs-always-y += foo
+# ... is a shorthand for
+# hostprogs += foo
+# always-y += foo
+hostprogs += $(hostprogs-always-y) $(hostprogs-always-m)
+always-y += $(hostprogs-always-y) $(hostprogs-always-m)
+
+# userprogs-always-y is likewise.
+userprogs += $(userprogs-always-y) $(userprogs-always-m)
+always-y += $(userprogs-always-y) $(userprogs-always-m)
+
# DTB
# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
extra-y += $(dtb-y)
@@ -111,12 +122,14 @@ basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname))
modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile))
-orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \
- $(ccflags-y) $(CFLAGS_$(target-stem).o)
-_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), $(orig_c_flags))
-orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \
- $(asflags-y) $(AFLAGS_$(target-stem).o)
-_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), $(orig_a_flags))
+_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
+ $(filter-out $(ccflags-remove-y), \
+ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
+ $(CFLAGS_$(target-stem).o))
+_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
+ $(filter-out $(asflags-remove-y), \
+ $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
+ $(AFLAGS_$(target-stem).o))
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds)
#
@@ -212,6 +225,9 @@ $(foreach m, $(notdir $1), \
$(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s)))))))
endef
+quiet_cmd_copy = COPY $@
+ cmd_copy = cp $< $@
+
# Shipped files
# ===========================================================================
@@ -259,6 +275,7 @@ quiet_cmd_gzip = GZIP $@
# DTC
# ---------------------------------------------------------------------------
DTC ?= $(objtree)/scripts/dtc/dtc
+DTC_FLAGS += -Wno-interrupt_provider
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)
@@ -274,7 +291,8 @@ endif
ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),)
DTC_FLAGS += -Wnode_name_chars_strict \
- -Wproperty_name_chars_strict
+ -Wproperty_name_chars_strict \
+ -Winterrupt_provider
endif
DTC_FLAGS += $(DTC_FLAGS_$(basetarget))
@@ -298,8 +316,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
$(call if_changed,dt_S_dtb)
quiet_cmd_dtc = DTC $@
-cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
- $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
$(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \
$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
@@ -408,6 +425,28 @@ quiet_cmd_xzkern = XZKERN $@
quiet_cmd_xzmisc = XZMISC $@
cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@
+# ZSTD
+# ---------------------------------------------------------------------------
+# Appends the uncompressed size of the data using size_append. The .zst
+# format has the size information available at the beginning of the file too,
+# but it's in a more complex format and it's good to avoid changing the part
+# of the boot code that reads the uncompressed size.
+#
+# Note that the bytes added by size_append will make the zstd tool think that
+# the file is corrupt. This is expected.
+#
+# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of
+# 128 MB. zstd22 is used for kernel compression because it is decompressed in a
+# single pass, so zstd doesn't need to allocate a window buffer. When streaming
+# decompression is used, like initramfs decompression, zstd22 should likely not
+# be used because it would require zstd to allocate a 128 MB buffer.
+
+quiet_cmd_zstd = ZSTD $@
+ cmd_zstd = { cat $(real-prereqs) | $(ZSTD) -19; $(size_append); } > $@
+
+quiet_cmd_zstd22 = ZSTD22 $@
+ cmd_zstd22 = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@
+
# ASM offsets
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 3651cbf6ad49..f54b6ac37ac2 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -124,9 +124,6 @@ existing-targets := $(wildcard $(sort $(targets)))
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
-PHONY += FORCE
-FORCE:
-
endif
.PHONY: $(PHONY)
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 5b15bc425ec9..27348029b2b8 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -1,6 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-ifdef CONFIG_UBSAN
-
ifdef CONFIG_UBSAN_ALIGNMENT
CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
endif
@@ -26,4 +24,3 @@ endif
# -fsanitize=* options makes GCC less smart than usual and
# increase number of 'maybe-uninitialized false-positives
CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized)
-endif
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh
index 0fd1cf0c2b94..693dfa1de430 100755
--- a/scripts/atomic/gen-atomic-fallback.sh
+++ b/scripts/atomic/gen-atomic-fallback.sh
@@ -58,6 +58,21 @@ cat << EOF
EOF
}
+gen_proto_order_variant()
+{
+ local meta="$1"; shift
+ local pfx="$1"; shift
+ local name="$1"; shift
+ local sfx="$1"; shift
+ local order="$1"; shift
+ local arch="$1"
+ local atomic="$2"
+
+ local basename="${arch}${atomic}_${pfx}${name}${sfx}"
+
+ printf "#define arch_${basename}${order} ${basename}${order}\n"
+}
+
#gen_proto_order_variants(meta, pfx, name, sfx, arch, atomic, int, args...)
gen_proto_order_variants()
{
@@ -72,6 +87,22 @@ gen_proto_order_variants()
local template="$(find_fallback_template "${pfx}" "${name}" "${sfx}" "${order}")"
+ if [ -z "$arch" ]; then
+ gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
+
+ if meta_has_acquire "${meta}"; then
+ gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
+ fi
+ if meta_has_release "${meta}"; then
+ gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
+ fi
+ if meta_has_relaxed "${meta}"; then
+ gen_proto_order_variant "${meta}" "${pfx}" "${name}" "${sfx}" "_relaxed" "$@"
+ fi
+
+ echo ""
+ fi
+
# If we don't have relaxed atomics, then we don't bother with ordering fallbacks
# read_acquire and set_release need to be templated, though
if ! meta_has_relaxed "${meta}"; then
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 290dd27d2809..eeb6a38c5551 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -2,5 +2,4 @@
#
# fixdep: used to generate dependency information during build process
-hostprogs := fixdep
-always-y := $(hostprogs)
+hostprogs-always-y += fixdep
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index 8c965f6a9881..d7ca46c612b3 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -26,6 +26,8 @@ def getsizes(file, format):
sym = {}
with os.popen("nm --size-sort " + file) as f:
for line in f:
+ if line.startswith("\n") or ":" in line:
+ continue
size, type, name = line.split()
if type in format:
# strip generated symbols
diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py
index 91fa668fa860..5bfa448b4704 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_helpers_doc.py
@@ -404,6 +404,7 @@ class PrinterHelpers(Printer):
type_fwds = [
'struct bpf_fib_lookup',
+ 'struct bpf_sk_lookup',
'struct bpf_perf_event_data',
'struct bpf_perf_event_value',
'struct bpf_pidns_info',
@@ -421,6 +422,12 @@ class PrinterHelpers(Printer):
'struct sockaddr',
'struct tcphdr',
'struct seq_file',
+ 'struct tcp6_sock',
+ 'struct tcp_sock',
+ 'struct tcp_timewait_sock',
+ 'struct tcp_request_sock',
+ 'struct udp6_sock',
+ 'struct task_struct',
'struct __sk_buff',
'struct sk_msg_md',
@@ -444,6 +451,7 @@ class PrinterHelpers(Printer):
'struct bpf_perf_event_data',
'struct bpf_perf_event_value',
'struct bpf_pidns_info',
+ 'struct bpf_sk_lookup',
'struct bpf_sock',
'struct bpf_sock_addr',
'struct bpf_sock_ops',
@@ -458,6 +466,12 @@ class PrinterHelpers(Printer):
'struct sockaddr',
'struct tcphdr',
'struct seq_file',
+ 'struct tcp6_sock',
+ 'struct tcp_sock',
+ 'struct tcp_timewait_sock',
+ 'struct tcp_request_sock',
+ 'struct udp6_sock',
+ 'struct task_struct',
}
mapped_types = {
'u8': '__u8',
@@ -475,6 +489,11 @@ class PrinterHelpers(Printer):
'struct sk_msg_buff': 'struct sk_msg_md',
'struct xdp_buff': 'struct xdp_md',
}
+ # Helpers overloaded for different context types.
+ overloaded_helpers = [
+ 'bpf_get_socket_cookie',
+ 'bpf_sk_assign',
+ ]
def print_header(self):
header = '''\
@@ -531,7 +550,7 @@ class PrinterHelpers(Printer):
for i, a in enumerate(proto['args']):
t = a['type']
n = a['name']
- if proto['name'] == 'bpf_get_socket_cookie' and i == 0:
+ if proto['name'] in self.overloaded_helpers and i == 0:
t = 'void'
n = 'ctx'
one_arg = '{}{}'.format(comma, self.map_type(t))
diff --git a/scripts/checkkconfigsymbols.py b/scripts/checkkconfigsymbols.py
index 00a10a293f4f..1548f9ce4682 100755
--- a/scripts/checkkconfigsymbols.py
+++ b/scripts/checkkconfigsymbols.py
@@ -34,7 +34,7 @@ REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
REGEX_KCONFIG_DEF = re.compile(DEF)
REGEX_KCONFIG_EXPR = re.compile(EXPR)
REGEX_KCONFIG_STMT = re.compile(STMT)
-REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
+REGEX_KCONFIG_HELP = re.compile(r"^\s+help\s*$")
REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
REGEX_QUOTES = re.compile("(\"(.*?)\")")
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 4c820607540b..60d4a79674b6 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -59,7 +59,7 @@ my $spelling_file = "$D/spelling.txt";
my $codespell = 0;
my $codespellfile = "/usr/share/codespell/dictionary.txt";
my $conststructsfile = "$D/const_structs.checkpatch";
-my $typedefsfile = "";
+my $typedefsfile;
my $color = "auto";
my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
# git output parsing needs US English output, so first set backtick child process LANGUAGE
@@ -588,6 +588,8 @@ our @mode_permission_funcs = (
["__ATTR", 2],
);
+my $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
+
#Create a search pattern for all these functions to speed up a loop below
our $mode_perms_search = "";
foreach my $entry (@mode_permission_funcs) {
@@ -756,7 +758,7 @@ sub read_words {
next;
}
- $$wordsRef .= '|' if ($$wordsRef ne "");
+ $$wordsRef .= '|' if (defined $$wordsRef);
$$wordsRef .= $line;
}
close($file);
@@ -766,16 +768,18 @@ sub read_words {
return 0;
}
-my $const_structs = "";
-read_words(\$const_structs, $conststructsfile)
- or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
+my $const_structs;
+if (show_type("CONST_STRUCT")) {
+ read_words(\$const_structs, $conststructsfile)
+ or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
+}
-my $typeOtherTypedefs = "";
-if (length($typedefsfile)) {
+if (defined($typedefsfile)) {
+ my $typeOtherTypedefs;
read_words(\$typeOtherTypedefs, $typedefsfile)
or warn "No additional types will be considered - file '$typedefsfile': $!\n";
+ $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
}
-$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
sub build_types {
my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
@@ -840,7 +844,6 @@ 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+)?[HLP]?LIST_HEAD\s*\(|
- (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
)};
@@ -3042,11 +3045,7 @@ sub process {
if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
$is_start = 1;
- } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
- if ($lines[$ln - 1] =~ "---help---") {
- WARN("CONFIG_DESCRIPTION",
- "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
- }
+ } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
$length = -1;
}
@@ -3311,6 +3310,42 @@ sub process {
}
}
+# check for repeated words separated by a single space
+ if ($rawline =~ /^\+/) {
+ while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
+
+ my $first = $1;
+ my $second = $2;
+
+ if ($first =~ /(?:struct|union|enum)/) {
+ pos($rawline) += length($first) + length($second) + 1;
+ next;
+ }
+
+ next if ($first ne $second);
+ next if ($first eq 'long');
+
+ if (WARN("REPEATED_WORD",
+ "Possible repeated word: '$first'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
+ }
+ }
+
+ # if it's a repeated word on consecutive lines in a comment block
+ if ($prevline =~ /$;+\s*$/ &&
+ $prevrawline =~ /($word_pattern)\s*$/) {
+ my $last_word = $1;
+ if ($rawline =~ /^\+\s*\*\s*$last_word /) {
+ if (WARN("REPEATED_WORD",
+ "Possible repeated word: '$last_word'\n" . $hereprev) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
+ }
+ }
+ }
+ }
+
# check for space before tabs.
if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
@@ -5021,8 +5056,30 @@ sub process {
my ($s, $c) = ($stat, $cond);
if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
- ERROR("ASSIGN_IN_IF",
- "do not use assignment in if condition\n" . $herecurr);
+ if (ERROR("ASSIGN_IN_IF",
+ "do not use assignment in if condition\n" . $herecurr) &&
+ $fix && $perl_version_ok) {
+ if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
+ my $space = $1;
+ my $not = $2;
+ my $statement = $3;
+ my $assigned = $4;
+ my $test = $8;
+ my $against = $9;
+ my $brace = $15;
+ fix_delete_line($fixlinenr, $rawline);
+ fix_insert_line($fixlinenr, "$space$statement;");
+ my $newline = "${space}if (";
+ $newline .= '!' if defined($not);
+ $newline .= '(' if (defined $not && defined($test) && defined($against));
+ $newline .= "$assigned";
+ $newline .= " $test $against" if (defined($test) && defined($against));
+ $newline .= ')' if (defined $not && defined($test) && defined($against));
+ $newline .= ')';
+ $newline .= " {" if (defined($brace));
+ fix_insert_line($fixlinenr + 1, $newline);
+ }
+ }
}
# Find out what is on the end of the line after the
@@ -5903,8 +5960,7 @@ sub process {
my $barriers = qr{
mb|
rmb|
- wmb|
- read_barrier_depends
+ wmb
}x;
my $barrier_stems = qr{
mb__before_atomic|
@@ -5953,12 +6009,6 @@ sub process {
}
}
-# check for smp_read_barrier_depends and read_barrier_depends
- if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
- WARN("READ_BARRIER_DEPENDS",
- "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\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",
@@ -6330,8 +6380,7 @@ sub process {
if (defined $cond) {
substr($s, 0, length($cond), '');
}
- if ($s =~ /^\s*;/ &&
- $function_name ne 'uninitialized_var')
+ if ($s =~ /^\s*;/)
{
WARN("AVOID_EXTERNS",
"externs should be avoided in .c files\n" . $herecurr);
@@ -6350,17 +6399,13 @@ sub process {
}
# check for function declarations that have arguments without identifier names
-# while avoiding uninitialized_var(x)
if (defined $stat &&
- $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
- (!defined($1) ||
- (defined($1) && $1 ne "uninitialized_var")) &&
- $2 ne "void") {
- my $args = trim($2);
+ $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
+ $1 ne "void") {
+ my $args = trim($1);
while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
my $arg = trim($1);
- if ($arg =~ /^$Type$/ &&
- $arg !~ /enum\s+$Ident$/) {
+ if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
WARN("FUNCTION_ARGUMENTS",
"function definition argument '$arg' should also have an identifier name\n" . $herecurr);
}
@@ -6478,6 +6523,12 @@ sub process {
}
}
+# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
+ if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^CONFIG_/) {
+ WARN("IS_ENABLED_CONFIG",
+ "IS_ENABLED($1) is normally used as IS_ENABLED(CONFIG_$1)\n" . $herecurr);
+ }
+
# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
my $config = $1;
@@ -6488,31 +6539,6 @@ sub process {
}
}
-# check for case / default statements not preceded by break/fallthrough/switch
- if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
- my $has_break = 0;
- my $has_statement = 0;
- my $count = 0;
- my $prevline = $linenr;
- while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
- $prevline--;
- my $rline = $rawlines[$prevline - 1];
- my $fline = $lines[$prevline - 1];
- last if ($fline =~ /^\@\@/);
- next if ($fline =~ /^\-/);
- next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
- $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
- next if ($fline =~ /^.[\s$;]*$/);
- $has_statement = 1;
- $count++;
- $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
- }
- if (!$has_break && $has_statement) {
- WARN("MISSING_BREAK",
- "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
- }
- }
-
# check for /* fallthrough */ like comment, prefer fallthrough;
my @fallthroughs = (
'fallthrough',
@@ -6628,7 +6654,8 @@ sub process {
# check for various structs that are normally const (ops, kgdb, device_tree)
# and avoid what seem like struct definitions 'struct foo {'
- if ($line !~ /\bconst\b/ &&
+ if (defined($const_structs) &&
+ $line !~ /\bconst\b/ &&
$line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
WARN("CONST_STRUCT",
"struct $1 should normally be const\n" . $herecurr);
diff --git a/scripts/coccinelle/api/device_attr_show.cocci b/scripts/coccinelle/api/device_attr_show.cocci
new file mode 100644
index 000000000000..d8ec4bb8ac41
--- /dev/null
+++ b/scripts/coccinelle/api/device_attr_show.cocci
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// From Documentation/filesystems/sysfs.txt:
+/// show() must not use snprintf() when formatting the value to be
+/// returned to user space. If you can guarantee that an overflow
+/// will never happen you can use sprintf() otherwise you must use
+/// scnprintf().
+///
+// Confidence: High
+// Copyright: (C) 2020 Denis Efremov ISPRAS
+// Options: --no-includes --include-headers
+//
+
+virtual report
+virtual org
+virtual context
+virtual patch
+
+@r depends on !patch@
+identifier show, dev, attr, buf;
+position p;
+@@
+
+ssize_t show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ <...
+* return snprintf@p(...);
+ ...>
+}
+
+@rp depends on patch@
+identifier show, dev, attr, buf;
+@@
+
+ssize_t show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ <...
+ return
+- snprintf
++ scnprintf
+ (...);
+ ...>
+}
+
+@script: python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: use scnprintf or sprintf")
+
+@script: python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: use scnprintf or sprintf")
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci
index 19f2645e6076..3c6dc5469ee4 100644
--- a/scripts/coccinelle/api/kstrdup.cocci
+++ b/scripts/coccinelle/api/kstrdup.cocci
@@ -66,7 +66,7 @@ position p1,p2;
* x = strlen(from) + 1;
... when != \( x = E1 \| from = E1 \)
-* to = \(kmalloc@p1\|kzalloc@p2\)(x,flag);
+* to = \(kmalloc@p1\|kzalloc@p1\)(x,flag);
... when != \(x = E2 \| from = E2 \| to = E2 \)
if (to==NULL || ...) S
... when != \(x = E3 \| from = E3 \| to = E3 \)
diff --git a/scripts/coccinelle/api/kzfree.cocci b/scripts/coccinelle/api/kzfree.cocci
new file mode 100644
index 000000000000..33625bd7cec9
--- /dev/null
+++ b/scripts/coccinelle/api/kzfree.cocci
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Use kzfree, kvfree_sensitive rather than memset or
+/// memzero_explicit followed by kfree
+///
+// Confidence: High
+// Copyright: (C) 2020 Denis Efremov ISPRAS
+// Options: --no-includes --include-headers
+//
+// Keywords: kzfree, kvfree_sensitive
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+@initialize:python@
+@@
+# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
+filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive'])
+
+def relevant(p):
+ return not (filter & {el.current_element for el in p})
+
+@cond@
+position ok;
+@@
+
+if (...)
+ \(memset@ok\|memzero_explicit@ok\)(...);
+
+@r depends on !patch forall@
+expression E;
+position p : script:python() { relevant(p) };
+position m != cond.ok;
+type T;
+@@
+
+(
+* memset@m((T)E, 0, ...);
+|
+* memzero_explicit@m((T)E, ...);
+)
+ ... when != E
+ when strict
+* \(kfree\|vfree\|kvfree\)(E)@p;
+
+@rp_memzero depends on patch@
+expression E, size;
+position p : script:python() { relevant(p) };
+position m != cond.ok;
+type T;
+@@
+
+- memzero_explicit@m((T)E, size);
+ ... when != E
+ when strict
+// TODO: uncomment when kfree_sensitive will be merged.
+// Only this case is commented out because developers
+// may not like patches like this since kzfree uses memset
+// internally (not memzero_explicit).
+//(
+//- kfree(E)@p;
+//+ kfree_sensitive(E);
+//|
+- \(vfree\|kvfree\)(E)@p;
++ kvfree_sensitive(E, size);
+//)
+
+@rp_memset depends on patch@
+expression E, size;
+position p : script:python() { relevant(p) };
+position m != cond.ok;
+type T;
+@@
+
+- memset@m((T)E, 0, size);
+ ... when != E
+ when strict
+(
+- kfree(E)@p;
++ kzfree(E);
+|
+- \(vfree\|kvfree\)(E)@p;
++ kvfree_sensitive(E, size);
+)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0],
+ "WARNING: opportunity for kzfree/kvfree_sensitive")
+
+@script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0],
+ "WARNING: opportunity for kzfree/kvfree_sensitive")
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci
index c809ab10bbce..e01e95108405 100644
--- a/scripts/coccinelle/api/memdup_user.cocci
+++ b/scripts/coccinelle/api/memdup_user.cocci
@@ -15,12 +15,22 @@ virtual context
virtual org
virtual report
+@initialize:python@
+@@
+filter = frozenset(['memdup_user', 'vmemdup_user'])
+
+def relevant(p):
+ return not (filter & {el.current_element for el in p})
+
@depends on patch@
expression from,to,size;
identifier l1,l2;
+position p : script:python() { relevant(p) };
@@
-- to = \(kmalloc\|kzalloc\)(size,GFP_KERNEL);
+- to = \(kmalloc@p\|kzalloc@p\)
+- (size,\(GFP_KERNEL\|GFP_USER\|
+- \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\));
+ to = memdup_user(from,size);
if (
- to==NULL
@@ -37,13 +47,49 @@ identifier l1,l2;
- ...+>
- }
+@depends on patch@
+expression from,to,size;
+identifier l1,l2;
+position p : script:python() { relevant(p) };
+@@
+
+- to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\));
++ to = vmemdup_user(from,size);
+ if (
+- to==NULL
++ IS_ERR(to)
+ || ...) {
+ <+... when != goto l1;
+- -ENOMEM
++ PTR_ERR(to)
+ ...+>
+ }
+- if (copy_from_user(to, from, size) != 0) {
+- <+... when != goto l2;
+- -EFAULT
+- ...+>
+- }
+
@r depends on !patch@
expression from,to,size;
-position p;
+position p : script:python() { relevant(p) };
statement S1,S2;
@@
-* to = \(kmalloc@p\|kzalloc@p\)(size,GFP_KERNEL);
+* to = \(kmalloc@p\|kzalloc@p\)
+ (size,\(GFP_KERNEL\|GFP_USER\|
+ \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\));
+ if (to==NULL || ...) S1
+ if (copy_from_user(to, from, size) != 0)
+ S2
+
+@rv depends on !patch@
+expression from,to,size;
+position p : script:python() { relevant(p) };
+statement S1,S2;
+@@
+
+* to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\));
if (to==NULL || ...) S1
if (copy_from_user(to, from, size) != 0)
S2
@@ -59,3 +105,15 @@ p << r.p;
@@
coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
+
+@script:python depends on org@
+p << rv.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING opportunity for vmemdup_user")
+
+@script:python depends on report@
+p << rv.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING opportunity for vmemdup_user")
diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci
index 3357bf4dbd7c..da80050b91ff 100644
--- a/scripts/coccinelle/free/devm_free.cocci
+++ b/scripts/coccinelle/free/devm_free.cocci
@@ -89,7 +89,7 @@ position p;
(
kfree@p(x)
|
- kzfree@p(x)
+ kfree_sensitive@p(x)
|
krealloc@p(x, ...)
|
@@ -112,7 +112,7 @@ position p != safe.p;
(
* kfree@p(x)
|
-* kzfree@p(x)
+* kfree_sensitive@p(x)
|
* krealloc@p(x, ...)
|
diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci
index b3290c4ee239..2045391e36a0 100644
--- a/scripts/coccinelle/free/ifnullfree.cocci
+++ b/scripts/coccinelle/free/ifnullfree.cocci
@@ -21,7 +21,7 @@ expression E;
(
kfree(E);
|
- kzfree(E);
+ kfree_sensitive(E);
|
debugfs_remove(E);
|
@@ -42,7 +42,7 @@ position p;
@@
* if (E != NULL)
-* \(kfree@p\|kzfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|
+* \(kfree@p\|kfree_sensitive@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|
* usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\|
* dma_pool_destroy@p\)(E);
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
index e9d50e718e46..168568386034 100644
--- a/scripts/coccinelle/free/kfree.cocci
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -24,7 +24,7 @@ position p1;
(
* kfree@p1(E)
|
-* kzfree@p1(E)
+* kfree_sensitive@p1(E)
)
@print expression@
@@ -68,7 +68,7 @@ while (1) { ...
(
* kfree@ok(E)
|
-* kzfree@ok(E)
+* kfree_sensitive@ok(E)
)
... when != break;
when != goto l;
@@ -86,7 +86,7 @@ position free.p1!=loop.ok,p2!={print.p,sz.p};
(
* kfree@p1(E,...)
|
-* kzfree@p1(E,...)
+* kfree_sensitive@p1(E,...)
)
...
(
diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci
index cfaf308328d8..142af6337a04 100644
--- a/scripts/coccinelle/free/kfreeaddr.cocci
+++ b/scripts/coccinelle/free/kfreeaddr.cocci
@@ -20,7 +20,7 @@ position p;
(
* kfree@p(&e->f)
|
-* kzfree@p(&e->f)
+* kfree_sensitive@p(&e->f)
)
@script:python depends on org@
diff --git a/scripts/coccinelle/misc/add_namespace.cocci b/scripts/coccinelle/misc/add_namespace.cocci
index 99e93a6c2e24..cbf1614163cb 100644
--- a/scripts/coccinelle/misc/add_namespace.cocci
+++ b/scripts/coccinelle/misc/add_namespace.cocci
@@ -6,6 +6,7 @@
/// add a missing namespace tag to a module source file.
///
+virtual nsdeps
virtual report
@has_ns_import@
@@ -16,10 +17,15 @@ MODULE_IMPORT_NS(ns);
// Add missing imports, but only adjacent to a MODULE_LICENSE statement.
// That ensures we are adding it only to the main module source file.
-@do_import depends on !has_ns_import@
+@do_import depends on !has_ns_import && nsdeps@
declarer name MODULE_LICENSE;
expression license;
identifier virtual.ns;
@@
MODULE_LICENSE(license);
+ MODULE_IMPORT_NS(ns);
+
+// Dummy rule for report mode that would otherwise be empty and make spatch
+// fail ("No rules apply.")
+@script:python depends on report@
+@@
diff --git a/scripts/coccinelle/misc/array_size_dup.cocci b/scripts/coccinelle/misc/array_size_dup.cocci
new file mode 100644
index 000000000000..fbc2ba1401d7
--- /dev/null
+++ b/scripts/coccinelle/misc/array_size_dup.cocci
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Check for array_size(), array3_size(), struct_size() duplicates.
+/// These patterns are detected:
+/// 1. An opencoded expression is used before array_size() to compute the same size
+/// 2. An opencoded expression is used after array_size() to compute the same size
+/// From security point of view only first case is relevant. These functions
+/// perform arithmetic overflow check. Thus, if we use an opencoded expression
+/// before a call to the *_size() function we can miss an overflow.
+///
+// Confidence: High
+// Copyright: (C) 2020 Denis Efremov ISPRAS
+// Options: --no-includes --include-headers --no-loops
+
+virtual context
+virtual report
+virtual org
+
+@as@
+expression E1, E2;
+@@
+
+array_size(E1, E2)
+
+@as_next@
+expression subE1 <= as.E1;
+expression subE2 <= as.E2;
+expression as.E1, as.E2, E3;
+assignment operator aop;
+position p1, p2;
+@@
+
+* E1 * E2@p1
+ ... when != \(subE1\|subE2\) aop E3
+ when != &\(subE1\|subE2\)
+* array_size(E1, E2)@p2
+
+@script:python depends on report@
+p1 << as_next.p1;
+p2 << as_next.p2;
+@@
+
+msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.report.print_report(p1[0], msg)
+
+@script:python depends on org@
+p1 << as_next.p1;
+p2 << as_next.p2;
+@@
+
+msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.org.print_todo(p1[0], msg)
+
+@as_prev@
+expression subE1 <= as.E1;
+expression subE2 <= as.E2;
+expression as.E1, as.E2, E3;
+assignment operator aop;
+position p1, p2;
+@@
+
+* array_size(E1, E2)@p1
+ ... when != \(subE1\|subE2\) aop E3
+ when != &\(subE1\|subE2\)
+* E1 * E2@p2
+
+@script:python depends on report@
+p1 << as_prev.p1;
+p2 << as_prev.p2;
+@@
+
+msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
+
+@script:python depends on org@
+p1 << as_prev.p1;
+p2 << as_prev.p2;
+@@
+
+msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.org.print_todo(p2[0], msg)
+
+@as3@
+expression E1, E2, E3;
+@@
+
+array3_size(E1, E2, E3)
+
+@as3_next@
+expression subE1 <= as3.E1;
+expression subE2 <= as3.E2;
+expression subE3 <= as3.E3;
+expression as3.E1, as3.E2, as3.E3, E4;
+assignment operator aop;
+position p1, p2;
+@@
+
+* E1 * E2 * E3@p1
+ ... when != \(subE1\|subE2\|subE3\) aop E4
+ when != &\(subE1\|subE2\|subE3\)
+* array3_size(E1, E2, E3)@p2
+
+@script:python depends on report@
+p1 << as3_next.p1;
+p2 << as3_next.p2;
+@@
+
+msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.report.print_report(p1[0], msg)
+
+@script:python depends on org@
+p1 << as3_next.p1;
+p2 << as3_next.p2;
+@@
+
+msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.org.print_todo(p1[0], msg)
+
+@as3_prev@
+expression subE1 <= as3.E1;
+expression subE2 <= as3.E2;
+expression subE3 <= as3.E3;
+expression as3.E1, as3.E2, as3.E3, E4;
+assignment operator aop;
+position p1, p2;
+@@
+
+* array3_size(E1, E2, E3)@p1
+ ... when != \(subE1\|subE2\|subE3\) aop E4
+ when != &\(subE1\|subE2\|subE3\)
+* E1 * E2 * E3@p2
+
+@script:python depends on report@
+p1 << as3_prev.p1;
+p2 << as3_prev.p2;
+@@
+
+msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
+
+@script:python depends on org@
+p1 << as3_prev.p1;
+p2 << as3_prev.p2;
+@@
+
+msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.org.print_todo(p2[0], msg)
+
+@ss@
+expression E1, E2, E3;
+@@
+
+struct_size(E1, E2, E3)
+
+@ss_next@
+expression subE3 <= ss.E3;
+expression ss.E1, ss.E2, ss.E3, E4;
+assignment operator aop;
+position p1, p2;
+@@
+
+* E1 * E2 + E3@p1
+ ... when != subE3 aop E4
+ when != &subE3
+* struct_size(E1, E2, E3)@p2
+
+@script:python depends on report@
+p1 << ss_next.p1;
+p2 << ss_next.p2;
+@@
+
+msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.report.print_report(p1[0], msg)
+
+@script:python depends on org@
+p1 << ss_next.p1;
+p2 << ss_next.p2;
+@@
+
+msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
+coccilib.org.print_todo(p1[0], msg)
+
+@ss_prev@
+expression subE3 <= ss.E3;
+expression ss.E1, ss.E2, ss.E3, E4;
+assignment operator aop;
+position p1, p2;
+@@
+
+* struct_size(E1, E2, E3)@p1
+ ... when != subE3 aop E4
+ when != &subE3
+* E1 * E2 + E3@p2
+
+@script:python depends on report@
+p1 << ss_prev.p1;
+p2 << ss_prev.p2;
+@@
+
+msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.report.print_report(p2[0], msg)
+
+@script:python depends on org@
+p1 << ss_prev.p1;
+p2 << ss_prev.p2;
+@@
+
+msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
+coccilib.org.print_todo(p2[0], msg)
diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch
index ac5f1267151d..e9df9cc28a85 100644
--- a/scripts/const_structs.checkpatch
+++ b/scripts/const_structs.checkpatch
@@ -44,6 +44,7 @@ platform_hibernation_ops
platform_suspend_ops
proto_ops
regmap_access_table
+regulator_ops
rpc_pipe_ops
rtc_class_ops
sd_desc
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index 13e5fbafdf2f..90398347e366 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -3,18 +3,68 @@
# (c) 2014, Sasha Levin <sasha.levin@oracle.com>
#set -x
-if [[ $# < 2 ]]; then
+if [[ $# < 1 ]]; then
echo "Usage:"
- echo " $0 [vmlinux] [base path] [modules path]"
+ echo " $0 -r <release> | <vmlinux> [base path] [modules path]"
exit 1
fi
-vmlinux=$1
-basepath=$2
-modpath=$3
+if [[ $1 == "-r" ]] ; then
+ vmlinux=""
+ basepath="auto"
+ modpath=""
+ release=$2
+
+ for fn in {,/usr/lib/debug}/boot/vmlinux-$release{,.debug} /lib/modules/$release{,/build}/vmlinux ; do
+ if [ -e "$fn" ] ; then
+ vmlinux=$fn
+ break
+ fi
+ done
+
+ if [[ $vmlinux == "" ]] ; then
+ echo "ERROR! vmlinux image for release $release is not found" >&2
+ exit 2
+ fi
+else
+ vmlinux=$1
+ basepath=${2-auto}
+ modpath=$3
+ release=""
+fi
+
declare -A cache
declare -A modcache
+find_module() {
+ if [[ "$modpath" != "" ]] ; then
+ for fn in $(find "$modpath" -name "${module//_/[-_]}.ko*") ; do
+ if readelf -WS "$fn" | grep -qwF .debug_line ; then
+ echo $fn
+ return
+ fi
+ done
+ return 1
+ fi
+
+ modpath=$(dirname "$vmlinux")
+ find_module && return
+
+ if [[ $release == "" ]] ; then
+ release=$(gdb -ex 'print init_uts_ns.name.release' -ex 'quit' -quiet -batch "$vmlinux" | sed -n 's/\$1 = "\(.*\)".*/\1/p')
+ fi
+
+ for dn in {/usr/lib/debug,}/lib/modules/$release ; do
+ if [ -e "$dn" ] ; then
+ modpath="$dn"
+ find_module && return
+ fi
+ done
+
+ modpath=""
+ return 1
+}
+
parse_symbol() {
# The structure of symbol at this point is:
# ([name]+[offset]/[total length])
@@ -27,9 +77,11 @@ parse_symbol() {
elif [[ "${modcache[$module]+isset}" == "isset" ]]; then
local objfile=${modcache[$module]}
else
- [[ $modpath == "" ]] && return
- local objfile=$(find "$modpath" -name "${module//_/[-_]}.ko*" -print -quit)
- [[ $objfile == "" ]] && return
+ local objfile=$(find_module)
+ if [[ $objfile == "" ]] ; then
+ echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2
+ return
+ fi
modcache[$module]=$objfile
fi
@@ -53,7 +105,11 @@ parse_symbol() {
if [[ "${cache[$module,$name]+isset}" == "isset" ]]; then
local base_addr=${cache[$module,$name]}
else
- local base_addr=$(nm "$objfile" | grep -i ' t ' | awk "/ $name\$/ {print \$1}" | head -n1)
+ local base_addr=$(nm "$objfile" | awk '$3 == "'$name'" && ($2 == "t" || $2 == "T") {print $1; exit}')
+ if [[ $base_addr == "" ]] ; then
+ # address not found
+ return
+ fi
cache[$module,$name]="$base_addr"
fi
# Let's start doing the math to get the exact address into the
@@ -84,8 +140,8 @@ parse_symbol() {
return
fi
- # Strip out the base of the path
- code=${code#$basepath/}
+ # Strip out the base of the path on each line
+ code=$(while read -r line; do echo "${line#$basepath/}"; done <<< "$code")
# In the case of inlines, move everything to same line
code=${code//$'\n'/' '}
@@ -145,6 +201,14 @@ handle_line() {
echo "${words[@]}" "$symbol $module"
}
+if [[ $basepath == "auto" ]] ; then
+ module=""
+ symbol="kernel_init+0x0/0x0"
+ parse_symbol
+ basepath=${symbol#kernel_init (}
+ basepath=${basepath%/init/main.c:*)}
+fi
+
while read line; do
# Let's see if we have an address in the line
if [[ $line =~ \[\<([^]]+)\>\] ]] ||
diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 0b44917f981c..a698ece43fff 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
# scripts/dtc makefile
-hostprogs := dtc
-always-$(CONFIG_DTC) += $(hostprogs)
-always-$(CHECK_DT_BINDING) += $(hostprogs)
+hostprogs-always-$(CONFIG_DTC) += dtc
+hostprogs-always-$(CHECK_DT_BINDING) += dtc
dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
srcpos.o checks.o util.o
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 4b3c486f1399..b7955dbd71ca 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -1022,6 +1022,9 @@ static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct no
}
WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells);
+#define I2C_OWN_SLAVE_ADDRESS (1U << 30)
+#define I2C_TEN_BIT_ADDRESS (1U << 31)
+
static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{
struct property *prop;
@@ -1044,6 +1047,8 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
}
reg = fdt32_to_cpu(*cells);
+ /* Ignore I2C_OWN_SLAVE_ADDRESS */
+ reg &= ~I2C_OWN_SLAVE_ADDRESS;
snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
if (!streq(unitname, unit_addr))
FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
@@ -1051,10 +1056,15 @@ static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node
for (len = prop->val.len; len > 0; len -= 4) {
reg = fdt32_to_cpu(*(cells++));
- if (reg > 0x3ff)
+ /* Ignore I2C_OWN_SLAVE_ADDRESS */
+ reg &= ~I2C_OWN_SLAVE_ADDRESS;
+
+ if ((reg & I2C_TEN_BIT_ADDRESS) && ((reg & ~I2C_TEN_BIT_ADDRESS) > 0x3ff))
FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
reg);
-
+ else if (reg > 0x7f)
+ FAIL_PROP(c, dti, node, prop, "I2C address must be less than 7-bits, got \"0x%x\". Set I2C_TEN_BIT_ADDRESS for 10 bit addresses or fix the property",
+ reg);
}
}
WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);
@@ -1547,6 +1557,28 @@ static bool node_is_interrupt_provider(struct node *node)
return false;
}
+
+static void check_interrupt_provider(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ if (!node_is_interrupt_provider(node))
+ return;
+
+ prop = get_property(node, "#interrupt-cells");
+ if (!prop)
+ FAIL(c, dti, node,
+ "Missing #interrupt-cells in interrupt provider");
+
+ prop = get_property(node, "#address-cells");
+ if (!prop)
+ FAIL(c, dti, node,
+ "Missing #address-cells in interrupt provider");
+}
+WARNING(interrupt_provider, check_interrupt_provider, NULL);
+
static void check_interrupts_property(struct check *c,
struct dt_info *dti,
struct node *node)
@@ -1604,7 +1636,7 @@ static void check_interrupts_property(struct check *c,
prop = get_property(irq_node, "#interrupt-cells");
if (!prop) {
- FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent");
+ /* We warn about that already in another test. */
return;
}
@@ -1828,6 +1860,7 @@ static struct check *check_table[] = {
&deprecated_gpio_property,
&gpios_property,
&interrupts_property,
+ &interrupt_provider,
&alias_paths,
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 6e74ecea55a3..a08f4159cd03 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -51,6 +51,37 @@ extern int annotate; /* annotate .dts with input source location */
typedef uint32_t cell_t;
+static inline uint16_t dtb_ld16(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint16_t)bp[0] << 8)
+ | bp[1];
+}
+
+static inline uint32_t dtb_ld32(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint32_t)bp[0] << 24)
+ | ((uint32_t)bp[1] << 16)
+ | ((uint32_t)bp[2] << 8)
+ | bp[3];
+}
+
+static inline uint64_t dtb_ld64(const void *p)
+{
+ const uint8_t *bp = (const uint8_t *)p;
+
+ return ((uint64_t)bp[0] << 56)
+ | ((uint64_t)bp[1] << 48)
+ | ((uint64_t)bp[2] << 40)
+ | ((uint64_t)bp[3] << 32)
+ | ((uint64_t)bp[4] << 24)
+ | ((uint64_t)bp[5] << 16)
+ | ((uint64_t)bp[6] << 8)
+ | bp[7];
+}
#define streq(a, b) (strcmp((a), (b)) == 0)
#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index bd6977eedcb8..07f10d2b5d79 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -156,7 +156,7 @@ static void asm_emit_data(void *e, struct data d)
emit_offset_label(f, m->ref, m->offset);
while ((d.len - off) >= sizeof(uint32_t)) {
- asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off))));
+ asm_emit_cell(e, dtb_ld32(d.val + off));
off += sizeof(uint32_t);
}
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 524b520c8486..93e4a2b56348 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -436,7 +436,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
return struct_size;
}
- if (can_assume(LIBFDT_ORDER) |
+ if (can_assume(LIBFDT_ORDER) ||
!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
/* no further work necessary */
err = fdt_move(fdt, buf, bufsize);
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 26759d5dfb8c..94ce4bb91a00 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -32,7 +32,7 @@ static int fdt_sw_probe_(void *fdt)
/* 'memrsv' state: Initial state after fdt_create()
*
* Allowed functions:
- * fdt_add_reservmap_entry()
+ * fdt_add_reservemap_entry()
* fdt_finish_reservemap() [moves to 'struct' state]
*/
static int fdt_sw_probe_memrsv_(void *fdt)
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 36fadcdea516..fe49b5d78938 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -9,6 +9,10 @@
#include "libfdt_env.h"
#include "fdt.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define FDT_FIRST_SUPPORTED_VERSION 0x02
#define FDT_LAST_SUPPORTED_VERSION 0x11
@@ -2069,4 +2073,8 @@ int fdt_overlay_apply(void *fdt, void *fdto);
const char *fdt_strerror(int errval);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* LIBFDT_H */
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index c9d980c8abfc..061ba8c9c5e8 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -110,13 +110,13 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
break;
case 2:
- fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
+ fprintf(f, "0x%02"PRIx16, dtb_ld16(p));
break;
case 4:
- fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
+ fprintf(f, "0x%02"PRIx32, dtb_ld32(p));
break;
case 8:
- fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
+ fprintf(f, "0x%02"PRIx64, dtb_ld64(p));
break;
}
if (p + width < end)
@@ -183,7 +183,7 @@ static enum markertype guess_value_type(struct property *prop)
nnotcelllbl++;
}
- if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
+ if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul))
&& (nnotstringlbl == 0)) {
return TYPE_STRING;
} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 61dd7112d6e4..0714799446f8 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.6.0-g87a656ae"
+#define DTC_VERSION "DTC 1.6.0-g9d7888cb"
diff --git a/scripts/dtc/yamltree.c b/scripts/dtc/yamltree.c
index 5b6ea8ea862f..4e93c12dc658 100644
--- a/scripts/dtc/yamltree.c
+++ b/scripts/dtc/yamltree.c
@@ -59,10 +59,10 @@ static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, ch
sprintf(buf, "0x%"PRIx8, *(uint8_t*)(data + off));
break;
case 2:
- sprintf(buf, "0x%"PRIx16, fdt16_to_cpu(*(fdt16_t*)(data + off)));
+ sprintf(buf, "0x%"PRIx16, dtb_ld16(data + off));
break;
case 4:
- sprintf(buf, "0x%"PRIx32, fdt32_to_cpu(*(fdt32_t*)(data + off)));
+ sprintf(buf, "0x%"PRIx32, dtb_ld32(data + off));
m = markers;
is_phandle = false;
for_each_marker_of_type(m, REF_PHANDLE) {
@@ -73,7 +73,7 @@ static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, ch
}
break;
case 8:
- sprintf(buf, "0x%"PRIx64, fdt64_to_cpu(*(fdt64_t*)(data + off)));
+ sprintf(buf, "0x%"PRIx64, dtb_ld64(data + off));
break;
}
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index ce0b99fb5847..ae19fb0243b9 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -78,7 +78,7 @@ config GCC_PLUGIN_RANDSTRUCT
source tree isn't cleaned after kernel installation).
The seed used for compilation is located at
- scripts/gcc-plgins/randomize_layout_seed.h. It remains after
+ scripts/gcc-plugins/randomize_layout_seed.h. It remains after
a make clean to allow for external modules to be compiled with
the existing seed and will be removed by a make mrproper or
make distclean.
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 4014ba7e2fbd..d66949bfeba4 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -1,22 +1,61 @@
# SPDX-License-Identifier: GPL-2.0
-GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
-HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti
-HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb
-HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat
-HOST_EXTRACXXFLAGS += -Wno-format-diag
-
-$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
+$(obj)/randomize_layout_plugin.so: $(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
+targets += randomize_layout_seed.h randomize_layout_hash.h
+
+# Build rules for plugins
+#
+# No extra code is needed for single-file plugins.
+# For multi-file plugins, use *-objs syntax to list the objects.
+#
+# If the plugin foo.so is compiled from foo.c and foo2.c, you can do:
+#
+# foo-objs := foo.o foo2.o
+
+always-y += $(GCC_PLUGIN)
-hostcxxlibs-y := $(GCC_PLUGIN)
-always-y := $(hostcxxlibs-y)
+GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)
-$(foreach p,$(hostcxxlibs-y:%.so=%),$(eval $(p)-objs := $(p).o))
+plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
+ -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++98 \
+ -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
+ -ggdb -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat \
+ -Wno-format-diag
+plugin_ldflags = -shared
+
+plugin-single := $(foreach m, $(GCC_PLUGIN), $(if $($(m:%.so=%-objs)),,$(m)))
+plugin-multi := $(filter-out $(plugin-single), $(GCC_PLUGIN))
+plugin-objs := $(sort $(foreach m, $(plugin-multi), $($(m:%.so=%-objs))))
+
+targets += $(plugin-single) $(plugin-multi) $(plugin-objs)
clean-files += *.so
+
+plugin-single := $(addprefix $(obj)/, $(plugin-single))
+plugin-multi := $(addprefix $(obj)/, $(plugin-multi))
+plugin-objs := $(addprefix $(obj)/, $(plugin-objs))
+
+quiet_cmd_plugin_cxx_so_c = HOSTCXX $@
+ cmd_plugin_cxx_so_c = $(HOSTCXX) $(plugin_cxxflags) $(plugin_ldflags) -o $@ $<
+
+$(plugin-single): $(obj)/%.so: $(src)/%.c FORCE
+ $(call if_changed_dep,plugin_cxx_so_c)
+
+quiet_cmd_plugin_ld_so_o = HOSTLD $@
+ cmd_plugin_ld_so_o = $(HOSTCXX) $(plugin_ldflags) -o $@ \
+ $(addprefix $(obj)/, $($(target-stem)-objs))
+
+$(plugin-multi): FORCE
+ $(call if_changed,plugin_ld_so_o)
+$(foreach m, $(notdir $(plugin-multi)), $(eval $(obj)/$m: $(addprefix $(obj)/, $($(m:%.so=%-objs)))))
+
+quiet_cmd_plugin_cxx_o_c = HOSTCXX $@
+ cmd_plugin_cxx_o_c = $(HOSTCXX) $(plugin_cxxflags) -c -o $@ $<
+
+$(plugin-objs): $(obj)/%.o: $(src)/%.c FORCE
+ $(call if_changed_dep,plugin_cxx_o_c)
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c b/scripts/gcc-plugins/cyc_complexity_plugin.c
index 1909ec617431..73124c2b3edd 100644
--- a/scripts/gcc-plugins/cyc_complexity_plugin.c
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -5,7 +5,7 @@
* Homepage:
* https://github.com/ephox-gcc-plugins/cyclomatic_complexity
*
- * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * https://en.wikipedia.org/wiki/Cyclomatic_complexity
* The complexity M is then defined as:
* M = E - N + 2P
* where
diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c
index 0f98634c20a0..caff4a6c7e9a 100644
--- a/scripts/gcc-plugins/sancov_plugin.c
+++ b/scripts/gcc-plugins/sancov_plugin.c
@@ -11,7 +11,7 @@
*
* You can read about it more here:
* https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296
- * http://lwn.net/Articles/674854/
+ * https://lwn.net/Articles/674854/
* https://github.com/google/syzkaller
* https://lwn.net/Articles/677764/
*
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
index cc75eeba0be1..48e141e07956 100644
--- a/scripts/gcc-plugins/stackleak_plugin.c
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -20,7 +20,7 @@
*
* Debugging:
* - use fprintf() to stderr, debug_generic_expr(), debug_gimple_stmt(),
- * print_rtl() and print_simple_rtl();
+ * print_rtl_single() and debug_rtx();
* - add "-fdump-tree-all -fdump-rtl-all" to the plugin CFLAGS in
* Makefile.gcc-plugins to see the verbose dumps of the gcc passes;
* - use gcc -E to understand the preprocessing shenanigans;
@@ -32,7 +32,10 @@
__visible int plugin_is_GPL_compatible;
static int track_frame_size = -1;
+static bool build_for_x86 = false;
static const char track_function[] = "stackleak_track_stack";
+static bool disable = false;
+static bool verbose = false;
/*
* Mark these global variables (roots) for gcc garbage collector since
@@ -43,32 +46,32 @@ static GTY(()) tree track_function_decl;
static struct plugin_info stackleak_plugin_info = {
.version = "201707101337",
.help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n"
+ "arch=target_arch\tspecify target build arch\n"
"disable\t\tdo not activate the plugin\n"
+ "verbose\t\tprint info about the instrumentation\n"
};
-static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after)
+static void add_stack_tracking_gcall(gimple_stmt_iterator *gsi, bool after)
{
gimple stmt;
- gcall *stackleak_track_stack;
+ gcall *gimple_call;
cgraph_node_ptr node;
basic_block bb;
- /* Insert call to void stackleak_track_stack(void) */
+ /* Insert calling stackleak_track_stack() */
stmt = gimple_build_call(track_function_decl, 0);
- stackleak_track_stack = as_a_gcall(stmt);
- if (after) {
- gsi_insert_after(gsi, stackleak_track_stack,
- GSI_CONTINUE_LINKING);
- } else {
- gsi_insert_before(gsi, stackleak_track_stack, GSI_SAME_STMT);
- }
+ gimple_call = as_a_gcall(stmt);
+ if (after)
+ gsi_insert_after(gsi, gimple_call, GSI_CONTINUE_LINKING);
+ else
+ gsi_insert_before(gsi, gimple_call, GSI_SAME_STMT);
/* Update the cgraph */
- bb = gimple_bb(stackleak_track_stack);
+ bb = gimple_bb(gimple_call);
node = cgraph_get_create_node(track_function_decl);
gcc_assert(node);
cgraph_create_edge(cgraph_get_node(current_function_decl), node,
- stackleak_track_stack, bb->count,
+ gimple_call, bb->count,
compute_call_stmt_bb_frequency(current_function_decl, bb));
}
@@ -85,6 +88,83 @@ static bool is_alloca(gimple stmt)
return false;
}
+static tree get_current_stack_pointer_decl(void)
+{
+ varpool_node_ptr node;
+
+ FOR_EACH_VARIABLE(node) {
+ tree var = NODE_DECL(node);
+ tree name = DECL_NAME(var);
+
+ if (DECL_NAME_LENGTH(var) != sizeof("current_stack_pointer") - 1)
+ continue;
+
+ if (strcmp(IDENTIFIER_POINTER(name), "current_stack_pointer"))
+ continue;
+
+ return var;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "stackleak: missing current_stack_pointer in %s()\n",
+ DECL_NAME_POINTER(current_function_decl));
+ }
+ return NULL_TREE;
+}
+
+static void add_stack_tracking_gasm(gimple_stmt_iterator *gsi, bool after)
+{
+ gasm *asm_call = NULL;
+ tree sp_decl, input;
+ vec<tree, va_gc> *inputs = NULL;
+
+ /* 'no_caller_saved_registers' is currently supported only for x86 */
+ gcc_assert(build_for_x86);
+
+ /*
+ * Insert calling stackleak_track_stack() in asm:
+ * asm volatile("call stackleak_track_stack"
+ * :: "r" (current_stack_pointer))
+ * Use ASM_CALL_CONSTRAINT trick from arch/x86/include/asm/asm.h.
+ * This constraint is taken into account during gcc shrink-wrapping
+ * optimization. It is needed to be sure that stackleak_track_stack()
+ * call is inserted after the prologue of the containing function,
+ * when the stack frame is prepared.
+ */
+ sp_decl = get_current_stack_pointer_decl();
+ if (sp_decl == NULL_TREE) {
+ add_stack_tracking_gcall(gsi, after);
+ return;
+ }
+ input = build_tree_list(NULL_TREE, build_const_char_string(2, "r"));
+ input = chainon(NULL_TREE, build_tree_list(input, sp_decl));
+ vec_safe_push(inputs, input);
+ asm_call = gimple_build_asm_vec("call stackleak_track_stack",
+ inputs, NULL, NULL, NULL);
+ gimple_asm_set_volatile(asm_call, true);
+ if (after)
+ gsi_insert_after(gsi, asm_call, GSI_CONTINUE_LINKING);
+ else
+ gsi_insert_before(gsi, asm_call, GSI_SAME_STMT);
+ update_stmt(asm_call);
+}
+
+static void add_stack_tracking(gimple_stmt_iterator *gsi, bool after)
+{
+ /*
+ * The 'no_caller_saved_registers' attribute is used for
+ * stackleak_track_stack(). If the compiler supports this attribute for
+ * the target arch, we can add calling stackleak_track_stack() in asm.
+ * That improves performance: we avoid useless operations with the
+ * caller-saved registers in the functions from which we will remove
+ * stackleak_track_stack() call during the stackleak_cleanup pass.
+ */
+ if (lookup_attribute_spec(get_identifier("no_caller_saved_registers")))
+ add_stack_tracking_gasm(gsi, after);
+ else
+ add_stack_tracking_gcall(gsi, after);
+}
+
/*
* Work with the GIMPLE representation of the code. Insert the
* stackleak_track_stack() call after alloca() and into the beginning
@@ -94,7 +174,7 @@ static unsigned int stackleak_instrument_execute(void)
{
basic_block bb, entry_bb;
bool prologue_instrumented = false, is_leaf = true;
- gimple_stmt_iterator gsi;
+ gimple_stmt_iterator gsi = { 0 };
/*
* ENTRY_BLOCK_PTR is a basic block which represents possible entry
@@ -122,8 +202,13 @@ static unsigned int stackleak_instrument_execute(void)
if (!is_alloca(stmt))
continue;
+ if (verbose) {
+ fprintf(stderr, "stackleak: be careful, alloca() in %s()\n",
+ DECL_NAME_POINTER(current_function_decl));
+ }
+
/* Insert stackleak_track_stack() call after alloca() */
- stackleak_add_track_stack(&gsi, true);
+ add_stack_tracking(&gsi, true);
if (bb == entry_bb)
prologue_instrumented = true;
}
@@ -168,7 +253,7 @@ static unsigned int stackleak_instrument_execute(void)
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
}
gsi = gsi_after_labels(bb);
- stackleak_add_track_stack(&gsi, false);
+ add_stack_tracking(&gsi, false);
return 0;
}
@@ -182,21 +267,10 @@ static bool large_stack_frame(void)
#endif
}
-/*
- * Work with the RTL representation of the code.
- * Remove the unneeded stackleak_track_stack() calls from the functions
- * which don't call alloca() and don't have a large enough stack frame size.
- */
-static unsigned int stackleak_cleanup_execute(void)
+static void remove_stack_tracking_gcall(void)
{
rtx_insn *insn, *next;
- if (cfun->calls_alloca)
- return 0;
-
- if (large_stack_frame())
- return 0;
-
/*
* Find stackleak_track_stack() calls. Loop through the chain of insns,
* which is an RTL representation of the code for a function.
@@ -257,6 +331,102 @@ static unsigned int stackleak_cleanup_execute(void)
}
#endif
}
+}
+
+static bool remove_stack_tracking_gasm(void)
+{
+ bool removed = false;
+ rtx_insn *insn, *next;
+
+ /* 'no_caller_saved_registers' is currently supported only for x86 */
+ gcc_assert(build_for_x86);
+
+ /*
+ * Find stackleak_track_stack() asm calls. Loop through the chain of
+ * insns, which is an RTL representation of the code for a function.
+ *
+ * The example of a matching insn:
+ * (insn 11 5 12 2 (parallel [ (asm_operands/v
+ * ("call stackleak_track_stack") ("") 0
+ * [ (reg/v:DI 7 sp [ current_stack_pointer ]) ]
+ * [ (asm_input:DI ("r")) ] [])
+ * (clobber (reg:CC 17 flags)) ]) -1 (nil))
+ */
+ for (insn = get_insns(); insn; insn = next) {
+ rtx body;
+
+ next = NEXT_INSN(insn);
+
+ /* Check the expression code of the insn */
+ if (!NONJUMP_INSN_P(insn))
+ continue;
+
+ /*
+ * Check the expression code of the insn body, which is an RTL
+ * Expression (RTX) describing the side effect performed by
+ * that insn.
+ */
+ body = PATTERN(insn);
+
+ if (GET_CODE(body) != PARALLEL)
+ continue;
+
+ body = XVECEXP(body, 0, 0);
+
+ if (GET_CODE(body) != ASM_OPERANDS)
+ continue;
+
+ if (strcmp(ASM_OPERANDS_TEMPLATE(body),
+ "call stackleak_track_stack")) {
+ continue;
+ }
+
+ delete_insn_and_edges(insn);
+ gcc_assert(!removed);
+ removed = true;
+ }
+
+ return removed;
+}
+
+/*
+ * Work with the RTL representation of the code.
+ * Remove the unneeded stackleak_track_stack() calls from the functions
+ * which don't call alloca() and don't have a large enough stack frame size.
+ */
+static unsigned int stackleak_cleanup_execute(void)
+{
+ const char *fn = DECL_NAME_POINTER(current_function_decl);
+ bool removed = false;
+
+ /*
+ * Leave stack tracking in functions that call alloca().
+ * Additional case:
+ * gcc before version 7 called allocate_dynamic_stack_space() from
+ * expand_stack_vars() for runtime alignment of constant-sized stack
+ * variables. That caused cfun->calls_alloca to be set for functions
+ * that in fact don't use alloca().
+ * For more info see gcc commit 7072df0aae0c59ae437e.
+ * Let's leave such functions instrumented as well.
+ */
+ if (cfun->calls_alloca) {
+ if (verbose)
+ fprintf(stderr, "stackleak: instrument %s(): calls_alloca\n", fn);
+ return 0;
+ }
+
+ /* Leave stack tracking in functions with large stack frame */
+ if (large_stack_frame()) {
+ if (verbose)
+ fprintf(stderr, "stackleak: instrument %s()\n", fn);
+ return 0;
+ }
+
+ if (lookup_attribute_spec(get_identifier("no_caller_saved_registers")))
+ removed = remove_stack_tracking_gasm();
+
+ if (!removed)
+ remove_stack_tracking_gcall();
return 0;
}
@@ -376,9 +546,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
/* Parse the plugin arguments */
for (i = 0; i < argc; i++) {
- if (!strcmp(argv[i].key, "disable"))
- return 0;
-
if (!strcmp(argv[i].key, "track-min-size")) {
if (!argv[i].value) {
error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
@@ -392,6 +559,19 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
plugin_name, argv[i].key, argv[i].value);
return 1;
}
+ } else if (!strcmp(argv[i].key, "arch")) {
+ if (!argv[i].value) {
+ error(G_("no value supplied for option '-fplugin-arg-%s-%s'"),
+ plugin_name, argv[i].key);
+ return 1;
+ }
+
+ if (!strcmp(argv[i].value, "x86"))
+ build_for_x86 = true;
+ } else if (!strcmp(argv[i].key, "disable")) {
+ disable = true;
+ } else if (!strcmp(argv[i].key, "verbose")) {
+ verbose = true;
} else {
error(G_("unknown option '-fplugin-arg-%s-%s'"),
plugin_name, argv[i].key);
@@ -399,6 +579,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
}
}
+ if (disable) {
+ if (verbose)
+ fprintf(stderr, "stackleak: disabled for this translation unit\n");
+ return 0;
+ }
+
/* Give the information about the plugin */
register_callback(plugin_name, PLUGIN_INFO, NULL,
&stackleak_plugin_info);
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index e89be8f5c859..b9ef2e162107 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -11,7 +11,7 @@
* otherwise leak kernel stack to userland if they aren't properly initialized
* by later code
*
- * Homepage: http://pax.grsecurity.net/
+ * Homepage: https://pax.grsecurity.net/
*
* Options:
* -fplugin-arg-structleak_plugin-disable
diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py
index 6ca93bd2949e..39cd1abd8559 100644
--- a/scripts/gdb/linux/genpd.py
+++ b/scripts/gdb/linux/genpd.py
@@ -49,17 +49,17 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary'''
else:
status_string = 'off-{}'.format(genpd['state_idx'])
- slave_names = []
+ child_names = []
for link in list_for_each_entry(
- genpd['master_links'],
+ genpd['parent_links'],
device_link_type.get_type().pointer(),
- 'master_node'):
- slave_names.apend(link['slave']['name'])
+ 'parent_node'):
+ child_names.append(link['child']['name'])
gdb.write('%-30s %-15s %s\n' % (
genpd['name'].string(),
status_string,
- ', '.join(slave_names)))
+ ', '.join(child_names)))
# Print devices in domain
for pm_data in list_for_each_entry(genpd['dev_list'],
@@ -70,7 +70,7 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary'''
gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev)))
def invoke(self, arg, from_tty):
- gdb.write('domain status slaves\n');
+ gdb.write('domain status children\n');
gdb.write(' /device runtime status\n');
gdb.write('----------------------------------------------------------------------\n');
for genpd in list_for_each_entry(
diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py
index c4b991607917..fe462855eefd 100644
--- a/scripts/gdb/linux/rbtree.py
+++ b/scripts/gdb/linux/rbtree.py
@@ -17,7 +17,7 @@ def rb_first(root):
raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
node = root['rb_node']
- if node is 0:
+ if node == 0:
return None
while node['rb_left']:
@@ -33,7 +33,7 @@ def rb_last(root):
raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
node = root['rb_node']
- if node is 0:
+ if node == 0:
return None
while node['rb_right']:
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
index be984aa29b75..1be9763cf8bb 100644
--- a/scripts/gdb/linux/symbols.py
+++ b/scripts/gdb/linux/symbols.py
@@ -96,7 +96,7 @@ lx-symbols command."""
return ""
attrs = sect_attrs['attrs']
section_name_to_address = {
- attrs[n]['name'].string(): attrs[n]['address']
+ attrs[n]['battr']['attr']['name'].string(): attrs[n]['address']
for n in range(int(sect_attrs['nsections']))}
args = []
for section_name in [".data", ".data..read_mostly", ".rodata", ".bss",
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
index d328de1e10ee..ce4f99935de5 100644
--- a/scripts/genksyms/Makefile
+++ b/scripts/genksyms/Makefile
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
-hostprogs := genksyms
-always-y := $(hostprogs)
+hostprogs-always-y += genksyms
genksyms-objs := genksyms.o parse.tab.o lex.lex.o
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index 955cf3aedf21..dd554bd436cc 100755
--- a/scripts/headers_install.sh
+++ b/scripts/headers_install.sh
@@ -11,7 +11,7 @@ then
echo "asm/inline/volatile keywords."
echo
echo "INFILE: header file to operate on"
- echo "OUTFILE: output file which the processed header is writen to"
+ echo "OUTFILE: output file which the processed header is written to"
exit 1
fi
@@ -86,11 +86,9 @@ arch/x86/include/uapi/asm/auxvec.h:CONFIG_X86_64
arch/x86/include/uapi/asm/mman.h:CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
include/uapi/asm-generic/fcntl.h:CONFIG_64BIT
include/uapi/linux/atmdev.h:CONFIG_COMPAT
-include/uapi/linux/elfcore.h:CONFIG_BINFMT_ELF_FDPIC
include/uapi/linux/eventpoll.h:CONFIG_PM_SLEEP
include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
include/uapi/linux/pktcdvd.h:CONFIG_CDROM_PKTCDVD_WCACHE
-include/uapi/linux/raw.h:CONFIG_MAX_RAW_DEVS
"
for c in $configs
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 6dc3078649fa..0096cd965332 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -109,6 +109,7 @@ static bool is_ignored_symbol(const char *name, char type)
".LASANPC", /* s390 kasan local symbols */
"__crc_", /* modversions */
"__efistub_", /* arm64 EFI stub namespace */
+ "__kvm_nvhe_", /* arm64 non-VHE KVM namespace */
NULL
};
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 12a67fdab541..c3d537cd0275 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-*.moc
+/qconf-moc.cc
*conf-cfg
#
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 426881ea954f..52b59bf9efe4 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -181,19 +181,22 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/mconf-cfg
# qconf: Used for the xconfig target based on Qt
hostprogs += qconf
-qconf-cxxobjs := qconf.o
+qconf-cxxobjs := qconf.o qconf-moc.o
qconf-objs := images.o $(common-objs)
HOSTLDLIBS_qconf = $(shell . $(obj)/qconf-cfg && echo $$libs)
HOSTCXXFLAGS_qconf.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
+HOSTCXXFLAGS_qconf-moc.o = $(shell . $(obj)/qconf-cfg && echo $$cflags)
-$(obj)/qconf.o: $(obj)/qconf-cfg $(obj)/qconf.moc
+$(obj)/qconf.o: $(obj)/qconf-cfg
quiet_cmd_moc = MOC $@
- cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) -i $< -o $@
+ cmd_moc = $(shell . $(obj)/qconf-cfg && echo $$moc) $< -o $@
-$(obj)/%.moc: $(src)/%.h $(obj)/qconf-cfg
- $(call cmd,moc)
+$(obj)/qconf-moc.cc: $(src)/qconf.h $(obj)/qconf-cfg FORCE
+ $(call if_changed,moc)
+
+targets += qconf-moc.cc
# gconf: Used for the gconfig target based on GTK+
hostprogs += gconf
diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c
index b4fa0e4a63a5..2f9afffa5d79 100644
--- a/scripts/kconfig/images.c
+++ b/scripts/kconfig/images.c
@@ -5,7 +5,7 @@
#include "images.h"
-const char *xpm_load[] = {
+const char * const xpm_load[] = {
"22 22 5 1",
". c None",
"# c #000000",
@@ -35,7 +35,7 @@ const char *xpm_load[] = {
"###############.......",
"......................"};
-const char *xpm_save[] = {
+const char * const xpm_save[] = {
"22 22 5 1",
". c None",
"# c #000000",
@@ -65,7 +65,7 @@ const char *xpm_save[] = {
"..##################..",
"......................"};
-const char *xpm_back[] = {
+const char * const xpm_back[] = {
"22 22 3 1",
". c None",
"# c #000083",
@@ -93,7 +93,7 @@ const char *xpm_back[] = {
"......................",
"......................"};
-const char *xpm_tree_view[] = {
+const char * const xpm_tree_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@@ -120,7 +120,7 @@ const char *xpm_tree_view[] = {
"......................",
"......................"};
-const char *xpm_single_view[] = {
+const char * const xpm_single_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@@ -147,7 +147,7 @@ const char *xpm_single_view[] = {
"......................",
"......................"};
-const char *xpm_split_view[] = {
+const char * const xpm_split_view[] = {
"22 22 2 1",
". c None",
"# c #000000",
@@ -174,7 +174,7 @@ const char *xpm_split_view[] = {
"......................",
"......................"};
-const char *xpm_symbol_no[] = {
+const char * const xpm_symbol_no[] = {
"12 12 2 1",
" c white",
". c black",
@@ -191,7 +191,7 @@ const char *xpm_symbol_no[] = {
" .......... ",
" "};
-const char *xpm_symbol_mod[] = {
+const char * const xpm_symbol_mod[] = {
"12 12 2 1",
" c white",
". c black",
@@ -208,7 +208,7 @@ const char *xpm_symbol_mod[] = {
" .......... ",
" "};
-const char *xpm_symbol_yes[] = {
+const char * const xpm_symbol_yes[] = {
"12 12 2 1",
" c white",
". c black",
@@ -225,7 +225,7 @@ const char *xpm_symbol_yes[] = {
" .......... ",
" "};
-const char *xpm_choice_no[] = {
+const char * const xpm_choice_no[] = {
"12 12 2 1",
" c white",
". c black",
@@ -242,7 +242,7 @@ const char *xpm_choice_no[] = {
" .... ",
" "};
-const char *xpm_choice_yes[] = {
+const char * const xpm_choice_yes[] = {
"12 12 2 1",
" c white",
". c black",
@@ -259,7 +259,7 @@ const char *xpm_choice_yes[] = {
" .... ",
" "};
-const char *xpm_menu[] = {
+const char * const xpm_menu[] = {
"12 12 2 1",
" c white",
". c black",
@@ -276,7 +276,7 @@ const char *xpm_menu[] = {
" .......... ",
" "};
-const char *xpm_menu_inv[] = {
+const char * const xpm_menu_inv[] = {
"12 12 2 1",
" c white",
". c black",
@@ -293,7 +293,7 @@ const char *xpm_menu_inv[] = {
" .......... ",
" "};
-const char *xpm_menuback[] = {
+const char * const xpm_menuback[] = {
"12 12 2 1",
" c white",
". c black",
@@ -310,7 +310,7 @@ const char *xpm_menuback[] = {
" .......... ",
" "};
-const char *xpm_void[] = {
+const char * const xpm_void[] = {
"12 12 2 1",
" c white",
". c black",
diff --git a/scripts/kconfig/images.h b/scripts/kconfig/images.h
index d8ff614bd087..7212dec2006c 100644
--- a/scripts/kconfig/images.h
+++ b/scripts/kconfig/images.h
@@ -10,21 +10,21 @@
extern "C" {
#endif
-extern const char *xpm_load[];
-extern const char *xpm_save[];
-extern const char *xpm_back[];
-extern const char *xpm_tree_view[];
-extern const char *xpm_single_view[];
-extern const char *xpm_split_view[];
-extern const char *xpm_symbol_no[];
-extern const char *xpm_symbol_mod[];
-extern const char *xpm_symbol_yes[];
-extern const char *xpm_choice_no[];
-extern const char *xpm_choice_yes[];
-extern const char *xpm_menu[];
-extern const char *xpm_menu_inv[];
-extern const char *xpm_menuback[];
-extern const char *xpm_void[];
+extern const char * const xpm_load[];
+extern const char * const xpm_save[];
+extern const char * const xpm_back[];
+extern const char * const xpm_tree_view[];
+extern const char * const xpm_single_view[];
+extern const char * const xpm_split_view[];
+extern const char * const xpm_symbol_no[];
+extern const char * const xpm_symbol_mod[];
+extern const char * const xpm_symbol_yes[];
+extern const char * const xpm_choice_no[];
+extern const char * const xpm_choice_yes[];
+extern const char * const xpm_menu[];
+extern const char * const xpm_menu_inv[];
+extern const char * const xpm_menuback[];
+extern const char * const xpm_void[];
#ifdef __cplusplus
}
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 6354c905b006..240109f965ae 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -36,7 +36,7 @@ struct buffer {
YY_BUFFER_STATE state;
};
-struct buffer *current_buf;
+static struct buffer *current_buf;
static int last_ts, first_ts;
@@ -105,7 +105,7 @@ n [A-Za-z0-9_-]
"endchoice" return T_ENDCHOICE;
"endif" return T_ENDIF;
"endmenu" return T_ENDMENU;
-"help"|"---help---" return T_HELP;
+"help" return T_HELP;
"hex" return T_HEX;
"if" return T_IF;
"imply" return T_IMPLY;
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index c0ac8f7b5f1a..bc390df49f1f 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -4,34 +4,25 @@
* Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
*/
-#include <qglobal.h>
-
-#include <QMainWindow>
-#include <QList>
-#include <qtextbrowser.h>
#include <QAction>
+#include <QApplication>
+#include <QCloseEvent>
+#include <QDebug>
+#include <QDesktopWidget>
#include <QFileDialog>
+#include <QLabel>
+#include <QLayout>
+#include <QList>
#include <QMenu>
-
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#include <qtoolbar.h>
-#include <qlayout.h>
-#include <qsplitter.h>
-#include <qlineedit.h>
-#include <qlabel.h>
-#include <qpushbutton.h>
-#include <qmenubar.h>
-#include <qmessagebox.h>
-#include <qregexp.h>
-#include <qevent.h>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QToolBar>
#include <stdlib.h>
#include "lkc.h"
#include "qconf.h"
-#include "qconf.moc"
#include "images.h"
@@ -40,11 +31,6 @@ static ConfigSettings *configSettings;
QAction *ConfigMainWindow::saveAction;
-static inline QString qgettext(const char* str)
-{
- return QString::fromLocal8Bit(str);
-}
-
ConfigSettings::ConfigSettings()
: QSettings("kernel.org", "qconf")
{
@@ -88,6 +74,13 @@ bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
return true;
}
+QIcon ConfigItem::symbolYesIcon;
+QIcon ConfigItem::symbolModIcon;
+QIcon ConfigItem::symbolNoIcon;
+QIcon ConfigItem::choiceYesIcon;
+QIcon ConfigItem::choiceNoIcon;
+QIcon ConfigItem::menuIcon;
+QIcon ConfigItem::menubackIcon;
/*
* set the new data
@@ -111,14 +104,14 @@ void ConfigItem::updateMenu(void)
list = listView();
if (goParent) {
- setPixmap(promptColIdx, list->menuBackPix);
+ setIcon(promptColIdx, menubackIcon);
prompt = "..";
goto set_prompt;
}
sym = menu->sym;
prop = menu->prompt;
- prompt = qgettext(menu_get_prompt(menu));
+ prompt = menu_get_prompt(menu);
if (prop) switch (prop->type) {
case P_MENU:
@@ -128,15 +121,15 @@ void ConfigItem::updateMenu(void)
*/
if (sym && list->rootEntry == menu)
break;
- setPixmap(promptColIdx, list->menuPix);
+ setIcon(promptColIdx, menuIcon);
} else {
if (sym)
break;
- setPixmap(promptColIdx, QIcon());
+ setIcon(promptColIdx, QIcon());
}
goto set_prompt;
case P_COMMENT:
- setPixmap(promptColIdx, QIcon());
+ setIcon(promptColIdx, QIcon());
goto set_prompt;
default:
;
@@ -144,7 +137,7 @@ void ConfigItem::updateMenu(void)
if (!sym)
goto set_prompt;
- setText(nameColIdx, QString::fromLocal8Bit(sym->name));
+ setText(nameColIdx, sym->name);
type = sym_get_type(sym);
switch (type) {
@@ -153,7 +146,7 @@ void ConfigItem::updateMenu(void)
char ch;
if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
- setPixmap(promptColIdx, QIcon());
+ setIcon(promptColIdx, QIcon());
setText(noColIdx, QString());
setText(modColIdx, QString());
setText(yesColIdx, QString());
@@ -163,22 +156,22 @@ void ConfigItem::updateMenu(void)
switch (expr) {
case yes:
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
- setPixmap(promptColIdx, list->choiceYesPix);
+ setIcon(promptColIdx, choiceYesIcon);
else
- setPixmap(promptColIdx, list->symbolYesPix);
+ setIcon(promptColIdx, symbolYesIcon);
setText(yesColIdx, "Y");
ch = 'Y';
break;
case mod:
- setPixmap(promptColIdx, list->symbolModPix);
+ setIcon(promptColIdx, symbolModIcon);
setText(modColIdx, "M");
ch = 'M';
break;
default:
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
- setPixmap(promptColIdx, list->choiceNoPix);
+ setIcon(promptColIdx, choiceNoIcon);
else
- setPixmap(promptColIdx, list->symbolNoPix);
+ setIcon(promptColIdx, symbolNoIcon);
setText(noColIdx, "N");
ch = 'N';
break;
@@ -274,7 +267,7 @@ void ConfigLineEdit::show(ConfigItem* i)
{
item = i;
if (sym_get_string_value(item->menu->sym))
- setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
+ setText(sym_get_string_value(item->menu->sym));
else
setText(QString());
Parent::show();
@@ -289,7 +282,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
case Qt::Key_Return:
case Qt::Key_Enter:
sym_set_string_value(item->menu->sym, text().toLatin1());
- parent()->updateList(item);
+ parent()->updateList();
break;
default:
Parent::keyPressEvent(e);
@@ -303,9 +296,6 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
ConfigList::ConfigList(ConfigView* p, const char *name)
: Parent(p),
updateAll(false),
- symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
- choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
- menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
rootEntry(0), headerPopup(0)
{
@@ -316,10 +306,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
setVerticalScrollMode(ScrollPerPixel);
setHorizontalScrollMode(ScrollPerPixel);
- if (mode == symbolMode)
- setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
- else
- setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
+ setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
connect(this, SIGNAL(itemSelectionChanged(void)),
SLOT(updateSelection(void)));
@@ -334,7 +321,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
}
- addColumn(promptColIdx);
+ showColumn(promptColIdx);
reinit();
}
@@ -352,21 +339,33 @@ bool ConfigList::menuSkip(struct menu *menu)
void ConfigList::reinit(void)
{
- removeColumn(dataColIdx);
- removeColumn(yesColIdx);
- removeColumn(modColIdx);
- removeColumn(noColIdx);
- removeColumn(nameColIdx);
+ hideColumn(dataColIdx);
+ hideColumn(yesColIdx);
+ hideColumn(modColIdx);
+ hideColumn(noColIdx);
+ hideColumn(nameColIdx);
if (showName)
- addColumn(nameColIdx);
+ showColumn(nameColIdx);
if (showRange) {
- addColumn(noColIdx);
- addColumn(modColIdx);
- addColumn(yesColIdx);
+ showColumn(noColIdx);
+ showColumn(modColIdx);
+ showColumn(yesColIdx);
}
if (showData)
- addColumn(dataColIdx);
+ showColumn(dataColIdx);
+
+ updateListAll();
+}
+
+void ConfigList::setOptionMode(QAction *action)
+{
+ if (action == showNormalAction)
+ optMode = normalOpt;
+ else if (action == showAllAction)
+ optMode = allOpt;
+ else
+ optMode = promptOpt;
updateListAll();
}
@@ -400,11 +399,6 @@ void ConfigList::updateSelection(void)
struct menu *menu;
enum prop_type type;
- if (mode == symbolMode)
- setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
- else
- setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
-
if (selectedItems().count() == 0)
return;
@@ -421,15 +415,15 @@ void ConfigList::updateSelection(void)
emit menuSelected(menu);
}
-void ConfigList::updateList(ConfigItem* item)
+void ConfigList::updateList()
{
ConfigItem* last = 0;
+ ConfigItem *item;
if (!rootEntry) {
if (mode != listMode)
goto update;
QTreeWidgetItemIterator it(this);
- ConfigItem* item;
while (*it) {
item = (ConfigItem*)(*it);
@@ -451,7 +445,7 @@ void ConfigList::updateList(ConfigItem* item)
}
if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
rootEntry->sym && rootEntry->prompt) {
- item = last ? last->nextSibling() : firstChild();
+ item = last ? last->nextSibling() : nullptr;
if (!item)
item = new ConfigItem(this, last, rootEntry, true);
else
@@ -463,7 +457,7 @@ void ConfigList::updateList(ConfigItem* item)
return;
}
update:
- updateMenuList(this, rootEntry);
+ updateMenuList(rootEntry);
update();
resizeColumnToContents(0);
}
@@ -488,7 +482,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
return;
if (oldval == no && item->menu->list)
item->setExpanded(true);
- parent()->updateList(item);
+ parent()->updateList();
break;
}
}
@@ -522,7 +516,7 @@ void ConfigList::changeValue(ConfigItem* item)
item->setExpanded(true);
}
if (oldexpr != newexpr)
- parent()->updateList(item);
+ parent()->updateList();
break;
case S_INT:
case S_HEX:
@@ -541,11 +535,11 @@ void ConfigList::setRootMenu(struct menu *menu)
type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
if (type != P_MENU)
return;
- updateMenuList(this, 0);
+ updateMenuList(0);
rootEntry = menu;
updateListAll();
if (currentItem()) {
- currentItem()->setSelected(hasFocus());
+ setSelected(currentItem(), hasFocus());
scrollToItem(currentItem());
}
}
@@ -645,7 +639,7 @@ hide:
}
}
-void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+void ConfigList::updateMenuList(struct menu *menu)
{
struct menu* child;
ConfigItem* item;
@@ -654,19 +648,19 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
enum prop_type type;
if (!menu) {
- while (parent->topLevelItemCount() > 0)
+ while (topLevelItemCount() > 0)
{
- delete parent->takeTopLevelItem(0);
+ delete takeTopLevelItem(0);
}
return;
}
- last = (ConfigItem*)parent->topLevelItem(0);
+ last = (ConfigItem *)topLevelItem(0);
if (last && !last->goParent)
last = 0;
for (child = menu->list; child; child = child->next) {
- item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
+ item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
type = child->prompt ? child->prompt->type : P_UNKNOWN;
switch (mode) {
@@ -687,7 +681,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
if (!child->sym && !child->list && !child->prompt)
continue;
if (!item || item->menu != child)
- item = new ConfigItem(parent, last, child, visible);
+ item = new ConfigItem(this, last, child, visible);
else
item->testUpdateMenu(visible);
@@ -700,7 +694,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
}
hide:
if (item && item->menu == child) {
- last = (ConfigItem*)parent->topLevelItem(0);
+ last = (ConfigItem *)topLevelItem(0);
if (last == item)
last = 0;
else while (last->nextSibling() != item)
@@ -791,7 +785,7 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
idx = header()->logicalIndexAt(x);
switch (idx) {
case promptColIdx:
- icon = item->pixmap(promptColIdx);
+ icon = item->icon(promptColIdx);
if (!icon.isNull()) {
int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
if (x >= off && x < off + icon.availableSizes().first().width()) {
@@ -802,7 +796,8 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
break;
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
if (ptype == P_MENU && rootEntry != menu &&
- mode != fullMode && mode != menuMode)
+ mode != fullMode && mode != menuMode &&
+ mode != listMode)
emit menuSelected(menu);
else
changeValue(item);
@@ -852,7 +847,7 @@ void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
if (!menu)
goto skip;
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
- if (ptype == P_MENU) {
+ if (ptype == P_MENU && mode != listMode) {
if (mode == singleMode)
emit itemSelected(menu);
else if (mode == symbolMode)
@@ -873,7 +868,7 @@ void ConfigList::focusInEvent(QFocusEvent *e)
ConfigItem* item = (ConfigItem *)currentItem();
if (item) {
- item->setSelected(true);
+ setSelected(item, true);
menu = item->menu;
}
emit gotFocus(menu);
@@ -881,46 +876,46 @@ void ConfigList::focusInEvent(QFocusEvent *e)
void ConfigList::contextMenuEvent(QContextMenuEvent *e)
{
- if (e->y() <= header()->geometry().bottom()) {
- if (!headerPopup) {
- QAction *action;
-
- headerPopup = new QMenu(this);
- action = new QAction("Show Name", this);
- action->setCheckable(true);
- connect(action, SIGNAL(toggled(bool)),
- parent(), SLOT(setShowName(bool)));
- connect(parent(), SIGNAL(showNameChanged(bool)),
- action, SLOT(setOn(bool)));
- action->setChecked(showName);
- headerPopup->addAction(action);
- action = new QAction("Show Range", this);
- action->setCheckable(true);
- connect(action, SIGNAL(toggled(bool)),
- parent(), SLOT(setShowRange(bool)));
- connect(parent(), SIGNAL(showRangeChanged(bool)),
- action, SLOT(setOn(bool)));
- action->setChecked(showRange);
- headerPopup->addAction(action);
- action = new QAction("Show Data", this);
- action->setCheckable(true);
- connect(action, SIGNAL(toggled(bool)),
- parent(), SLOT(setShowData(bool)));
- connect(parent(), SIGNAL(showDataChanged(bool)),
- action, SLOT(setOn(bool)));
- action->setChecked(showData);
- headerPopup->addAction(action);
- }
- headerPopup->exec(e->globalPos());
- e->accept();
- } else
- e->ignore();
+ if (!headerPopup) {
+ QAction *action;
+
+ headerPopup = new QMenu(this);
+ action = new QAction("Show Name", this);
+ action->setCheckable(true);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowName(bool)));
+ connect(parent(), SIGNAL(showNameChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setChecked(showName);
+ headerPopup->addAction(action);
+
+ action = new QAction("Show Range", this);
+ action->setCheckable(true);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowRange(bool)));
+ connect(parent(), SIGNAL(showRangeChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setChecked(showRange);
+ headerPopup->addAction(action);
+
+ action = new QAction("Show Data", this);
+ action->setCheckable(true);
+ connect(action, SIGNAL(toggled(bool)),
+ parent(), SLOT(setShowData(bool)));
+ connect(parent(), SIGNAL(showDataChanged(bool)),
+ action, SLOT(setOn(bool)));
+ action->setChecked(showData);
+ headerPopup->addAction(action);
+ }
+
+ headerPopup->exec(e->globalPos());
+ e->accept();
}
ConfigView*ConfigView::viewList;
-QAction *ConfigView::showNormalAction;
-QAction *ConfigView::showAllAction;
-QAction *ConfigView::showPromptAction;
+QAction *ConfigList::showNormalAction;
+QAction *ConfigList::showAllAction;
+QAction *ConfigList::showPromptAction;
ConfigView::ConfigView(QWidget* parent, const char *name)
: Parent(parent)
@@ -951,18 +946,6 @@ ConfigView::~ConfigView(void)
}
}
-void ConfigView::setOptionMode(QAction *act)
-{
- if (act == showNormalAction)
- list->optMode = normalOpt;
- else if (act == showAllAction)
- list->optMode = allOpt;
- else
- list->optMode = promptOpt;
-
- list->updateListAll();
-}
-
void ConfigView::setShowName(bool b)
{
if (list->showName != b) {
@@ -1001,12 +984,12 @@ void ConfigList::setAllOpen(bool open)
}
}
-void ConfigView::updateList(ConfigItem* item)
+void ConfigView::updateList()
{
ConfigView* v;
for (v = viewList; v; v = v->nextView)
- v->list->updateList(item);
+ v->list->updateList();
}
void ConfigView::updateListAll(void)
@@ -1021,7 +1004,7 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
: Parent(parent), sym(0), _menu(0)
{
setObjectName(name);
-
+ setOpenLinks(false);
if (!objectName().isEmpty()) {
configSettings->beginGroup(objectName());
@@ -1094,7 +1077,7 @@ void ConfigInfoView::menuInfo(void)
if (sym->name) {
head += " (";
if (showDebug())
- head += QString().sprintf("<a href=\"s%p\">", sym);
+ head += QString().sprintf("<a href=\"s%s\">", sym->name);
head += print_filter(sym->name);
if (showDebug())
head += "</a>";
@@ -1103,7 +1086,7 @@ void ConfigInfoView::menuInfo(void)
} else if (sym->name) {
head += "<big><b>";
if (showDebug())
- head += QString().sprintf("<a href=\"s%p\">", sym);
+ head += QString().sprintf("<a href=\"s%s\">", sym->name);
head += print_filter(sym->name);
if (showDebug())
head += "</a>";
@@ -1154,13 +1137,16 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
switch (prop->type) {
case P_PROMPT:
case P_MENU:
- debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
+ debug += QString().sprintf("prompt: <a href=\"m%s\">", sym->name);
debug += print_filter(prop->text);
debug += "</a><br>";
break;
case P_DEFAULT:
case P_SELECT:
case P_RANGE:
+ case P_COMMENT:
+ case P_IMPLY:
+ case P_SYMBOL:
debug += prop_get_type_name(prop->type);
debug += ": ";
expr_print(prop->expr, expr_print_help, &debug, E_NONE);
@@ -1226,13 +1212,62 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
QString str2 = print_filter(str);
if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
- *text += QString().sprintf("<a href=\"s%p\">", sym);
+ *text += QString().sprintf("<a href=\"s%s\">", sym->name);
*text += str2;
*text += "</a>";
} else
*text += str2;
}
+void ConfigInfoView::clicked(const QUrl &url)
+{
+ QByteArray str = url.toEncoded();
+ const std::size_t count = str.size();
+ char *data = new char[count + 1];
+ struct symbol **result;
+ struct menu *m = NULL;
+
+ if (count < 1) {
+ qInfo() << "Clicked link is empty";
+ delete[] data;
+ return;
+ }
+
+ memcpy(data, str.constData(), count);
+ data[count] = '\0';
+
+ /* Seek for exact match */
+ data[0] = '^';
+ strcat(data, "$");
+ result = sym_re_search(data);
+ if (!result) {
+ qInfo() << "Clicked symbol is invalid:" << data;
+ delete[] data;
+ return;
+ }
+
+ sym = *result;
+
+ /* Seek for the menu which holds the symbol */
+ for (struct property *prop = sym->prop; prop; prop = prop->next) {
+ if (prop->type != P_PROMPT && prop->type != P_MENU)
+ continue;
+ m = prop->menu;
+ break;
+ }
+
+ if (!m) {
+ /* Symbol is not visible as a menu */
+ symbolInfo();
+ emit showDebugChanged(true);
+ } else {
+ emit menuSelected(m);
+ }
+
+ free(result);
+ delete data;
+}
+
QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
{
QMenu* popup = Parent::createStandardContextMenu(pos);
@@ -1252,16 +1287,17 @@ void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Parent::contextMenuEvent(e);
}
-ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
: Parent(parent), result(NULL)
{
- setObjectName(name);
+ setObjectName("search");
setWindowTitle("Search Config");
QVBoxLayout* layout1 = new QVBoxLayout(this);
layout1->setContentsMargins(11, 11, 11, 11);
layout1->setSpacing(6);
- QHBoxLayout* layout2 = new QHBoxLayout(0);
+
+ QHBoxLayout* layout2 = new QHBoxLayout();
layout2->setContentsMargins(0, 0, 0, 0);
layout2->setSpacing(6);
layout2->addWidget(new QLabel("Find:", this));
@@ -1276,9 +1312,9 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
split = new QSplitter(this);
split->setOrientation(Qt::Vertical);
- list = new ConfigView(split, name);
+ list = new ConfigView(split, "search");
list->list->mode = listMode;
- info = new ConfigInfoView(split, name);
+ info = new ConfigInfoView(split, "search");
connect(list->list, SIGNAL(menuChanged(struct menu *)),
info, SLOT(setInfo(struct menu *)));
connect(list->list, SIGNAL(menuChanged(struct menu *)),
@@ -1286,25 +1322,23 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
layout1->addWidget(split);
- if (name) {
- QVariant x, y;
- int width, height;
- bool ok;
+ QVariant x, y;
+ int width, height;
+ bool ok;
- configSettings->beginGroup(name);
- width = configSettings->value("/window width", parent->width() / 2).toInt();
- height = configSettings->value("/window height", parent->height() / 2).toInt();
- resize(width, height);
- x = configSettings->value("/window x");
- y = configSettings->value("/window y");
- if ((x.isValid())&&(y.isValid()))
- move(x.toInt(), y.toInt());
- QList<int> sizes = configSettings->readSizes("/split", &ok);
- if (ok)
- split->setSizes(sizes);
- configSettings->endGroup();
- connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
- }
+ configSettings->beginGroup("search");
+ width = configSettings->value("/window width", parent->width() / 2).toInt();
+ height = configSettings->value("/window height", parent->height() / 2).toInt();
+ resize(width, height);
+ x = configSettings->value("/window x");
+ y = configSettings->value("/window y");
+ if (x.isValid() && y.isValid())
+ move(x.toInt(), y.toInt());
+ QList<int> sizes = configSettings->readSizes("/split", &ok);
+ if (ok)
+ split->setSizes(sizes);
+ configSettings->endGroup();
+ connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
}
void ConfigSearchWindow::saveSettings(void)
@@ -1346,7 +1380,6 @@ void ConfigSearchWindow::search(void)
ConfigMainWindow::ConfigMainWindow(void)
: searchWindow(0)
{
- QMenuBar* menu;
bool ok = true;
QVariant x, y;
int width, height;
@@ -1367,6 +1400,15 @@ ConfigMainWindow::ConfigMainWindow(void)
if ((x.isValid())&&(y.isValid()))
move(x.toInt(), y.toInt());
+ // set up icons
+ ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
+ ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
+ ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
+ ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
+ ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
+ ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
+ ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
+
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(widget);
setCentralWidget(widget);
@@ -1397,23 +1439,23 @@ ConfigMainWindow::ConfigMainWindow(void)
setTabOrder(configList, helpText);
configList->setFocus();
- menu = menuBar();
- toolBar = new QToolBar("Tools", this);
- addToolBar(toolBar);
-
backAction = new QAction(QPixmap(xpm_back), "Back", this);
- connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
- backAction->setEnabled(false);
+ connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
+
QAction *quitAction = new QAction("&Quit", this);
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
- connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
+ connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
+
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
- connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
+ connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
+
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
- connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
+ connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
+
conf_set_changed_callback(conf_changed);
+
// Set saveAction's initial state
conf_changed();
configname = xstrdup(conf_get_configname());
@@ -1446,17 +1488,17 @@ ConfigMainWindow::ConfigMainWindow(void)
QActionGroup *optGroup = new QActionGroup(this);
optGroup->setExclusive(true);
- connect(optGroup, SIGNAL(triggered(QAction*)), configView,
+ connect(optGroup, SIGNAL(triggered(QAction*)), configList,
SLOT(setOptionMode(QAction *)));
- connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
+ connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
SLOT(setOptionMode(QAction *)));
- configView->showNormalAction = new QAction("Show Normal Options", optGroup);
- configView->showAllAction = new QAction("Show All Options", optGroup);
- configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
- configView->showNormalAction->setCheckable(true);
- configView->showAllAction->setCheckable(true);
- configView->showPromptAction->setCheckable(true);
+ ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
+ ConfigList::showNormalAction->setCheckable(true);
+ ConfigList::showAllAction = new QAction("Show All Options", optGroup);
+ ConfigList::showAllAction->setCheckable(true);
+ ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
+ ConfigList::showPromptAction->setCheckable(true);
QAction *showDebugAction = new QAction("Show Debug Info", this);
showDebugAction->setCheckable(true);
@@ -1469,6 +1511,7 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
// init tool bar
+ QToolBar *toolBar = addToolBar("Tools");
toolBar->addAction(backAction);
toolBar->addSeparator();
toolBar->addAction(loadAction);
@@ -1478,33 +1521,35 @@ ConfigMainWindow::ConfigMainWindow(void)
toolBar->addAction(splitViewAction);
toolBar->addAction(fullViewAction);
- // create config menu
- QMenu* config = menu->addMenu("&File");
- config->addAction(loadAction);
- config->addAction(saveAction);
- config->addAction(saveAsAction);
- config->addSeparator();
- config->addAction(quitAction);
+ // create file menu
+ QMenu *menu = menuBar()->addMenu("&File");
+ menu->addAction(loadAction);
+ menu->addAction(saveAction);
+ menu->addAction(saveAsAction);
+ menu->addSeparator();
+ menu->addAction(quitAction);
// create edit menu
- QMenu* editMenu = menu->addMenu("&Edit");
- editMenu->addAction(searchAction);
+ menu = menuBar()->addMenu("&Edit");
+ menu->addAction(searchAction);
// create options menu
- QMenu* optionMenu = menu->addMenu("&Option");
- optionMenu->addAction(showNameAction);
- optionMenu->addAction(showRangeAction);
- optionMenu->addAction(showDataAction);
- optionMenu->addSeparator();
- optionMenu->addActions(optGroup->actions());
- optionMenu->addSeparator();
- optionMenu->addAction(showDebugAction);
+ menu = menuBar()->addMenu("&Option");
+ menu->addAction(showNameAction);
+ menu->addAction(showRangeAction);
+ menu->addAction(showDataAction);
+ menu->addSeparator();
+ menu->addActions(optGroup->actions());
+ menu->addSeparator();
+ menu->addAction(showDebugAction);
// create help menu
- menu->addSeparator();
- QMenu* helpMenu = menu->addMenu("&Help");
- helpMenu->addAction(showIntroAction);
- helpMenu->addAction(showAboutAction);
+ menu = menuBar()->addMenu("&Help");
+ menu->addAction(showIntroAction);
+ menu->addAction(showAboutAction);
+
+ connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
+ helpText, SLOT (clicked (const QUrl &)) );
connect(configList, SIGNAL(menuChanged(struct menu *)),
helpText, SLOT(setInfo(struct menu *)));
@@ -1604,28 +1649,18 @@ void ConfigMainWindow::saveConfigAs(void)
void ConfigMainWindow::searchConfig(void)
{
if (!searchWindow)
- searchWindow = new ConfigSearchWindow(this, "search");
+ searchWindow = new ConfigSearchWindow(this);
searchWindow->show();
}
void ConfigMainWindow::changeItens(struct menu *menu)
{
configList->setRootMenu(menu);
-
- if (configList->rootEntry->parent == &rootmenu)
- backAction->setEnabled(false);
- else
- backAction->setEnabled(true);
}
void ConfigMainWindow::changeMenu(struct menu *menu)
{
menuList->setRootMenu(menu);
-
- if (menuList->rootEntry->parent == &rootmenu)
- backAction->setEnabled(false);
- else
- backAction->setEnabled(true);
}
void ConfigMainWindow::setMenuLink(struct menu *menu)
@@ -1645,22 +1680,26 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
return;
list->setRootMenu(parent);
break;
- case symbolMode:
+ case menuMode:
if (menu->flags & MENU_ROOT) {
- configList->setRootMenu(menu);
+ menuList->setRootMenu(menu);
configList->clearSelection();
- list = menuList;
- } else {
list = configList;
+ } else {
parent = menu_get_parent_menu(menu->parent);
if (!parent)
return;
- item = menuList->findConfigItem(parent);
+
+ /* Select the config view */
+ item = configList->findConfigItem(parent);
if (item) {
- item->setSelected(true);
- menuList->scrollToItem(item);
+ configList->setSelected(item, true);
+ configList->scrollToItem(item);
}
- list->setRootMenu(parent);
+
+ menuList->setRootMenu(parent);
+ menuList->clearSelection();
+ list = menuList;
}
break;
case fullMode:
@@ -1673,9 +1712,10 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
if (list) {
item = list->findConfigItem(menu);
if (item) {
- item->setSelected(true);
+ list->setSelected(item, true);
list->scrollToItem(item);
list->setFocus();
+ helpText->setInfo(menu);
}
}
}
@@ -1688,25 +1728,10 @@ void ConfigMainWindow::listFocusChanged(void)
void ConfigMainWindow::goBack(void)
{
- ConfigItem* item, *oldSelection;
-
- configList->setParentMenu();
if (configList->rootEntry == &rootmenu)
- backAction->setEnabled(false);
-
- if (menuList->selectedItems().count() == 0)
return;
- item = (ConfigItem*)menuList->selectedItems().first();
- oldSelection = item;
- while (item) {
- if (item->menu == configList->rootEntry) {
- oldSelection->setSelected(false);
- item->setSelected(true);
- break;
- }
- item = (ConfigItem*)item->parent();
- }
+ configList->setParentMenu();
}
void ConfigMainWindow::showSingleView(void)
@@ -1718,6 +1743,8 @@ void ConfigMainWindow::showSingleView(void)
fullViewAction->setEnabled(true);
fullViewAction->setChecked(false);
+ backAction->setEnabled(true);
+
menuView->hide();
menuList->setRootMenu(0);
configList->mode = singleMode;
@@ -1737,6 +1764,8 @@ void ConfigMainWindow::showSplitView(void)
fullViewAction->setEnabled(true);
fullViewAction->setChecked(false);
+ backAction->setEnabled(false);
+
configList->mode = menuMode;
if (configList->rootEntry == &rootmenu)
configList->updateListAll();
@@ -1760,6 +1789,8 @@ void ConfigMainWindow::showFullView(void)
fullViewAction->setEnabled(false);
fullViewAction->setChecked(true);
+ backAction->setEnabled(false);
+
menuView->hide();
menuList->setRootMenu(0);
configList->mode = fullMode;
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index c879d79ce817..461df6419f15 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -3,17 +3,17 @@
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
*/
-#include <QTextBrowser>
-#include <QTreeWidget>
-#include <QMainWindow>
+#include <QCheckBox>
+#include <QDialog>
#include <QHeaderView>
-#include <qsettings.h>
+#include <QLineEdit>
+#include <QMainWindow>
#include <QPushButton>
#include <QSettings>
-#include <QLineEdit>
#include <QSplitter>
-#include <QCheckBox>
-#include <QDialog>
+#include <QTextBrowser>
+#include <QTreeWidget>
+
#include "expr.h"
class ConfigView;
@@ -45,11 +45,17 @@ class ConfigList : public QTreeWidget {
public:
ConfigList(ConfigView* p, const char *name = 0);
void reinit(void);
+ ConfigItem* findConfigItem(struct menu *);
ConfigView* parent(void) const
{
return (ConfigView*)Parent::parent();
}
- ConfigItem* findConfigItem(struct menu *);
+ void setSelected(QTreeWidgetItem *item, bool enable) {
+ for (int i = 0; i < selectedItems().size(); i++)
+ selectedItems().at(i)->setSelected(false);
+
+ item->setSelected(enable);
+ }
protected:
void keyPressEvent(QKeyEvent *e);
@@ -63,11 +69,13 @@ protected:
public slots:
void setRootMenu(struct menu *menu);
- void updateList(ConfigItem *item);
+ void updateList();
void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item);
void updateSelection(void);
void saveSettings(void);
+ void setOptionMode(QAction *action);
+
signals:
void menuChanged(struct menu *menu);
void menuSelected(struct menu *menu);
@@ -79,39 +87,19 @@ public:
void updateListAll(void)
{
updateAll = true;
- updateList(NULL);
+ updateList();
updateAll = false;
}
- ConfigList* listView()
- {
- return this;
- }
- ConfigItem* firstChild() const
- {
- return (ConfigItem *)children().first();
- }
- void addColumn(colIdx idx)
- {
- showColumn(idx);
- }
- void removeColumn(colIdx idx)
- {
- hideColumn(idx);
- }
void setAllOpen(bool open);
void setParentMenu(void);
bool menuSkip(struct menu *);
void updateMenuList(ConfigItem *parent, struct menu*);
- void updateMenuList(ConfigList *parent, struct menu*);
+ void updateMenuList(struct menu *menu);
bool updateAll;
- QPixmap symbolYesPix, symbolModPix, symbolNoPix;
- QPixmap choiceYesPix, choiceNoPix;
- QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
-
bool showName, showRange, showData;
enum listMode mode;
enum optionMode optMode;
@@ -119,6 +107,8 @@ public:
QPalette disabledColorGroup;
QPalette inactivedColorGroup;
QMenu* headerPopup;
+
+ static QAction *showNormalAction, *showAllAction, *showPromptAction;
};
class ConfigItem : public QTreeWidgetItem {
@@ -166,28 +156,16 @@ public:
return ret;
}
- void setText(colIdx idx, const QString& text)
- {
- Parent::setText(idx, text);
- }
- QString text(colIdx idx) const
- {
- return Parent::text(idx);
- }
- void setPixmap(colIdx idx, const QIcon &icon)
- {
- Parent::setIcon(idx, icon);
- }
- const QIcon pixmap(colIdx idx) const
- {
- return icon(idx);
- }
// TODO: Implement paintCell
ConfigItem* nextItem;
struct menu *menu;
bool visible;
bool goParent;
+
+ static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon;
+ static QIcon choiceYesIcon, choiceNoIcon;
+ static QIcon menuIcon, menubackIcon;
};
class ConfigLineEdit : public QLineEdit {
@@ -212,7 +190,7 @@ class ConfigView : public QWidget {
public:
ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void);
- static void updateList(ConfigItem* item);
+ static void updateList();
static void updateListAll(void);
bool showName(void) const { return list->showName; }
@@ -222,7 +200,6 @@ public slots:
void setShowName(bool);
void setShowRange(bool);
void setShowData(bool);
- void setOptionMode(QAction *);
signals:
void showNameChanged(bool);
void showRangeChanged(bool);
@@ -233,10 +210,6 @@ public:
static ConfigView* viewList;
ConfigView* nextView;
-
- static QAction *showNormalAction;
- static QAction *showAllAction;
- static QAction *showPromptAction;
};
class ConfigInfoView : public QTextBrowser {
@@ -250,6 +223,7 @@ public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
void setShowDebug(bool);
+ void clicked (const QUrl &url);
signals:
void showDebugChanged(bool);
@@ -273,7 +247,7 @@ class ConfigSearchWindow : public QDialog {
Q_OBJECT
typedef class QDialog Parent;
public:
- ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0);
+ ConfigSearchWindow(ConfigMainWindow *parent);
public slots:
void saveSettings(void);
@@ -323,7 +297,6 @@ protected:
ConfigView *configView;
ConfigList *configList;
ConfigInfoView *helpText;
- QToolBar *toolBar;
QAction *backAction;
QAction *singleViewAction;
QAction *splitViewAction;
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 9363e37b8870..ffa3ec65cc90 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -15,15 +15,21 @@ struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_mod = {
+};
+
+struct symbol symbol_mod = {
.name = "m",
.curr = { "m", mod },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_no = {
+};
+
+struct symbol symbol_no = {
.name = "n",
.curr = { "n", no },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_empty = {
+};
+
+static struct symbol symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
@@ -31,7 +37,7 @@ struct symbol symbol_yes = {
struct symbol *sym_defconfig_list;
struct symbol *modules_sym;
-tristate modules_val;
+static tristate modules_val;
enum symbol_type sym_get_type(struct symbol *sym)
{
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index b4c963f8364e..d1b445665ad6 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -81,6 +81,7 @@ Output selection modifiers:
Other parameters:
-v Verbose output, more warnings and other information.
-h Print this help.
+ -Werror Treat warnings as errors.
EOF
print $message;
@@ -273,6 +274,7 @@ my $kernelversion;
my $dohighlight = "";
my $verbose = 0;
+my $Werror = 0;
my $output_mode = "rst";
my $output_preformatted = 0;
my $no_doc_sections = 0;
@@ -319,6 +321,18 @@ if (defined($ENV{'KBUILD_VERBOSE'})) {
$verbose = "$ENV{'KBUILD_VERBOSE'}";
}
+if (defined($ENV{'KDOC_WERROR'})) {
+ $Werror = "$ENV{'KDOC_WERROR'}";
+}
+
+if (defined($ENV{'KCFLAGS'})) {
+ my $kcflags = "$ENV{'KCFLAGS'}";
+
+ if ($kcflags =~ /Werror/) {
+ $Werror = 1;
+ }
+}
+
# Generated docbook code is inserted in a template at a point where
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
@@ -433,6 +447,8 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
push(@export_file_list, $file);
} elsif ($cmd eq "v") {
$verbose = 1;
+ } elsif ($cmd eq "Werror") {
+ $Werror = 1;
} elsif (($cmd eq "h") || ($cmd eq "help")) {
usage();
} elsif ($cmd eq 'no-doc-sections') {
@@ -1083,7 +1099,9 @@ sub dump_struct($$) {
$members =~ s/\s*__packed\s*/ /gos;
$members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
$members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
+
# replace DECLARE_BITMAP
+ $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
$members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
# replace DECLARE_HASHTABLE
$members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
@@ -1769,6 +1787,11 @@ sub process_proto_function($$) {
$prototype =~ s@/\*.*?\*/@@gos; # strip comments.
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
$prototype =~ s@^\s+@@gos; # strip leading spaces
+
+ # Handle prototypes for function pointers like:
+ # int (*pcs_config)(struct foo)
+ $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos;
+
if ($prototype =~ /SYSCALL_DEFINE/) {
syscall_munge();
}
@@ -2255,4 +2278,9 @@ if ($verbose && $warnings) {
print STDERR "$warnings warnings\n";
}
-exit($output_mode eq "none" ? 0 : $errors);
+if ($Werror && $warnings) {
+ print STDERR "$warnings warnings as Errors\n";
+ exit($warnings);
+} else {
+ exit($output_mode eq "none" ? 0 : $errors)
+}
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 92dd745906f4..e6e2d9e5ff48 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -30,6 +30,10 @@
# Error out on error
set -e
+LD="$1"
+KBUILD_LDFLAGS="$2"
+LDFLAGS_vmlinux="$3"
+
# Nice output in kbuild format
# Will be supressed by "make -s"
info()
@@ -336,6 +340,12 @@ fi
vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o}
+# fill in BTF IDs
+if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
+info BTFIDS vmlinux
+${RESOLVE_BTFIDS} vmlinux
+fi
+
if [ -n "${CONFIG_BUILDTIME_TABLE_SORT}" ]; then
info SORTTAB vmlinux
if ! sorttable vmlinux; then
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
index 296b6a3878b2..78071681d924 100644
--- a/scripts/mod/Makefile
+++ b/scripts/mod/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y
-hostprogs := modpost mk_elfconfig
-always-y := $(hostprogs) empty.o
+hostprogs-always-y += modpost mk_elfconfig
+always-y += empty.o
modpost-objs := modpost.o file2alias.o sumversion.o
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index 010be8ba2116..27007c18e754 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -216,6 +216,8 @@ int main(void)
DEVID(sdw_device_id);
DEVID_FIELD(sdw_device_id, mfg_id);
DEVID_FIELD(sdw_device_id, part_id);
+ DEVID_FIELD(sdw_device_id, sdw_version);
+ DEVID_FIELD(sdw_device_id, class_id);
DEVID(fsl_mc_device_id);
DEVID_FIELD(fsl_mc_device_id, vendor);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 9599e2a3f1e6..2417dd1dee33 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1258,15 +1258,19 @@ static int do_hda_entry(const char *filename, void *symval, char *alias)
return 1;
}
-/* Looks like: sdw:mNpN */
+/* Looks like: sdw:mNpNvNcN */
static int do_sdw_entry(const char *filename, void *symval, char *alias)
{
DEF_FIELD(symval, sdw_device_id, mfg_id);
DEF_FIELD(symval, sdw_device_id, part_id);
+ DEF_FIELD(symval, sdw_device_id, sdw_version);
+ DEF_FIELD(symval, sdw_device_id, class_id);
strcpy(alias, "sdw:");
ADD(alias, "m", mfg_id != 0, mfg_id);
ADD(alias, "p", part_id != 0, part_id);
+ ADD(alias, "v", sdw_version != 0, sdw_version);
+ ADD(alias, "c", class_id != 0, class_id);
add_wildcard(alias);
return 1;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 6aea65c65745..69341b36f271 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -138,11 +138,20 @@ char *read_text_file(const char *filename)
char *get_line(char **stringp)
{
+ char *orig = *stringp, *next;
+
/* do not return the unwanted extra line at EOF */
- if (*stringp && **stringp == '\0')
+ if (!orig || *orig == '\0')
return NULL;
- return strsep(stringp, "\n");
+ /* don't use strsep here, it is not available everywhere */
+ next = strchr(orig, '\n');
+ if (next)
+ *next++ = '\0';
+
+ *stringp = next;
+
+ return orig;
}
/* A list of all modules we processed */
diff --git a/scripts/nsdeps b/scripts/nsdeps
index 03a8e7cbe6c7..dab4c1a0e27d 100644
--- a/scripts/nsdeps
+++ b/scripts/nsdeps
@@ -29,7 +29,7 @@ fi
generate_deps_for_ns() {
$SPATCH --very-quiet --in-place --sp-file \
- $srctree/scripts/coccinelle/misc/add_namespace.cocci -D ns=$1 $2
+ $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2
}
generate_deps() {
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index fb1578e72ab9..936198a90477 100755
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -53,6 +53,18 @@ rm -rf -- "${tmpdir}"
mkdir -p -- "${tmpdir}/boot"
dirs=boot
+
+#
+# Try to install dtbs
+#
+if grep -q '^CONFIG_OF_EARLY_FLATTREE=y' include/config/auto.conf; then
+ # Only some architectures with OF support have this target
+ if [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then
+ $MAKE ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_DTBS_PATH="${tmpdir}/boot/dtbs/${KERNELRELEASE}" dtbs_install
+ fi
+fi
+
+
#
# Try to install modules
#
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
index df1adbfb8ead..48fbd3d0284a 100755
--- a/scripts/package/mkdebian
+++ b/scripts/package/mkdebian
@@ -175,7 +175,7 @@ Section: kernel
Priority: optional
Maintainer: $maintainer
Build-Depends: bc, rsync, kmod, cpio, bison, flex | flex:native $extra_build_depends
-Homepage: http://www.kernel.org/
+Homepage: https://www.kernel.org/
Package: $packagename
Architecture: $debarch
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 8640c278f1aa..7c477ca7dc98 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -46,7 +46,7 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF
License: GPL
Group: System Environment/Kernel
Vendor: The Linux Community
- URL: http://www.kernel.org
+ URL: https://www.kernel.org
$S Source: kernel-$__KERNELRELEASE.tar.gz
Provides: $PROVIDES
%define __spec_install_post /usr/lib/rpm/brp-compress || :
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 7225107a9aaf..b9c2ee7ab43f 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -42,6 +42,8 @@
#define R_ARM_THM_CALL 10
#define R_ARM_CALL 28
+#define R_AARCH64_CALL26 283
+
static int fd_map; /* File descriptor for file being modified. */
static int mmap_failed; /* Boolean flag. */
static char gpfx; /* prefix for global symbol name (sometimes '_') */
@@ -434,6 +436,11 @@ static int arm_is_fake_mcount(Elf32_Rel const *rp)
return 1;
}
+static int arm64_is_fake_mcount(Elf64_Rel const *rp)
+{
+ return ELF64_R_TYPE(w(rp->r_info)) != R_AARCH64_CALL26;
+}
+
/* 64-bit EM_MIPS has weird ELF64_Rela.r_info.
* http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
* We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40]
@@ -547,6 +554,7 @@ static int do_file(char const *const fname)
make_nop = make_nop_arm64;
rel_type_nop = R_AARCH64_NONE;
ideal_nop = ideal_nop4_arm64;
+ is_fake_mcount64 = arm64_is_fake_mcount;
break;
case EM_IA_64: reltype = R_IA64_IMM64; break;
case EM_MIPS: /* reltype: e_class */ break;
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
index 74eab03e31d4..f9b19524da11 100644
--- a/scripts/recordmcount.h
+++ b/scripts/recordmcount.h
@@ -29,6 +29,11 @@
#undef has_rel_mcount
#undef tot_relsize
#undef get_mcountsym
+#undef find_symtab
+#undef get_shnum
+#undef set_shnum
+#undef get_shstrndx
+#undef get_symindex
#undef get_sym_str_and_relp
#undef do_func
#undef Elf_Addr
@@ -58,6 +63,11 @@
# define __has_rel_mcount __has64_rel_mcount
# define has_rel_mcount has64_rel_mcount
# define tot_relsize tot64_relsize
+# define find_symtab find_symtab64
+# define get_shnum get_shnum64
+# define set_shnum set_shnum64
+# define get_shstrndx get_shstrndx64
+# define get_symindex get_symindex64
# define get_sym_str_and_relp get_sym_str_and_relp_64
# define do_func do64
# define get_mcountsym get_mcountsym_64
@@ -91,6 +101,11 @@
# define __has_rel_mcount __has32_rel_mcount
# define has_rel_mcount has32_rel_mcount
# define tot_relsize tot32_relsize
+# define find_symtab find_symtab32
+# define get_shnum get_shnum32
+# define set_shnum set_shnum32
+# define get_shstrndx get_shstrndx32
+# define get_symindex get_symindex32
# define get_sym_str_and_relp get_sym_str_and_relp_32
# define do_func do32
# define get_mcountsym get_mcountsym_32
@@ -173,6 +188,67 @@ static int MIPS_is_fake_mcount(Elf_Rel const *rp)
return is_fake;
}
+static unsigned int get_symindex(Elf_Sym const *sym, Elf32_Word const *symtab,
+ Elf32_Word const *symtab_shndx)
+{
+ unsigned long offset;
+ int index;
+
+ if (sym->st_shndx != SHN_XINDEX)
+ return w2(sym->st_shndx);
+
+ offset = (unsigned long)sym - (unsigned long)symtab;
+ index = offset / sizeof(*sym);
+
+ return w(symtab_shndx[index]);
+}
+
+static unsigned int get_shnum(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
+{
+ if (shdr0 && !ehdr->e_shnum)
+ return w(shdr0->sh_size);
+
+ return w2(ehdr->e_shnum);
+}
+
+static void set_shnum(Elf_Ehdr *ehdr, Elf_Shdr *shdr0, unsigned int new_shnum)
+{
+ if (new_shnum >= SHN_LORESERVE) {
+ ehdr->e_shnum = 0;
+ shdr0->sh_size = w(new_shnum);
+ } else
+ ehdr->e_shnum = w2(new_shnum);
+}
+
+static int get_shstrndx(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
+{
+ if (ehdr->e_shstrndx != SHN_XINDEX)
+ return w2(ehdr->e_shstrndx);
+
+ return w(shdr0->sh_link);
+}
+
+static void find_symtab(Elf_Ehdr *const ehdr, Elf_Shdr const *shdr0,
+ unsigned const nhdr, Elf32_Word **symtab,
+ Elf32_Word **symtab_shndx)
+{
+ Elf_Shdr const *relhdr;
+ unsigned k;
+
+ *symtab = NULL;
+ *symtab_shndx = NULL;
+
+ for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
+ if (relhdr->sh_type == SHT_SYMTAB)
+ *symtab = (void *)ehdr + relhdr->sh_offset;
+ else if (relhdr->sh_type == SHT_SYMTAB_SHNDX)
+ *symtab_shndx = (void *)ehdr + relhdr->sh_offset;
+
+ if (*symtab && *symtab_shndx)
+ break;
+ }
+}
+
/* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
static int append_func(Elf_Ehdr *const ehdr,
Elf_Shdr *const shstr,
@@ -188,10 +264,12 @@ static int append_func(Elf_Ehdr *const ehdr,
char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
? ".rela__mcount_loc"
: ".rel__mcount_loc";
- unsigned const old_shnum = w2(ehdr->e_shnum);
uint_t const old_shoff = _w(ehdr->e_shoff);
uint_t const old_shstr_sh_size = _w(shstr->sh_size);
uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
+ Elf_Shdr *const shdr0 = (Elf_Shdr *)(old_shoff + (void *)ehdr);
+ unsigned int const old_shnum = get_shnum(ehdr, shdr0);
+ unsigned int const new_shnum = 2 + old_shnum; /* {.rel,}__mcount_loc */
uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
uint_t new_e_shoff;
@@ -201,6 +279,8 @@ static int append_func(Elf_Ehdr *const ehdr,
t += (_align & -t); /* word-byte align */
new_e_shoff = t;
+ set_shnum(ehdr, shdr0, new_shnum);
+
/* body for new shstrtab */
if (ulseek(sb.st_size, SEEK_SET) < 0)
return -1;
@@ -255,7 +335,6 @@ static int append_func(Elf_Ehdr *const ehdr,
return -1;
ehdr->e_shoff = _w(new_e_shoff);
- ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */
if (ulseek(0, SEEK_SET) < 0)
return -1;
if (uwrite(ehdr, sizeof(*ehdr)) < 0)
@@ -434,6 +513,8 @@ static int find_secsym_ndx(unsigned const txtndx,
uint_t *const recvalp,
unsigned int *sym_index,
Elf_Shdr const *const symhdr,
+ Elf32_Word const *symtab,
+ Elf32_Word const *symtab_shndx,
Elf_Ehdr const *const ehdr)
{
Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
@@ -445,7 +526,7 @@ static int find_secsym_ndx(unsigned const txtndx,
for (symp = sym0, t = nsym; t; --t, ++symp) {
unsigned int const st_bind = ELF_ST_BIND(symp->st_info);
- if (txtndx == w2(symp->st_shndx)
+ if (txtndx == get_symindex(symp, symtab, symtab_shndx)
/* avoid STB_WEAK */
&& (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
/* function symbols on ARM have quirks, avoid them */
@@ -516,21 +597,23 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0,
return totrelsz;
}
-
/* Overall supervision for Elf32 ET_REL file. */
static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
unsigned const reltype)
{
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
+ (void *)ehdr);
- unsigned const nhdr = w2(ehdr->e_shnum);
- Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)];
+ unsigned const nhdr = get_shnum(ehdr, shdr0);
+ Elf_Shdr *const shstr = &shdr0[get_shstrndx(ehdr, shdr0)];
char const *const shstrtab = (char const *)(_w(shstr->sh_offset)
+ (void *)ehdr);
Elf_Shdr const *relhdr;
unsigned k;
+ Elf32_Word *symtab;
+ Elf32_Word *symtab_shndx;
+
/* Upper bound on space: assume all relevant relocs are for mcount. */
unsigned totrelsz;
@@ -561,6 +644,8 @@ static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
return -1;
}
+ find_symtab(ehdr, shdr0, nhdr, &symtab, &symtab_shndx);
+
for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
char const *const txtname = has_rel_mcount(relhdr, shdr0,
shstrtab, fname);
@@ -577,6 +662,7 @@ static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
result = find_secsym_ndx(w(relhdr->sh_info), txtname,
&recval, &recsym,
&shdr0[symsec_sh_link],
+ symtab, symtab_shndx,
ehdr);
if (result)
goto out;
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
index 70cf8d95d07c..1faf7f07e8db 100644
--- a/scripts/selinux/genheaders/Makefile
+++ b/scripts/selinux/genheaders/Makefile
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-hostprogs := genheaders
+hostprogs-always-y += genheaders
HOST_EXTRACFLAGS += \
-I$(srctree)/include/uapi -I$(srctree)/include \
-I$(srctree)/security/selinux/include
-
-always-y := $(hostprogs)
diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile
index 3026f3c2aa2b..d61058ddd15c 100644
--- a/scripts/selinux/mdp/Makefile
+++ b/scripts/selinux/mdp/Makefile
@@ -1,8 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-hostprogs := mdp
+hostprogs-always-y += mdp
HOST_EXTRACFLAGS += \
-I$(srctree)/include/uapi -I$(srctree)/include \
-I$(srctree)/security/selinux/include -I$(objtree)/include
-always-y := $(hostprogs)
clean-files := policy.* file_contexts
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index 576d11a60417..6ceb88eb9b59 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -67,8 +67,14 @@ int main(int argc, char *argv[])
initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
/* print out the sids */
- for (i = 1; i < initial_sid_to_string_len; i++)
- fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
+ for (i = 1; i < initial_sid_to_string_len; i++) {
+ const char *name = initial_sid_to_string[i];
+
+ if (name)
+ fprintf(fout, "sid %s\n", name);
+ else
+ fprintf(fout, "sid unused%d\n", i);
+ }
fprintf(fout, "\n");
/* print out the class permissions */
@@ -126,9 +132,16 @@ int main(int argc, char *argv[])
#define OBJUSERROLETYPE "user_u:object_r:base_t"
/* default sids */
- for (i = 1; i < initial_sid_to_string_len; i++)
- fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n",
- initial_sid_to_string[i], mls ? ":" SYSTEMLOW : "");
+ for (i = 1; i < initial_sid_to_string_len; i++) {
+ const char *name = initial_sid_to_string[i];
+
+ if (name)
+ fprintf(fout, "sid %s ", name);
+ else
+ fprintf(fout, "sid unused%d\n", i);
+ fprintf(fout, SUBJUSERROLETYPE "%s\n",
+ mls ? ":" SYSTEMLOW : "");
+ }
fprintf(fout, "\n");
#define FS_USE(behavior, fstype) \
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
index ec6b5e81eba1..0ef3abfc4a51 100644
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -255,6 +255,45 @@ static void x86_sort_relative_table(char *extab_image, int image_size)
}
}
+static void s390_sort_relative_table(char *extab_image, int image_size)
+{
+ int i;
+
+ for (i = 0; i < image_size; i += 16) {
+ char *loc = extab_image + i;
+ uint64_t handler;
+
+ w(r((uint32_t *)loc) + i, (uint32_t *)loc);
+ w(r((uint32_t *)(loc + 4)) + (i + 4), (uint32_t *)(loc + 4));
+ /*
+ * 0 is a special self-relative handler value, which means that
+ * handler should be ignored. It is safe, because it means that
+ * handler field points to itself, which should never happen.
+ * When creating extable-relative values, keep it as 0, since
+ * this should never occur either: it would mean that handler
+ * field points to the first extable entry.
+ */
+ handler = r8((uint64_t *)(loc + 8));
+ if (handler)
+ handler += i + 8;
+ w8(handler, (uint64_t *)(loc + 8));
+ }
+
+ qsort(extab_image, image_size / 16, 16, compare_relative_table);
+
+ for (i = 0; i < image_size; i += 16) {
+ char *loc = extab_image + i;
+ uint64_t handler;
+
+ w(r((uint32_t *)loc) - i, (uint32_t *)loc);
+ w(r((uint32_t *)(loc + 4)) - (i + 4), (uint32_t *)(loc + 4));
+ handler = r8((uint64_t *)(loc + 8));
+ if (handler)
+ handler -= i + 8;
+ w8(handler, (uint64_t *)(loc + 8));
+ }
+}
+
static int do_file(char const *const fname, void *addr)
{
int rc = -1;
@@ -297,6 +336,8 @@ static int do_file(char const *const fname, void *addr)
custom_sort = x86_sort_relative_table;
break;
case EM_S390:
+ custom_sort = s390_sort_relative_table;
+ break;
case EM_AARCH64:
case EM_PARISC:
case EM_PPC:
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
index c45e9afaab2d..f253681e7e2a 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -149,6 +149,7 @@ arbitary||arbitrary
architechture||architecture
arguement||argument
arguements||arguments
+arithmatic||arithmetic
aritmetic||arithmetic
arne't||aren't
arraival||arrival
@@ -454,6 +455,7 @@ destorys||destroys
destroied||destroyed
detabase||database
deteced||detected
+detectt||detect
develope||develop
developement||development
developped||developed
@@ -545,6 +547,7 @@ entires||entries
entites||entities
entrys||entries
enocded||encoded
+enought||enough
enterily||entirely
enviroiment||environment
enviroment||environment
@@ -556,11 +559,14 @@ equivelant||equivalent
equivilant||equivalent
eror||error
errorr||error
+errror||error
estbalishment||establishment
etsablishment||establishment
etsbalishment||establishment
+evalution||evaluation
excecutable||executable
exceded||exceeded
+exceds||exceeds
exceeed||exceed
excellant||excellent
execeeded||exceeded
@@ -583,6 +589,7 @@ explictly||explicitly
expresion||expression
exprimental||experimental
extened||extended
+exteneded||extended||extended
extensability||extensibility
extention||extension
extenstion||extension
@@ -610,10 +617,12 @@ feautures||features
fetaure||feature
fetaures||features
fileystem||filesystem
+fimrware||firmware
fimware||firmware
firmare||firmware
firmaware||firmware
firware||firmware
+firwmare||firmware
finanize||finalize
findn||find
finilizes||finalizes
@@ -661,6 +670,7 @@ globel||global
grabing||grabbing
grahical||graphical
grahpical||graphical
+granularty||granularity
grapic||graphic
grranted||granted
guage||gauge
@@ -906,6 +916,7 @@ miximum||maximum
mmnemonic||mnemonic
mnay||many
modfiy||modify
+modifer||modifier
modulues||modules
momery||memory
memomry||memory
@@ -915,6 +926,7 @@ monochromo||monochrome
monocrome||monochrome
mopdule||module
mroe||more
+multipler||multiplier
mulitplied||multiplied
multidimensionnal||multidimensional
multipe||multiple
@@ -952,6 +964,7 @@ occassionally||occasionally
occationally||occasionally
occurance||occurrence
occurances||occurrences
+occurd||occurred
occured||occurred
occurence||occurrence
occure||occurred
@@ -1058,6 +1071,7 @@ precission||precision
preemptable||preemptible
prefered||preferred
prefferably||preferably
+prefitler||prefilter
premption||preemption
prepaired||prepared
preperation||preparation
@@ -1101,6 +1115,7 @@ pronunce||pronounce
propery||property
propigate||propagate
propigation||propagation
+propogation||propagation
propogate||propagate
prosess||process
protable||portable
@@ -1316,6 +1331,7 @@ sturcture||structure
subdirectoires||subdirectories
suble||subtle
substract||subtract
+submited||submitted
submition||submission
suceed||succeed
succesfully||successfully
@@ -1324,6 +1340,7 @@ successed||succeeded
successfull||successful
successfuly||successfully
sucessfully||successfully
+sucessful||successful
sucess||success
superflous||superfluous
superseeded||superseded
@@ -1409,6 +1426,7 @@ transormed||transformed
trasfer||transfer
trasmission||transmission
treshold||threshold
+triggerd||triggered
trigerred||triggered
trigerring||triggering
trun||turn
@@ -1421,6 +1439,7 @@ uknown||unknown
usccess||success
usupported||unsupported
uncommited||uncommitted
+uncompatible||incompatible
unconditionaly||unconditionally
undeflow||underflow
underun||underrun
diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install
index c680c3efb176..40fa6923e80a 100755
--- a/scripts/sphinx-pre-install
+++ b/scripts/sphinx-pre-install
@@ -323,10 +323,6 @@ sub check_sphinx()
$rec_sphinx_upgrade = 1;
return;
}
- if ($cur_version lt $min_pdf_version) {
- $rec_sphinx_upgrade = 1;
- return;
- }
# On version check mode, just assume Sphinx has all mandatory deps
exit (0) if ($version_check);
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 4e18ae5282a6..32d3f53af10b 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -91,20 +91,10 @@ all_sources()
all_compiled_sources()
{
- for i in $(all_sources); do
- case "$i" in
- *.[cS])
- j=${i/\.[cS]/\.o}
- j="${j#$tree}"
- if [ -e $j ]; then
- echo $i
- fi
- ;;
- *)
- echo $i
- ;;
- esac
- done
+ realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) \
+ include/generated/autoconf.h $(find -name "*.cmd" -exec \
+ grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ |
+ awk '!a[$0]++') | sort -u
}
all_target_sources()