summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include23
-rw-r--r--scripts/Kconfig.include8
-rw-r--r--scripts/Makefile18
-rw-r--r--scripts/Makefile.build82
-rw-r--r--scripts/Makefile.clean13
-rw-r--r--scripts/Makefile.extrawarn4
-rw-r--r--scripts/Makefile.gcc-plugins2
-rw-r--r--scripts/Makefile.host44
-rw-r--r--scripts/Makefile.kasan3
-rw-r--r--scripts/Makefile.kcov4
-rw-r--r--scripts/Makefile.kcsan15
-rw-r--r--scripts/Makefile.lib146
-rw-r--r--scripts/Makefile.modpost72
-rw-r--r--scripts/Makefile.package8
-rw-r--r--scripts/Makefile.ubsan3
-rw-r--r--scripts/Makefile.userprogs45
-rwxr-xr-xscripts/atomic/fallbacks/acquire6
-rwxr-xr-xscripts/atomic/fallbacks/add_negative8
-rwxr-xr-xscripts/atomic/fallbacks/add_unless8
-rwxr-xr-xscripts/atomic/fallbacks/andnot6
-rwxr-xr-xscripts/atomic/fallbacks/dec6
-rwxr-xr-xscripts/atomic/fallbacks/dec_and_test8
-rwxr-xr-xscripts/atomic/fallbacks/dec_if_positive8
-rwxr-xr-xscripts/atomic/fallbacks/dec_unless_positive8
-rwxr-xr-xscripts/atomic/fallbacks/fence6
-rwxr-xr-xscripts/atomic/fallbacks/fetch_add_unless10
-rwxr-xr-xscripts/atomic/fallbacks/inc6
-rwxr-xr-xscripts/atomic/fallbacks/inc_and_test8
-rwxr-xr-xscripts/atomic/fallbacks/inc_not_zero8
-rwxr-xr-xscripts/atomic/fallbacks/inc_unless_negative8
-rwxr-xr-xscripts/atomic/fallbacks/read_acquire4
-rwxr-xr-xscripts/atomic/fallbacks/release6
-rwxr-xr-xscripts/atomic/fallbacks/set_release4
-rwxr-xr-xscripts/atomic/fallbacks/sub_and_test8
-rwxr-xr-xscripts/atomic/fallbacks/try_cmpxchg6
-rwxr-xr-xscripts/atomic/gen-atomic-fallback.sh62
-rwxr-xr-xscripts/atomic/gen-atomic-instrumented.sh9
-rwxr-xr-xscripts/atomic/gen-atomic-long.sh3
-rw-r--r--scripts/atomic/gen-atomics.sh5
-rw-r--r--scripts/basic/Makefile3
-rw-r--r--scripts/basic/fixdep.c2
-rwxr-xr-xscripts/bloat-o-meter2
-rwxr-xr-xscripts/bpf_helpers_doc.py29
-rwxr-xr-xscripts/checkkconfigsymbols.py2
-rwxr-xr-xscripts/checkpatch.pl234
-rwxr-xr-xscripts/checkstack.pl87
-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/coccinelle/misc/newline_in_nl_msg.cocci75
-rw-r--r--scripts/const_structs.checkpatch1
-rwxr-xr-xscripts/decode_stacktrace.sh86
-rw-r--r--scripts/dtc/Makefile10
-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/extract-cert.c2
-rw-r--r--scripts/gcc-plugins/Kconfig4
-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
-rw-r--r--scripts/genksyms/keywords.c4
-rwxr-xr-xscripts/get_maintainer.pl46
-rwxr-xr-xscripts/headers_install.sh18
-rw-r--r--scripts/kallsyms.c17
-rw-r--r--scripts/kconfig/.gitignore2
-rw-r--r--scripts/kconfig/Makefile24
-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/lkc.h47
-rw-r--r--scripts/kconfig/lkc_proto.h14
-rw-r--r--scripts/kconfig/menu.c3
-rw-r--r--scripts/kconfig/nconf.c1
-rw-r--r--scripts/kconfig/parser.y30
-rw-r--r--scripts/kconfig/qconf.cc630
-rw-r--r--scripts/kconfig/qconf.h89
-rwxr-xr-xscripts/kconfig/streamline_config.pl24
-rw-r--r--scripts/kconfig/symbol.c16
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/Kconfig35
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/__init__.py17
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout02
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout14
-rw-r--r--scripts/kconfig/tests/rand_nested_choice/expected_stdout25
-rwxr-xr-xscripts/kernel-doc73
-rwxr-xr-xscripts/link-vmlinux.sh40
-rwxr-xr-xscripts/mkcompile_h3
-rwxr-xr-xscripts/mksysmap2
-rw-r--r--scripts/mod/Makefile4
-rw-r--r--scripts/mod/devicetable-offsets.c2
-rw-r--r--scripts/mod/file2alias.c8
-rw-r--r--scripts/mod/modpost.c398
-rw-r--r--scripts/mod/modpost.h19
-rw-r--r--scripts/mod/sumversion.c117
-rwxr-xr-xscripts/modules-check.sh16
-rw-r--r--scripts/nsdeps2
-rwxr-xr-xscripts/package/buildtar18
-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.txt28
-rwxr-xr-xscripts/sphinx-pre-install287
-rwxr-xr-xscripts/tags.sh24
-rwxr-xr-xscripts/xz_wrap.sh2
128 files changed, 2964 insertions, 1481 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 6cabf20ce66a..83a1637417e5 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -16,7 +16,7 @@ pound := \#
dot-target = $(dir $@).$(notdir $@)
###
-# The temporary file to save gcc -MD generated dependencies must not
+# The temporary file to save gcc -MMD generated dependencies must not
# contain a comma
depfile = $(subst $(comma),_,$(dot-target).d)
@@ -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 9fcbfac15d1d..a467b9323442 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -45,11 +45,20 @@ 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
+endif
+
ifndef obj
$(warning kbuild: Makefile.build is included improperly)
endif
@@ -63,19 +72,27 @@ endif
# ===========================================================================
+# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
+subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
+subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
+
+targets-for-builtin := $(extra-y)
+
ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
-lib-target := $(obj)/lib.a
+targets-for-builtin += $(obj)/lib.a
endif
ifdef need-builtin
-builtin-target := $(obj)/built-in.a
+targets-for-builtin += $(obj)/built-in.a
endif
-ifeq ($(CONFIG_MODULES)$(need-modorder),y1)
-modorder-target := $(obj)/modules.order
+targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
+
+ifdef need-modorder
+targets-for-modules += $(obj)/modules.order
endif
-mod-targets := $(patsubst %.o, %.mod, $(obj-m))
+targets += $(targets-for-builtin) $(targets-for-modules)
# Linus' kernel sanity checking tool
ifeq ($(KBUILD_CHECKSRC),1)
@@ -238,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)
@@ -263,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)); \
@@ -274,8 +291,6 @@ cmd_mod = { \
$(obj)/%.mod: $(obj)/%.o FORCE
$(call if_changed,mod)
-targets += $(mod-targets)
-
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
@@ -348,8 +363,9 @@ endif
$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE
$(call if_changed_rule,as_o_S)
-targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y)
-targets += $(extra-y) $(always-y) $(MAKECMDGOALS)
+targets += $(filter-out $(subdir-builtin), $(real-obj-y))
+targets += $(filter-out $(subdir-modorder), $(real-obj-m))
+targets += $(lib-y) $(always-y) $(MAKECMDGOALS)
# Linker scripts preprocessor (.lds.S -> .lds)
# ---------------------------------------------------------------------------
@@ -373,44 +389,40 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
# ---------------------------------------------------------------------------
# To build objects in subdirs, we need to descend into the directories
-$(obj)/%/built-in.a: $(obj)/% ;
+$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
+$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
#
# Rule to compile a set of .o files into one .a file (without symbol table)
#
-ifdef builtin-target
quiet_cmd_ar_builtin = AR $@
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
-$(builtin-target): $(real-obj-y) FORCE
+$(obj)/built-in.a: $(real-obj-y) FORCE
$(call if_changed,ar_builtin)
-targets += $(builtin-target)
-endif # builtin-target
-
#
# Rule to create modules.order file
#
# Create commands to either record .ko file or cat modules.order from
# a subdirectory
-$(modorder-target): $(subdir-ym) FORCE
- $(Q){ $(foreach m, $(modorder), \
- $(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \
+# Add $(obj-m) as the prerequisite to avoid updating the timestamp of
+# modules.order unless contained modules are updated.
+
+cmd_modules_order = { $(foreach m, $(real-prereqs), \
+ $(if $(filter %/modules.order, $m), cat $m, echo $(patsubst %.o,%.ko,$m));) :; } \
| $(AWK) '!x[$$0]++' - > $@
+$(obj)/modules.order: $(obj-m) FORCE
+ $(call if_changed,modules_order)
+
#
# Rule to compile a set of .o files into one .a file (with symbol table)
#
-ifdef lib-target
-
-$(lib-target): $(lib-y) FORCE
+$(obj)/lib.a: $(lib-y) FORCE
$(call if_changed,ar)
-targets += $(lib-target)
-
-endif
-
# NOTE:
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
# module is turned into a multi object module, $^ will contain header file
@@ -473,8 +485,8 @@ endif
else
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
- $(if $(KBUILD_MODULES),$(obj-m) $(mod-targets) $(modorder-target)) \
+__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
+ $(if $(KBUILD_MODULES), $(targets-for-modules)) \
$(subdir-ym) $(always-y)
@:
@@ -487,8 +499,8 @@ PHONY += $(subdir-ym)
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@ \
$(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \
- need-builtin=$(if $(filter $@/built-in.a, $(subdir-obj-y)),1) \
- need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1))
+ need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \
+ need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1)
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
@@ -506,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 075f0cc2d8d7..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-) \
- $(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..95e4cdb94fe9 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
@@ -65,7 +66,7 @@ KBUILD_CFLAGS += -Wnested-externs
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)
@@ -85,6 +86,7 @@ KBUILD_CFLAGS += -Wpacked
KBUILD_CFLAGS += -Wpadded
KBUILD_CFLAGS += -Wpointer-arith
KBUILD_CFLAGS += -Wredundant-decls
+KBUILD_CFLAGS += -Wsign-compare
KBUILD_CFLAGS += -Wswitch-default
KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat)
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 2045855d0b75..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
@@ -88,8 +80,8 @@ _hostcxx_flags += -I $(objtree)/$(obj)
endif
endif
-hostc_flags = -Wp,-MD,$(depfile) $(_hostc_flags)
-hostcxx_flags = -Wp,-MD,$(depfile) $(_hostcxx_flags)
+hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags)
+hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags)
#####
# Compile programs on the host
@@ -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
new file mode 100644
index 000000000000..c50f27b3ac56
--- /dev/null
+++ b/scripts/Makefile.kcsan
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+# 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)
+endif
+
+# Keep most options here optional, to allow enabling more compilers if absence
+# of some options does not break KCSAN nor causes false positive reports.
+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)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 4b799737722c..3d599716940c 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -4,8 +4,18 @@ asflags-y += $(EXTRA_AFLAGS)
ccflags-y += $(EXTRA_CFLAGS)
cppflags-y += $(EXTRA_CPPFLAGS)
ldflags-y += $(EXTRA_LDFLAGS)
+ifneq ($(always),)
+$(warning 'always' is deprecated. Please use 'always-y' instead)
always-y += $(always)
-hostprogs += $(hostprogs-y) $(hostprogs-m)
+endif
+ifneq ($(hostprogs-y),)
+$(warning 'hostprogs-y' is deprecated. Please use 'hostprogs' instead)
+hostprogs += $(hostprogs-y)
+endif
+ifneq ($(hostprogs-m),)
+$(warning 'hostprogs-m' is deprecated. Please use 'hostprogs' instead)
+hostprogs += $(hostprogs-m)
+endif
# flags that take effect in current and sub directories
KBUILD_AFLAGS += $(subdir-asflags-y)
@@ -22,40 +32,35 @@ obj-m := $(filter-out $(obj-y),$(obj-m))
# Filter out objects already built-in
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
-# Determine modorder.
-# Unfortunately, we don't have information about ordering between -y
-# and -m subdirs. Just put -y's first.
-modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
+# Subdirectories we need to descend into
+subdir-ym := $(sort $(subdir-y) $(subdir-m) \
+ $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m))))
+
+# Handle objects in subdirs:
+# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and
+# foo/modules.order
+# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order
+#
+# Generate modules.order to determine modorder. Unfortunately, we don't have
+# information about ordering between -y and -m subdirs. Just put -y's first.
+
+ifdef need-modorder
+obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m))
+else
+obj-m := $(filter-out %/, $(obj-m))
+endif
-# Handle objects in subdirs
-# ---------------------------------------------------------------------------
-# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a
-# and add the directory to the list of dirs to descend into: $(subdir-y)
-# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
-# and add the directory to the list of dirs to descend into: $(subdir-m)
-__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
-subdir-y += $(__subdir-y)
-__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
-subdir-m += $(__subdir-m)
ifdef need-builtin
obj-y := $(patsubst %/, %/built-in.a, $(obj-y))
else
obj-y := $(filter-out %/, $(obj-y))
endif
-obj-m := $(filter-out %/, $(obj-m))
-
-# Subdirectories we need to descend into
-subdir-ym := $(sort $(subdir-y) $(subdir-m))
# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object
multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))), $(m))))
multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)) $($(m:.o=-))), $(m))))
multi-used := $(multi-used-y) $(multi-used-m)
-# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
-# tell kbuild to descend
-subdir-obj-y := $(filter %/built-in.a, $(obj-y))
-
# Replace multi-part objects by their individual parts,
# including built-in.a from subdirectories
real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
@@ -63,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)
@@ -78,10 +94,8 @@ endif
extra-y := $(addprefix $(obj)/,$(extra-y))
always-y := $(addprefix $(obj)/,$(always-y))
targets := $(addprefix $(obj)/,$(targets))
-modorder := $(addprefix $(obj)/,$(modorder))
obj-m := $(addprefix $(obj)/,$(obj-m))
lib-y := $(addprefix $(obj)/,$(lib-y))
-subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
@@ -108,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)
#
@@ -149,6 +165,16 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_KCOV))
endif
+#
+# Enable KCSAN flags except some files or directories we don't want to check
+# (depends on variables KCSAN_SANITIZE_obj.o, KCSAN_SANITIZE)
+#
+ifeq ($(CONFIG_KCSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \
+ $(CFLAGS_KCSAN))
+endif
+
# $(srctree)/$(src) for including checkin headers from generated source files
# $(objtree)/$(obj) for including generated headers from checkin source files
ifeq ($(KBUILD_EXTMOD),)
@@ -171,22 +197,22 @@ modkern_aflags = $(if $(part-of-module), \
$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \
$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
-c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
-include $(srctree)/include/linux/compiler_types.h \
$(_c_flags) $(modkern_cflags) \
$(basename_flags) $(modname_flags)
-a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_a_flags) $(modkern_aflags)
-cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
+cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_cpp_flags)
ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes
-dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
+dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
$(addprefix -I,$(DTC_INCLUDE)) \
-undef -D__DTS__
@@ -199,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
# ===========================================================================
@@ -241,11 +270,12 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
# ---------------------------------------------------------------------------
quiet_cmd_gzip = GZIP $@
- cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@
+ cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@
# DTC
# ---------------------------------------------------------------------------
DTC ?= $(objtree)/scripts/dtc/dtc
+DTC_FLAGS += -Wno-interrupt_provider
# Disable noisy checks by default
ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),)
@@ -261,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))
@@ -285,15 +316,14 @@ $(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) $< ; \
- $(DTC) -O $(2) -o $@ -b 0 \
+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) ; \
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
- $(call if_changed_dep,dtc,dtb)
+ $(call if_changed_dep,dtc)
DT_CHECKER ?= dt-validate
DT_BINDING_DIR := Documentation/devicetree/bindings
@@ -304,7 +334,7 @@ quiet_cmd_dtb_check = CHECK $@
cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@
define rule_dtc
- $(call cmd_and_fixdep,dtc,yaml)
+ $(call cmd_and_fixdep,dtc)
$(call cmd,dtb_check)
endef
@@ -334,19 +364,19 @@ printf "%08x\n" $$dec_size | \
)
quiet_cmd_bzip2 = BZIP2 $@
- cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9; $(size_append); } > $@
+ cmd_bzip2 = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
# Lzma
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
- cmd_lzma = { cat $(real-prereqs) | lzma -9; $(size_append); } > $@
+ cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
quiet_cmd_lzo = LZO $@
- cmd_lzo = { cat $(real-prereqs) | lzop -9; $(size_append); } > $@
+ cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
quiet_cmd_lz4 = LZ4 $@
- cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout; \
+ cmd_lz4 = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \
$(size_append); } > $@
# U-Boot mkimage
@@ -393,7 +423,29 @@ quiet_cmd_xzkern = XZKERN $@
$(size_append); } > $@
quiet_cmd_xzmisc = XZMISC $@
- cmd_xzmisc = cat $(real-prereqs) | xz --check=crc32 --lzma2=dict=1MiB > $@
+ 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 957eed6a17a5..f54b6ac37ac2 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -43,34 +43,30 @@ __modpost:
include include/config/auto.conf
include scripts/Kbuild.include
-kernelsymfile := $(objtree)/Module.symvers
-modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
-
MODPOST = scripts/mod/modpost \
$(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
- $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
- $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \
- $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
- $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \
- $(if $(KBUILD_MODPOST_WARN),-w)
+ $(if $(KBUILD_MODPOST_WARN),-w) \
+ -o $@
ifdef MODPOST_VMLINUX
-quiet_cmd_modpost = MODPOST vmlinux.o
- cmd_modpost = $(MODPOST) vmlinux.o
+quiet_cmd_modpost = MODPOST $@
+ cmd_modpost = $(MODPOST) $<
-__modpost:
+vmlinux.symvers: vmlinux.o
$(call cmd,modpost)
-else
+__modpost: vmlinux.symvers
-MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - \
- $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS))
+else
ifeq ($(KBUILD_EXTMOD),)
-MODPOST += $(wildcard vmlinux)
+
+input-symdump := vmlinux.symvers
+output-symdump := Module.symvers
+
else
# set src + obj - they may be used in the modules's Makefile
@@ -80,22 +76,54 @@ src := $(obj)
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \
$(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile)
+
+# modpost option for external modules
+MODPOST += -e
+
+input-symdump := Module.symvers $(KBUILD_EXTRA_SYMBOLS)
+output-symdump := $(KBUILD_EXTMOD)/Module.symvers
+
endif
-# find all modules listed in modules.order
-modules := $(sort $(shell cat $(MODORDER)))
+# modpost options for modules (both in-kernel and external)
+MODPOST += \
+ $(addprefix -i ,$(wildcard $(input-symdump))) \
+ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
+ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N)
-# Read out modules.order instead of expanding $(modules) to pass in modpost.
+# 'make -i -k' ignores compile errors, and builds as many modules as possible.
+ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),)
+MODPOST += -n
+endif
+
+# Clear VPATH to not search for *.symvers in $(srctree). Check only $(objtree).
+VPATH :=
+$(input-symdump):
+ @echo >&2 'WARNING: Symbol version dump "$@" is missing.'
+ @echo >&2 ' Modules may not have dependencies or modversions.'
+
+# Read out modules.order to pass in modpost.
# Otherwise, allmodconfig would fail with "Argument list too long".
-quiet_cmd_modpost = MODPOST $(words $(modules)) modules
- cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST)
+quiet_cmd_modpost = MODPOST $@
+ cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T -
-__modpost:
- $(call cmd,modpost)
+$(output-symdump): $(MODORDER) $(input-symdump) FORCE
+ $(call if_changed,modpost)
+
+targets += $(output-symdump)
+
+__modpost: $(output-symdump)
ifneq ($(KBUILD_MODPOST_NOFINAL),1)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
endif
+PHONY += FORCE
+FORCE:
+
+existing-targets := $(wildcard $(sort $(targets)))
+
+-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
+
endif
.PHONY: $(PHONY)
diff --git a/scripts/Makefile.package b/scripts/Makefile.package
index 02135d2671a6..f952fb64789d 100644
--- a/scripts/Makefile.package
+++ b/scripts/Makefile.package
@@ -45,7 +45,7 @@ if test "$(objtree)" != "$(srctree)"; then \
false; \
fi ; \
$(srctree)/scripts/setlocalversion --save-scmversion; \
-tar -cz $(RCS_TAR_IGNORE) -f $(2).tar.gz \
+tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \
--transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3); \
rm -f $(objtree)/.scmversion
@@ -127,9 +127,9 @@ util/PERF-VERSION-GEN $(CURDIR)/$(perf-tar)/); \
tar rf $(perf-tar).tar $(perf-tar)/HEAD $(perf-tar)/PERF-VERSION-FILE; \
rm -r $(perf-tar); \
$(if $(findstring tar-src,$@),, \
-$(if $(findstring bz2,$@),bzip2, \
-$(if $(findstring gz,$@),gzip, \
-$(if $(findstring xz,$@),xz, \
+$(if $(findstring bz2,$@),$(KBZIP2), \
+$(if $(findstring gz,$@),$(KGZIP), \
+$(if $(findstring xz,$@),$(XZ), \
$(error unknown target $@)))) \
-f -9 $(perf-tar).tar)
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/Makefile.userprogs b/scripts/Makefile.userprogs
new file mode 100644
index 000000000000..fb415297337a
--- /dev/null
+++ b/scripts/Makefile.userprogs
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Build userspace programs for the target system
+#
+
+# Executables compiled from a single .c file
+user-csingle := $(foreach m, $(userprogs), $(if $($(m)-objs),,$(m)))
+
+# Executables linked based on several .o files
+user-cmulti := $(foreach m, $(userprogs), $(if $($(m)-objs),$(m)))
+
+# Objects compiled from .c files
+user-cobjs := $(sort $(foreach m, $(userprogs), $($(m)-objs)))
+
+user-csingle := $(addprefix $(obj)/, $(user-csingle))
+user-cmulti := $(addprefix $(obj)/, $(user-cmulti))
+user-cobjs := $(addprefix $(obj)/, $(user-cobjs))
+
+user_ccflags = -Wp,-MMD,$(depfile) $(KBUILD_USERCFLAGS) $(userccflags) \
+ $($(target-stem)-userccflags)
+user_ldflags = $(KBUILD_USERLDFLAGS) $(userldflags) $($(target-stem)-userldflags)
+
+# Create an executable from a single .c file
+quiet_cmd_user_cc_c = CC [U] $@
+ cmd_user_cc_c = $(CC) $(user_ccflags) $(user_ldflags) -o $@ $< \
+ $($(target-stem)-userldlibs)
+$(user-csingle): $(obj)/%: $(src)/%.c FORCE
+ $(call if_changed_dep,user_cc_c)
+
+# Link an executable based on list of .o files
+quiet_cmd_user_ld = LD [U] $@
+ cmd_user_ld = $(CC) $(user_ldflags) -o $@ \
+ $(addprefix $(obj)/, $($(target-stem)-objs)) \
+ $($(target-stem)-userldlibs)
+$(user-cmulti): FORCE
+ $(call if_changed,user_ld)
+$(call multi_depend, $(user-cmulti), , -objs)
+
+# Create .o file from a .c file
+quiet_cmd_user_cc_o_c = CC [U] $@
+ cmd_user_cc_o_c = $(CC) $(user_ccflags) -c -o $@ $<
+$(user-cobjs): $(obj)/%.o: $(src)/%.c FORCE
+ $(call if_changed_dep,user_cc_o_c)
+
+targets += $(user-csingle) $(user-cmulti) $(user-cobjs)
diff --git a/scripts/atomic/fallbacks/acquire b/scripts/atomic/fallbacks/acquire
index e38871e64db6..59c00529dc7c 100755
--- a/scripts/atomic/fallbacks/acquire
+++ b/scripts/atomic/fallbacks/acquire
@@ -1,8 +1,8 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}${name}${sfx}_acquire(${params})
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}${name}${sfx}_acquire(${params})
{
- ${ret} ret = ${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+ ${ret} ret = ${arch}${atomic}_${pfx}${name}${sfx}_relaxed(${args});
__atomic_acquire_fence();
return ret;
}
diff --git a/scripts/atomic/fallbacks/add_negative b/scripts/atomic/fallbacks/add_negative
index e6f4815637de..a66635bceefb 100755
--- a/scripts/atomic/fallbacks/add_negative
+++ b/scripts/atomic/fallbacks/add_negative
@@ -1,6 +1,6 @@
cat <<EOF
/**
- * ${atomic}_add_negative - add and test if negative
+ * ${arch}${atomic}_add_negative - add and test if negative
* @i: integer value to add
* @v: pointer of type ${atomic}_t
*
@@ -8,9 +8,9 @@ cat <<EOF
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
-static inline bool
-${atomic}_add_negative(${int} i, ${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_add_negative(${int} i, ${atomic}_t *v)
{
- return ${atomic}_add_return(i, v) < 0;
+ return ${arch}${atomic}_add_return(i, v) < 0;
}
EOF
diff --git a/scripts/atomic/fallbacks/add_unless b/scripts/atomic/fallbacks/add_unless
index 792533885fbf..2ff598a3f9ec 100755
--- a/scripts/atomic/fallbacks/add_unless
+++ b/scripts/atomic/fallbacks/add_unless
@@ -1,6 +1,6 @@
cat << EOF
/**
- * ${atomic}_add_unless - add unless the number is already a given value
+ * ${arch}${atomic}_add_unless - add unless the number is already a given value
* @v: pointer of type ${atomic}_t
* @a: the amount to add to v...
* @u: ...unless v is equal to u.
@@ -8,9 +8,9 @@ cat << EOF
* Atomically adds @a to @v, if @v was not already @u.
* Returns true if the addition was done.
*/
-static inline bool
-${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
+static __always_inline bool
+${arch}${atomic}_add_unless(${atomic}_t *v, ${int} a, ${int} u)
{
- return ${atomic}_fetch_add_unless(v, a, u) != u;
+ return ${arch}${atomic}_fetch_add_unless(v, a, u) != u;
}
EOF
diff --git a/scripts/atomic/fallbacks/andnot b/scripts/atomic/fallbacks/andnot
index 9f3a3216b5e3..3f18663dcefb 100755
--- a/scripts/atomic/fallbacks/andnot
+++ b/scripts/atomic/fallbacks/andnot
@@ -1,7 +1,7 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}andnot${sfx}${order}(${int} i, ${atomic}_t *v)
{
- ${retstmt}${atomic}_${pfx}and${sfx}${order}(~i, v);
+ ${retstmt}${arch}${atomic}_${pfx}and${sfx}${order}(~i, v);
}
EOF
diff --git a/scripts/atomic/fallbacks/dec b/scripts/atomic/fallbacks/dec
index 10bbc82be31d..e2e01f0574bb 100755
--- a/scripts/atomic/fallbacks/dec
+++ b/scripts/atomic/fallbacks/dec
@@ -1,7 +1,7 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}dec${sfx}${order}(${atomic}_t *v)
{
- ${retstmt}${atomic}_${pfx}sub${sfx}${order}(1, v);
+ ${retstmt}${arch}${atomic}_${pfx}sub${sfx}${order}(1, v);
}
EOF
diff --git a/scripts/atomic/fallbacks/dec_and_test b/scripts/atomic/fallbacks/dec_and_test
index 0ce7103b3df2..e8a5e492eb5f 100755
--- a/scripts/atomic/fallbacks/dec_and_test
+++ b/scripts/atomic/fallbacks/dec_and_test
@@ -1,15 +1,15 @@
cat <<EOF
/**
- * ${atomic}_dec_and_test - decrement and test
+ * ${arch}${atomic}_dec_and_test - decrement and test
* @v: pointer of type ${atomic}_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
-static inline bool
-${atomic}_dec_and_test(${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_dec_and_test(${atomic}_t *v)
{
- return ${atomic}_dec_return(v) == 0;
+ return ${arch}${atomic}_dec_return(v) == 0;
}
EOF
diff --git a/scripts/atomic/fallbacks/dec_if_positive b/scripts/atomic/fallbacks/dec_if_positive
index c52eacec43c8..527adec89c37 100755
--- a/scripts/atomic/fallbacks/dec_if_positive
+++ b/scripts/atomic/fallbacks/dec_if_positive
@@ -1,14 +1,14 @@
cat <<EOF
-static inline ${ret}
-${atomic}_dec_if_positive(${atomic}_t *v)
+static __always_inline ${ret}
+${arch}${atomic}_dec_if_positive(${atomic}_t *v)
{
- ${int} dec, c = ${atomic}_read(v);
+ ${int} dec, c = ${arch}${atomic}_read(v);
do {
dec = c - 1;
if (unlikely(dec < 0))
break;
- } while (!${atomic}_try_cmpxchg(v, &c, dec));
+ } while (!${arch}${atomic}_try_cmpxchg(v, &c, dec));
return dec;
}
diff --git a/scripts/atomic/fallbacks/dec_unless_positive b/scripts/atomic/fallbacks/dec_unless_positive
index 8a2578f14268..dcab6848ca1e 100755
--- a/scripts/atomic/fallbacks/dec_unless_positive
+++ b/scripts/atomic/fallbacks/dec_unless_positive
@@ -1,13 +1,13 @@
cat <<EOF
-static inline bool
-${atomic}_dec_unless_positive(${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_dec_unless_positive(${atomic}_t *v)
{
- ${int} c = ${atomic}_read(v);
+ ${int} c = ${arch}${atomic}_read(v);
do {
if (unlikely(c > 0))
return false;
- } while (!${atomic}_try_cmpxchg(v, &c, c - 1));
+ } while (!${arch}${atomic}_try_cmpxchg(v, &c, c - 1));
return true;
}
diff --git a/scripts/atomic/fallbacks/fence b/scripts/atomic/fallbacks/fence
index 82f68fa6931a..3764fc8ce945 100755
--- a/scripts/atomic/fallbacks/fence
+++ b/scripts/atomic/fallbacks/fence
@@ -1,10 +1,10 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}${name}${sfx}(${params})
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}${name}${sfx}(${params})
{
${ret} ret;
__atomic_pre_full_fence();
- ret = ${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+ ret = ${arch}${atomic}_${pfx}${name}${sfx}_relaxed(${args});
__atomic_post_full_fence();
return ret;
}
diff --git a/scripts/atomic/fallbacks/fetch_add_unless b/scripts/atomic/fallbacks/fetch_add_unless
index d2c091db7eae..0e0b9aef1515 100755
--- a/scripts/atomic/fallbacks/fetch_add_unless
+++ b/scripts/atomic/fallbacks/fetch_add_unless
@@ -1,6 +1,6 @@
cat << EOF
/**
- * ${atomic}_fetch_add_unless - add unless the number is already a given value
+ * ${arch}${atomic}_fetch_add_unless - add unless the number is already a given value
* @v: pointer of type ${atomic}_t
* @a: the amount to add to v...
* @u: ...unless v is equal to u.
@@ -8,15 +8,15 @@ cat << EOF
* Atomically adds @a to @v, so long as @v was not already @u.
* Returns original value of @v
*/
-static inline ${int}
-${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
+static __always_inline ${int}
+${arch}${atomic}_fetch_add_unless(${atomic}_t *v, ${int} a, ${int} u)
{
- ${int} c = ${atomic}_read(v);
+ ${int} c = ${arch}${atomic}_read(v);
do {
if (unlikely(c == u))
break;
- } while (!${atomic}_try_cmpxchg(v, &c, c + a));
+ } while (!${arch}${atomic}_try_cmpxchg(v, &c, c + a));
return c;
}
diff --git a/scripts/atomic/fallbacks/inc b/scripts/atomic/fallbacks/inc
index f866b3ad2353..15ec62946e8c 100755
--- a/scripts/atomic/fallbacks/inc
+++ b/scripts/atomic/fallbacks/inc
@@ -1,7 +1,7 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}inc${sfx}${order}(${atomic}_t *v)
{
- ${retstmt}${atomic}_${pfx}add${sfx}${order}(1, v);
+ ${retstmt}${arch}${atomic}_${pfx}add${sfx}${order}(1, v);
}
EOF
diff --git a/scripts/atomic/fallbacks/inc_and_test b/scripts/atomic/fallbacks/inc_and_test
index 4e2068869f7e..cecc8322a21f 100755
--- a/scripts/atomic/fallbacks/inc_and_test
+++ b/scripts/atomic/fallbacks/inc_and_test
@@ -1,15 +1,15 @@
cat <<EOF
/**
- * ${atomic}_inc_and_test - increment and test
+ * ${arch}${atomic}_inc_and_test - increment and test
* @v: pointer of type ${atomic}_t
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
* other cases.
*/
-static inline bool
-${atomic}_inc_and_test(${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_inc_and_test(${atomic}_t *v)
{
- return ${atomic}_inc_return(v) == 0;
+ return ${arch}${atomic}_inc_return(v) == 0;
}
EOF
diff --git a/scripts/atomic/fallbacks/inc_not_zero b/scripts/atomic/fallbacks/inc_not_zero
index a7c45c8d107c..50f2d4d48279 100755
--- a/scripts/atomic/fallbacks/inc_not_zero
+++ b/scripts/atomic/fallbacks/inc_not_zero
@@ -1,14 +1,14 @@
cat <<EOF
/**
- * ${atomic}_inc_not_zero - increment unless the number is zero
+ * ${arch}${atomic}_inc_not_zero - increment unless the number is zero
* @v: pointer of type ${atomic}_t
*
* Atomically increments @v by 1, if @v is non-zero.
* Returns true if the increment was done.
*/
-static inline bool
-${atomic}_inc_not_zero(${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_inc_not_zero(${atomic}_t *v)
{
- return ${atomic}_add_unless(v, 1, 0);
+ return ${arch}${atomic}_add_unless(v, 1, 0);
}
EOF
diff --git a/scripts/atomic/fallbacks/inc_unless_negative b/scripts/atomic/fallbacks/inc_unless_negative
index 0c266e71dbd4..87629e0d4a80 100755
--- a/scripts/atomic/fallbacks/inc_unless_negative
+++ b/scripts/atomic/fallbacks/inc_unless_negative
@@ -1,13 +1,13 @@
cat <<EOF
-static inline bool
-${atomic}_inc_unless_negative(${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_inc_unless_negative(${atomic}_t *v)
{
- ${int} c = ${atomic}_read(v);
+ ${int} c = ${arch}${atomic}_read(v);
do {
if (unlikely(c < 0))
return false;
- } while (!${atomic}_try_cmpxchg(v, &c, c + 1));
+ } while (!${arch}${atomic}_try_cmpxchg(v, &c, c + 1));
return true;
}
diff --git a/scripts/atomic/fallbacks/read_acquire b/scripts/atomic/fallbacks/read_acquire
index 75863b5203f7..341a88dccaa7 100755
--- a/scripts/atomic/fallbacks/read_acquire
+++ b/scripts/atomic/fallbacks/read_acquire
@@ -1,6 +1,6 @@
cat <<EOF
-static inline ${ret}
-${atomic}_read_acquire(const ${atomic}_t *v)
+static __always_inline ${ret}
+${arch}${atomic}_read_acquire(const ${atomic}_t *v)
{
return smp_load_acquire(&(v)->counter);
}
diff --git a/scripts/atomic/fallbacks/release b/scripts/atomic/fallbacks/release
index 3f628a3802d9..f8906d537c0f 100755
--- a/scripts/atomic/fallbacks/release
+++ b/scripts/atomic/fallbacks/release
@@ -1,8 +1,8 @@
cat <<EOF
-static inline ${ret}
-${atomic}_${pfx}${name}${sfx}_release(${params})
+static __always_inline ${ret}
+${arch}${atomic}_${pfx}${name}${sfx}_release(${params})
{
__atomic_release_fence();
- ${retstmt}${atomic}_${pfx}${name}${sfx}_relaxed(${args});
+ ${retstmt}${arch}${atomic}_${pfx}${name}${sfx}_relaxed(${args});
}
EOF
diff --git a/scripts/atomic/fallbacks/set_release b/scripts/atomic/fallbacks/set_release
index 45bb5e0cfc08..76068272d5f5 100755
--- a/scripts/atomic/fallbacks/set_release
+++ b/scripts/atomic/fallbacks/set_release
@@ -1,6 +1,6 @@
cat <<EOF
-static inline void
-${atomic}_set_release(${atomic}_t *v, ${int} i)
+static __always_inline void
+${arch}${atomic}_set_release(${atomic}_t *v, ${int} i)
{
smp_store_release(&(v)->counter, i);
}
diff --git a/scripts/atomic/fallbacks/sub_and_test b/scripts/atomic/fallbacks/sub_and_test
index 289ef17a2d7a..c580f4c2136e 100755
--- a/scripts/atomic/fallbacks/sub_and_test
+++ b/scripts/atomic/fallbacks/sub_and_test
@@ -1,6 +1,6 @@
cat <<EOF
/**
- * ${atomic}_sub_and_test - subtract value from variable and test result
+ * ${arch}${atomic}_sub_and_test - subtract value from variable and test result
* @i: integer value to subtract
* @v: pointer of type ${atomic}_t
*
@@ -8,9 +8,9 @@ cat <<EOF
* true if the result is zero, or false for all
* other cases.
*/
-static inline bool
-${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
+static __always_inline bool
+${arch}${atomic}_sub_and_test(${int} i, ${atomic}_t *v)
{
- return ${atomic}_sub_return(i, v) == 0;
+ return ${arch}${atomic}_sub_return(i, v) == 0;
}
EOF
diff --git a/scripts/atomic/fallbacks/try_cmpxchg b/scripts/atomic/fallbacks/try_cmpxchg
index 4ed85e2f5378..06db0f738e45 100755
--- a/scripts/atomic/fallbacks/try_cmpxchg
+++ b/scripts/atomic/fallbacks/try_cmpxchg
@@ -1,9 +1,9 @@
cat <<EOF
-static inline bool
-${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
+static __always_inline bool
+${arch}${atomic}_try_cmpxchg${order}(${atomic}_t *v, ${int} *old, ${int} new)
{
${int} r, o = *old;
- r = ${atomic}_cmpxchg${order}(v, o, new);
+ r = ${arch}${atomic}_cmpxchg${order}(v, o, new);
if (unlikely(r != o))
*old = r;
return likely(r == o);
diff --git a/scripts/atomic/gen-atomic-fallback.sh b/scripts/atomic/gen-atomic-fallback.sh
index 1bd7c1707633..693dfa1de430 100755
--- a/scripts/atomic/gen-atomic-fallback.sh
+++ b/scripts/atomic/gen-atomic-fallback.sh
@@ -2,10 +2,11 @@
# SPDX-License-Identifier: GPL-2.0
ATOMICDIR=$(dirname $0)
+ARCH=$2
. ${ATOMICDIR}/atomic-tbl.sh
-#gen_template_fallback(template, meta, pfx, name, sfx, order, atomic, int, args...)
+#gen_template_fallback(template, meta, pfx, name, sfx, order, arch, atomic, int, args...)
gen_template_fallback()
{
local template="$1"; shift
@@ -14,10 +15,11 @@ gen_template_fallback()
local name="$1"; shift
local sfx="$1"; shift
local order="$1"; shift
+ local arch="$1"; shift
local atomic="$1"; shift
local int="$1"; shift
- local atomicname="${atomic}_${pfx}${name}${sfx}${order}"
+ local atomicname="${arch}${atomic}_${pfx}${name}${sfx}${order}"
local ret="$(gen_ret_type "${meta}" "${int}")"
local retstmt="$(gen_ret_stmt "${meta}")"
@@ -32,7 +34,7 @@ gen_template_fallback()
fi
}
-#gen_proto_fallback(meta, pfx, name, sfx, order, atomic, int, args...)
+#gen_proto_fallback(meta, pfx, name, sfx, order, arch, atomic, int, args...)
gen_proto_fallback()
{
local meta="$1"; shift
@@ -56,19 +58,51 @@ cat << EOF
EOF
}
-#gen_proto_order_variants(meta, pfx, name, sfx, atomic, int, args...)
+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()
{
local meta="$1"; shift
local pfx="$1"; shift
local name="$1"; shift
local sfx="$1"; shift
- local atomic="$1"
+ local arch="$1"
+ local atomic="$2"
- local basename="${atomic}_${pfx}${name}${sfx}"
+ local basename="${arch}${atomic}_${pfx}${name}${sfx}"
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
@@ -94,7 +128,7 @@ gen_proto_order_variants()
gen_basic_fallbacks "${basename}"
if [ ! -z "${template}" ]; then
- printf "#endif /* ${atomic}_${pfx}${name}${sfx} */\n\n"
+ printf "#endif /* ${arch}${atomic}_${pfx}${name}${sfx} */\n\n"
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "" "$@"
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_acquire" "$@"
gen_proto_fallback "${meta}" "${pfx}" "${name}" "${sfx}" "_release" "$@"
@@ -149,20 +183,19 @@ cat << EOF
#ifndef _LINUX_ATOMIC_FALLBACK_H
#define _LINUX_ATOMIC_FALLBACK_H
+#include <linux/compiler.h>
+
EOF
-for xchg in "xchg" "cmpxchg" "cmpxchg64"; do
+for xchg in "${ARCH}xchg" "${ARCH}cmpxchg" "${ARCH}cmpxchg64"; do
gen_xchg_fallbacks "${xchg}"
done
grep '^[a-z]' "$1" | while read name meta args; do
- gen_proto "${meta}" "${name}" "atomic" "int" ${args}
+ gen_proto "${meta}" "${name}" "${ARCH}" "atomic" "int" ${args}
done
cat <<EOF
-#define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
-#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
-
#ifdef CONFIG_GENERIC_ATOMIC64
#include <asm-generic/atomic64.h>
#endif
@@ -170,12 +203,9 @@ cat <<EOF
EOF
grep '^[a-z]' "$1" | while read name meta args; do
- gen_proto "${meta}" "${name}" "atomic64" "s64" ${args}
+ gen_proto "${meta}" "${name}" "${ARCH}" "atomic64" "s64" ${args}
done
cat <<EOF
-#define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
-#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
-
#endif /* _LINUX_ATOMIC_FALLBACK_H */
EOF
diff --git a/scripts/atomic/gen-atomic-instrumented.sh b/scripts/atomic/gen-atomic-instrumented.sh
index e09812372b17..6afadf73da17 100755
--- a/scripts/atomic/gen-atomic-instrumented.sh
+++ b/scripts/atomic/gen-atomic-instrumented.sh
@@ -20,7 +20,7 @@ gen_param_check()
# We don't write to constant parameters
[ ${type#c} != ${type} ] && rw="read"
- printf "\tkasan_check_${rw}(${name}, sizeof(*${name}));\n"
+ printf "\tinstrument_atomic_${rw}(${name}, sizeof(*${name}));\n"
}
#gen_param_check(arg...)
@@ -84,7 +84,7 @@ gen_proto_order_variant()
[ ! -z "${guard}" ] && printf "#if ${guard}\n"
cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
${atomicname}(${params})
{
${checks}
@@ -107,7 +107,7 @@ cat <<EOF
#define ${xchg}(ptr, ...) \\
({ \\
typeof(ptr) __ai_ptr = (ptr); \\
- kasan_check_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\
+ instrument_atomic_write(__ai_ptr, ${mult}sizeof(*__ai_ptr)); \\
arch_${xchg}(__ai_ptr, __VA_ARGS__); \\
})
EOF
@@ -147,7 +147,8 @@ cat << EOF
#define _ASM_GENERIC_ATOMIC_INSTRUMENTED_H
#include <linux/build_bug.h>
-#include <linux/kasan-checks.h>
+#include <linux/compiler.h>
+#include <linux/instrumented.h>
EOF
diff --git a/scripts/atomic/gen-atomic-long.sh b/scripts/atomic/gen-atomic-long.sh
index c240a7231b2e..e318d3f92e53 100755
--- a/scripts/atomic/gen-atomic-long.sh
+++ b/scripts/atomic/gen-atomic-long.sh
@@ -46,7 +46,7 @@ gen_proto_order_variant()
local retstmt="$(gen_ret_stmt "${meta}")"
cat <<EOF
-static inline ${ret}
+static __always_inline ${ret}
atomic_long_${name}(${params})
{
${retstmt}${atomic}_${name}(${argscast});
@@ -64,6 +64,7 @@ cat << EOF
#ifndef _ASM_GENERIC_ATOMIC_LONG_H
#define _ASM_GENERIC_ATOMIC_LONG_H
+#include <linux/compiler.h>
#include <asm/types.h>
#ifdef CONFIG_64BIT
diff --git a/scripts/atomic/gen-atomics.sh b/scripts/atomic/gen-atomics.sh
index 000dc6437893..d29e159ef489 100644
--- a/scripts/atomic/gen-atomics.sh
+++ b/scripts/atomic/gen-atomics.sh
@@ -10,10 +10,11 @@ LINUXDIR=${ATOMICDIR}/../..
cat <<EOF |
gen-atomic-instrumented.sh asm-generic/atomic-instrumented.h
gen-atomic-long.sh asm-generic/atomic-long.h
+gen-atomic-fallback.sh linux/atomic-arch-fallback.h arch_
gen-atomic-fallback.sh linux/atomic-fallback.h
EOF
-while read script header; do
- /bin/sh ${ATOMICDIR}/${script} ${ATOMICTBL} > ${LINUXDIR}/include/${header}
+while read script header args; do
+ /bin/sh ${ATOMICDIR}/${script} ${ATOMICTBL} ${args} > ${LINUXDIR}/include/${header}
HASH="$(sha1sum ${LINUXDIR}/include/${header})"
HASH="${HASH%% *}"
printf "// %s\n" "${HASH}" >> ${LINUXDIR}/include/${header}
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/basic/fixdep.c b/scripts/basic/fixdep.c
index 877ca2c88246..d98540552941 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -160,7 +160,7 @@ struct item {
struct item *next;
unsigned int len;
unsigned int hash;
- char name[0];
+ char name[];
};
#define HASHSZ 256
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 f43d193aff3a..5bfa448b4704 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_helpers_doc.py
@@ -318,6 +318,11 @@ may be interested in:
of eBPF maps are used with a given helper function.
* *kernel/bpf/* directory contains other files in which additional helpers are
defined (for cgroups, sockmaps, etc.).
+* The bpftool utility can be used to probe the availability of helper functions
+ on the system (as well as supported program and map types, and a number of
+ other parameters). To do so, run **bpftool feature probe** (see
+ **bpftool-feature**\ (8) for details). Add the **unprivileged** keyword to
+ list features available to unprivileged users.
Compatibility between helper functions and program types can generally be found
in the files where helper functions are defined. Look for the **struct
@@ -338,6 +343,7 @@ SEE ALSO
========
**bpf**\ (2),
+**bpftool**\ (8),
**cgroups**\ (7),
**ip**\ (8),
**perf_event_open**\ (2),
@@ -398,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',
@@ -414,6 +421,13 @@ class PrinterHelpers(Printer):
'struct sk_reuseport_md',
'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',
@@ -437,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',
@@ -450,6 +465,13 @@ class PrinterHelpers(Printer):
'struct sk_reuseport_md',
'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',
@@ -467,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 = '''\
@@ -523,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 b83be177edf0..504d2e431c60 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
@@ -246,6 +246,8 @@ list_types(0) if ($list_types);
$fix = 1 if ($fix_inplace);
$check_orig = $check;
+die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
+
my $exit = 0;
my $perl_version_ok = 1;
@@ -269,11 +271,11 @@ if ($color =~ /^[01]$/) {
} elsif ($color =~ /^auto$/i) {
$color = (-t STDOUT);
} else {
- die "Invalid color mode: $color\n";
+ die "$P: Invalid color mode: $color\n";
}
# skip TAB size 1 to avoid additional checks on $tabsize - 1
-die "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
+die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
sub hash_save_array_words {
my ($hashRef, $arrayRef) = @_;
@@ -586,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) {
@@ -754,7 +758,7 @@ sub read_words {
next;
}
- $$wordsRef .= '|' if ($$wordsRef ne "");
+ $$wordsRef .= '|' if (defined $$wordsRef);
$$wordsRef .= $line;
}
close($file);
@@ -764,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)";
@@ -838,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*\(
)};
@@ -1060,6 +1065,7 @@ for my $filename (@ARGV) {
while (<$FILE>) {
chomp;
push(@rawlines, $_);
+ $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
}
close($FILE);
@@ -1676,8 +1682,16 @@ sub ctx_statement_level {
sub ctx_locate_comment {
my ($first_line, $end_line) = @_;
+ # If c99 comment on the current line, or the line before or after
+ my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
+ return $current_comment if (defined $current_comment);
+ ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
+ return $current_comment if (defined $current_comment);
+ ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
+ return $current_comment if (defined $current_comment);
+
# Catch a comment on the end of the line itself.
- my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
+ ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
return $current_comment if (defined $current_comment);
# Look through the context and try and figure out if there is a
@@ -2396,7 +2410,7 @@ sub process {
if ($rawline=~/^\+\+\+\s+(\S+)/) {
$setup_docs = 0;
- if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
+ if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
$setup_docs = 1;
}
#next;
@@ -2596,7 +2610,7 @@ sub process {
if (($last_binding_patch != -1) &&
($last_binding_patch ^ $is_binding_patch)) {
WARN("DT_SPLIT_BINDING_PATCH",
- "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
+ "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
}
}
@@ -2625,8 +2639,8 @@ sub process {
# Check if the commit log has what seems like a diff which can confuse patch
if ($in_commit_log && !$commit_log_has_diff &&
- (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
- $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
+ (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
+ $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
$line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
$line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
ERROR("DIFF_IN_COMMIT_MSG",
@@ -3031,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;
}
@@ -3062,14 +3072,43 @@ sub process {
#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
}
-# check for MAINTAINERS entries that don't have the right form
- if ($realfile =~ /^MAINTAINERS$/ &&
- $rawline =~ /^\+[A-Z]:/ &&
- $rawline !~ /^\+[A-Z]:\t\S/) {
- if (WARN("MAINTAINERS_STYLE",
- "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
- $fix) {
- $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
+# check MAINTAINERS entries
+ if ($realfile =~ /^MAINTAINERS$/) {
+# check MAINTAINERS entries for the right form
+ if ($rawline =~ /^\+[A-Z]:/ &&
+ $rawline !~ /^\+[A-Z]:\t\S/) {
+ if (WARN("MAINTAINERS_STYLE",
+ "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
+ }
+ }
+# check MAINTAINERS entries for the right ordering too
+ my $preferred_order = 'MRLSWQBCPTFXNK';
+ if ($rawline =~ /^\+[A-Z]:/ &&
+ $prevrawline =~ /^[\+ ][A-Z]:/) {
+ $rawline =~ /^\+([A-Z]):\s*(.*)/;
+ my $cur = $1;
+ my $curval = $2;
+ $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
+ my $prev = $1;
+ my $prevval = $2;
+ my $curindex = index($preferred_order, $cur);
+ my $previndex = index($preferred_order, $prev);
+ if ($curindex < 0) {
+ WARN("MAINTAINERS_STYLE",
+ "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
+ } else {
+ if ($previndex >= 0 && $curindex < $previndex) {
+ WARN("MAINTAINERS_STYLE",
+ "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
+ } elsif ((($prev eq 'F' && $cur eq 'F') ||
+ ($prev eq 'X' && $cur eq 'X')) &&
+ ($prevval cmp $curval) > 0) {
+ WARN("MAINTAINERS_STYLE",
+ "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
+ }
+ }
}
}
@@ -3271,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";
@@ -4203,6 +4278,17 @@ sub process {
"ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
}
+# ENOTSUPP is not a standard error code and should be avoided in new patches.
+# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
+# Similarly to ENOSYS warning a small number of false positives is expected.
+ if (!$file && $line =~ /\bENOTSUPP\b/) {
+ if (WARN("ENOTSUPP",
+ "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
+ }
+ }
+
# function brace can't be on same line, except for #defines of do while,
# or if closed on same line
if ($perl_version_ok &&
@@ -4970,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
@@ -5852,8 +5960,7 @@ sub process {
my $barriers = qr{
mb|
rmb|
- wmb|
- read_barrier_depends
+ wmb
}x;
my $barrier_stems = qr{
mb__before_atomic|
@@ -5894,10 +6001,12 @@ 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 for data_race without a comment.
+ if ($line =~ /\bdata_race\s*\(/) {
+ if (!ctx_has_comment($first_line, $linenr)) {
+ WARN("DATA_RACE",
+ "data_race without comment\n" . $herecurr);
+ }
}
# check of hardware specific defines
@@ -6271,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);
@@ -6291,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);
}
@@ -6337,7 +6441,7 @@ sub process {
if (!grep(/$name/, @setup_docs)) {
CHK("UNDOCUMENTED_SETUP",
- "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
+ "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
}
}
@@ -6419,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;
@@ -6429,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',
@@ -6569,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/checkstack.pl b/scripts/checkstack.pl
index 371bd17a4983..d2c38584ece6 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -34,8 +34,10 @@ use strict;
# $& (whole re) matches the complete objdump line with the stack growth
# $1 (first bracket) matches the dynamic amount of the stack growth
#
+# $sub: subroutine for special handling to check stack usage.
+#
# use anything else and feel the pain ;)
-my (@stack, $re, $dre, $x, $xs, $funcre);
+my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
{
my $arch = shift;
if ($arch eq "") {
@@ -43,6 +45,11 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
chomp($arch);
}
+ $min_stack = shift;
+ if ($min_stack eq "" || $min_stack !~ /^\d+$/) {
+ $min_stack = 100;
+ }
+
$x = "[0-9a-f]"; # hex character
$xs = "[0-9a-f ]"; # hex character or space
$funcre = qr/^$x* <(.*)>:$/;
@@ -53,7 +60,8 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
$dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o;
} elsif ($arch eq 'arm') {
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
- $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+ $re = qr/.*sub.*sp, sp, #([0-9]{1,4})/o;
+ $sub = \&arm_push_handling;
} elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) {
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
# or
@@ -107,13 +115,50 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
}
#
+# To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM,
+# if FRAME POINTER is enabled.
+# e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+#
+sub arm_push_handling {
+ my $regex = qr/.*push.*fp, ip, lr, pc}/o;
+ my $size = 0;
+ my $line_arg = shift;
+
+ if ($line_arg =~ m/$regex/) {
+ $size = $line_arg =~ tr/,//;
+ $size = ($size + 1) * 4;
+ }
+
+ return $size;
+}
+
+#
# main()
#
-my ($func, $file, $lastslash);
+my ($func, $file, $lastslash, $total_size, $addr, $intro);
+
+$total_size = 0;
while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
+ next if $line !~ m/^($xs*)/;
+ if ($total_size > $min_stack) {
+ push @stack, "$intro$total_size\n";
+ }
+
+ $addr = $1;
+ $addr =~ s/ /0/g;
+ $addr = "0x$addr";
+
+ $intro = "$addr $func [$file]:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+
+ $total_size = 0;
}
elsif ($line =~ m/(.*):\s*file format/) {
$file = $1;
@@ -134,37 +179,23 @@ while (my $line = <STDIN>) {
}
next if ($size > 0x10000000);
- next if $line !~ m/^($xs*)/;
- my $addr = $1;
- $addr =~ s/ /0/g;
- $addr = "0x$addr";
-
- my $intro = "$addr $func [$file]:";
- my $padlen = 56 - length($intro);
- while ($padlen > 0) {
- $intro .= ' ';
- $padlen -= 8;
- }
- next if ($size < 100);
- push @stack, "$intro$size\n";
+ $total_size += $size;
}
elsif (defined $dre && $line =~ m/$dre/) {
- my $size = "Dynamic ($1)";
+ my $size = $1;
- next if $line !~ m/^($xs*)/;
- my $addr = $1;
- $addr =~ s/ /0/g;
- $addr = "0x$addr";
+ $size = hex($size) if ($size =~ /^0x/);
+ $total_size += $size;
+ }
+ elsif (defined $sub) {
+ my $size = &$sub($line);
- my $intro = "$addr $func [$file]:";
- my $padlen = 56 - length($intro);
- while ($padlen > 0) {
- $intro .= ' ';
- $padlen -= 8;
- }
- push @stack, "$intro$size\n";
+ $total_size += $size;
}
}
+if ($total_size > $min_stack) {
+ push @stack, "$intro$total_size\n";
+}
# Sort output by size (last field)
print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
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/coccinelle/misc/newline_in_nl_msg.cocci b/scripts/coccinelle/misc/newline_in_nl_msg.cocci
new file mode 100644
index 000000000000..c175886e4015
--- /dev/null
+++ b/scripts/coccinelle/misc/newline_in_nl_msg.cocci
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Catch strings ending in newline with GENL_SET_ERR_MSG, NL_SET_ERR_MSG,
+/// NL_SET_ERR_MSG_MOD.
+///
+// Confidence: Very High
+// Copyright: (C) 2020 Intel Corporation
+// URL: http://coccinelle.lip6.fr/
+// Options: --no-includes --include-headers
+
+virtual context
+virtual org
+virtual report
+
+@r depends on context || org || report@
+expression e;
+constant m;
+position p;
+@@
+ \(GENL_SET_ERR_MSG\|NL_SET_ERR_MSG\|NL_SET_ERR_MSG_MOD\)(e,m@p)
+
+@script:python@
+m << r.m;
+@@
+
+if not m.endswith("\\n\""):
+ cocci.include_match(False)
+
+@r1 depends on r@
+identifier fname;
+expression r.e;
+constant r.m;
+position r.p;
+@@
+ fname(e,m@p)
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context && r@
+identifier r1.fname;
+expression r.e;
+constant r.m;
+@@
+* fname(e,m)
+
+//----------------------------------------------------------
+// For org mode
+//----------------------------------------------------------
+
+@script:python depends on org@
+fname << r1.fname;
+m << r.m;
+p << r.p;
+@@
+
+if m.endswith("\\n\""):
+ msg="WARNING avoid newline at end of message in %s" % (fname)
+ msg_safe=msg.replace("[","@(").replace("]",")")
+ coccilib.org.print_todo(p[0], msg_safe)
+
+//----------------------------------------------------------
+// For report mode
+//----------------------------------------------------------
+
+@script:python depends on report@
+fname << r1.fname;
+m << r.m;
+p << r.p;
+@@
+
+if m.endswith("\\n\""):
+ msg="WARNING avoid newline at end of message in %s" % (fname)
+ coccilib.report.print_report(p[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 ef85f8b7d4a7..4852bf44e913 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -1,16 +1,15 @@
# 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
dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
# Source files need to get at the userspace version of libfdt_env.h to compile
-HOST_EXTRACFLAGS := -I $(srctree)/$(src)/libfdt
+HOST_EXTRACFLAGS += -I $(srctree)/$(src)/libfdt
ifeq ($(shell pkg-config --exists yaml-0.1 2>/dev/null && echo yes),)
ifneq ($(CHECK_DT_BINDING)$(CHECK_DTBS),)
@@ -20,6 +19,9 @@ endif
HOST_EXTRACFLAGS += -DNO_YAML
else
dtc-objs += yamltree.o
+# To include <yaml.h> installed in a non-default path
+HOSTCFLAGS_yamltree.o := $(shell pkg-config --cflags yaml-0.1)
+# To link libyaml installed in a non-default path
HOSTLDLIBS_dtc := $(shell pkg-config yaml-0.1 --libs)
endif
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/extract-cert.c b/scripts/extract-cert.c
index b071bf476fea..3bc48c726c41 100644
--- a/scripts/extract-cert.c
+++ b/scripts/extract-cert.c
@@ -71,7 +71,7 @@ static void drain_openssl_errors(void)
static const char *key_pass;
static BIO *wb;
static char *cert_dst;
-int kbuild_verbose;
+static int kbuild_verbose;
static void write_cert(X509 *x509)
{
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index 013ba3a57669..ae19fb0243b9 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -8,7 +8,7 @@ config HAVE_GCC_PLUGINS
menuconfig GCC_PLUGINS
bool "GCC plugins"
depends on HAVE_GCC_PLUGINS
- depends on CC_IS_GCC && GCC_VERSION >= 40800
+ depends on CC_IS_GCC
depends on $(success,$(srctree)/scripts/gcc-plugin.sh $(CC))
default y
help
@@ -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 80f354289eeb..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 := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
-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/genksyms/keywords.c b/scripts/genksyms/keywords.c
index 7a85c4e21175..057c6cabad1d 100644
--- a/scripts/genksyms/keywords.c
+++ b/scripts/genksyms/keywords.c
@@ -25,9 +25,9 @@ static struct resword {
{ "__int128_t", BUILTIN_INT_KEYW },
{ "__uint128_t", BUILTIN_INT_KEYW },
- // According to rth, c99 defines "_Bool", __restrict", __restrict__", "restrict". KAO
+ // According to rth, c99 defines "_Bool", "__restrict", "__restrict__", "restrict". KAO
{ "_Bool", BOOL_KEYW },
- { "_restrict", RESTRICT_KEYW },
+ { "__restrict", RESTRICT_KEYW },
{ "__restrict__", RESTRICT_KEYW },
{ "restrict", RESTRICT_KEYW },
{ "asm", ASM_KEYW },
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 6cbcd1a3e113..484d2fbf5921 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -19,6 +19,7 @@ my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
use Cwd;
use File::Find;
+use File::Spec::Functions;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
@@ -57,7 +58,7 @@ my $status = 0;
my $letters = "";
my $keywords = 1;
my $sections = 0;
-my $file_emails = 0;
+my $email_file_emails = 0;
my $from_filename = 0;
my $pattern_depth = 0;
my $self_test = undef;
@@ -69,6 +70,12 @@ my $vcs_used = 0;
my $exit = 0;
+my @files = ();
+my @fixes = (); # If a patch description includes Fixes: lines
+my @range = ();
+my @keyword_tvi = ();
+my @file_emails = ();
+
my %commit_author_hash;
my %commit_signer_hash;
@@ -266,7 +273,7 @@ if (!GetOptions(
'pattern-depth=i' => \$pattern_depth,
'k|keywords!' => \$keywords,
'sections!' => \$sections,
- 'fe|file-emails!' => \$file_emails,
+ 'fe|file-emails!' => \$email_file_emails,
'f|file' => \$from_filename,
'find-maintainer-files' => \$find_maintainer_files,
'mpath|maintainer-path=s' => \$maintainer_path,
@@ -424,6 +431,22 @@ sub read_all_maintainer_files {
}
}
+sub maintainers_in_file {
+ my ($file) = @_;
+
+ return if ($file =~ m@\bMAINTAINERS$@);
+
+ if (-f $file && ($email_file_emails || $file =~ /\.yaml$/)) {
+ open(my $f, '<', $file)
+ or die "$P: Can't open $file: $!\n";
+ my $text = do { local($/) ; <$f> };
+ close($f);
+
+ my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
+ push(@file_emails, clean_file_emails(@poss_addr));
+ }
+}
+
#
# Read mail address map
#
@@ -504,18 +527,13 @@ sub read_mailmap {
## use the filenames on the command line or find the filenames in the patchfiles
-my @files = ();
-my @fixes = (); # If a patch description includes Fixes: lines
-my @range = ();
-my @keyword_tvi = ();
-my @file_emails = ();
-
if (!@ARGV) {
push(@ARGV, "&STDIN");
}
foreach my $file (@ARGV) {
if ($file ne "&STDIN") {
+ $file = canonpath($file);
##if $file is a directory and it lacks a trailing slash, add one
if ((-d $file)) {
$file =~ s@([^/])$@$1/@;
@@ -527,7 +545,7 @@ foreach my $file (@ARGV) {
$file =~ s/^\Q${cur_path}\E//; #strip any absolute path
$file =~ s/^\Q${lk_path}\E//; #or the path to the lk tree
push(@files, $file);
- if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
+ if ($file ne "MAINTAINERS" && -f $file && $keywords) {
open(my $f, '<', $file)
or die "$P: Can't open $file: $!\n";
my $text = do { local($/) ; <$f> };
@@ -539,10 +557,6 @@ foreach my $file (@ARGV) {
}
}
}
- if ($file_emails) {
- my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
- push(@file_emails, clean_file_emails(@poss_addr));
- }
}
} else {
my $file_cnt = @files;
@@ -923,6 +937,8 @@ sub get_maintainers {
print("\n");
}
}
+
+ maintainers_in_file($file);
}
if ($keywords) {
@@ -1835,7 +1851,7 @@ tm toggle maintainers
tg toggle git entries
tl toggle open list entries
ts toggle subscriber list entries
-f emails in file [$file_emails]
+f emails in file [$email_file_emails]
k keywords in file [$keywords]
r remove duplicates [$email_remove_duplicates]
p# pattern match depth [$pattern_depth]
@@ -1960,7 +1976,7 @@ EOT
bool_invert(\$email_git_all_signature_types);
$rerun = 1;
} elsif ($sel eq "f") {
- bool_invert(\$file_emails);
+ bool_invert(\$email_file_emails);
$rerun = 1;
} elsif ($sel eq "r") {
bool_invert(\$email_remove_duplicates);
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index a07668a5c36b..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
@@ -64,7 +64,7 @@ configs=$(sed -e '
d
' $OUTFILE)
-# The entries in the following list are not warned.
+# The entries in the following list do not result in an error.
# Please do not add a new entry. This list is only for existing ones.
# The list will be reduced gradually, and deleted eventually. (hopefully)
#
@@ -81,35 +81,31 @@ arch/ia64/include/uapi/asm/cmpxchg.h:CONFIG_IA64_DEBUG_CMPXCHG
arch/m68k/include/uapi/asm/ptrace.h:CONFIG_COLDFIRE
arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_NO
arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_SUPPORT
-arch/sh/include/uapi/asm/ptrace.h:CONFIG_CPU_SH5
-arch/sh/include/uapi/asm/sigcontext.h:CONFIG_CPU_SH5
-arch/sh/include/uapi/asm/stat.h:CONFIG_CPU_SH5
arch/x86/include/uapi/asm/auxvec.h:CONFIG_IA32_EMULATION
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
do
- warn=1
+ leak_error=1
for ignore in $config_leak_ignores
do
if echo "$INFILE:$c" | grep -q "$ignore$"; then
- warn=
+ leak_error=
break
fi
done
- if [ "$warn" = 1 ]; then
- echo "warning: $INFILE: leak $c to user-space" >&2
+ if [ "$leak_error" = 1 ]; then
+ echo "error: $INFILE: leak $c to user-space" >&2
+ exit 1
fi
done
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 6dc3078649fa..7ecd2ccba531 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -82,6 +82,7 @@ static char *sym_name(const struct sym_entry *s)
static bool is_ignored_symbol(const char *name, char type)
{
+ /* Symbol names that exactly match to the following are ignored.*/
static const char * const ignored_symbols[] = {
/*
* Symbols which vary between passes. Passes 1 and 2 must have
@@ -104,14 +105,17 @@ static bool is_ignored_symbol(const char *name, char type)
NULL
};
+ /* Symbol names that begin with the following are ignored.*/
static const char * const ignored_prefixes[] = {
"$", /* local symbols for ARM, MIPS, etc. */
".LASANPC", /* s390 kasan local symbols */
"__crc_", /* modversions */
"__efistub_", /* arm64 EFI stub namespace */
+ "__kvm_nvhe_", /* arm64 non-VHE KVM namespace */
NULL
};
+ /* Symbol names that end with the following are ignored.*/
static const char * const ignored_suffixes[] = {
"_from_arm", /* arm */
"_from_thumb", /* arm */
@@ -119,9 +123,15 @@ static bool is_ignored_symbol(const char *name, char type)
NULL
};
+ /* Symbol names that contain the following are ignored.*/
+ static const char * const ignored_matches[] = {
+ ".long_branch.", /* ppc stub */
+ ".plt_branch.", /* ppc stub */
+ NULL
+ };
+
const char * const *p;
- /* Exclude symbols which vary between passes. */
for (p = ignored_symbols; *p; p++)
if (!strcmp(name, *p))
return true;
@@ -137,6 +147,11 @@ static bool is_ignored_symbol(const char *name, char type)
return true;
}
+ for (p = ignored_matches; *p; p++) {
+ if (strstr(name, *p))
+ return true;
+ }
+
if (type == 'U' || type == 'u')
return true;
/* exclude debugging symbols */
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 c9d0a4a8efb3..52b59bf9efe4 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -96,11 +96,13 @@ configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/c
PHONY += kvmconfig
kvmconfig: kvm_guest.config
- @:
+ @echo >&2 "WARNING: 'make $@' will be removed after Linux 5.10"
+ @echo >&2 " Please use 'make $<' instead."
PHONY += xenconfig
xenconfig: xen.config
- @:
+ @echo >&2 "WARNING: 'make $@' will be removed after Linux 5.10"
+ @echo >&2 " Please use 'make $<' instead."
PHONY += tinyconfig
tinyconfig:
@@ -123,7 +125,9 @@ help:
@echo ' gconfig - Update current config utilising a GTK+ based front-end'
@echo ' oldconfig - Update current config utilising a provided .config as base'
@echo ' localmodconfig - Update current config disabling modules not loaded'
+ @echo ' except those preserved by LMC_KEEP environment variable'
@echo ' localyesconfig - Update current config converting local mods to core'
+ @echo ' except those preserved by LMC_KEEP environment variable'
@echo ' defconfig - New config with default from ARCH supplied defconfig'
@echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
@echo ' allnoconfig - New config where all options are answered with no'
@@ -137,9 +141,6 @@ help:
@echo ' helpnewconfig - List new options and help text'
@echo ' olddefconfig - Same as oldconfig but sets new symbols to their'
@echo ' default value without prompting'
- @echo ' kvmconfig - Enable additional options for kvm guest kernel support'
- @echo ' xenconfig - Enable additional options for xen dom0 and guest kernel'
- @echo ' support'
@echo ' tinyconfig - Configure the tiniest possible kernel'
@echo ' testconfig - Run Kconfig unit tests (requires python3 and pytest)'
@@ -180,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/lkc.h b/scripts/kconfig/lkc.h
index d4ca8297364f..8454649b17bd 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -66,23 +66,6 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
fprintf(stderr, "Error in writing or end of file.\n");
}
-/* menu.c */
-void _menu_init(void);
-void menu_warn(struct menu *menu, const char *fmt, ...);
-struct menu *menu_add_menu(void);
-void menu_end_menu(void);
-void menu_add_entry(struct symbol *sym);
-void menu_add_dep(struct expr *dep);
-void menu_add_visibility(struct expr *dep);
-struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
-void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
-void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
-void menu_add_option_modules(void);
-void menu_add_option_defconfig_list(void);
-void menu_add_option_allnoconfig_y(void);
-void menu_finalize(struct menu *parent);
-void menu_set_type(int type);
-
/* util.c */
struct file *file_lookup(const char *name);
void *xmalloc(size_t size);
@@ -109,6 +92,36 @@ void str_append(struct gstr *gs, const char *s);
void str_printf(struct gstr *gs, const char *fmt, ...);
const char *str_get(struct gstr *gs);
+/* menu.c */
+void _menu_init(void);
+void menu_warn(struct menu *menu, const char *fmt, ...);
+struct menu *menu_add_menu(void);
+void menu_end_menu(void);
+void menu_add_entry(struct symbol *sym);
+void menu_add_dep(struct expr *dep);
+void menu_add_visibility(struct expr *dep);
+struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
+void menu_add_option_modules(void);
+void menu_add_option_defconfig_list(void);
+void menu_add_option_allnoconfig_y(void);
+void menu_finalize(struct menu *parent);
+void menu_set_type(int type);
+
+extern struct menu rootmenu;
+
+bool menu_is_empty(struct menu *menu);
+bool menu_is_visible(struct menu *menu);
+bool menu_has_prompt(struct menu *menu);
+const char *menu_get_prompt(struct menu *menu);
+struct menu *menu_get_root_menu(struct menu *menu);
+struct menu *menu_get_parent_menu(struct menu *menu);
+bool menu_has_help(struct menu *menu);
+const char *menu_get_help(struct menu *menu);
+struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
+void menu_get_ext_help(struct menu *menu, struct gstr *help);
+
/* symbol.c */
void sym_clear_all_valid(void);
struct symbol *sym_choice_default(struct symbol *sym);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index f9ab98238aef..9e81be33c40f 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -12,20 +12,6 @@ bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(void));
void conf_set_message_callback(void (*fn)(const char *s));
-/* menu.c */
-extern struct menu rootmenu;
-
-bool menu_is_empty(struct menu *menu);
-bool menu_is_visible(struct menu *menu);
-bool menu_has_prompt(struct menu *menu);
-const char * menu_get_prompt(struct menu *menu);
-struct menu * menu_get_root_menu(struct menu *menu);
-struct menu * menu_get_parent_menu(struct menu *menu);
-bool menu_has_help(struct menu *menu);
-const char * menu_get_help(struct menu *menu);
-struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
-void menu_get_ext_help(struct menu *menu, struct gstr *help);
-
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index e436ba44c9c5..a5fbd6ccc006 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -65,7 +65,8 @@ void menu_add_entry(struct symbol *sym)
struct menu *menu_add_menu(void)
{
last_entry_ptr = &current_entry->list;
- return current_menu = current_entry;
+ current_menu = current_entry;
+ return current_menu;
}
void menu_end_menu(void)
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index daf1c1506ec4..e0f965529166 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -755,7 +755,6 @@ static void build_conf(struct menu *menu)
switch (ptype) {
case P_MENU:
child_count++;
- prompt = prompt;
if (single_menu_mode) {
item_make(menu, 'm',
"%s%*c%s",
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 708b6c4b13ca..190f1117f35a 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -119,20 +119,24 @@ mainmenu_stmt: T_MAINMENU T_WORD_QUOTE T_EOL
stmt_list:
/* empty */
- | stmt_list common_stmt
+ | stmt_list assignment_stmt
| stmt_list choice_stmt
+ | stmt_list comment_stmt
+ | stmt_list config_stmt
+ | stmt_list if_stmt
| stmt_list menu_stmt
+ | stmt_list menuconfig_stmt
+ | stmt_list source_stmt
| stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
| stmt_list error T_EOL { zconf_error("invalid statement"); }
;
-common_stmt:
- if_stmt
- | comment_stmt
- | config_stmt
- | menuconfig_stmt
- | source_stmt
- | assignment_stmt
+stmt_list_in_choice:
+ /* empty */
+ | stmt_list_in_choice comment_stmt
+ | stmt_list_in_choice config_stmt
+ | stmt_list_in_choice if_stmt_in_choice
+ | stmt_list_in_choice error T_EOL { zconf_error("invalid statement"); }
;
/* config/menuconfig entry */
@@ -254,7 +258,7 @@ choice_end: end
}
};
-choice_stmt: choice_entry choice_block choice_end
+choice_stmt: choice_entry stmt_list_in_choice choice_end
;
choice_option_list:
@@ -305,11 +309,6 @@ default:
| T_DEF_BOOL { $$ = S_BOOLEAN; }
| T_DEF_TRISTATE { $$ = S_TRISTATE; }
-choice_block:
- /* empty */
- | choice_block common_stmt
-;
-
/* if entry */
if_entry: T_IF expr T_EOL
@@ -331,6 +330,9 @@ if_end: end
if_stmt: if_entry stmt_list if_end
;
+if_stmt_in_choice: if_entry stmt_list_in_choice if_end
+;
+
/* menu entry */
menu: T_MENU T_WORD_QUOTE T_EOL
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index c0ac8f7b5f1a..8ce624a3b54b 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(setChecked(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(setChecked(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(setChecked(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());
@@ -1029,6 +1012,16 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
configSettings->endGroup();
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
}
+
+ contextMenu = createStandardContextMenu();
+ QAction *action = new QAction("Show Debug Info", contextMenu);
+
+ action->setCheckable(true);
+ connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
+ connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
+ action->setChecked(showDebug());
+ contextMenu->addSeparator();
+ contextMenu->addAction(action);
}
void ConfigInfoView::saveSettings(void)
@@ -1083,108 +1076,119 @@ void ConfigInfoView::symbolInfo(void)
void ConfigInfoView::menuInfo(void)
{
struct symbol* sym;
- QString head, debug, help;
+ QString info;
+ QTextStream stream(&info);
sym = _menu->sym;
if (sym) {
if (_menu->prompt) {
- head += "<big><b>";
- head += print_filter(_menu->prompt->text);
- head += "</b></big>";
+ stream << "<big><b>";
+ stream << print_filter(_menu->prompt->text);
+ stream << "</b></big>";
if (sym->name) {
- head += " (";
+ stream << " (";
if (showDebug())
- head += QString().sprintf("<a href=\"s%p\">", sym);
- head += print_filter(sym->name);
+ stream << "<a href=\"s" << sym->name << "\">";
+ stream << print_filter(sym->name);
if (showDebug())
- head += "</a>";
- head += ")";
+ stream << "</a>";
+ stream << ")";
}
} else if (sym->name) {
- head += "<big><b>";
+ stream << "<big><b>";
if (showDebug())
- head += QString().sprintf("<a href=\"s%p\">", sym);
- head += print_filter(sym->name);
+ stream << "<a href=\"s" << sym->name << "\">";
+ stream << print_filter(sym->name);
if (showDebug())
- head += "</a>";
- head += "</b></big>";
+ stream << "</a>";
+ stream << "</b></big>";
}
- head += "<br><br>";
+ stream << "<br><br>";
if (showDebug())
- debug = debug_info(sym);
+ stream << debug_info(sym);
struct gstr help_gstr = str_new();
+
menu_get_ext_help(_menu, &help_gstr);
- help = print_filter(str_get(&help_gstr));
+ stream << print_filter(str_get(&help_gstr));
str_free(&help_gstr);
} else if (_menu->prompt) {
- head += "<big><b>";
- head += print_filter(_menu->prompt->text);
- head += "</b></big><br><br>";
+ stream << "<big><b>";
+ stream << print_filter(_menu->prompt->text);
+ stream << "</b></big><br><br>";
if (showDebug()) {
if (_menu->prompt->visible.expr) {
- debug += "&nbsp;&nbsp;dep: ";
- expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
- debug += "<br><br>";
+ stream << "&nbsp;&nbsp;dep: ";
+ expr_print(_menu->prompt->visible.expr,
+ expr_print_help, &stream, E_NONE);
+ stream << "<br><br>";
}
+
+ stream << "defined at " << _menu->file->name << ":"
+ << _menu->lineno << "<br><br>";
}
}
- if (showDebug())
- debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
- setText(head + debug + help);
+ setText(info);
}
QString ConfigInfoView::debug_info(struct symbol *sym)
{
QString debug;
+ QTextStream stream(&debug);
- debug += "type: ";
- debug += print_filter(sym_type_name(sym->type));
+ stream << "type: ";
+ stream << print_filter(sym_type_name(sym->type));
if (sym_is_choice(sym))
- debug += " (choice)";
+ stream << " (choice)";
debug += "<br>";
if (sym->rev_dep.expr) {
- debug += "reverse dep: ";
- expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
- debug += "<br>";
+ stream << "reverse dep: ";
+ expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
+ stream << "<br>";
}
for (struct property *prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_PROMPT:
case P_MENU:
- debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
- debug += print_filter(prop->text);
- debug += "</a><br>";
+ stream << "prompt: <a href=\"m" << sym->name << "\">";
+ stream << print_filter(prop->text);
+ stream << "</a><br>";
break;
case P_DEFAULT:
case P_SELECT:
case P_RANGE:
- debug += prop_get_type_name(prop->type);
- debug += ": ";
- expr_print(prop->expr, expr_print_help, &debug, E_NONE);
- debug += "<br>";
+ case P_COMMENT:
+ case P_IMPLY:
+ case P_SYMBOL:
+ stream << prop_get_type_name(prop->type);
+ stream << ": ";
+ expr_print(prop->expr, expr_print_help,
+ &stream, E_NONE);
+ stream << "<br>";
break;
case P_CHOICE:
if (sym_is_choice(sym)) {
- debug += "choice: ";
- expr_print(prop->expr, expr_print_help, &debug, E_NONE);
- debug += "<br>";
+ stream << "choice: ";
+ expr_print(prop->expr, expr_print_help,
+ &stream, E_NONE);
+ stream << "<br>";
}
break;
default:
- debug += "unknown property: ";
- debug += prop_get_type_name(prop->type);
- debug += "<br>";
+ stream << "unknown property: ";
+ stream << prop_get_type_name(prop->type);
+ stream << "<br>";
}
if (prop->visible.expr) {
- debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
- expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
- debug += "<br>";
+ stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
+ expr_print(prop->visible.expr, expr_print_help,
+ &stream, E_NONE);
+ stream << "<br>";
}
}
- debug += "<br>";
+ stream << "<br>";
return debug;
}
@@ -1222,46 +1226,81 @@ QString ConfigInfoView::print_filter(const QString &str)
void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
{
- QString* text = reinterpret_cast<QString*>(data);
- QString str2 = print_filter(str);
+ QTextStream *stream = reinterpret_cast<QTextStream *>(data);
if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
- *text += QString().sprintf("<a href=\"s%p\">", sym);
- *text += str2;
- *text += "</a>";
- } else
- *text += str2;
+ *stream << "<a href=\"s" << sym->name << "\">";
+ *stream << print_filter(str);
+ *stream << "</a>";
+ } else {
+ *stream << print_filter(str);
+ }
}
-QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
+void ConfigInfoView::clicked(const QUrl &url)
{
- QMenu* popup = Parent::createStandardContextMenu(pos);
- QAction* action = new QAction("Show Debug Info", popup);
+ QByteArray str = url.toEncoded();
+ const std::size_t count = str.size();
+ char *data = new char[count + 1];
+ struct symbol **result;
+ struct menu *m = NULL;
- action->setCheckable(true);
- connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
- connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
- action->setChecked(showDebug());
- popup->addSeparator();
- popup->addAction(action);
- return popup;
+ if (count < 1) {
+ 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) {
+ 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;
}
-void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
+void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
{
- Parent::contextMenuEvent(e);
+ contextMenu->popup(event->globalPos());
+ event->accept();
}
-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 +1315,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 +1325,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 +1383,6 @@ void ConfigSearchWindow::search(void)
ConfigMainWindow::ConfigMainWindow(void)
: searchWindow(0)
{
- QMenuBar* menu;
bool ok = true;
QVariant x, y;
int width, height;
@@ -1367,6 +1403,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 +1442,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 +1491,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 +1514,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 +1524,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 +1652,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 +1683,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 +1715,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 +1731,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 +1746,8 @@ void ConfigMainWindow::showSingleView(void)
fullViewAction->setEnabled(true);
fullViewAction->setChecked(false);
+ backAction->setEnabled(true);
+
menuView->hide();
menuList->setRootMenu(0);
configList->mode = singleMode;
@@ -1737,6 +1767,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 +1792,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..f97376a8123f 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;
@@ -30,7 +30,7 @@ public:
};
enum colIdx {
- promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
+ promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx
};
enum listMode {
singleMode, menuMode, symbolMode, fullMode, listMode
@@ -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,15 +210,12 @@ public:
static ConfigView* viewList;
ConfigView* nextView;
-
- static QAction *showNormalAction;
- static QAction *showAllAction;
- static QAction *showPromptAction;
};
class ConfigInfoView : public QTextBrowser {
Q_OBJECT
typedef class QTextBrowser Parent;
+ QMenu *contextMenu;
public:
ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; }
@@ -250,6 +224,7 @@ public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
void setShowDebug(bool);
+ void clicked (const QUrl &url);
signals:
void showDebugChanged(bool);
@@ -261,8 +236,7 @@ protected:
QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str);
- QMenu *createStandardContextMenu(const QPoint & pos);
- void contextMenuEvent(QContextMenuEvent *e);
+ void contextMenuEvent(QContextMenuEvent *event);
struct symbol *sym;
struct menu *_menu;
@@ -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/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index e2f8504f5a2d..1c78ba49ca99 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -143,6 +143,7 @@ my %depends;
my %selects;
my %prompts;
my %objects;
+my %config2kfile;
my $var;
my $iflevel = 0;
my @ifdeps;
@@ -201,6 +202,7 @@ sub read_kconfig {
if (/^\s*(menu)?config\s+(\S+)\s*$/) {
$state = "NEW";
$config = $2;
+ $config2kfile{"CONFIG_$config"} = $kconfig;
# Add depends for 'if' nesting
for (my $i = 0; $i < $iflevel; $i++) {
@@ -591,6 +593,23 @@ while ($repeat) {
}
my %setconfigs;
+my @preserved_kconfigs;
+if (defined($ENV{'LMC_KEEP'})) {
+ @preserved_kconfigs = split(/:/,$ENV{LMC_KEEP});
+}
+
+sub in_preserved_kconfigs {
+ my $kconfig = $config2kfile{$_[0]};
+ if (!defined($kconfig)) {
+ return 0;
+ }
+ foreach my $excl (@preserved_kconfigs) {
+ if($kconfig =~ /^$excl/) {
+ return 1;
+ }
+ }
+ return 0;
+}
# Finally, read the .config file and turn off any module enabled that
# we could not find a reason to keep enabled.
@@ -644,6 +663,11 @@ foreach my $line (@config_file) {
}
if (/^(CONFIG.*)=(m|y)/) {
+ if (in_preserved_kconfigs($1)) {
+ dprint "Preserve config $1";
+ print;
+ next;
+ }
if (defined($configs{$1})) {
if ($localyesconfig) {
$setconfigs{$1} = 'y';
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 3dc81397d003..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)
{
@@ -831,7 +837,7 @@ struct symbol *sym_lookup(const char *name, int flags)
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
- symbol->flags |= flags;
+ symbol->flags = flags;
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
diff --git a/scripts/kconfig/tests/rand_nested_choice/Kconfig b/scripts/kconfig/tests/rand_nested_choice/Kconfig
deleted file mode 100644
index 8350de7f732b..000000000000
--- a/scripts/kconfig/tests/rand_nested_choice/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-choice
- prompt "choice"
-
-config A
- bool "A"
-
-config B
- bool "B"
-
-if B
-choice
- prompt "sub choice"
-
-config C
- bool "C"
-
-config D
- bool "D"
-
-if D
-choice
- prompt "subsub choice"
-
-config E
- bool "E"
-
-endchoice
-endif # D
-
-endchoice
-endif # B
-
-endchoice
diff --git a/scripts/kconfig/tests/rand_nested_choice/__init__.py b/scripts/kconfig/tests/rand_nested_choice/__init__.py
deleted file mode 100644
index 9e4b2db53581..000000000000
--- a/scripts/kconfig/tests/rand_nested_choice/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-"""
-Set random values recursively in nested choices.
-
-Kconfig can create a choice-in-choice structure by using 'if' statement.
-randconfig should correctly set random choice values.
-
-Related Linux commit: 3b9a19e08960e5cdad5253998637653e592a3c29
-"""
-
-
-def test(conf):
- for i in range(20):
- assert conf.randconfig() == 0
- assert (conf.config_contains('expected_stdout0') or
- conf.config_contains('expected_stdout1') or
- conf.config_contains('expected_stdout2'))
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
deleted file mode 100644
index 05450f3d4eb5..000000000000
--- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout0
+++ /dev/null
@@ -1,2 +0,0 @@
-CONFIG_A=y
-# CONFIG_B is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
deleted file mode 100644
index 37ab29584157..000000000000
--- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout1
+++ /dev/null
@@ -1,4 +0,0 @@
-# CONFIG_A is not set
-CONFIG_B=y
-CONFIG_C=y
-# CONFIG_D is not set
diff --git a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2 b/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
deleted file mode 100644
index 849ff47e9848..000000000000
--- a/scripts/kconfig/tests/rand_nested_choice/expected_stdout2
+++ /dev/null
@@ -1,5 +0,0 @@
-# CONFIG_A is not set
-CONFIG_B=y
-# CONFIG_C is not set
-CONFIG_D=y
-CONFIG_E=y
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index f746ca8fa403..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;
@@ -213,7 +214,9 @@ my $type_constant = '\b``([^\`]+)``\b';
my $type_constant2 = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
+my $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params
+my $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params
my $type_env = '(\$\w+)';
my $type_enum = '\&(enum\s*([_\w]+))';
my $type_struct = '\&(struct\s*([_\w]+))';
@@ -236,6 +239,7 @@ my @highlights_man = (
[$type_typedef, "\\\\fI\$1\\\\fP"],
[$type_union, "\\\\fI\$1\\\\fP"],
[$type_param, "\\\\fI\$1\\\\fP"],
+ [$type_param_ref, "\\\\fI\$1\$2\\\\fP"],
[$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
[$type_fallback, "\\\\fI\$1\\\\fP"]
);
@@ -249,6 +253,7 @@ my @highlights_rst = (
[$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
[$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
[$type_fp_param, "**\$1\\\\(\\\\)**"],
+ [$type_fp_param2, "**\$1\\\\(\\\\)**"],
[$type_func, "\$1()"],
[$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
[$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
@@ -256,7 +261,7 @@ my @highlights_rst = (
[$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
# in rst this can refer to any type
[$type_fallback, "\\:c\\:type\\:`\$1`"],
- [$type_param, "**\$1**"]
+ [$type_param_ref, "**\$1\$2**"]
);
my $blankline_rst = "\n";
@@ -269,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;
@@ -315,9 +321,21 @@ 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:
-# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
+# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
# We keep track of number of generated entries and generate a dummy
# if needs be to ensure the expanded template can be postprocessed
# into html.
@@ -327,13 +345,14 @@ my $lineprefix="";
# Parser states
use constant {
- STATE_NORMAL => 0, # normal code
- STATE_NAME => 1, # looking for function name
- STATE_BODY_MAYBE => 2, # body - or maybe more description
- STATE_BODY => 3, # the body of the comment
- STATE_PROTO => 4, # scanning prototype
- STATE_DOCBLOCK => 5, # documentation block
- STATE_INLINE => 6, # gathering documentation outside main block
+ STATE_NORMAL => 0, # normal code
+ STATE_NAME => 1, # looking for function name
+ STATE_BODY_MAYBE => 2, # body - or maybe more description
+ STATE_BODY => 3, # the body of the comment
+ STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line
+ STATE_PROTO => 5, # scanning prototype
+ STATE_DOCBLOCK => 6, # documentation block
+ STATE_INLINE => 7, # gathering doc outside main block
};
my $state;
my $in_doc_sect;
@@ -428,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') {
@@ -1078,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;
@@ -1764,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();
}
@@ -1953,6 +1981,12 @@ sub process_body($$) {
}
}
+ if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
+ dump_section($file, $section, $contents);
+ $section = $section_default;
+ $contents = "";
+ }
+
if (/$doc_sect/i) { # case insensitive for supported section names
$newsection = $1;
$newcontents = $2;
@@ -2006,18 +2040,21 @@ sub process_body($$) {
$state = STATE_PROTO;
$brcount = 0;
} elsif (/$doc_content/) {
- # miguel-style comment kludge, look for blank lines after
- # @parameter line to signify start of description
if ($1 eq "") {
- if ($section =~ m/^@/ || $section eq $section_context) {
+ if ($section eq $section_context) {
dump_section($file, $section, $contents);
$section = $section_default;
$contents = "";
$new_start_line = $.;
+ $state = STATE_BODY;
} else {
+ if ($section ne $section_default) {
+ $state = STATE_BODY_WITH_BLANK_LINE;
+ } else {
+ $state = STATE_BODY;
+ }
$contents .= "\n";
}
- $state = STATE_BODY;
} elsif ($state == STATE_BODY_MAYBE) {
# Continued declaration purpose
chomp($declaration_purpose);
@@ -2169,7 +2206,8 @@ sub process_file($) {
process_normal();
} elsif ($state == STATE_NAME) {
process_name($file, $_);
- } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) {
+ } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE ||
+ $state == STATE_BODY_WITH_BLANK_LINE) {
process_body($file, $_);
} elsif ($state == STATE_INLINE) { # scanning for inline parameters
process_inline($file, $_);
@@ -2240,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 d09ab4afbda4..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()
@@ -55,6 +59,29 @@ modpost_link()
${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
}
+objtool_link()
+{
+ local objtoolopt;
+
+ if [ -n "${CONFIG_VMLINUX_VALIDATION}" ]; then
+ objtoolopt="check"
+ if [ -z "${CONFIG_FRAME_POINTER}" ]; then
+ objtoolopt="${objtoolopt} --no-fp"
+ fi
+ if [ -n "${CONFIG_GCOV_KERNEL}" ]; then
+ objtoolopt="${objtoolopt} --no-unreachable"
+ fi
+ if [ -n "${CONFIG_RETPOLINE}" ]; then
+ objtoolopt="${objtoolopt} --retpoline"
+ fi
+ if [ -n "${CONFIG_X86_SMAP}" ]; then
+ objtoolopt="${objtoolopt} --uaccess"
+ fi
+ info OBJTOOL ${1}
+ tools/objtool/objtool ${objtoolopt} ${1}
+ fi
+}
+
# Link of vmlinux
# ${1} - output file
# ${2}, ${3}, ... - optional extra .o files
@@ -120,8 +147,8 @@ gen_btf()
fi
pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
- if [ "${pahole_ver}" -lt "113" ]; then
- echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13"
+ if [ "${pahole_ver}" -lt "116" ]; then
+ echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
return 1
fi
@@ -218,8 +245,6 @@ on_signals()
}
trap on_signals HUP INT QUIT TERM
-#
-#
# Use "make V=1" to debug this script
case "${KBUILD_VERBOSE}" in
*1*)
@@ -251,6 +276,7 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
#link vmlinux.o
info LD vmlinux.o
modpost_link vmlinux.o
+objtool_link vmlinux.o
# modpost vmlinux.o to check for section mismatches
${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
@@ -314,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/mkcompile_h b/scripts/mkcompile_h
index 5b80a4699740..baf3ab8d9d49 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -6,7 +6,7 @@ ARCH=$2
SMP=$3
PREEMPT=$4
PREEMPT_RT=$5
-CC=$6
+CC_VERSION="$6"
LD=$7
vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; }
@@ -62,7 +62,6 @@ UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)"
printf '#define LINUX_COMPILE_BY "%s"\n' "$LINUX_COMPILE_BY"
echo \#define LINUX_COMPILE_HOST \"$LINUX_COMPILE_HOST\"
- CC_VERSION=$($CC -v 2>&1 | grep ' version ' | sed 's/[[:space:]]*$//')
LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \
| sed 's/[[:space:]]*$//')
printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION"
diff --git a/scripts/mksysmap b/scripts/mksysmap
index a35acc0d0b82..9aa23d15862a 100755
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -41,4 +41,4 @@
# so we just ignore them to let readprofile continue to work.
# (At least sparc64 has __crc_ in the middle).
-$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( .L\)' > $2
+$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2
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 02d5d79da284..2417dd1dee33 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -954,6 +954,8 @@ static const struct dmifield {
{ "bvn", DMI_BIOS_VENDOR },
{ "bvr", DMI_BIOS_VERSION },
{ "bd", DMI_BIOS_DATE },
+ { "br", DMI_BIOS_RELEASE },
+ { "efr", DMI_EC_FIRMWARE_RELEASE },
{ "svn", DMI_SYS_VENDOR },
{ "pn", DMI_PRODUCT_NAME },
{ "pvr", DMI_PRODUCT_VERSION },
@@ -1256,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 5c3c50c5ec52..69341b36f271 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -30,8 +30,6 @@ static int have_vmlinux = 0;
static int all_versions = 0;
/* If we are modposting external module set to 1 */
static int external_module = 0;
-/* Warn about section mismatch in vmlinux if set to 1 */
-static int vmlinux_section_warnings = 1;
/* Only warn about unresolved symbols */
static int warn_unresolved = 0;
/* How a symbol is exported */
@@ -90,26 +88,70 @@ static inline bool strends(const char *str, const char *postfix)
return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
}
-static int is_vmlinux(const char *modname)
+void *do_nofail(void *ptr, const char *expr)
{
- const char *myname;
+ if (!ptr)
+ fatal("Memory allocation failure: %s.\n", expr);
- myname = strrchr(modname, '/');
- if (myname)
- myname++;
- else
- myname = modname;
+ return ptr;
+}
+
+char *read_text_file(const char *filename)
+{
+ struct stat st;
+ size_t nbytes;
+ int fd;
+ char *buf;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ perror(filename);
+ exit(1);
+ }
- return (strcmp(myname, "vmlinux") == 0) ||
- (strcmp(myname, "vmlinux.o") == 0);
+ if (fstat(fd, &st) < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ buf = NOFAIL(malloc(st.st_size + 1));
+
+ nbytes = st.st_size;
+
+ while (nbytes) {
+ ssize_t bytes_read;
+
+ bytes_read = read(fd, buf, nbytes);
+ if (bytes_read < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ nbytes -= bytes_read;
+ }
+ buf[st.st_size] = '\0';
+
+ close(fd);
+
+ return buf;
}
-void *do_nofail(void *ptr, const char *expr)
+char *get_line(char **stringp)
{
- if (!ptr)
- fatal("Memory allocation failure: %s.\n", expr);
+ char *orig = *stringp, *next;
- return ptr;
+ /* do not return the unwanted extra line at EOF */
+ if (!orig || *orig == '\0')
+ return NULL;
+
+ /* 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 */
@@ -128,24 +170,20 @@ static struct module *find_module(const char *modname)
static struct module *new_module(const char *modname)
{
struct module *mod;
- char *p;
- mod = NOFAIL(malloc(sizeof(*mod)));
+ mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
memset(mod, 0, sizeof(*mod));
- p = NOFAIL(strdup(modname));
-
- /* strip trailing .o */
- if (strends(p, ".o")) {
- p[strlen(p) - 2] = '\0';
- mod->is_dot_o = 1;
- }
/* add to list */
- mod->name = p;
+ strcpy(mod->name, modname);
+ mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
mod->gpl_compatible = -1;
mod->next = modules;
modules = mod;
+ if (mod->is_vmlinux)
+ have_vmlinux = 1;
+
return mod;
}
@@ -161,12 +199,9 @@ struct symbol {
int crc_valid;
char *namespace;
unsigned int weak:1;
- unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
- unsigned int kernel:1; /* 1 if symbol is from kernel
- * (only for external modules) **/
unsigned int is_static:1; /* 1 if symbol is not global */
enum export export; /* Type of export */
- char name[0];
+ char name[];
};
static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
@@ -288,29 +323,32 @@ static enum export export_no(const char *s)
return export_unknown;
}
-static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
+static void *sym_get_data_by_offset(const struct elf_info *info,
+ unsigned int secindex, unsigned long offset)
{
- return (void *)elf->hdr +
- elf->sechdrs[elf->secindex_strings].sh_offset +
- sechdr->sh_name;
-}
+ Elf_Shdr *sechdr = &info->sechdrs[secindex];
-static const char *sec_name(struct elf_info *elf, int secindex)
-{
- return sech_name(elf, &elf->sechdrs[secindex]);
+ if (info->hdr->e_type != ET_REL)
+ offset -= sechdr->sh_addr;
+
+ return (void *)info->hdr + sechdr->sh_offset + offset;
}
static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
{
- unsigned int secindex = get_secindex(info, sym);
- Elf_Shdr *sechdr = &info->sechdrs[secindex];
- unsigned long offset;
+ return sym_get_data_by_offset(info, get_secindex(info, sym),
+ sym->st_value);
+}
- offset = sym->st_value;
- if (info->hdr->e_type != ET_REL)
- offset -= sechdr->sh_addr;
+static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
+{
+ return sym_get_data_by_offset(info, info->secindex_strings,
+ sechdr->sh_name);
+}
- return (void *)info->hdr + sechdr->sh_offset + offset;
+static const char *sec_name(const struct elf_info *info, int secindex)
+{
+ return sech_name(info, &info->sechdrs[secindex]);
}
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
@@ -386,17 +424,15 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
if (!s) {
s = new_symbol(name, mod, export);
- } else if (!external_module || is_vmlinux(s->module->name) ||
+ } else if (!external_module || s->module->is_vmlinux ||
s->module == mod) {
warn("%s: '%s' exported twice. Previous export was in %s%s\n",
mod->name, name, s->module->name,
- is_vmlinux(s->module->name) ? "" : ".ko");
+ s->module->is_vmlinux ? "" : ".ko");
return s;
}
s->module = mod;
- s->vmlinux = is_vmlinux(mod->name);
- s->kernel = 0;
s->export = export;
return s;
}
@@ -416,7 +452,7 @@ static void sym_set_crc(const char *name, unsigned int crc)
s->crc_valid = 1;
}
-void *grab_file(const char *filename, unsigned long *size)
+static void *grab_file(const char *filename, size_t *size)
{
struct stat st;
void *map = MAP_FAILED;
@@ -438,41 +474,7 @@ failed:
return map;
}
-/**
- * Return a copy of the next line in a mmap'ed file.
- * spaces in the beginning of the line is trimmed away.
- * Return a pointer to a static buffer.
- **/
-char *get_next_line(unsigned long *pos, void *file, unsigned long size)
-{
- static char line[4096];
- int skip = 1;
- size_t len = 0;
- signed char *p = (signed char *)file + *pos;
- char *s = line;
-
- for (; *pos < size ; (*pos)++) {
- if (skip && isspace(*p)) {
- p++;
- continue;
- }
- skip = 0;
- if (*p != '\n' && (*pos < size)) {
- len++;
- *s++ = *p++;
- if (len > 4095)
- break; /* Too long, stop */
- } else {
- /* End of string */
- *s = '\0';
- return line;
- }
- }
- /* End of buffer */
- return NULL;
-}
-
-void release_file(void *file, unsigned long size)
+static void release_file(void *file, size_t size)
{
munmap(file, size);
}
@@ -528,9 +530,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
/* Check if file offset is correct */
if (hdr->e_shoff > info->size) {
- fatal("section header offset=%lu in file '%s' is bigger than "
- "filesize=%lu\n", (unsigned long)hdr->e_shoff,
- filename, info->size);
+ fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
+ (unsigned long)hdr->e_shoff, filename, info->size);
return 0;
}
@@ -683,7 +684,7 @@ static void handle_modversion(const struct module *mod,
if (sym->st_shndx == SHN_UNDEF) {
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
- symname, mod->name, is_vmlinux(mod->name) ? "":".ko");
+ symname, mod->name, mod->is_vmlinux ? "" : ".ko");
return;
}
@@ -705,8 +706,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info,
enum export export;
const char *name;
- if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
- strstarts(symname, "__ksymtab"))
+ if (strstarts(symname, "__ksymtab"))
export = export_from_secname(info, get_secindex(info, sym));
else
export = export_from_sec(info, get_secindex(info, sym));
@@ -948,7 +948,7 @@ static void check_section(const char *modname, struct elf_info *elf,
#define DATA_SECTIONS ".data", ".data.rel"
#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
- ".kprobes.text", ".cpuidle.text"
+ ".kprobes.text", ".cpuidle.text", ".noinstr.text"
#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
".fixup", ".entry.text", ".exception.text", ".text.*", \
".coldtext"
@@ -1752,11 +1752,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
static unsigned int *reloc_location(struct elf_info *elf,
Elf_Shdr *sechdr, Elf_Rela *r)
{
- Elf_Shdr *sechdrs = elf->sechdrs;
- int section = sechdr->sh_info;
-
- return (void *)elf->hdr + sechdrs[section].sh_offset +
- r->r_offset;
+ return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
}
static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
@@ -2005,34 +2001,36 @@ static void read_symbols(const char *modname)
if (!parse_elf(&info, modname))
return;
- mod = new_module(modname);
-
- /* When there's no vmlinux, don't print warnings about
- * unresolved symbols (since there'll be too many ;) */
- if (is_vmlinux(modname)) {
- have_vmlinux = 1;
- mod->skip = 1;
- }
-
- license = get_modinfo(&info, "license");
- if (!license && !is_vmlinux(modname))
- warn("missing MODULE_LICENSE() in %s\n"
- "see include/linux/module.h for "
- "more information\n", modname);
- while (license) {
- if (license_is_gpl_compatible(license))
- mod->gpl_compatible = 1;
- else {
- mod->gpl_compatible = 0;
- break;
+ {
+ char *tmp;
+
+ /* strip trailing .o */
+ tmp = NOFAIL(strdup(modname));
+ tmp[strlen(tmp) - 2] = '\0';
+ mod = new_module(tmp);
+ free(tmp);
+ }
+
+ if (!mod->is_vmlinux) {
+ license = get_modinfo(&info, "license");
+ if (!license)
+ warn("missing MODULE_LICENSE() in %s\n", modname);
+ while (license) {
+ if (license_is_gpl_compatible(license))
+ mod->gpl_compatible = 1;
+ else {
+ mod->gpl_compatible = 0;
+ break;
+ }
+ license = get_next_modinfo(&info, "license", license);
}
- license = get_next_modinfo(&info, "license", license);
- }
- namespace = get_modinfo(&info, "import_ns");
- while (namespace) {
- add_namespace(&mod->imported_namespaces, namespace);
- namespace = get_next_modinfo(&info, "import_ns", namespace);
+ namespace = get_modinfo(&info, "import_ns");
+ while (namespace) {
+ add_namespace(&mod->imported_namespaces, namespace);
+ namespace = get_next_modinfo(&info, "import_ns",
+ namespace);
+ }
}
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
@@ -2070,16 +2068,14 @@ static void read_symbols(const char *modname)
}
}
- if (!is_vmlinux(modname) || vmlinux_section_warnings)
- check_sec_ref(mod, modname, &info);
+ check_sec_ref(mod, modname, &info);
- version = get_modinfo(&info, "version");
- if (version)
- maybe_frob_rcs_version(modname, version, info.modinfo,
- version - (char *)info.hdr);
- if (version || (all_versions && !is_vmlinux(modname)))
- get_src_version(modname, mod->srcversion,
- sizeof(mod->srcversion)-1);
+ if (!mod->is_vmlinux) {
+ version = get_modinfo(&info, "version");
+ if (version || all_versions)
+ get_src_version(modname, mod->srcversion,
+ sizeof(mod->srcversion) - 1);
+ }
parse_elf_finish(&info);
@@ -2143,20 +2139,18 @@ void buf_write(struct buffer *buf, const char *s, int len)
static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
{
- const char *e = is_vmlinux(m) ?"":".ko";
-
switch (exp) {
case export_gpl:
- fatal("GPL-incompatible module %s%s "
- "uses GPL-only symbol '%s'\n", m, e, s);
+ fatal("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
+ m, s);
break;
case export_unused_gpl:
- fatal("GPL-incompatible module %s%s "
- "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
+ fatal("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n",
+ m, s);
break;
case export_gpl_future:
- warn("GPL-incompatible module %s%s "
- "uses future GPL-only symbol '%s'\n", m, e, s);
+ warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n",
+ m, s);
break;
case export_plain:
case export_unused:
@@ -2168,13 +2162,11 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
static void check_for_unused(enum export exp, const char *m, const char *s)
{
- const char *e = is_vmlinux(m) ?"":".ko";
-
switch (exp) {
case export_unused:
case export_unused_gpl:
- warn("module %s%s "
- "uses symbol '%s' marked UNUSED\n", m, e, s);
+ warn("module %s.ko uses symbol '%s' marked UNUSED\n",
+ m, s);
break;
default:
/* ignore */
@@ -2251,6 +2243,7 @@ static void add_header(struct buffer *b, struct module *mod)
* Include build-salt.h after module.h in order to
* inherit the definitions.
*/
+ buf_printf(b, "#define INCLUDE_VERMAGIC\n");
buf_printf(b, "#include <linux/build-salt.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n");
buf_printf(b, "#include <linux/compiler.h>\n");
@@ -2348,7 +2341,7 @@ static void add_depends(struct buffer *b, struct module *mod)
/* Clear ->seen flag of modules that own symbols needed by this. */
for (s = mod->unres; s; s = s->next)
if (s->module)
- s->module->seen = is_vmlinux(s->module->name);
+ s->module->seen = s->module->is_vmlinux;
buf_printf(b, "\n");
buf_printf(b, "MODULE_INFO(depends, \"");
@@ -2381,6 +2374,25 @@ static void add_srcversion(struct buffer *b, struct module *mod)
}
}
+static void write_buf(struct buffer *b, const char *fname)
+{
+ FILE *file;
+
+ file = fopen(fname, "w");
+ if (!file) {
+ perror(fname);
+ exit(1);
+ }
+ if (fwrite(b->p, 1, b->pos, file) != b->pos) {
+ perror(fname);
+ exit(1);
+ }
+ if (fclose(file) != 0) {
+ perror(fname);
+ exit(1);
+ }
+}
+
static void write_if_changed(struct buffer *b, const char *fname)
{
char *tmp;
@@ -2413,32 +2425,24 @@ static void write_if_changed(struct buffer *b, const char *fname)
close_write:
fclose(file);
write:
- file = fopen(fname, "w");
- if (!file) {
- perror(fname);
- exit(1);
- }
- if (fwrite(b->p, 1, b->pos, file) != b->pos) {
- perror(fname);
- exit(1);
- }
- fclose(file);
+ write_buf(b, fname);
}
/* parse Module.symvers file. line format:
* 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
**/
-static void read_dump(const char *fname, unsigned int kernel)
+static void read_dump(const char *fname)
{
- unsigned long size, pos = 0;
- void *file = grab_file(fname, &size);
- char *line;
+ char *buf, *pos, *line;
- if (!file)
+ buf = read_text_file(fname);
+ if (!buf)
/* No symbol versions, silently ignore */
return;
- while ((line = get_next_line(&pos, file, size))) {
+ pos = buf;
+
+ while ((line = get_line(&pos))) {
char *symname, *namespace, *modname, *d, *export;
unsigned int crc;
struct module *mod;
@@ -2462,21 +2466,18 @@ static void read_dump(const char *fname, unsigned int kernel)
goto fail;
mod = find_module(modname);
if (!mod) {
- if (is_vmlinux(modname))
- have_vmlinux = 1;
mod = new_module(modname);
- mod->skip = 1;
+ mod->from_dump = 1;
}
s = sym_add_exported(symname, mod, export_no(export));
- s->kernel = kernel;
s->is_static = 0;
sym_set_crc(symname, crc);
sym_update_namespace(symname, namespace);
}
- release_file(file, size);
+ free(buf);
return;
fail:
- release_file(file, size);
+ free(buf);
fatal("parse error in symbol dump file\n");
}
@@ -2488,7 +2489,7 @@ static int dump_sym(struct symbol *sym)
{
if (!external_module)
return 1;
- if (sym->vmlinux || sym->kernel)
+ if (sym->module->from_dump)
return 0;
return 1;
}
@@ -2514,7 +2515,7 @@ static void write_dump(const char *fname)
symbol = symbol->next;
}
}
- write_if_changed(&buf, fname);
+ write_buf(&buf, fname);
free(buf.p);
}
@@ -2526,7 +2527,7 @@ static void write_namespace_deps_files(const char *fname)
for (mod = modules; mod; mod = mod->next) {
- if (mod->skip || !mod->missing_namespaces)
+ if (mod->from_dump || !mod->missing_namespaces)
continue;
buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
@@ -2541,8 +2542,8 @@ static void write_namespace_deps_files(const char *fname)
free(ns_deps_buf.p);
}
-struct ext_sym_list {
- struct ext_sym_list *next;
+struct dump_list {
+ struct dump_list *next;
const char *file;
};
@@ -2550,28 +2551,24 @@ int main(int argc, char **argv)
{
struct module *mod;
struct buffer buf = { };
- char *kernel_read = NULL;
char *missing_namespace_deps = NULL;
char *dump_write = NULL, *files_source = NULL;
int opt;
int err;
int n;
- struct ext_sym_list *extsym_iter;
- struct ext_sym_list *extsym_start = NULL;
+ struct dump_list *dump_read_start = NULL;
+ struct dump_list **dump_read_iter = &dump_read_start;
- while ((opt = getopt(argc, argv, "i:e:mnsT:o:awENd:")) != -1) {
+ while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
switch (opt) {
- case 'i':
- kernel_read = optarg;
- external_module = 1;
- break;
case 'e':
external_module = 1;
- extsym_iter =
- NOFAIL(malloc(sizeof(*extsym_iter)));
- extsym_iter->next = extsym_start;
- extsym_iter->file = optarg;
- extsym_start = extsym_iter;
+ break;
+ case 'i':
+ *dump_read_iter =
+ NOFAIL(calloc(1, sizeof(**dump_read_iter)));
+ (*dump_read_iter)->file = optarg;
+ dump_read_iter = &(*dump_read_iter)->next;
break;
case 'm':
modversions = 1;
@@ -2585,9 +2582,6 @@ int main(int argc, char **argv)
case 'a':
all_versions = 1;
break;
- case 's':
- vmlinux_section_warnings = 0;
- break;
case 'T':
files_source = optarg;
break;
@@ -2608,13 +2602,13 @@ int main(int argc, char **argv)
}
}
- if (kernel_read)
- read_dump(kernel_read, 1);
- while (extsym_start) {
- read_dump(extsym_start->file, 0);
- extsym_iter = extsym_start->next;
- free(extsym_start);
- extsym_start = extsym_iter;
+ while (dump_read_start) {
+ struct dump_list *tmp;
+
+ read_dump(dump_read_start->file);
+ tmp = dump_read_start->next;
+ free(dump_read_start);
+ dump_read_start = tmp;
}
while (optind < argc)
@@ -2623,12 +2617,19 @@ int main(int argc, char **argv)
if (files_source)
read_symbols_from_files(files_source);
+ /*
+ * When there's no vmlinux, don't print warnings about
+ * unresolved symbols (since there'll be too many ;)
+ */
+ if (!have_vmlinux)
+ warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
+
err = 0;
for (mod = modules; mod; mod = mod->next) {
char fname[PATH_MAX];
- if (mod->skip)
+ if (mod->is_vmlinux || mod->from_dump)
continue;
buf.pos = 0;
@@ -2661,13 +2662,6 @@ int main(int argc, char **argv)
struct symbol *s;
for (s = symbolhash[n]; s; s = s->next) {
- /*
- * Do not check "vmlinux". This avoids the same warnings
- * shown twice, and false-positives for ARCH=um.
- */
- if (is_vmlinux(s->module->name) && !s->module->is_dot_o)
- continue;
-
if (s->is_static)
warn("\"%s\" [%s] is a static %s\n",
s->name, s->module->name,
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 60dca9b7106b..3aa052722233 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -111,29 +111,29 @@ buf_write(struct buffer *buf, const char *s, int len);
struct namespace_list {
struct namespace_list *next;
- char namespace[0];
+ char namespace[];
};
struct module {
struct module *next;
- const char *name;
int gpl_compatible;
struct symbol *unres;
+ int from_dump; /* 1 if module was loaded from *.symvers */
+ int is_vmlinux;
int seen;
- int skip;
int has_init;
int has_cleanup;
struct buffer dev_table_buf;
char srcversion[25];
- int is_dot_o;
// Missing namespace dependencies
struct namespace_list *missing_namespaces;
// Actual imported namespaces
struct namespace_list *imported_namespaces;
+ char name[];
};
struct elf_info {
- unsigned long size;
+ size_t size;
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
Elf_Sym *symtab_start;
@@ -187,16 +187,11 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
void add_moddevtable(struct buffer *buf, struct module *mod);
/* sumversion.c */
-void maybe_frob_rcs_version(const char *modfilename,
- char *version,
- void *modinfo,
- unsigned long modinfo_offset);
void get_src_version(const char *modname, char sum[], unsigned sumlen);
/* from modpost.c */
-void *grab_file(const char *filename, unsigned long *size);
-char* get_next_line(unsigned long *pos, void *file, unsigned long size);
-void release_file(void *file, unsigned long size);
+char *read_text_file(const char *filename);
+char *get_line(char **stringp);
enum loglevel {
LOG_WARN,
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index 63062024ce0e..d587f40f1117 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -258,9 +258,8 @@ static int parse_file(const char *fname, struct md4_ctx *md)
char *file;
unsigned long i, len;
- file = grab_file(fname, &len);
- if (!file)
- return 0;
+ file = read_text_file(fname);
+ len = strlen(file);
for (i = 0; i < len; i++) {
/* Collapse and ignore \ and CR. */
@@ -287,7 +286,7 @@ static int parse_file(const char *fname, struct md4_ctx *md)
add_char(file[i], md);
}
- release_file(file, len);
+ free(file);
return 1;
}
/* Check whether the file is a static library or not */
@@ -304,9 +303,8 @@ static int is_static_library(const char *objfile)
* to figure out source files. */
static int parse_source_files(const char *objfile, struct md4_ctx *md)
{
- char *cmd, *file, *line, *dir;
+ char *cmd, *file, *line, *dir, *pos;
const char *base;
- unsigned long flen, pos = 0;
int dirlen, ret = 0, check_files = 0;
cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd")));
@@ -324,14 +322,12 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
strncpy(dir, objfile, dirlen);
dir[dirlen] = '\0';
- file = grab_file(cmd, &flen);
- if (!file) {
- warn("could not find %s for %s\n", cmd, objfile);
- goto out;
- }
+ file = read_text_file(cmd);
+
+ pos = file;
/* Sum all files in the same dir or subdirs. */
- while ((line = get_next_line(&pos, file, flen)) != NULL) {
+ while ((line = get_line(&pos))) {
char* p = line;
if (strncmp(line, "source_", sizeof("source_")-1) == 0) {
@@ -382,8 +378,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
/* Everyone parsed OK */
ret = 1;
out_file:
- release_file(file, flen);
-out:
+ free(file);
free(dir);
free(cmd);
return ret;
@@ -392,106 +387,34 @@ out:
/* Calc and record src checksum. */
void get_src_version(const char *modname, char sum[], unsigned sumlen)
{
- void *file;
- unsigned long len;
+ char *buf, *pos, *firstline;
struct md4_ctx md;
- char *sources, *end, *fname;
+ char *fname;
char filelist[PATH_MAX + 1];
/* objects for a module are listed in the first line of *.mod file. */
snprintf(filelist, sizeof(filelist), "%.*smod",
(int)strlen(modname) - 1, modname);
- file = grab_file(filelist, &len);
- if (!file)
- /* not a module or .mod file missing - ignore */
- return;
+ buf = read_text_file(filelist);
- sources = file;
-
- end = strchr(sources, '\n');
- if (!end) {
+ pos = buf;
+ firstline = get_line(&pos);
+ if (!firstline) {
warn("bad ending versions file for %s\n", modname);
- goto release;
+ goto free;
}
- *end = '\0';
md4_init(&md);
- while ((fname = strsep(&sources, " ")) != NULL) {
+ while ((fname = strsep(&firstline, " "))) {
if (!*fname)
continue;
if (!(is_static_library(fname)) &&
!parse_source_files(fname, &md))
- goto release;
+ goto free;
}
md4_final_ascii(&md, sum, sumlen);
-release:
- release_file(file, len);
-}
-
-static void write_version(const char *filename, const char *sum,
- unsigned long offset)
-{
- int fd;
-
- fd = open(filename, O_RDWR);
- if (fd < 0) {
- warn("changing sum in %s failed: %s\n",
- filename, strerror(errno));
- return;
- }
-
- if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
- warn("changing sum in %s:%lu failed: %s\n",
- filename, offset, strerror(errno));
- goto out;
- }
-
- if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
- warn("writing sum in %s failed: %s\n",
- filename, strerror(errno));
- goto out;
- }
-out:
- close(fd);
-}
-
-static int strip_rcs_crap(char *version)
-{
- unsigned int len, full_len;
-
- if (strncmp(version, "$Revision", strlen("$Revision")) != 0)
- return 0;
-
- /* Space for version string follows. */
- full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2;
-
- /* Move string to start with version number: prefix will be
- * $Revision$ or $Revision: */
- len = strlen("$Revision");
- if (version[len] == ':' || version[len] == '$')
- len++;
- while (isspace(version[len]))
- len++;
- memmove(version, version+len, full_len-len);
- full_len -= len;
-
- /* Preserve up to next whitespace. */
- len = 0;
- while (version[len] && !isspace(version[len]))
- len++;
- memmove(version + len, version + strlen(version),
- full_len - strlen(version));
- return 1;
-}
-
-/* Clean up RCS-style version numbers. */
-void maybe_frob_rcs_version(const char *modfilename,
- char *version,
- void *modinfo,
- unsigned long version_offset)
-{
- if (strip_rcs_crap(version))
- write_version(modfilename, version, version_offset);
+free:
+ free(buf);
}
diff --git a/scripts/modules-check.sh b/scripts/modules-check.sh
index f51f446707b8..43de226071ae 100755
--- a/scripts/modules-check.sh
+++ b/scripts/modules-check.sh
@@ -3,14 +3,24 @@
set -e
+if [ $# != 1 ]; then
+ echo "Usage: $0 <modules.order>" >& 2
+ exit 1
+fi
+
+exit_code=0
+
# Check uniqueness of module names
check_same_name_modules()
{
- for m in $(sed 's:.*/::' modules.order | sort | uniq -d)
+ for m in $(sed 's:.*/::' $1 | sort | uniq -d)
do
- echo "warning: same module names found:" >&2
+ echo "error: the following would cause module name conflict:" >&2
sed -n "/\/$m/s:^: :p" modules.order >&2
+ exit_code=1
done
}
-check_same_name_modules
+check_same_name_modules "$1"
+
+exit $exit_code
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 77c7caefede1..936198a90477 100755
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -28,15 +28,15 @@ case "${1}" in
opts=
;;
targz-pkg)
- opts=--gzip
+ opts="-I ${KGZIP}"
tarball=${tarball}.gz
;;
tarbz2-pkg)
- opts=--bzip2
+ opts="-I ${KBZIP2}"
tarball=${tarball}.bz2
;;
tarxz-pkg)
- opts=--xz
+ opts="-I ${XZ}"
tarball=${tarball}.xz
;;
*)
@@ -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 d9cd24cf0d40..feb2efaaa5e6 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -59,6 +59,7 @@ actualy||actually
acumulating||accumulating
acumulative||accumulative
acumulator||accumulator
+acutally||actually
adapater||adapter
addional||additional
additionaly||additionally
@@ -148,6 +149,7 @@ arbitary||arbitrary
architechture||architecture
arguement||argument
arguements||arguments
+arithmatic||arithmetic
aritmetic||arithmetic
arne't||aren't
arraival||arrival
@@ -249,6 +251,7 @@ calescing||coalescing
calle||called
callibration||calibration
callled||called
+callser||caller
calucate||calculate
calulate||calculate
cancelation||cancellation
@@ -452,6 +455,7 @@ destorys||destroys
destroied||destroyed
detabase||database
deteced||detected
+detectt||detect
develope||develop
developement||development
developped||developed
@@ -543,6 +547,7 @@ entires||entries
entites||entities
entrys||entries
enocded||encoded
+enought||enough
enterily||entirely
enviroiment||environment
enviroment||environment
@@ -554,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
@@ -581,6 +589,7 @@ explictly||explicitly
expresion||expression
exprimental||experimental
extened||extended
+exteneded||extended
extensability||extensibility
extention||extension
extenstion||extension
@@ -608,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
@@ -659,6 +670,7 @@ globel||global
grabing||grabbing
grahical||graphical
grahpical||graphical
+granularty||granularity
grapic||graphic
grranted||granted
guage||gauge
@@ -671,6 +683,7 @@ hanlde||handle
hanled||handled
happend||happened
harware||hardware
+havind||having
heirarchically||hierarchically
helpfull||helpful
hexdecimal||hexadecimal
@@ -845,6 +858,7 @@ logile||logfile
loobpack||loopback
loosing||losing
losted||lost
+maangement||management
machinary||machinery
maibox||mailbox
maintainance||maintenance
@@ -902,14 +916,17 @@ miximum||maximum
mmnemonic||mnemonic
mnay||many
modfiy||modify
+modifer||modifier
modulues||modules
momery||memory
memomry||memory
+monitring||monitoring
monochorome||monochrome
monochromo||monochrome
monocrome||monochrome
mopdule||module
mroe||more
+multipler||multiplier
mulitplied||multiplied
multidimensionnal||multidimensional
multipe||multiple
@@ -947,6 +964,7 @@ occassionally||occasionally
occationally||occasionally
occurance||occurrence
occurances||occurrences
+occurd||occurred
occured||occurred
occurence||occurrence
occure||occurred
@@ -1010,6 +1028,7 @@ partiton||partition
pased||passed
passin||passing
pathes||paths
+pattrns||patterns
pecularities||peculiarities
peformance||performance
peforming||performing
@@ -1052,6 +1071,7 @@ precission||precision
preemptable||preemptible
prefered||preferred
prefferably||preferably
+prefitler||prefilter
premption||preemption
prepaired||prepared
preperation||preparation
@@ -1095,6 +1115,7 @@ pronunce||pronounce
propery||property
propigate||propagate
propigation||propagation
+propogation||propagation
propogate||propagate
prosess||process
protable||portable
@@ -1256,6 +1277,7 @@ shoule||should
shrinked||shrunk
siginificantly||significantly
signabl||signal
+significanly||significantly
similary||similarly
similiar||similar
simlar||similar
@@ -1309,6 +1331,7 @@ sturcture||structure
subdirectoires||subdirectories
suble||subtle
substract||subtract
+submited||submitted
submition||submission
suceed||succeed
succesfully||successfully
@@ -1317,6 +1340,7 @@ successed||succeeded
successfull||successful
successfuly||successfully
sucessfully||successfully
+sucessful||successful
sucess||success
superflous||superfluous
superseeded||superseded
@@ -1371,6 +1395,7 @@ thead||thread
therfore||therefore
thier||their
threds||threads
+threee||three
threshhold||threshold
thresold||threshold
throught||through
@@ -1401,6 +1426,7 @@ transormed||transformed
trasfer||transfer
trasmission||transmission
treshold||threshold
+triggerd||triggered
trigerred||triggered
trigerring||triggering
trun||turn
@@ -1410,8 +1436,10 @@ tyep||type
udpate||update
uesd||used
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 fa3fb05cd54b..40fa6923e80a 100755
--- a/scripts/sphinx-pre-install
+++ b/scripts/sphinx-pre-install
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
use strict;
-# Copyright (c) 2017-2019 Mauro Carvalho Chehab <mchehab@kernel.org>
+# Copyright (c) 2017-2020 Mauro Carvalho Chehab <mchehab@kernel.org>
#
my $prefix = "./";
@@ -22,10 +22,16 @@ my $need = 0;
my $optional = 0;
my $need_symlink = 0;
my $need_sphinx = 0;
+my $need_venv = 0;
+my $need_virtualenv = 0;
my $rec_sphinx_upgrade = 0;
my $install = "";
my $virtenv_dir = "";
+my $python_cmd = "";
my $min_version;
+my $cur_version;
+my $rec_version = "1.7.9"; # PDF won't build here
+my $min_pdf_version = "2.4.4"; # Min version where pdf builds
#
# Command line arguments
@@ -142,12 +148,30 @@ sub findprog($)
}
}
+sub find_python_no_venv()
+{
+ my $prog = shift;
+
+ my $cur_dir = qx(pwd);
+ $cur_dir =~ s/\s+$//;
+
+ foreach my $dir (split(/:/, $ENV{PATH})) {
+ next if ($dir =~ m,($cur_dir)/sphinx,);
+ return "$dir/python3" if(-x "$dir/python3");
+ }
+ foreach my $dir (split(/:/, $ENV{PATH})) {
+ next if ($dir =~ m,($cur_dir)/sphinx,);
+ return "$dir/python" if(-x "$dir/python");
+ }
+ return "python";
+}
+
sub check_program($$)
{
my $prog = shift;
my $is_optional = shift;
- return if findprog($prog);
+ return $prog if findprog($prog);
add_package($prog, $is_optional);
}
@@ -168,9 +192,9 @@ sub check_python_module($$)
my $prog = shift;
my $is_optional = shift;
- my $err = system("python3 -c 'import $prog' 2>/dev/null /dev/null");
- return if ($err == 0);
- my $err = system("python -c 'import $prog' 2>/dev/null /dev/null");
+ return if (!$python_cmd);
+
+ my $err = system("$python_cmd -c 'import $prog' 2>/dev/null /dev/null");
return if ($err == 0);
add_package($prog, $is_optional);
@@ -225,23 +249,33 @@ sub get_sphinx_fname()
return $fname;
}
- if ($virtualenv) {
- my $prog = findprog("virtualenv-3");
- $prog = findprog("virtualenv-3.5") if (!$prog);
+ return "";
+}
- check_program("virtualenv", 0) if (!$prog);
- $need_sphinx = 1;
- } else {
- add_package("python-sphinx", 0);
- }
+sub get_sphinx_version($)
+{
+ my $cmd = shift;
+ my $ver;
- return "";
+ open IN, "$cmd --version 2>&1 |";
+ while (<IN>) {
+ if (m/^\s*sphinx-build\s+([\d\.]+)(\+\/[\da-f]+)?$/) {
+ $ver=$1;
+ last;
+ }
+ # Sphinx 1.2.x uses a different format
+ if (m/^\s*Sphinx.*\s+([\d\.]+)$/) {
+ $ver=$1;
+ last;
+ }
+ }
+ close IN;
+ return $ver;
}
sub check_sphinx()
{
- my $rec_version;
- my $cur_version;
+ my $default_version;
open IN, $conf or die "Can't open $conf";
while (<IN>) {
@@ -257,45 +291,35 @@ sub check_sphinx()
open IN, $requirement_file or die "Can't open $requirement_file";
while (<IN>) {
if (m/^\s*Sphinx\s*==\s*([\d\.]+)$/) {
- $rec_version=$1;
+ $default_version=$1;
last;
}
}
close IN;
- die "Can't get recommended sphinx version from $requirement_file" if (!$min_version);
+ die "Can't get default sphinx version from $requirement_file" if (!$default_version);
- $virtenv_dir = $virtenv_prefix . $rec_version;
+ $virtenv_dir = $virtenv_prefix . $default_version;
my $sphinx = get_sphinx_fname();
- return if ($sphinx eq "");
-
- open IN, "$sphinx --version 2>&1 |" or die "$sphinx returned an error";
- while (<IN>) {
- if (m/^\s*sphinx-build\s+([\d\.]+)(\+\/[\da-f]+)?$/) {
- $cur_version=$1;
- last;
- }
- # Sphinx 1.2.x uses a different format
- if (m/^\s*Sphinx.*\s+([\d\.]+)$/) {
- $cur_version=$1;
- last;
- }
+ if ($sphinx eq "") {
+ $need_sphinx = 1;
+ return;
}
- close IN;
+
+ $cur_version = get_sphinx_version($sphinx);
+ die ("$sphinx returned an error") if (!$cur_version);
die "$sphinx didn't return its version" if (!$cur_version);
if ($cur_version lt $min_version) {
printf "ERROR: Sphinx version is %s. It should be >= %s (recommended >= %s)\n",
- $cur_version, $min_version, $rec_version;;
+ $cur_version, $min_version, $default_version;
$need_sphinx = 1;
return;
}
if ($cur_version lt $rec_version) {
- printf "Sphinx version %s\n", $cur_version;
- print "Warning: It is recommended at least Sphinx version $rec_version.\n";
$rec_sphinx_upgrade = 1;
return;
}
@@ -336,6 +360,7 @@ sub give_debian_hints()
my %map = (
"python-sphinx" => "python3-sphinx",
"sphinx_rtd_theme" => "python3-sphinx-rtd-theme",
+ "ensurepip" => "python3-venv",
"virtualenv" => "virtualenv",
"dot" => "graphviz",
"convert" => "imagemagick",
@@ -349,7 +374,8 @@ sub give_debian_hints()
"fonts-dejavu", 2);
check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
- "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc"],
+ "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
+ "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc"],
"fonts-noto-cjk", 2);
}
@@ -446,9 +472,11 @@ sub give_opensuse_hints()
"convert" => "ImageMagick",
"Pod::Usage" => "perl-Pod-Usage",
"xelatex" => "texlive-xetex-bin",
- "rsvg-convert" => "rsvg-view",
);
+ # On Tumbleweed, this package is also named rsvg-convert
+ $map{"rsvg-convert"} = "rsvg-view" if (!($system_release =~ /Tumbleweed/));
+
my @suse_tex_pkgs = (
"texlive-babel-english",
"texlive-caption",
@@ -491,7 +519,7 @@ sub give_mageia_hints()
"convert" => "ImageMagick",
"Pod::Usage" => "perl-Pod-Usage",
"xelatex" => "texlive",
- "rsvg-convert" => "librsvg2-tools",
+ "rsvg-convert" => "librsvg2",
);
my @tex_pkgs = (
@@ -500,16 +528,29 @@ sub give_mageia_hints()
$map{"latexmk"} = "texlive-collection-basic";
+ my $packager_cmd;
+ my $noto_sans;
+ if ($system_release =~ /OpenMandriva/) {
+ $packager_cmd = "dnf install";
+ $noto_sans = "noto-sans-cjk-fonts";
+ @tex_pkgs = ( "texlive-collection-fontsextra" );
+ } else {
+ $packager_cmd = "urpmi";
+ $noto_sans = "google-noto-sans-cjk-ttc-fonts";
+ }
+
+
if ($pdf) {
- check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc"],
- "google-noto-sans-cjk-ttc-fonts", 2);
+ check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
+ "/usr/share/fonts/TTF/NotoSans-Regular.ttf"],
+ $noto_sans, 2);
}
check_rpm_missing(\@tex_pkgs, 2) if ($pdf);
check_missing(\%map);
return if (!$need && !$optional);
- printf("You should run:\n\n\tsudo urpmi $install\n");
+ printf("You should run:\n\n\tsudo $packager_cmd $install\n");
}
sub give_arch_linux_hints()
@@ -557,7 +598,8 @@ sub give_gentoo_hints()
"media-fonts/dejavu", 2) if ($pdf);
if ($pdf) {
- check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf"],
+ check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf",
+ "/usr/share/fonts/noto-cjk/NotoSerifCJK-Regular.ttc"],
"media-fonts/noto-cjk", 2);
}
@@ -572,10 +614,10 @@ sub give_gentoo_hints()
my $portage_imagemagick = "/etc/portage/package.use/imagemagick";
my $portage_cairo = "/etc/portage/package.use/graphviz";
- if (qx(cat $portage_imagemagick) ne "$imagemagick\n") {
+ if (qx(grep imagemagick $portage_imagemagick 2>/dev/null) eq "") {
printf("\tsudo su -c 'echo \"$imagemagick\" > $portage_imagemagick'\n")
}
- if (qx(cat $portage_cairo) ne "$cairo\n") {
+ if (qx(grep graphviz $portage_cairo 2>/dev/null) eq "") {
printf("\tsudo su -c 'echo \"$cairo\" > $portage_cairo'\n");
}
@@ -622,6 +664,10 @@ sub check_distros()
give_mageia_hints;
return;
}
+ if ($system_release =~ /OpenMandriva/) {
+ give_mageia_hints;
+ return;
+ }
if ($system_release =~ /Arch Linux/) {
give_arch_linux_hints;
return;
@@ -651,22 +697,58 @@ sub check_distros()
sub deactivate_help()
{
- printf "\tIf you want to exit the virtualenv, you can use:\n";
+ printf "\nIf you want to exit the virtualenv, you can use:\n";
printf "\tdeactivate\n";
}
sub check_needs()
{
- # Check for needed programs/tools
+ # Check if Sphinx is already accessible from current environment
check_sphinx();
if ($system_release) {
- print "Detected OS: $system_release.\n\n";
+ print "Detected OS: $system_release.\n";
} else {
- print "Unknown OS\n\n";
+ print "Unknown OS\n";
+ }
+ printf "Sphinx version: %s\n\n", $cur_version if ($cur_version);
+
+ # Check python command line, trying first python3
+ $python_cmd = findprog("python3");
+ $python_cmd = check_program("python", 0) if (!$python_cmd);
+
+ # Check the type of virtual env, depending on Python version
+ if ($python_cmd) {
+ if ($virtualenv) {
+ my $tmp = qx($python_cmd --version 2>&1);
+ if ($tmp =~ m/(\d+\.)(\d+\.)/) {
+ if ($1 >= 3 && $2 >= 3) {
+ $need_venv = 1; # python 3.3 or upper
+ } else {
+ $need_virtualenv = 1;
+ }
+ if ($1 < 3) {
+ # Complain if it finds python2 (or worse)
+ printf "Warning: python$1 support is deprecated. Use it with caution!\n";
+ }
+ } else {
+ die "Warning: couldn't identify $python_cmd version!";
+ }
+ } else {
+ add_package("python-sphinx", 0);
+ }
}
- print "To upgrade Sphinx, use:\n\n" if ($rec_sphinx_upgrade);
+ # Set virtualenv command line, if python < 3.3
+ my $virtualenv_cmd;
+ if ($need_virtualenv) {
+ $virtualenv_cmd = findprog("virtualenv-3");
+ $virtualenv_cmd = findprog("virtualenv-3.5") if (!$virtualenv_cmd);
+ if (!$virtualenv_cmd) {
+ check_program("virtualenv", 0);
+ $virtualenv_cmd = "virtualenv";
+ }
+ }
# Check for needed programs/tools
check_perl_module("Pod::Usage", 0);
@@ -681,46 +763,81 @@ sub check_needs()
check_program("rsvg-convert", 2) if ($pdf);
check_program("latexmk", 2) if ($pdf);
+ if ($need_sphinx || $rec_sphinx_upgrade) {
+ check_python_module("ensurepip", 0) if ($need_venv);
+ }
+
+ # Do distro-specific checks and output distro-install commands
check_distros();
+ if (!$python_cmd) {
+ if ($need == 1) {
+ die "Can't build as $need mandatory dependency is missing";
+ } elsif ($need) {
+ die "Can't build as $need mandatory dependencies are missing";
+ }
+ }
+
+ # Check if sphinx-build is called sphinx-build-3
if ($need_symlink) {
printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n",
which("sphinx-build-3");
}
+
+ # NOTE: if the system has a too old Sphinx version installed,
+ # it will recommend installing a newer version using virtualenv
+
if ($need_sphinx || $rec_sphinx_upgrade) {
my $min_activate = "$ENV{'PWD'}/${virtenv_prefix}${min_version}/bin/activate";
my @activates = glob "$ENV{'PWD'}/${virtenv_prefix}*/bin/activate";
+ if ($cur_version lt $rec_version) {
+ print "Warning: It is recommended at least Sphinx version $rec_version.\n";
+ print " If you want pdf, you need at least $min_pdf_version.\n";
+ }
+ if ($cur_version lt $min_pdf_version) {
+ print "Note: It is recommended at least Sphinx version $min_pdf_version if you need PDF support.\n";
+ }
@activates = sort {$b cmp $a} @activates;
-
- if ($need_sphinx && scalar @activates > 0 && $activates[0] ge $min_activate) {
- printf "\nNeed to activate a compatible Sphinx version on virtualenv with:\n";
- printf "\t. $activates[0]\n";
- deactivate_help();
- exit (1);
- } else {
- my $rec_activate = "$virtenv_dir/bin/activate";
- my $virtualenv = findprog("virtualenv-3");
- my $rec_python3 = "";
- $virtualenv = findprog("virtualenv-3.5") if (!$virtualenv);
- $virtualenv = findprog("virtualenv") if (!$virtualenv);
- $virtualenv = "virtualenv" if (!$virtualenv);
-
- my $rel = "";
- if (index($system_release, "Ubuntu") != -1) {
- $rel = $1 if ($system_release =~ /Ubuntu\s+(\d+)[.]/);
- if ($rel && $rel >= 16) {
- $rec_python3 = " -p python3";
- }
+ my ($activate, $ver);
+ foreach my $f (@activates) {
+ next if ($f lt $min_activate);
+
+ my $sphinx_cmd = $f;
+ $sphinx_cmd =~ s/activate/sphinx-build/;
+ next if (! -f $sphinx_cmd);
+
+ $ver = get_sphinx_version($sphinx_cmd);
+ if ($need_sphinx && ($ver ge $min_version)) {
+ $activate = $f;
+ last;
+ } elsif ($ver gt $cur_version) {
+ $activate = $f;
+ last;
}
- if (index($system_release, "Debian") != -1) {
- $rel = $1 if ($system_release =~ /Debian\s+(\d+)/);
- if ($rel && $rel >= 7) {
- $rec_python3 = " -p python3";
- }
+ }
+ if ($activate ne "") {
+ if ($need_sphinx) {
+ printf "\nNeed to activate Sphinx (version $ver) on virtualenv with:\n";
+ printf "\t. $activate\n";
+ deactivate_help();
+ exit (1);
+ } else {
+ printf "\nYou may also use a newer Sphinx (version $ver) with:\n";
+ printf "\tdeactivate && . $activate\n";
}
+ } else {
+ my $rec_activate = "$virtenv_dir/bin/activate";
+
+ print "To upgrade Sphinx, use:\n\n" if ($rec_sphinx_upgrade);
+
+ $python_cmd = find_python_no_venv();
- printf "\t$virtualenv$rec_python3 $virtenv_dir\n";
+ if ($need_venv) {
+ printf "\t$python_cmd -m venv $virtenv_dir\n";
+ } else {
+ printf "\t$virtualenv_cmd $virtenv_dir\n";
+ }
printf "\t. $rec_activate\n";
printf "\tpip install -r $requirement_file\n";
deactivate_help();
@@ -780,6 +897,24 @@ $system_release = catcheck("/etc/system-release") if !$system_release;
$system_release = catcheck("/etc/redhat-release") if !$system_release;
$system_release = catcheck("/etc/lsb-release") if !$system_release;
$system_release = catcheck("/etc/gentoo-release") if !$system_release;
+
+# This seems more common than LSB these days
+if (!$system_release) {
+ my %os_var;
+ if (open IN, "cat /etc/os-release|") {
+ while (<IN>) {
+ if (m/^([\w\d\_]+)=\"?([^\"]*)\"?\n/) {
+ $os_var{$1}=$2;
+ }
+ }
+ $system_release = $os_var{"NAME"};
+ if (defined($os_var{"VERSION_ID"})) {
+ $system_release .= " " . $os_var{"VERSION_ID"} if (defined($os_var{"VERSION_ID"}));
+ } else {
+ $system_release .= " " . $os_var{"VERSION"};
+ }
+ }
+}
$system_release = catcheck("/etc/issue") if !$system_release;
$system_release =~ s/\s+$//;
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 4e18ae5282a6..850f4ccb6afc 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -26,7 +26,11 @@ else
fi
# ignore userspace tools
-ignore="$ignore ( -path ${tree}tools ) -prune -o"
+if [ -n "$COMPILED_SOURCE" ]; then
+ ignore="$ignore ( -path ./tools ) -prune -o"
+else
+ ignore="$ignore ( -path ${tree}tools ) -prune -o"
+fi
# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
if [ "${ALLSOURCE_ARCHS}" = "" ]; then
@@ -91,20 +95,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 $ignore -name "*.cmd" -exec \
+ grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ |
+ awk '!a[$0]++') | sort -u
}
all_target_sources()
diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh
index 7a2d372f4885..76e9cbcfbeab 100755
--- a/scripts/xz_wrap.sh
+++ b/scripts/xz_wrap.sh
@@ -20,4 +20,4 @@ case $SRCARCH in
sparc) BCJ=--sparc ;;
esac
-exec xz --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB
+exec $XZ --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB