summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Kbuild.include23
-rw-r--r--scripts/Kconfig.include8
-rw-r--r--scripts/Makefile3
-rw-r--r--scripts/Makefile.build121
-rw-r--r--scripts/Makefile.compiler12
-rw-r--r--scripts/Makefile.debug29
-rw-r--r--scripts/Makefile.extrawarn14
-rw-r--r--scripts/Makefile.gcc-plugins2
-rw-r--r--scripts/Makefile.host34
-rw-r--r--scripts/Makefile.kmsan8
-rw-r--r--scripts/Makefile.lib68
-rw-r--r--scripts/Makefile.modfinal10
-rw-r--r--scripts/Makefile.modinst3
-rw-r--r--scripts/Makefile.modpost114
-rw-r--r--scripts/Makefile.package9
-rw-r--r--scripts/Makefile.vmlinux21
-rw-r--r--scripts/Makefile.vmlinux_o47
-rw-r--r--scripts/asn1_compiler.c6
-rwxr-xr-xscripts/atomic/check-atomics.sh33
-rwxr-xr-xscripts/bloat-o-meter47
-rwxr-xr-xscripts/bpf_doc.py104
-rwxr-xr-xscripts/cc-version.sh12
-rwxr-xr-xscripts/check-blacklist-hashes.awk37
-rwxr-xr-xscripts/check-local-export97
-rwxr-xr-xscripts/checkpatch.pl25
-rwxr-xr-xscripts/checkstack.pl4
-rwxr-xr-xscripts/clang-tools/gen_compile_commands.py19
-rwxr-xr-xscripts/clang-tools/run-clang-tools.py2
-rw-r--r--scripts/coccinelle/api/alloc/zalloc-simple.cocci2
-rw-r--r--scripts/coccinelle/api/atomic_as_refcounter.cocci2
-rw-r--r--scripts/coccinelle/api/check_bq27xxx_data.cocci2
-rw-r--r--scripts/coccinelle/api/d_find_alias.cocci2
-rw-r--r--scripts/coccinelle/api/err_cast.cocci2
-rw-r--r--scripts/coccinelle/api/kstrdup.cocci2
-rw-r--r--scripts/coccinelle/api/memdup.cocci2
-rw-r--r--scripts/coccinelle/api/memdup_user.cocci2
-rw-r--r--scripts/coccinelle/api/pm_runtime.cocci2
-rw-r--r--scripts/coccinelle/api/resource_size.cocci2
-rw-r--r--scripts/coccinelle/free/clk_put.cocci2
-rw-r--r--scripts/coccinelle/free/devm_free.cocci2
-rw-r--r--scripts/coccinelle/free/ifnulldev_put.cocci55
-rw-r--r--scripts/coccinelle/free/iounmap.cocci2
-rw-r--r--scripts/coccinelle/free/kfree.cocci2
-rw-r--r--scripts/coccinelle/free/kfreeaddr.cocci2
-rw-r--r--scripts/coccinelle/free/pci_free_consistent.cocci2
-rw-r--r--scripts/coccinelle/iterators/device_node_continue.cocci2
-rw-r--r--scripts/coccinelle/iterators/for_each_child.cocci2
-rw-r--r--scripts/coccinelle/iterators/itnull.cocci2
-rw-r--r--scripts/coccinelle/iterators/list_entry_update.cocci2
-rw-r--r--scripts/coccinelle/iterators/use_after_iter.cocci2
-rw-r--r--scripts/coccinelle/locks/call_kern.cocci2
-rw-r--r--scripts/coccinelle/locks/double_lock.cocci2
-rw-r--r--scripts/coccinelle/locks/flags.cocci2
-rw-r--r--scripts/coccinelle/locks/mini_lock.cocci2
-rw-r--r--scripts/coccinelle/misc/boolreturn.cocci59
-rw-r--r--scripts/coccinelle/misc/cstptr.cocci2
-rw-r--r--scripts/coccinelle/misc/doubleinit.cocci2
-rw-r--r--scripts/coccinelle/misc/ifcol.cocci2
-rw-r--r--scripts/coccinelle/misc/newline_in_nl_msg.cocci2
-rw-r--r--scripts/coccinelle/misc/noderef.cocci2
-rw-r--r--scripts/coccinelle/misc/orplus.cocci2
-rw-r--r--scripts/coccinelle/misc/returnvar.cocci2
-rw-r--r--scripts/coccinelle/misc/semicolon.cocci2
-rw-r--r--scripts/coccinelle/misc/test_addr.cocci (renamed from scripts/coccinelle/misc/ifaddr.cocci)6
-rw-r--r--scripts/coccinelle/misc/warn.cocci2
-rw-r--r--scripts/coccinelle/null/badzero.cocci2
-rw-r--r--scripts/coccinelle/null/deref_null.cocci2
-rw-r--r--scripts/coccinelle/null/eno.cocci2
-rw-r--r--scripts/coccinelle/null/kmerr.cocci2
-rw-r--r--scripts/coccinelle/tests/doublebitand.cocci2
-rw-r--r--scripts/coccinelle/tests/doubletest.cocci2
-rw-r--r--scripts/coccinelle/tests/odd_ptr_err.cocci2
-rw-r--r--scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci2
-rwxr-xr-xscripts/decode_stacktrace.sh14
-rwxr-xr-xscripts/dtc/dt-extract-compatibles69
-rw-r--r--scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h0
-rwxr-xr-xscripts/dummy-tools/gcc10
-rwxr-xr-xscripts/extract-ikconfig1
-rwxr-xr-xscripts/faddr2line7
-rwxr-xr-xscripts/gcc-goto.sh22
-rwxr-xr-xscripts/gcc-ld30
-rw-r--r--scripts/gcc-plugins/latent_entropy_plugin.c2
-rw-r--r--scripts/gcc-plugins/stackleak_plugin.c2
-rw-r--r--scripts/gcc-plugins/structleak_plugin.c2
-rw-r--r--scripts/gdb/linux/dmesg.py9
-rw-r--r--scripts/gdb/linux/symbols.py2
-rw-r--r--scripts/gdb/linux/utils.py14
-rw-r--r--scripts/gdb/vmlinux-gdb.py2
-rwxr-xr-xscripts/generate_rust_analyzer.py135
-rw-r--r--scripts/generate_rust_target.rs182
-rwxr-xr-xscripts/get_feat.pl2
-rw-r--r--scripts/head-object-list.txt53
-rwxr-xr-xscripts/headers_install.sh2
-rwxr-xr-xscripts/is_rust_module.sh16
-rw-r--r--scripts/kallsyms.c108
-rw-r--r--scripts/kconfig/conf.c2
-rw-r--r--scripts/kconfig/confdata.c75
-rw-r--r--scripts/kconfig/lkc.h6
-rw-r--r--scripts/kconfig/menu.c5
-rwxr-xr-xscripts/kconfig/qconf-cfg.sh1
-rwxr-xr-xscripts/kernel-doc82
-rwxr-xr-xscripts/link-vmlinux.sh72
-rwxr-xr-xscripts/min-tool-version.sh6
-rwxr-xr-xscripts/mkcompile_h96
-rwxr-xr-xscripts/mksysmap24
-rw-r--r--scripts/mod/file2alias.c4
-rw-r--r--scripts/mod/modpost.c288
-rw-r--r--scripts/mod/modpost.h33
-rw-r--r--scripts/module.lds.S25
-rwxr-xr-xscripts/package/mkspec7
-rwxr-xr-xscripts/remove-stale-files6
-rwxr-xr-xscripts/rust_is_available.sh160
-rw-r--r--scripts/rust_is_available_bindgen_libclang.h2
-rwxr-xr-xscripts/selinux/install_policy.sh5
-rw-r--r--scripts/sign-file.c2
-rwxr-xr-xscripts/sphinx-pre-install90
-rwxr-xr-xscripts/tags.sh9
-rwxr-xr-xscripts/tracing/draw_functrace.py2
119 files changed, 1698 insertions, 1105 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index eed308bef604..b7aec8eb1bd4 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
/asn1_compiler
/bin2c
+/generate_rust_target
/insert-sys-cert
/kallsyms
/module.lds
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index ece44b735061..2bc08ace38a3 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\
quiet_redirect :=
silent_redirect := exec >/dev/null;
+# Delete the target on interruption
+#
+# GNU Make automatically deletes the target if it has already been changed by
+# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make
+# will delete incomplete targets), and resume it later.
+#
+# However, this does not work when the stderr is piped to another program, like
+# $ make >&2 | tee log
+# Make dies with SIGPIPE before cleaning the targets.
+#
+# To address it, we clean the target in signal traps.
+#
+# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM.
+# So, we cover them, and also SIGPIPE just in case.
+#
+# Of course, this is unneeded for phony targets.
+delete-on-interrupt = \
+ $(if $(filter-out $(PHONY), $@), \
+ $(foreach sig, HUP INT QUIT TERM PIPE, \
+ trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
+
# printing commands
-cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1))
+cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1))
###
# if_changed - execute command if any prerequisite is newer than
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include
index 0496efd6e117..274125307ebd 100644
--- a/scripts/Kconfig.include
+++ b/scripts/Kconfig.include
@@ -25,7 +25,7 @@ failure = $(if-success,$(1),n,y)
# $(cc-option,<flag>)
# Return y if the compiler supports <flag>, n otherwise
-cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o)
+cc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(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
@@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1))
as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)
# check if $(CC) and $(LD) exist
-$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
+$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
-# Get the compiler name, version, and error out if it is not supported.
+# Get the C compiler name, version, and error out if it is not supported.
cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
-$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.)
+$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.)
cc-name := $(shell,set -- $(cc-info) && echo $1)
cc-version := $(shell,set -- $(cc-info) && echo $2)
diff --git a/scripts/Makefile b/scripts/Makefile
index f084f08ed176..1575af84d557 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,6 +10,9 @@ 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_EXTRA_CERTIFICATE) += insert-sys-cert
+hostprogs-always-$(CONFIG_RUST) += generate_rust_target
+
+generate_rust_target-rust := y
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
HOSTLDLIBS_sorttable = -lpthread
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index cac070aee791..22adbf89cb31 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -5,8 +5,8 @@
src := $(obj)
-PHONY := __build
-__build:
+PHONY := $(obj)/
+$(obj)/:
# Init all relevant variables used in kbuild files so
# 1) they have correct type
@@ -26,6 +26,7 @@ EXTRA_CPPFLAGS :=
EXTRA_LDFLAGS :=
asflags-y :=
ccflags-y :=
+rustflags-y :=
cppflags-y :=
ldflags-y :=
@@ -271,6 +272,65 @@ quiet_cmd_cc_lst_c = MKLST $@
$(obj)/%.lst: $(src)/%.c FORCE
$(call if_changed_dep,cc_lst_c)
+# Compile Rust sources (.rs)
+# ---------------------------------------------------------------------------
+
+rust_allowed_features := core_ffi_c
+
+rust_common_cmd = \
+ RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \
+ -Zallow-features=$(rust_allowed_features) \
+ -Zcrate-attr=no_std \
+ -Zcrate-attr='feature($(rust_allowed_features))' \
+ --extern alloc --extern kernel \
+ --crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \
+ --crate-name $(basename $(notdir $@))
+
+rust_handle_depfile = \
+ mv $(obj)/$(basename $(notdir $@)).d $(depfile); \
+ sed -i '/^\#/d' $(depfile)
+
+# `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit
+# will be used. We explicitly request `-Ccodegen-units=1` in any case, and
+# the compiler shows a warning if it is not 1. However, if we ever stop
+# requesting it explicitly and we start using some other `--emit` that does not
+# imply it (and for which codegen is performed), then we would be out of sync,
+# i.e. the outputs we would get for the different single targets (e.g. `.ll`)
+# would not match each other.
+
+quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+ cmd_rustc_o_rs = \
+ $(rust_common_cmd) --emit=dep-info,obj $<; \
+ $(rust_handle_depfile)
+
+$(obj)/%.o: $(src)/%.rs FORCE
+ $(call if_changed_dep,rustc_o_rs)
+
+quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+ cmd_rustc_rsi_rs = \
+ $(rust_common_cmd) --emit=dep-info -Zunpretty=expanded $< >$@; \
+ command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \
+ $(rust_handle_depfile)
+
+$(obj)/%.rsi: $(src)/%.rs FORCE
+ $(call if_changed_dep,rustc_rsi_rs)
+
+quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+ cmd_rustc_s_rs = \
+ $(rust_common_cmd) --emit=dep-info,asm $<; \
+ $(rust_handle_depfile)
+
+$(obj)/%.s: $(src)/%.rs FORCE
+ $(call if_changed_dep,rustc_s_rs)
+
+quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+ cmd_rustc_ll_rs = \
+ $(rust_common_cmd) --emit=dep-info,llvm-ir $<; \
+ $(rust_handle_depfile)
+
+$(obj)/%.ll: $(src)/%.rs FORCE
+ $(call if_changed_dep,rustc_ll_rs)
+
# Compile assembler sources (.S)
# ---------------------------------------------------------------------------
@@ -323,7 +383,7 @@ $(obj)/%.o: $(src)/%.S FORCE
targets += $(filter-out $(subdir-builtin), $(real-obj-y))
targets += $(filter-out $(subdir-modorder), $(real-obj-m))
-targets += $(real-dtb-y) $(lib-y) $(always-y) $(MAKECMDGOALS)
+targets += $(real-dtb-y) $(lib-y) $(always-y)
# Linker scripts preprocessor (.lds.S -> .lds)
# ---------------------------------------------------------------------------
@@ -358,9 +418,8 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
quiet_cmd_ar_builtin = AR $@
cmd_ar_builtin = rm -f $@; \
- echo $(patsubst $(obj)/%,%,$(real-prereqs)) | \
- sed -E 's:([^ ]+):$(obj)/\1:g' | \
- xargs $(AR) cDPrST $@
+ $(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \
+ $(AR) cDPrST $@
$(obj)/built-in.a: $(real-obj-y) FORCE
$(call if_changed,ar_builtin)
@@ -375,7 +434,7 @@ $(obj)/built-in.a: $(real-obj-y) FORCE
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)
@@ -401,8 +460,6 @@ $(multi-obj-m): %.o: %.mod FORCE
$(call if_changed_rule,ld_multi_m)
$(call multi_depend, $(multi-obj-m), .o, -objs -y -m)
-targets := $(filter-out $(PHONY), $(targets))
-
# Add intermediate targets:
# When building objects with specific suffix patterns, add intermediate
# targets that the final targets are derived from.
@@ -421,52 +478,29 @@ targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \
# Build
# ---------------------------------------------------------------------------
-ifdef single-build
-
-KBUILD_SINGLE_TARGETS := $(filter $(obj)/%, $(KBUILD_SINGLE_TARGETS))
-
-curdir-single := $(sort $(foreach x, $(KBUILD_SINGLE_TARGETS), \
- $(if $(filter $(x) $(basename $(x)).o, $(targets)), $(x))))
-
-# Handle single targets without any rule: show "Nothing to be done for ..." or
-# "No rule to make target ..." depending on whether the target exists.
-unknown-single := $(filter-out $(addsuffix /%, $(subdir-ym)), \
- $(filter-out $(curdir-single), $(KBUILD_SINGLE_TARGETS)))
-
-single-subdirs := $(foreach d, $(subdir-ym), \
- $(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d)))
-
-__build: $(curdir-single) $(single-subdirs)
-ifneq ($(unknown-single),)
- $(Q)$(MAKE) -f /dev/null $(unknown-single)
-endif
+$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
+ $(if $(KBUILD_MODULES), $(targets-for-modules)) \
+ $(subdir-ym) $(always-y)
@:
-ifeq ($(curdir-single),)
-# Nothing to do in this directory. Do not include any .*.cmd file for speed-up
-targets :=
-else
-targets += $(curdir-single)
-endif
+# Single targets
+# ---------------------------------------------------------------------------
-else
+single-subdirs := $(foreach d, $(subdir-ym), $(if $(filter $d/%, $(MAKECMDGOALS)), $d))
+single-subdir-goals := $(filter $(addsuffix /%, $(single-subdirs)), $(MAKECMDGOALS))
-__build: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
- $(if $(KBUILD_MODULES), $(targets-for-modules)) \
- $(subdir-ym) $(always-y)
+$(single-subdir-goals): $(single-subdirs)
@:
-endif
-
# Descending
# ---------------------------------------------------------------------------
PHONY += $(subdir-ym)
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@ \
- $(if $(filter $@/, $(KBUILD_SINGLE_TARGETS)),single-build=) \
need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \
- need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1)
+ need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) \
+ $(filter $@/%, $(single-subdir-goals))
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
@@ -475,6 +509,9 @@ PHONY += FORCE
FORCE:
+targets += $(filter-out $(single-subdir-goals), $(MAKECMDGOALS))
+targets := $(filter-out $(PHONY), $(targets))
+
# Read all saved command lines and dependencies for the $(targets) we
# may be building above, using $(if_changed{,_dep}). As an
# optimization, we don't need to read them if the target does not
diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler
index 86ecd2ac874c..20d353dcabfb 100644
--- a/scripts/Makefile.compiler
+++ b/scripts/Makefile.compiler
@@ -21,8 +21,8 @@ TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
# automatically cleaned up.
try-run = $(shell set -e; \
TMP=$(TMPOUT)/tmp; \
- mkdir -p $(TMPOUT); \
trap "rm -rf $(TMPOUT)" EXIT; \
+ mkdir -p $(TMPOUT); \
if ($(1)) >/dev/null 2>&1; \
then echo "$(2)"; \
else echo "$(3)"; \
@@ -61,9 +61,13 @@ cc-option-yn = $(call try-run,\
cc-disable-warning = $(call try-run,\
$(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)
-cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4))
+# gcc-min-version
+# Usage: cflags-$(call gcc-min-version, 70100) += -foo
+gcc-min-version = $(shell [ $(CONFIG_GCC_VERSION)0 -ge $(1)0 ] && echo y)
+
+# clang-min-version
+# Usage: cflags-$(call clang-min-version, 110000) += -foo
+clang-min-version = $(shell [ $(CONFIG_CLANG_VERSION)0 -ge $(1)0 ] && echo y)
# ld-option
# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug
index 9f39b0130551..332c486f705f 100644
--- a/scripts/Makefile.debug
+++ b/scripts/Makefile.debug
@@ -1,26 +1,30 @@
DEBUG_CFLAGS :=
+DEBUG_RUSTFLAGS :=
+
+debug-flags-y := -g
ifdef CONFIG_DEBUG_INFO_SPLIT
DEBUG_CFLAGS += -gsplit-dwarf
-else
-DEBUG_CFLAGS += -g
-endif
-
-ifndef CONFIG_AS_IS_LLVM
-KBUILD_AFLAGS += -Wa,-gdwarf-2
endif
-ifndef CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
-dwarf-version-$(CONFIG_DEBUG_INFO_DWARF4) := 4
-dwarf-version-$(CONFIG_DEBUG_INFO_DWARF5) := 5
-DEBUG_CFLAGS += -gdwarf-$(dwarf-version-y)
+debug-flags-$(CONFIG_DEBUG_INFO_DWARF4) += -gdwarf-4
+debug-flags-$(CONFIG_DEBUG_INFO_DWARF5) += -gdwarf-5
+ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_AS_IS_GNU),yy)
+# Clang does not pass -g or -gdwarf-* option down to GAS.
+# Add -Wa, prefix to explicitly specify the flags.
+KBUILD_AFLAGS += $(addprefix -Wa$(comma), $(debug-flags-y))
endif
+DEBUG_CFLAGS += $(debug-flags-y)
+KBUILD_AFLAGS += $(debug-flags-y)
ifdef CONFIG_DEBUG_INFO_REDUCED
DEBUG_CFLAGS += -fno-var-tracking
+DEBUG_RUSTFLAGS += -Cdebuginfo=1
ifdef CONFIG_CC_IS_GCC
DEBUG_CFLAGS += -femit-struct-debug-baseonly
endif
+else
+DEBUG_RUSTFLAGS += -Cdebuginfo=2
endif
ifdef CONFIG_DEBUG_INFO_COMPRESSED
@@ -29,5 +33,8 @@ KBUILD_AFLAGS += -gz=zlib
KBUILD_LDFLAGS += --compress-debug-sections=zlib
endif
-KBUILD_CFLAGS += $(DEBUG_CFLAGS)
+KBUILD_CFLAGS += $(DEBUG_CFLAGS)
export DEBUG_CFLAGS
+
+KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS)
+export DEBUG_RUSTFLAGS
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index f5f0d6f09053..6bbba36c5969 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -47,12 +47,24 @@ else
ifdef CONFIG_CC_IS_CLANG
KBUILD_CFLAGS += -Wno-initializer-overrides
+# Clang before clang-16 would warn on default argument promotions.
+ifneq ($(call clang-min-version, 160000),y)
+# Disable -Wformat
KBUILD_CFLAGS += -Wno-format
+# Then re-enable flags that were part of the -Wformat group that aren't
+# problematic.
+KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier
+KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull
+# Requires clang-12+.
+ifeq ($(call clang-min-version, 120000),y)
+KBUILD_CFLAGS += -Wformat-insufficient-args
+endif
+endif
KBUILD_CFLAGS += -Wno-sign-compare
-KBUILD_CFLAGS += -Wno-format-zero-length
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
+KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
endif
endif
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 692d64a70542..e4deaf5fa571 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -4,7 +4,7 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \
+= -DLATENT_ENTROPY_PLUGIN
ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
- DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable
+ DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable -ULATENT_ENTROPY_PLUGIN
endif
export DISABLE_LATENT_ENTROPY_PLUGIN
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 278b4d6ac945..da133780b751 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -22,6 +22,8 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
# to preprocess a data file.
#
# Both C and C++ are supported, but preferred language is C for such utilities.
+# Rust is also supported, but it may only be used in scenarios where a Rust
+# toolchain is required to be available (e.g. when `CONFIG_RUST` is enabled).
#
# Sample syntax (see Documentation/kbuild/makefiles.rst for reference)
# hostprogs := bin2hex
@@ -37,15 +39,20 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
# qconf-objs := menu.o
# Will compile qconf as a C++ program, and menu as a C program.
# They are linked as C++ code to the executable qconf
+#
+# hostprogs := target
+# target-rust := y
+# Will compile `target` as a Rust program, using `target.rs` as the crate root.
+# The crate may consist of several source files.
# C code
# Executables compiled from a single .c file
host-csingle := $(foreach m,$(hostprogs), \
- $(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
+ $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m)))
# C executables linked based on several .o files
host-cmulti := $(foreach m,$(hostprogs),\
- $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
+ $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m))))
# Object (.o) files compiled from .c files
host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
@@ -58,11 +65,17 @@ 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)))
+# Rust code
+# Executables compiled from a single Rust crate (which may consist of
+# one or more .rs files)
+host-rust := $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m)))
+
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-rust := $(addprefix $(obj)/,$(host-rust))
#####
# Handle options to gcc. Support building with separate output directory
@@ -71,6 +84,8 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
$(HOSTCFLAGS_$(target-stem).o)
_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
$(HOSTCXXFLAGS_$(target-stem).o)
+_hostrust_flags = $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
+ $(HOSTRUSTFLAGS_$(target-stem))
# $(objtree)/$(obj) for including generated headers from checkin source files
ifeq ($(KBUILD_EXTMOD),)
@@ -82,6 +97,7 @@ endif
hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags)
hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags)
+hostrust_flags = $(_hostrust_flags)
#####
# Compile programs on the host
@@ -128,5 +144,17 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
+# Create executable from a single Rust crate (which may consist of
+# one or more `.rs` files)
+# host-rust -> Executable
+quiet_cmd_host-rust = HOSTRUSTC $@
+ cmd_host-rust = \
+ $(HOSTRUSTC) $(hostrust_flags) --emit=dep-info,link \
+ --out-dir=$(obj)/ $<; \
+ mv $(obj)/$(target-stem).d $(depfile); \
+ sed -i '/^\#/d' $(depfile)
+$(host-rust): $(obj)/%: $(src)/%.rs FORCE
+ $(call if_changed_dep,host-rust)
+
targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
- $(host-cxxmulti) $(host-cxxobjs)
+ $(host-cxxmulti) $(host-cxxobjs) $(host-rust)
diff --git a/scripts/Makefile.kmsan b/scripts/Makefile.kmsan
new file mode 100644
index 000000000000..b5b0aa61322e
--- /dev/null
+++ b/scripts/Makefile.kmsan
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+kmsan-cflags := -fsanitize=kernel-memory
+
+ifdef CONFIG_KMSAN_CHECK_PARAM_RETVAL
+kmsan-cflags += -fsanitize-memory-param-retval
+endif
+
+export CFLAGS_KMSAN := $(kmsan-cflags)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 3fb6a99e78c4..3aa384cec76b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -8,6 +8,7 @@ ldflags-y += $(EXTRA_LDFLAGS)
# flags that take effect in current and sub directories
KBUILD_AFLAGS += $(subdir-asflags-y)
KBUILD_CFLAGS += $(subdir-ccflags-y)
+KBUILD_RUSTFLAGS += $(subdir-rustflags-y)
# Figure out what we need to build from the various variables
# ===========================================================================
@@ -89,6 +90,7 @@ always-y += $(dtb-y)
# Add subdir path
+ifneq ($(obj),.)
extra-y := $(addprefix $(obj)/,$(extra-y))
always-y := $(addprefix $(obj)/,$(always-y))
targets := $(addprefix $(obj)/,$(targets))
@@ -100,6 +102,7 @@ multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m))
multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y))
real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y))
subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
+endif
# Finds the multi-part object the current object will be linked into.
# If the object belongs to two or more multi-part objects, list them all.
@@ -128,6 +131,10 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(ccflags-remove-y), \
$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
$(CFLAGS_$(target-stem).o))
+_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \
+ $(filter-out $(rustflags-remove-y), \
+ $(KBUILD_RUSTFLAGS) $(rustflags-y)) \
+ $(RUSTFLAGS_$(target-stem).o))
_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(asflags-remove-y), \
$(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
@@ -157,6 +164,15 @@ _c_flags += $(if $(patsubst n%,, \
endif
endif
+ifeq ($(CONFIG_KMSAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \
+ $(CFLAGS_KMSAN))
+_c_flags += $(if $(patsubst n%,, \
+ $(KMSAN_ENABLE_CHECKS_$(basetarget).o)$(KMSAN_ENABLE_CHECKS)y), \
+ , -mllvm -msan-disable-checks=1)
+endif
+
ifeq ($(CONFIG_UBSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \
@@ -202,6 +218,11 @@ modkern_cflags = \
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags))
+modkern_rustflags = \
+ $(if $(part-of-module), \
+ $(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \
+ $(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL))
+
modkern_aflags = $(if $(part-of-module), \
$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \
$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
@@ -211,6 +232,8 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_c_flags) $(modkern_cflags) \
$(basename_flags) $(modname_flags)
+rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
+
a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_a_flags) $(modkern_aflags)
@@ -229,25 +252,26 @@ ifdef CONFIG_OBJTOOL
objtool := $(objtree)/tools/objtool/objtool
-objtool_args = \
- $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
- $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \
- $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \
- $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
- $(if $(CONFIG_UNWINDER_ORC), --orc) \
- $(if $(CONFIG_RETPOLINE), --retpoline) \
- $(if $(CONFIG_RETHUNK), --rethunk) \
- $(if $(CONFIG_SLS), --sls) \
- $(if $(CONFIG_STACK_VALIDATION), --stackval) \
- $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \
- $(if $(CONFIG_HAVE_UACCESS_VALIDATION), --uaccess) \
+objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label
+objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr
+objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt
+objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount
+objtool-args-$(CONFIG_UNWINDER_ORC) += --orc
+objtool-args-$(CONFIG_RETPOLINE) += --retpoline
+objtool-args-$(CONFIG_RETHUNK) += --rethunk
+objtool-args-$(CONFIG_SLS) += --sls
+objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval
+objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
+objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
+objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
+
+objtool-args = $(objtool-args-y) \
$(if $(delay-objtool), --link) \
- $(if $(part-of-module), --module) \
- $(if $(CONFIG_GCOV_KERNEL), --no-unreachable)
+ $(if $(part-of-module), --module)
delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT))
-cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@)
+cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@)
cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
endif # CONFIG_OBJTOOL
@@ -371,17 +395,15 @@ DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m)
DT_BINDING_DIR := Documentation/devicetree/bindings
DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json
-quiet_cmd_dtb_check = CHECK $@
- cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true
+quiet_cmd_dtb = DTC_CHK $@
+ cmd_dtb = $(cmd_dtc) ; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true
+else
+quiet_cmd_dtb = $(quiet_cmd_dtc)
+ cmd_dtb = $(cmd_dtc)
endif
-define rule_dtc
- $(call cmd_and_fixdep,dtc)
- $(call cmd,dtb_check)
-endef
-
$(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
- $(call if_changed_rule,dtc)
+ $(call if_changed_dep,dtb)
$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
$(call if_changed_dep,dtc)
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index 35100e981f4a..25bedd83644b 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M] $@
quiet_cmd_btf_ko = BTF [M] $@
cmd_btf_ko = \
- if [ -f vmlinux ]; then \
+ if [ ! -f vmlinux ]; then \
+ printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
+ elif [ -n "$(CONFIG_RUST)" ] && $(srctree)/scripts/is_rust_module.sh $@; then \
+ printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \
+ else \
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
$(RESOLVE_BTFIDS) -b vmlinux $@; \
- else \
- printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
fi;
# Same as newer-prereqs, but allows to exclude specified extra dependencies
@@ -55,7 +57,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
# Re-generate module BTFs if either module's .ko or vmlinux changed
-$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
+$(modules): %.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
+$(call if_changed_except,ld_ko_o,vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 16a02e9237d3..a4c987c23750 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -18,6 +18,9 @@ INSTALL_MOD_DIR ?= extra
dst := $(MODLIB)/$(INSTALL_MOD_DIR)
endif
+$(foreach x, % :, $(if $(findstring $x, $(dst)), \
+ $(error module installation path cannot contain '$x')))
+
suffix-y :=
suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 911606496341..7740ce3b29e8 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -32,49 +32,58 @@
# Step 4 is solely used to allow module versioning in external modules,
# where the CRC of each module is retrieved from the Module.symvers file.
-# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
-# This is solely useful to speed up test compiles
-
PHONY := __modpost
__modpost:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
-MODPOST = scripts/mod/modpost \
+modpost-args = \
$(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
+ $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
+ $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \
-o $@
-ifdef MODPOST_VMLINUX
-
-quiet_cmd_modpost = MODPOST $@
- cmd_modpost = $(MODPOST) $<
-
-vmlinux.symvers: vmlinux.o
- $(call cmd,modpost)
-
-__modpost: vmlinux.symvers
-
-else
+# 'make -i -k' ignores compile errors, and builds as many modules as possible.
+ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),)
+modpost-args += -n
+endif
ifeq ($(KBUILD_EXTMOD),)
-input-symdump := vmlinux.symvers
-output-symdump := modules-only.symvers
-
-quiet_cmd_cat = GEN $@
- cmd_cat = cat $(real-prereqs) > $@
+# Generate the list of in-tree objects in vmlinux
+# ---------------------------------------------------------------------------
-ifneq ($(wildcard vmlinux.symvers),)
-
-__modpost: Module.symvers
-Module.symvers: vmlinux.symvers modules-only.symvers FORCE
- $(call if_changed,cat)
-
-targets += Module.symvers
+# This is used to retrieve symbol versions generated by genksyms.
+ifdef CONFIG_MODVERSIONS
+vmlinux.symvers Module.symvers: .vmlinux.objs
+endif
+# Ignore libgcc.a
+# Some architectures do '$(CC) --print-libgcc-file-name' to borrow libgcc.a
+# from the toolchain, but there is no EXPORT_SYMBOL in it.
+
+quiet_cmd_vmlinux_objs = GEN $@
+ cmd_vmlinux_objs = \
+ for f in $(real-prereqs); do \
+ case $${f} in \
+ *libgcc.a) ;; \
+ *) $(AR) t $${f} ;; \
+ esac \
+ done > $@
+
+targets += .vmlinux.objs
+.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
+ $(call if_changed,vmlinux_objs)
+
+vmlinux.o-if-present := $(wildcard vmlinux.o)
+output-symdump := vmlinux.symvers
+
+ifdef KBUILD_MODULES
+output-symdump := $(if $(vmlinux.o-if-present), Module.symvers, modules-only.symvers)
+missing-input := $(filter-out $(vmlinux.o-if-present),vmlinux.o)
endif
else
@@ -86,54 +95,37 @@ src := $(obj)
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
include $(or $(wildcard $(src)/Kbuild), $(src)/Makefile)
-# modpost option for external modules
-MODPOST += -e
-
-input-symdump := Module.symvers $(KBUILD_EXTRA_SYMBOLS)
+module.symvers-if-present := $(wildcard Module.symvers)
output-symdump := $(KBUILD_EXTMOD)/Module.symvers
+missing-input := $(filter-out $(module.symvers-if-present), Module.symvers)
-endif
-
-existing-input-symdump := $(wildcard $(input-symdump))
+modpost-args += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS))
-# modpost options for modules (both in-kernel and external)
-MODPOST += \
- $(addprefix -i ,$(existing-input-symdump)) \
- $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
- $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N)
+endif # ($(KBUILD_EXTMOD),)
-# 'make -i -k' ignores compile errors, and builds as many modules as possible.
-ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),)
-MODPOST += -n
+ifneq ($(KBUILD_MODPOST_WARN)$(missing-input),)
+modpost-args += -w
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.'
- @echo >&2 ' You may get many unresolved symbol warnings.'
+modorder-if-needed := $(if $(KBUILD_MODULES), $(MODORDER))
-# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
-ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)
-MODPOST += -w
-endif
+MODPOST = scripts/mod/modpost
# Read out modules.order to pass in modpost.
# Otherwise, allmodconfig would fail with "Argument list too long".
quiet_cmd_modpost = MODPOST $@
- cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T -
-
-$(output-symdump): $(MODORDER) $(input-symdump) FORCE
- $(call if_changed,modpost)
+ cmd_modpost = \
+ $(if $(missing-input), \
+ echo >&2 "WARNING: $(missing-input) is missing."; \
+ echo >&2 " Modules may not have dependencies or modversions."; \
+ echo >&2 " You may get many unresolved symbol warnings.";) \
+ sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) $(vmlinux.o-if-present) -T -
targets += $(output-symdump)
+$(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(moudle.symvers-if-present) $(MODPOST) FORCE
+ $(call if_changed,modpost)
__modpost: $(output-symdump)
-ifneq ($(KBUILD_MODPOST_NOFINAL),1)
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
-endif
-
PHONY += FORCE
FORCE:
@@ -141,6 +133,4 @@ 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 77b612183c08..8bbcced67c22 100644
--- a/scripts/Makefile.package
+++ b/scripts/Makefile.package
@@ -29,7 +29,10 @@ KDEB_SOURCENAME ?= linux-upstream
KBUILD_PKG_ROOTCMD ?="fakeroot -u"
export KDEB_SOURCENAME
# Include only those top-level files that are needed by make, plus the GPL copy
-TAR_CONTENT := $(KBUILD_ALLDIRS) .config .scmversion Makefile \
+TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \
+ include init io_uring ipc kernel lib mm net samples scripts \
+ security sound tools usr virt \
+ .config .scmversion Makefile \
Kbuild Kconfig COPYING $(wildcard localversion*)
MKSPEC := $(srctree)/scripts/package/mkspec
@@ -56,7 +59,7 @@ rpm-pkg:
$(MAKE) clean
$(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
- +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \
+ +rpmbuild $(RPMOPTS) --target $(UTS_MACHINE)-linux -ta $(KERNELPATH).tar.gz \
--define='_smp_mflags %{nil}'
# binrpm-pkg
@@ -66,7 +69,7 @@ binrpm-pkg:
$(MAKE) -f $(srctree)/Makefile
$(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec
+rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
- $(UTS_MACHINE) -bb $(objtree)/binkernel.spec
+ $(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec
PHONY += deb-pkg
deb-pkg:
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
index 7a63abf22399..49946cb96844 100644
--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -1,18 +1,37 @@
# SPDX-License-Identifier: GPL-2.0-only
+PHONY := __default
+__default: vmlinux
+
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
include $(srctree)/scripts/Makefile.lib
+targets :=
+
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
%.o: %.c FORCE
$(call if_changed_dep,cc_o_c)
-targets := $(MAKECMDGOALS)
+ifdef CONFIG_MODULES
+targets += .vmlinux.export.o
+vmlinux: .vmlinux.export.o
+endif
+
+ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
+
+# Final link of vmlinux with optional arch pass after final link
+cmd_link_vmlinux = \
+ $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \
+ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
+
+targets += vmlinux
+vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
+ +$(call if_changed_dep,link_vmlinux)
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 84019814f33f..0edfdb40364b 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
PHONY := __default
-__default: vmlinux.o
+__default: vmlinux.o modules.builtin.modinfo modules.builtin
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
@@ -18,7 +18,7 @@ quiet_cmd_gen_initcalls_lds = GEN $@
$(PERL) $(real-prereqs) > $@
.tmp_initcalls.lds: $(srctree)/scripts/generate_initcall_order.pl \
- $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE
+ vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
$(call if_changed,gen_initcalls_lds)
targets := .tmp_initcalls.lds
@@ -35,18 +35,11 @@ endif
objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
-# Reuse objtool_args defined in scripts/Makefile.lib if LTO or IBT is enabled.
-#
-# Add some more flags as needed.
-# --no-unreachable and --link might be added twice, but it is fine.
-#
-# Expand objtool_args to a simple variable to avoid circular reference.
+vmlinux-objtool-args-$(delay-objtool) += $(objtool-args-y)
+vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
+vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret)
-objtool_args := \
- $(if $(delay-objtool),$(objtool_args)) \
- $(if $(CONFIG_NOINSTR_VALIDATION), --noinstr $(if $(CONFIG_CPU_UNRET_ENTRY), --unret)) \
- $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \
- --link
+objtool-args = $(vmlinux-objtool-args-y) --link
# Link of vmlinux.o used for section mismatch analysis
# ---------------------------------------------------------------------------
@@ -55,7 +48,7 @@ quiet_cmd_ld_vmlinux.o = LD $@
cmd_ld_vmlinux.o = \
$(LD) ${KBUILD_LDFLAGS} -r -o $@ \
$(addprefix -T , $(initcalls-lds)) \
- --whole-archive $(KBUILD_VMLINUX_OBJS) --no-whole-archive \
+ --whole-archive vmlinux.a --no-whole-archive \
--start-group $(KBUILD_VMLINUX_LIBS) --end-group \
$(cmd_objtool)
@@ -64,11 +57,35 @@ define rule_ld_vmlinux.o
$(call cmd,gen_objtooldep)
endef
-vmlinux.o: $(initcalls-lds) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) FORCE
+vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
$(call if_changed_rule,ld_vmlinux.o)
targets += vmlinux.o
+# module.builtin.modinfo
+# ---------------------------------------------------------------------------
+
+OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary
+
+targets += modules.builtin.modinfo
+modules.builtin.modinfo: vmlinux.o FORCE
+ $(call if_changed,objcopy)
+
+# module.builtin
+# ---------------------------------------------------------------------------
+
+# The second line aids cases where multiple modules share the same object.
+
+quiet_cmd_modules_builtin = GEN $@
+ cmd_modules_builtin = \
+ tr '\0' '\n' < $< | \
+ sed -n 's/^[[:alnum:]:_]*\.file=//p' | \
+ tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@
+
+targets += modules.builtin
+modules.builtin: modules.builtin.modinfo FORCE
+ $(call if_changed,modules_builtin)
+
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
diff --git a/scripts/asn1_compiler.c b/scripts/asn1_compiler.c
index adabd4145264..71d4a7c87900 100644
--- a/scripts/asn1_compiler.c
+++ b/scripts/asn1_compiler.c
@@ -832,7 +832,7 @@ static void parse(void)
static struct element *element_list;
-static struct element *alloc_elem(struct token *type)
+static struct element *alloc_elem(void)
{
struct element *e = calloc(1, sizeof(*e));
if (!e) {
@@ -860,7 +860,7 @@ static struct element *parse_type(struct token **_cursor, struct token *end,
char *p;
int labelled = 0, implicit = 0;
- top = element = alloc_elem(cursor);
+ top = element = alloc_elem();
element->class = ASN1_UNIV;
element->method = ASN1_PRIM;
element->tag = token_to_tag[cursor->token_type];
@@ -939,7 +939,7 @@ static struct element *parse_type(struct token **_cursor, struct token *end,
if (!implicit)
element->method |= ASN1_CONS;
element->compound = implicit ? TAG_OVERRIDE : SEQUENCE;
- element->children = alloc_elem(cursor);
+ element->children = alloc_elem();
element = element->children;
element->class = ASN1_UNIV;
element->method = ASN1_PRIM;
diff --git a/scripts/atomic/check-atomics.sh b/scripts/atomic/check-atomics.sh
deleted file mode 100755
index 0e7bab3eb0d1..000000000000
--- a/scripts/atomic/check-atomics.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-#
-# Check if atomic headers are up-to-date
-
-ATOMICDIR=$(dirname $0)
-ATOMICTBL=${ATOMICDIR}/atomics.tbl
-LINUXDIR=${ATOMICDIR}/../..
-
-echo '' | sha1sum - > /dev/null 2>&1
-if [ $? -ne 0 ]; then
- printf "sha1sum not available, skipping atomic header checks.\n"
- exit 0
-fi
-
-cat <<EOF |
-linux/atomic/atomic-instrumented.h
-linux/atomic/atomic-long.h
-linux/atomic/atomic-arch-fallback.h
-EOF
-while read header; do
- OLDSUM="$(tail -n 1 ${LINUXDIR}/include/${header})"
- OLDSUM="${OLDSUM#// }"
-
- NEWSUM="$(sed '$d' ${LINUXDIR}/include/${header} | sha1sum)"
- NEWSUM="${NEWSUM%% *}"
-
- if [ "${OLDSUM}" != "${NEWSUM}" ]; then
- printf "warning: generated include/${header} has been modified.\n"
- fi
-done
-
-exit 0
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index 4dd6a804ce41..f9553f60a14a 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -7,24 +7,31 @@
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
-import sys, os, re
+import sys, os, re, argparse
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
-if len(sys.argv) < 3:
- sys.stderr.write("usage: %s [option] file1 file2\n" % sys.argv[0])
- sys.stderr.write("The options are:\n")
- sys.stderr.write("-c categorize output based on symbol type\n")
- sys.stderr.write("-d Show delta of Data Section\n")
- sys.stderr.write("-t Show delta of text Section\n")
- sys.exit(-1)
+parser = argparse.ArgumentParser(description="Simple script used to compare the symbol sizes of 2 object files")
+group = parser.add_mutually_exclusive_group()
+group.add_argument('-c', help='categorize output based on symbol type', action='store_true')
+group.add_argument('-d', help='Show delta of Data Section', action='store_true')
+group.add_argument('-t', help='Show delta of text Section', action='store_true')
+parser.add_argument('-p', dest='prefix', help='Arch prefix for the tool being used. Useful in cross build scenarios')
+parser.add_argument('file1', help='First file to compare')
+parser.add_argument('file2', help='Second file to compare')
+
+args = parser.parse_args()
re_NUMBER = re.compile(r'\.[0-9]+')
def getsizes(file, format):
sym = {}
- with os.popen("nm --size-sort " + file) as f:
+ nm = "nm"
+ if args.prefix:
+ nm = "{}nm".format(args.prefix)
+
+ with os.popen("{} --size-sort {}".format(nm, file)) as f:
for line in f:
if line.startswith("\n") or ":" in line:
continue
@@ -77,9 +84,9 @@ def calc(oldfile, newfile, format):
delta.reverse()
return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
-def print_result(symboltype, symbolformat, argc):
+def print_result(symboltype, symbolformat):
grow, shrink, add, remove, up, down, delta, old, new, otot, ntot = \
- calc(sys.argv[argc - 1], sys.argv[argc], symbolformat)
+ calc(args.file1, args.file2, symbolformat)
print("add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
(add, remove, grow, shrink, up, -down, up-down))
@@ -93,13 +100,13 @@ def print_result(symboltype, symbolformat, argc):
percent = 0
print("Total: Before=%d, After=%d, chg %+.2f%%" % (otot, ntot, percent))
-if sys.argv[1] == "-c":
- print_result("Function", "tT", 3)
- print_result("Data", "dDbB", 3)
- print_result("RO Data", "rR", 3)
-elif sys.argv[1] == "-d":
- print_result("Data", "dDbBrR", 3)
-elif sys.argv[1] == "-t":
- print_result("Function", "tT", 3)
+if args.c:
+ print_result("Function", "tT")
+ print_result("Data", "dDbB")
+ print_result("RO Data", "rR")
+elif args.d:
+ print_result("Data", "dDbBrR")
+elif args.t:
+ print_result("Function", "tT")
else:
- print_result("Function", "tTdDbBrR", 2)
+ print_result("Function", "tTdDbBrR")
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index 855b937e7585..d5c389df6045 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -10,6 +10,9 @@ from __future__ import print_function
import argparse
import re
import sys, os
+import subprocess
+
+helpersDocStart = 'Start of BPF helper function descriptions:'
class NoHelperFound(BaseException):
pass
@@ -47,6 +50,10 @@ class Helper(APIElement):
@desc: textual description of the helper function
@ret: description of the return value of the helper function
"""
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.enum_val = None
+
def proto_break_down(self):
"""
Break down helper function protocol into smaller chunks: return type,
@@ -89,6 +96,7 @@ class HeaderParser(object):
self.commands = []
self.desc_unique_helpers = set()
self.define_unique_helpers = []
+ self.helper_enum_vals = {}
self.desc_syscalls = []
self.enum_syscalls = []
@@ -233,7 +241,7 @@ class HeaderParser(object):
self.enum_syscalls = re.findall('(BPF\w+)+', bpf_cmd_str)
def parse_desc_helpers(self):
- self.seek_to('* Start of BPF helper function descriptions:',
+ self.seek_to(helpersDocStart,
'Could not find start of eBPF helper descriptions list')
while True:
try:
@@ -245,30 +253,54 @@ class HeaderParser(object):
break
def parse_define_helpers(self):
- # Parse the number of FN(...) in #define __BPF_FUNC_MAPPER to compare
- # later with the number of unique function names present in description.
+ # Parse FN(...) in #define __BPF_FUNC_MAPPER to compare later with the
+ # number of unique function names present in description and use the
+ # correct enumeration value.
# Note: seek_to(..) discards the first line below the target search text,
# resulting in FN(unspec) being skipped and not added to self.define_unique_helpers.
self.seek_to('#define __BPF_FUNC_MAPPER(FN)',
'Could not find start of eBPF helper definition list')
- # Searches for either one or more FN(\w+) defines or a backslash for newline
- p = re.compile('\s*(FN\(\w+\))+|\\\\')
+ # Searches for one FN(\w+) define or a backslash for newline
+ p = re.compile('\s*FN\((\w+)\)|\\\\')
fn_defines_str = ''
+ i = 1 # 'unspec' is skipped as mentioned above
while True:
capture = p.match(self.line)
if capture:
fn_defines_str += self.line
+ self.helper_enum_vals[capture.expand(r'bpf_\1')] = i
+ i += 1
else:
break
self.line = self.reader.readline()
# Find the number of occurences of FN(\w+)
self.define_unique_helpers = re.findall('FN\(\w+\)', fn_defines_str)
+ def assign_helper_values(self):
+ seen_helpers = set()
+ for helper in self.helpers:
+ proto = helper.proto_break_down()
+ name = proto['name']
+ try:
+ enum_val = self.helper_enum_vals[name]
+ except KeyError:
+ raise Exception("Helper %s is missing from enum bpf_func_id" % name)
+
+ # Enforce current practice of having the descriptions ordered
+ # by enum value.
+ seen_helpers.add(name)
+ desc_val = len(seen_helpers)
+ if desc_val != enum_val:
+ raise Exception("Helper %s comment order (#%d) must be aligned with its position (#%d) in enum bpf_func_id" % (name, desc_val, enum_val))
+
+ helper.enum_val = enum_val
+
def run(self):
self.parse_desc_syscall()
self.parse_enum_syscall()
self.parse_desc_helpers()
self.parse_define_helpers()
+ self.assign_helper_values()
self.reader.close()
###############################################################################
@@ -333,27 +365,7 @@ class PrinterRST(Printer):
.. Copyright (C) All BPF authors and contributors from 2014 to present.
.. See git log include/uapi/linux/bpf.h in kernel tree for details.
..
-.. %%%LICENSE_START(VERBATIM)
-.. Permission is granted to make and distribute verbatim copies of this
-.. manual provided the copyright notice and this permission notice are
-.. preserved on all copies.
-..
-.. Permission is granted to copy and distribute modified versions of this
-.. manual under the conditions for verbatim copying, provided that the
-.. entire resulting derived work is distributed under the terms of a
-.. permission notice identical to this one.
-..
-.. Since the Linux kernel and libraries are constantly changing, this
-.. manual page may be incorrect or out-of-date. The author(s) assume no
-.. responsibility for errors or omissions, or for damages resulting from
-.. the use of the information contained herein. The author(s) may not
-.. have taken the same level of care in the production of this manual,
-.. which is licensed free of charge, as they might when working
-.. professionally.
-..
-.. Formatted or processed versions of this manual, if unaccompanied by
-.. the source, must acknowledge the copyright and authors of this work.
-.. %%%LICENSE_END
+.. SPDX-License-Identifier: Linux-man-pages-copyleft
..
.. Please do not edit this file. It was generated from the documentation
.. located in file include/uapi/linux/bpf.h of the Linux kernel sources
@@ -377,6 +389,31 @@ class PrinterRST(Printer):
print('')
+ def get_kernel_version(self):
+ try:
+ version = subprocess.run(['git', 'describe'], cwd=linuxRoot,
+ capture_output=True, check=True)
+ version = version.stdout.decode().rstrip()
+ except:
+ try:
+ version = subprocess.run(['make', 'kernelversion'], cwd=linuxRoot,
+ capture_output=True, check=True)
+ version = version.stdout.decode().rstrip()
+ except:
+ return 'Linux'
+ return 'Linux {version}'.format(version=version)
+
+ def get_last_doc_update(self, delimiter):
+ try:
+ cmd = ['git', 'log', '-1', '--pretty=format:%cs', '--no-patch',
+ '-L',
+ '/{}/,/\*\//:include/uapi/linux/bpf.h'.format(delimiter)]
+ date = subprocess.run(cmd, cwd=linuxRoot,
+ capture_output=True, check=True)
+ return date.stdout.decode().rstrip()
+ except:
+ return ''
+
class PrinterHelpersRST(PrinterRST):
"""
A printer for dumping collected information about helpers as a ReStructured
@@ -398,6 +435,8 @@ list of eBPF helper functions
-------------------------------------------------------------------------------
:Manual section: 7
+:Version: {version}
+{date_field}{date}
DESCRIPTION
===========
@@ -430,8 +469,13 @@ kernel at the top).
HELPERS
=======
'''
+ kernelVersion = self.get_kernel_version()
+ lastUpdate = self.get_last_doc_update(helpersDocStart)
+
PrinterRST.print_license(self)
- print(header)
+ print(header.format(version=kernelVersion,
+ date_field = ':Date: ' if lastUpdate else '',
+ date=lastUpdate))
def print_footer(self):
footer = '''
@@ -635,6 +679,8 @@ class PrinterHelpers(Printer):
'struct bpf_timer',
'struct mptcp_sock',
'struct bpf_dynptr',
+ 'struct iphdr',
+ 'struct ipv6hdr',
]
known_types = {
'...',
@@ -686,6 +732,8 @@ class PrinterHelpers(Printer):
'struct bpf_timer',
'struct mptcp_sock',
'struct bpf_dynptr',
+ 'struct iphdr',
+ 'struct ipv6hdr',
}
mapped_types = {
'u8': '__u8',
@@ -777,7 +825,7 @@ class PrinterHelpers(Printer):
comma = ', '
print(one_arg, end='')
- print(') = (void *) %d;' % len(self.seen_helpers))
+ print(') = (void *) %d;' % helper.enum_val)
print('')
###############################################################################
diff --git a/scripts/cc-version.sh b/scripts/cc-version.sh
index f1952c522466..2401c86fcf53 100755
--- a/scripts/cc-version.sh
+++ b/scripts/cc-version.sh
@@ -1,13 +1,13 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
-# Print the compiler name and its version in a 5 or 6-digit form.
+# Print the C compiler name and its version in a 5 or 6-digit form.
# Also, perform the minimum version check.
set -e
-# Print the compiler name and some version components.
-get_compiler_info()
+# Print the C compiler name and some version components.
+get_c_compiler_info()
{
cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
#if defined(__clang__)
@@ -32,7 +32,7 @@ get_canonical_version()
# $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc".
orig_args="$@"
-set -- $(get_compiler_info "$@")
+set -- $(get_c_compiler_info "$@")
name=$1
@@ -52,7 +52,7 @@ ICC)
min_version=$($min_tool_version icc)
;;
*)
- echo "$orig_args: unknown compiler" >&2
+ echo "$orig_args: unknown C compiler" >&2
exit 1
;;
esac
@@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version)
if [ "$cversion" -lt "$min_cversion" ]; then
echo >&2 "***"
- echo >&2 "*** Compiler is too old."
+ echo >&2 "*** C compiler is too old."
echo >&2 "*** Your $name version: $version"
echo >&2 "*** Minimum $name version: $min_version"
echo >&2 "***"
diff --git a/scripts/check-blacklist-hashes.awk b/scripts/check-blacklist-hashes.awk
deleted file mode 100755
index 107c1d3204d4..000000000000
--- a/scripts/check-blacklist-hashes.awk
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/awk -f
-# SPDX-License-Identifier: GPL-2.0
-#
-# Copyright © 2020, Microsoft Corporation. All rights reserved.
-#
-# Author: Mickaël Salaün <mic@linux.microsoft.com>
-#
-# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of
-# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a
-# colon (":"), and finally an even number of hexadecimal lowercase characters
-# (up to 128).
-
-BEGIN {
- RS = ","
-}
-{
- if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) {
- print "Not a string (item " NR "):", $0;
- exit 1;
- }
- if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) {
- print "Unknown prefix (item " NR "):", part1[1];
- exit 1;
- }
- if (!match(part2[2], "^([0-9a-f]+)$", part3)) {
- print "Not a lowercase hexadecimal string (item " NR "):", part2[2];
- exit 1;
- }
- if (length(part3[1]) > 128) {
- print "Hash string too long (item " NR "):", part3[1];
- exit 1;
- }
- if (length(part3[1]) % 2 == 1) {
- print "Not an even number of hexadecimal characters (item " NR "):", part3[1];
- exit 1;
- }
-}
diff --git a/scripts/check-local-export b/scripts/check-local-export
index 6ccc2f467416..f90b5a9c67b3 100755
--- a/scripts/check-local-export
+++ b/scripts/check-local-export
@@ -1,25 +1,14 @@
-#!/usr/bin/env bash
+#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2022 Masahiro Yamada <masahiroy@kernel.org>
+# Copyright (C) 2022 Owen Rafferty <owen@owenrafferty.com>
#
# Exit with error if a local exported symbol is found.
# EXPORT_SYMBOL should be used for global symbols.
set -e
-
-# catch errors from ${NM}
-set -o pipefail
-
-# Run the last element of a pipeline in the current shell.
-# Without this, the while-loop would be executed in a subshell, and
-# the changes made to 'symbol_types' and 'export_symbols' would be lost.
-shopt -s lastpipe
-
-declare -A symbol_types
-declare -a export_symbols
-
-exit_code=0
+pid=$$
# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows
# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by
@@ -29,43 +18,53 @@ exit_code=0
# TODO:
# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of
# binutils to 2.37, llvm to 13.0.0.
-# Then, the following line will be really simple:
-# ${NM} --quiet ${1} |
+# Then, the following line will be simpler:
+# { ${NM} --quiet ${1} || kill 0; } |
+
+{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; kill $pid; } } |
+${AWK} -v "file=${1}" '
+BEGIN {
+ i = 0
+}
+
+# Skip the line if the number of fields is less than 3.
+#
+# case 1)
+# For undefined symbols, the first field (value) is empty.
+# The outout looks like this:
+# " U _printk"
+# It is unneeded to record undefined symbols.
+#
+# case 2)
+# For Clang LTO, llvm-nm outputs a line with type t but empty name:
+# "---------------- t"
+!length($3) {
+ next
+}
-{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } |
-while read value type name
-do
- # Skip the line if the number of fields is less than 3.
- #
- # case 1)
- # For undefined symbols, the first field (value) is empty.
- # The outout looks like this:
- # " U _printk"
- # It is unneeded to record undefined symbols.
- #
- # case 2)
- # For Clang LTO, llvm-nm outputs a line with type 't' but empty name:
- # "---------------- t"
- if [[ -z ${name} ]]; then
- continue
- fi
+# save (name, type) in the associative array
+{ symbol_types[$3]=$2 }
- # save (name, type) in the associative array
- symbol_types[${name}]=${type}
+# append the exported symbol to the array
+($3 ~ /^__ksymtab_/) {
+ export_symbols[i] = $3
+ sub(/^__ksymtab_/, "", export_symbols[i])
+ i++
+}
- # append the exported symbol to the array
- if [[ ${name} == __ksymtab_* ]]; then
- export_symbols+=(${name#__ksymtab_})
- fi
-done
+END {
+ exit_code = 0
+ for (j = 0; j < i; ++j) {
+ name = export_symbols[j]
+ # nm(3) says "If lowercase, the symbol is usually local"
+ if (symbol_types[name] ~ /[a-z]/) {
+ printf "%s: error: local symbol %s was exported\n",
+ file, name | "cat 1>&2"
+ exit_code = 1
+ }
+ }
-for name in "${export_symbols[@]}"
-do
- # nm(3) says "If lowercase, the symbol is usually local"
- if [[ ${symbol_types[$name]} =~ [a-z] ]]; then
- echo "$@: error: local symbol '${name}' was exported" >&2
- exit_code=1
- fi
-done
+ exit exit_code
+}'
-exit ${exit_code}
+exit $?
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 503e8abbb2c1..c8a616a9d034 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1042,7 +1042,8 @@ 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*\(|
- (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
+ (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(|
+ (?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\(
)};
our %allow_repeated_words = (
@@ -3615,7 +3616,7 @@ sub process {
my $comment = "";
if ($realfile =~ /\.(h|s|S)$/) {
$comment = '/*';
- } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
+ } elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) {
$comment = '//';
} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
$comment = '#';
@@ -3663,7 +3664,7 @@ sub process {
}
# check we are in a valid source file if not then ignore this hunk
- next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
+ next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/);
# check for using SPDX-License-Identifier on the wrong line number
if ($realline != $checklicenseline &&
@@ -3750,7 +3751,7 @@ sub process {
if ($realfile =~ /\.S$/ &&
$line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
WARN("AVOID_L_PREFIX",
- "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr);
+ "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr);
}
# check we are in a valid source file C or perl if not then ignore this hunk
@@ -4694,12 +4695,12 @@ sub process {
}
}
-# avoid BUG() or BUG_ON()
- if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
+# do not use BUG() or variants
+ if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) {
my $msg_level = \&WARN;
$msg_level = \&CHK if ($file);
&{$msg_level}("AVOID_BUG",
- "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
+ "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr);
}
# avoid LINUX_VERSION_CODE
@@ -5720,7 +5721,7 @@ sub process {
$var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
#Ignore some three character SI units explicitly, like MiB and KHz
$var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
- while ($var =~ m{($Ident)}g) {
+ while ($var =~ m{\b($Ident)}g) {
my $word = $1;
next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
if ($check) {
@@ -6782,15 +6783,19 @@ sub process {
}
if ($bad_specifier ne "") {
my $stat_real = get_stat_real($linenr, $lc);
+ my $msg_level = \&WARN;
my $ext_type = "Invalid";
my $use = "";
if ($bad_specifier =~ /p[Ff]/) {
$use = " - use %pS instead";
$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
+ } elsif ($bad_specifier =~ /pA/) {
+ $use = " - '%pA' is only intended to be used from Rust code";
+ $msg_level = \&ERROR;
}
- WARN("VSPRINTF_POINTER_EXTENSION",
- "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
+ &{$msg_level}("VSPRINTF_POINTER_EXTENSION",
+ "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
}
}
}
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index d2c38584ece6..d48dfed6d3db 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -16,6 +16,7 @@
# AArch64, PARISC ports by Kyle McMartin
# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
# ppc64le port by Breno Leitao <leitao@debian.org>
+# riscv port by Wadim Mueller <wafgo01@gmail.com>
#
# Usage:
# objdump -d vmlinux | scripts/checkstack.pl [arch]
@@ -108,6 +109,9 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
} elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
# f0019d10: 9d e3 bf 90 save %sp, -112, %sp
$re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
+ } elsif ($arch =~ /^riscv(64)?$/) {
+ #ffffffff8036e868: c2010113 addi sp,sp,-992
+ $re = qr/.*addi.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
} else {
print("wrong or unknown architecture \"$arch\"\n");
exit
diff --git a/scripts/clang-tools/gen_compile_commands.py b/scripts/clang-tools/gen_compile_commands.py
index 47da25b3ba7d..d800b2c0af97 100755
--- a/scripts/clang-tools/gen_compile_commands.py
+++ b/scripts/clang-tools/gen_compile_commands.py
@@ -109,20 +109,6 @@ def to_cmdfile(path):
return os.path.join(dir, '.' + base + '.cmd')
-def cmdfiles_for_o(obj):
- """Generate the iterator of .cmd files associated with the object
-
- Yield the .cmd file used to build the given object
-
- Args:
- obj: The object path
-
- Yields:
- The path to .cmd file
- """
- yield to_cmdfile(obj)
-
-
def cmdfiles_for_a(archive, ar):
"""Generate the iterator of .cmd files associated with the archive.
@@ -211,13 +197,10 @@ def main():
for path in paths:
# If 'path' is a directory, handle all .cmd files under it.
# Otherwise, handle .cmd files associated with the file.
- # Most of built-in objects are linked via archives (built-in.a or lib.a)
- # but some objects are linked to vmlinux directly.
+ # built-in objects are linked via vmlinux.a
# Modules are listed in modules.order.
if os.path.isdir(path):
cmdfiles = cmdfiles_in_dir(path)
- elif path.endswith('.o'):
- cmdfiles = cmdfiles_for_o(path)
elif path.endswith('.a'):
cmdfiles = cmdfiles_for_a(path, ar)
elif path.endswith('modules.order'):
diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py
index f754415af398..bb78c9bde55c 100755
--- a/scripts/clang-tools/run-clang-tools.py
+++ b/scripts/clang-tools/run-clang-tools.py
@@ -12,7 +12,6 @@ compile_commands.json.
import argparse
import json
import multiprocessing
-import os
import subprocess
import sys
@@ -51,6 +50,7 @@ def run_analysis(entry):
checks += "linuxkernel-*"
else:
checks += "clang-analyzer-*"
+ checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
p = subprocess.run(["clang-tidy", "-p", args.path, checks, entry["file"]],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
index b3d0c3c230c1..d66c45356691 100644
--- a/scripts/coccinelle/api/alloc/zalloc-simple.cocci
+++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
@@ -10,7 +10,7 @@
// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU.
// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6.
// Copyright: (C) 2017 Himanshu Jha
-// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --no-includes --include-headers
//
// Keywords: kmalloc, kzalloc
diff --git a/scripts/coccinelle/api/atomic_as_refcounter.cocci b/scripts/coccinelle/api/atomic_as_refcounter.cocci
index 0f78d94abc35..e63d52408b86 100644
--- a/scripts/coccinelle/api/atomic_as_refcounter.cocci
+++ b/scripts/coccinelle/api/atomic_as_refcounter.cocci
@@ -5,7 +5,7 @@
// Copyright (c) 2016-2017, Elena Reshetova, Intel Corporation
//
// Confidence: Moderate
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --include-headers --very-quiet
virtual report
diff --git a/scripts/coccinelle/api/check_bq27xxx_data.cocci b/scripts/coccinelle/api/check_bq27xxx_data.cocci
index fae539ef0ce5..27366c6169ec 100644
--- a/scripts/coccinelle/api/check_bq27xxx_data.cocci
+++ b/scripts/coccinelle/api/check_bq27xxx_data.cocci
@@ -6,7 +6,7 @@
///
// Confidence: High
// Copyright: (C) 2017 Julia Lawall, Inria/LIP6,
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Requires: 1.0.7
// Keywords: BQ27XXX_DATA
diff --git a/scripts/coccinelle/api/d_find_alias.cocci b/scripts/coccinelle/api/d_find_alias.cocci
index 47e050166f20..3489001378ab 100644
--- a/scripts/coccinelle/api/d_find_alias.cocci
+++ b/scripts/coccinelle/api/d_find_alias.cocci
@@ -4,7 +4,7 @@
// Keywords: d_find_alias, dput
//
// Confidence: Moderate
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --include-headers
virtual context
diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci
index 0e661c8d8d6f..7f9dc1212c74 100644
--- a/scripts/coccinelle/api/err_cast.cocci
+++ b/scripts/coccinelle/api/err_cast.cocci
@@ -6,7 +6,7 @@
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options:
//
// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci
index 3c6dc5469ee4..8a61534676da 100644
--- a/scripts/coccinelle/api/kstrdup.cocci
+++ b/scripts/coccinelle/api/kstrdup.cocci
@@ -5,7 +5,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci
index 30b15df734e5..d28741c69873 100644
--- a/scripts/coccinelle/api/memdup.cocci
+++ b/scripts/coccinelle/api/memdup.cocci
@@ -5,7 +5,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci
index e01e95108405..03e7afa09eee 100644
--- a/scripts/coccinelle/api/memdup_user.cocci
+++ b/scripts/coccinelle/api/memdup_user.cocci
@@ -6,7 +6,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/api/pm_runtime.cocci b/scripts/coccinelle/api/pm_runtime.cocci
index 1ccce3fd00b8..4b9778874453 100644
--- a/scripts/coccinelle/api/pm_runtime.cocci
+++ b/scripts/coccinelle/api/pm_runtime.cocci
@@ -4,7 +4,7 @@
// Keywords: pm_runtime
// Confidence: Medium
// Copyright (C) 2013 Texas Instruments Incorporated -
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --include-headers
virtual patch
diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci
index a9a571ac04ce..16857072d162 100644
--- a/scripts/coccinelle/api/resource_size.cocci
+++ b/scripts/coccinelle/api/resource_size.cocci
@@ -7,7 +7,7 @@
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options:
//
// Keywords: resource_size
diff --git a/scripts/coccinelle/free/clk_put.cocci b/scripts/coccinelle/free/clk_put.cocci
index 7237b49496f6..3c732cb7210b 100644
--- a/scripts/coccinelle/free/clk_put.cocci
+++ b/scripts/coccinelle/free/clk_put.cocci
@@ -8,7 +8,7 @@
// Confidence: Moderate
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options:
diff --git a/scripts/coccinelle/free/devm_free.cocci b/scripts/coccinelle/free/devm_free.cocci
index da80050b91ff..0880729badbc 100644
--- a/scripts/coccinelle/free/devm_free.cocci
+++ b/scripts/coccinelle/free/devm_free.cocci
@@ -17,7 +17,7 @@
// Confidence: Moderate
// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/free/ifnulldev_put.cocci b/scripts/coccinelle/free/ifnulldev_put.cocci
new file mode 100644
index 000000000000..2bd2e8fae485
--- /dev/null
+++ b/scripts/coccinelle/free/ifnulldev_put.cocci
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/// Since commit b37a46683739 ("netdevice: add the case if dev is NULL"),
+/// NULL check before dev_{put, hold} functions is not needed.
+///
+/// Based on ifnullfree.cocci by Fabian Frederick.
+///
+// Copyright: (C) 2022 Ziyang Xuan.
+// Comments: -
+// Options: --no-includes --include-headers
+// Version min: 5.15
+
+virtual patch
+virtual org
+virtual report
+virtual context
+
+@r2 depends on patch@
+expression E;
+@@
+- if (E != NULL)
+(
+ __dev_put(E);
+|
+ dev_put(E);
+|
+ dev_put_track(E, ...);
+|
+ __dev_hold(E);
+|
+ dev_hold(E);
+|
+ dev_hold_track(E, ...);
+)
+
+@r depends on context || report || org @
+expression E;
+position p;
+@@
+
+* if (E != NULL)
+* \(__dev_put@p\|dev_put@p\|dev_put_track@p\|__dev_hold@p\|dev_hold@p\|
+* dev_hold_track@p\)(E, ...);
+
+@script:python depends on org@
+p << r.p;
+@@
+
+cocci.print_main("NULL check before dev_{put, hold} functions is not needed", p)
+
+@script:python depends on report@
+p << r.p;
+@@
+
+msg = "WARNING: NULL check before dev_{put, hold} functions is not needed."
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/free/iounmap.cocci b/scripts/coccinelle/free/iounmap.cocci
index 63b81d0c97b6..90d85fa7bfdf 100644
--- a/scripts/coccinelle/free/iounmap.cocci
+++ b/scripts/coccinelle/free/iounmap.cocci
@@ -8,7 +8,7 @@
// Confidence: Moderate
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options:
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
index 9b6e2037c2a9..6338bbac2f7f 100644
--- a/scripts/coccinelle/free/kfree.cocci
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -9,7 +9,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/free/kfreeaddr.cocci b/scripts/coccinelle/free/kfreeaddr.cocci
index 142af6337a04..85635a36f0ac 100644
--- a/scripts/coccinelle/free/kfreeaddr.cocci
+++ b/scripts/coccinelle/free/kfreeaddr.cocci
@@ -3,7 +3,7 @@
///
// Confidence: High
// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/free/pci_free_consistent.cocci b/scripts/coccinelle/free/pci_free_consistent.cocci
index d51e92556b42..e062b9ba09ff 100644
--- a/scripts/coccinelle/free/pci_free_consistent.cocci
+++ b/scripts/coccinelle/free/pci_free_consistent.cocci
@@ -3,7 +3,7 @@
///
// Confidence: Moderate
// Copyright: (C) 2013 Petr Strnad.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Keywords: pci_free_consistent, pci_alloc_consistent
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/iterators/device_node_continue.cocci b/scripts/coccinelle/iterators/device_node_continue.cocci
index f8cd14dfa604..5713c9cf59ff 100644
--- a/scripts/coccinelle/iterators/device_node_continue.cocci
+++ b/scripts/coccinelle/iterators/device_node_continue.cocci
@@ -4,7 +4,7 @@
///
// Confidence: High
// Copyright: (C) 2015 Julia Lawall, Inria.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --no-includes --include-headers
// Requires: 1.0.4
// Keywords: for_each_child_of_node, etc.
diff --git a/scripts/coccinelle/iterators/for_each_child.cocci b/scripts/coccinelle/iterators/for_each_child.cocci
index bc394615948e..2ea98a61a1f2 100644
--- a/scripts/coccinelle/iterators/for_each_child.cocci
+++ b/scripts/coccinelle/iterators/for_each_child.cocci
@@ -5,7 +5,7 @@
///
// Confidence: High
// Copyright: (C) 2020 Sumera Priyadarsini
-// URL: http://coccinelle.lip6.fr
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --no-includes --include-headers
virtual patch
diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci
index 9b362b98d7a1..7d34802f2724 100644
--- a/scripts/coccinelle/iterators/itnull.cocci
+++ b/scripts/coccinelle/iterators/itnull.cocci
@@ -10,7 +10,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci
index d62e8a16085f..9a7593667da6 100644
--- a/scripts/coccinelle/iterators/list_entry_update.cocci
+++ b/scripts/coccinelle/iterators/list_entry_update.cocci
@@ -8,7 +8,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/iterators/use_after_iter.cocci b/scripts/coccinelle/iterators/use_after_iter.cocci
index 676edd562eef..f67110ba7290 100644
--- a/scripts/coccinelle/iterators/use_after_iter.cocci
+++ b/scripts/coccinelle/iterators/use_after_iter.cocci
@@ -10,7 +10,7 @@
// Confidence: Moderate
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci
index 5ca0d81b0015..3720f86d67c5 100644
--- a/scripts/coccinelle/locks/call_kern.cocci
+++ b/scripts/coccinelle/locks/call_kern.cocci
@@ -8,7 +8,7 @@
// Copyright: (C) 2012 Nicolas Palix.
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci
index 9e88a578957c..619cfc714409 100644
--- a/scripts/coccinelle/locks/double_lock.cocci
+++ b/scripts/coccinelle/locks/double_lock.cocci
@@ -7,7 +7,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci
index 7f990cd55f5a..44acf20a98dd 100644
--- a/scripts/coccinelle/locks/flags.cocci
+++ b/scripts/coccinelle/locks/flags.cocci
@@ -5,7 +5,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci
index c3ad098f4a5b..71065d8a5d54 100644
--- a/scripts/coccinelle/locks/mini_lock.cocci
+++ b/scripts/coccinelle/locks/mini_lock.cocci
@@ -10,7 +10,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/boolreturn.cocci b/scripts/coccinelle/misc/boolreturn.cocci
deleted file mode 100644
index 29d2bf41e95d..000000000000
--- a/scripts/coccinelle/misc/boolreturn.cocci
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/// Return statements in functions returning bool should use
-/// true/false instead of 1/0.
-//
-// Confidence: High
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual report
-virtual context
-
-@r1 depends on patch@
-identifier fn;
-typedef bool;
-symbol false;
-symbol true;
-@@
-
-bool fn ( ... )
-{
-<...
-return
-(
-- 0
-+ false
-|
-- 1
-+ true
-)
- ;
-...>
-}
-
-@r2 depends on report || context@
-identifier fn;
-position p;
-@@
-
-bool fn ( ... )
-{
-<...
-return
-(
-* 0@p
-|
-* 1@p
-)
- ;
-...>
-}
-
-
-@script:python depends on report@
-p << r2.p;
-fn << r2.fn;
-@@
-
-msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn
-coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/misc/cstptr.cocci b/scripts/coccinelle/misc/cstptr.cocci
index c52e3c8ca9b3..74acf34bee03 100644
--- a/scripts/coccinelle/misc/cstptr.cocci
+++ b/scripts/coccinelle/misc/cstptr.cocci
@@ -5,7 +5,7 @@
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci
index 2f80d3ab38dd..7dbfde3f44e1 100644
--- a/scripts/coccinelle/misc/doubleinit.cocci
+++ b/scripts/coccinelle/misc/doubleinit.cocci
@@ -7,7 +7,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci
index da0351ed5740..442742467c18 100644
--- a/scripts/coccinelle/misc/ifcol.cocci
+++ b/scripts/coccinelle/misc/ifcol.cocci
@@ -12,7 +12,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/newline_in_nl_msg.cocci b/scripts/coccinelle/misc/newline_in_nl_msg.cocci
index c175886e4015..9baffe55d917 100644
--- a/scripts/coccinelle/misc/newline_in_nl_msg.cocci
+++ b/scripts/coccinelle/misc/newline_in_nl_msg.cocci
@@ -5,7 +5,7 @@
///
// Confidence: Very High
// Copyright: (C) 2020 Intel Corporation
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --no-includes --include-headers
virtual context
diff --git a/scripts/coccinelle/misc/noderef.cocci b/scripts/coccinelle/misc/noderef.cocci
index 72de62a77a44..37ee7358d742 100644
--- a/scripts/coccinelle/misc/noderef.cocci
+++ b/scripts/coccinelle/misc/noderef.cocci
@@ -5,7 +5,7 @@
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/orplus.cocci b/scripts/coccinelle/misc/orplus.cocci
index 52203dc2ca4b..3a1566f1aec9 100644
--- a/scripts/coccinelle/misc/orplus.cocci
+++ b/scripts/coccinelle/misc/orplus.cocci
@@ -6,7 +6,7 @@
// Confidence: Moderate
// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2013 Gilles Muller, INRIA/LIP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/returnvar.cocci b/scripts/coccinelle/misc/returnvar.cocci
index ce0d9eebc7e1..7ffc55bf51f9 100644
--- a/scripts/coccinelle/misc/returnvar.cocci
+++ b/scripts/coccinelle/misc/returnvar.cocci
@@ -4,7 +4,7 @@
///
// Confidence: Moderate
// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments: Comments on code can be deleted if near code that is removed.
// "when strict" can be removed to get more hits, but adds false
// positives
diff --git a/scripts/coccinelle/misc/semicolon.cocci b/scripts/coccinelle/misc/semicolon.cocci
index a53edb026dad..4476bf873deb 100644
--- a/scripts/coccinelle/misc/semicolon.cocci
+++ b/scripts/coccinelle/misc/semicolon.cocci
@@ -4,7 +4,7 @@
///
// Confidence: Moderate
// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments: Some false positives on empty default cases in switch statements.
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/misc/ifaddr.cocci b/scripts/coccinelle/misc/test_addr.cocci
index fc92e8fcbfcb..d559b297476c 100644
--- a/scripts/coccinelle/misc/ifaddr.cocci
+++ b/scripts/coccinelle/misc/test_addr.cocci
@@ -4,7 +4,7 @@
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
@@ -14,12 +14,10 @@ virtual context
@r@
expression x;
-statement S1,S2;
position p;
@@
-*if@p (&x)
- S1 else S2
+*\(&x@p == NULL \| &x@p != NULL\)
@script:python depends on org@
p << r.p;
diff --git a/scripts/coccinelle/misc/warn.cocci b/scripts/coccinelle/misc/warn.cocci
index e379661e240d..b5f428035d03 100644
--- a/scripts/coccinelle/misc/warn.cocci
+++ b/scripts/coccinelle/misc/warn.cocci
@@ -4,7 +4,7 @@
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/null/badzero.cocci b/scripts/coccinelle/null/badzero.cocci
index 882dd65313ab..35d443825c2a 100644
--- a/scripts/coccinelle/null/badzero.cocci
+++ b/scripts/coccinelle/null/badzero.cocci
@@ -10,7 +10,7 @@
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Requires: 1.0.0
// Options:
diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci
index 98f1e7faf503..fdf098d4f522 100644
--- a/scripts/coccinelle/null/deref_null.cocci
+++ b/scripts/coccinelle/null/deref_null.cocci
@@ -7,7 +7,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments: -I ... -all_includes can give more complete results
// Options:
diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci
index 81584ff87956..7107d6c8db9e 100644
--- a/scripts/coccinelle/null/eno.cocci
+++ b/scripts/coccinelle/null/eno.cocci
@@ -5,7 +5,7 @@
// Copyright: (C) 2010-2012 Nicolas Palix.
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci
index d0e004d4e130..68db20de62eb 100644
--- a/scripts/coccinelle/null/kmerr.cocci
+++ b/scripts/coccinelle/null/kmerr.cocci
@@ -9,7 +9,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci
index 0f0b94e7debd..025436a15040 100644
--- a/scripts/coccinelle/tests/doublebitand.cocci
+++ b/scripts/coccinelle/tests/doublebitand.cocci
@@ -9,7 +9,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci
index b35519cddb13..c3d94c31959f 100644
--- a/scripts/coccinelle/tests/doubletest.cocci
+++ b/scripts/coccinelle/tests/doubletest.cocci
@@ -8,7 +8,7 @@
// Copyright: (C) 2010 Nicolas Palix, DIKU.
// Copyright: (C) 2010 Julia Lawall, DIKU.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Comments:
// Options: --no-includes --include-headers
diff --git a/scripts/coccinelle/tests/odd_ptr_err.cocci b/scripts/coccinelle/tests/odd_ptr_err.cocci
index 11d4e2b6deb8..377436abe2d0 100644
--- a/scripts/coccinelle/tests/odd_ptr_err.cocci
+++ b/scripts/coccinelle/tests/odd_ptr_err.cocci
@@ -6,7 +6,7 @@
// Confidence: High
// Copyright: (C) 2012, 2015 Julia Lawall, INRIA.
// Copyright: (C) 2012, 2015 Gilles Muller, INRIA.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --no-includes --include-headers
virtual patch
diff --git a/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci b/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci
index 91e286ace54c..5e188c62d8a9 100644
--- a/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci
+++ b/scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci
@@ -13,7 +13,7 @@
///
// Confidence: Average
// Copyright: (C) 2015 Andrzej Hajda, Samsung Electronics Co., Ltd.
-// URL: http://coccinelle.lip6.fr/
+// URL: https://coccinelle.gitlabpages.inria.fr/website
// Options: --all-includes
virtual context
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index 7075e26ab2c4..564c5632e1a2 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -8,6 +8,14 @@ usage() {
echo " $0 -r <release> | <vmlinux> [<base path>|auto] [<modules path>]"
}
+# Try to find a Rust demangler
+if type llvm-cxxfilt >/dev/null 2>&1 ; then
+ cppfilt=llvm-cxxfilt
+elif type c++filt >/dev/null 2>&1 ; then
+ cppfilt=c++filt
+ cppfilt_opts=-i
+fi
+
if [[ $1 == "-r" ]] ; then
vmlinux=""
basepath="auto"
@@ -180,6 +188,12 @@ parse_symbol() {
# In the case of inlines, move everything to same line
code=${code//$'\n'/' '}
+ # Demangle if the name looks like a Rust symbol and if
+ # we got a Rust demangler
+ if [[ $name =~ ^_R && $cppfilt != "" ]] ; then
+ name=$("$cppfilt" "$cppfilt_opts" "$name")
+ fi
+
# Replace old address with pretty line numbers
symbol="$segment$name ($code)"
}
diff --git a/scripts/dtc/dt-extract-compatibles b/scripts/dtc/dt-extract-compatibles
new file mode 100755
index 000000000000..a1119762ed08
--- /dev/null
+++ b/scripts/dtc/dt-extract-compatibles
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-only
+
+import os
+import glob
+import re
+import argparse
+
+
+def parse_of_declare_macros(data):
+ """ Find all compatible strings in OF_DECLARE() style macros """
+ compat_list = []
+ # CPU_METHOD_OF_DECLARE does not have a compatible string
+ for m in re.finditer(r'(?<!CPU_METHOD_)(IRQCHIP|OF)_(DECLARE|MATCH)(_DRIVER)?\(.*?\)', data):
+ try:
+ compat = re.search(r'"(.*?)"', m[0])[1]
+ except:
+ # Fails on compatible strings in #define, so just skip
+ continue
+ compat_list += [compat]
+
+ return compat_list
+
+
+def parse_of_device_id(data):
+ """ Find all compatible strings in of_device_id structs """
+ compat_list = []
+ for m in re.finditer(r'of_device_id\s+[a-zA-Z0-9_]+\[\]\s*=\s*({.*?);', data):
+ compat_list += re.findall(r'\.compatible\s+=\s+"([a-zA-Z0-9_\-,]+)"', m[1])
+
+ return compat_list
+
+
+def parse_compatibles(file):
+ with open(file, 'r', encoding='utf-8') as f:
+ data = f.read().replace('\n', '')
+
+ compat_list = parse_of_declare_macros(data)
+ compat_list += parse_of_device_id(data)
+
+ return compat_list
+
+def print_compat(filename, compatibles):
+ if not compatibles:
+ return
+ if show_filename:
+ compat_str = ' '.join(compatibles)
+ print(filename + ": compatible(s): " + compat_str)
+ else:
+ print(*compatibles, sep='\n')
+
+show_filename = False
+
+if __name__ == "__main__":
+ ap = argparse.ArgumentParser()
+ ap.add_argument("cfile", type=str, nargs='*', help="C source files or directories to parse")
+ ap.add_argument('-H', '--with-filename', help="Print filename with compatibles", action="store_true")
+ args = ap.parse_args()
+
+ show_filename = args.with_filename
+
+ for f in args.cfile:
+ if os.path.isdir(f):
+ for filename in glob.iglob(f + "/**/*.c", recursive=True):
+ compat_list = parse_compatibles(filename)
+ print_compat(filename, compat_list)
+ else:
+ compat_list = parse_compatibles(f)
+ print_compat(f, compat_list)
diff --git a/scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h b/scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/scripts/dummy-tools/dummy-plugin-dir/include/plugin-version.h
diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc
index b2483149bbe5..1db1889f6d81 100755
--- a/scripts/dummy-tools/gcc
+++ b/scripts/dummy-tools/gcc
@@ -59,7 +59,7 @@ fi
if arg_contain -E "$@"; then
# For scripts/cc-version.sh; This emulates GCC 20.0.0
if arg_contain - "$@"; then
- sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}'
+ sed -n '/^GCC/{s/__GNUC__/20/; s/__GNUC_MINOR__/0/; s/__GNUC_PATCHLEVEL__/0/; p;}; s/__LONG_DOUBLE_128__/1/ p'
exit 0
else
echo "no input files" >&2
@@ -96,12 +96,8 @@ fi
# To set GCC_PLUGINS
if arg_contain -print-file-name=plugin "$@"; then
- plugin_dir=$(mktemp -d)
-
- mkdir -p $plugin_dir/include
- touch $plugin_dir/include/plugin-version.h
-
- echo $plugin_dir
+ # Use $0 to find the in-tree dummy directory
+ echo "$(dirname "$(readlink -f "$0")")/dummy-plugin-dir"
exit 0
fi
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
index 3b42f255e2ba..8df33e7d6daa 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -62,6 +62,7 @@ try_decompress 'BZh' xy bunzip2
try_decompress '\135\0\0\0' xxx unlzma
try_decompress '\211\114\132' xy 'lzop -d'
try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
+try_decompress '\050\265\057\375' xxx unzstd
# Bail out:
echo "$me: Cannot find kernel config." >&2
diff --git a/scripts/faddr2line b/scripts/faddr2line
index 94ed98dd899f..5514c23f45c2 100755
--- a/scripts/faddr2line
+++ b/scripts/faddr2line
@@ -61,6 +61,7 @@ die() {
READELF="${CROSS_COMPILE:-}readelf"
ADDR2LINE="${CROSS_COMPILE:-}addr2line"
AWK="awk"
+GREP="grep"
command -v ${AWK} >/dev/null 2>&1 || die "${AWK} isn't installed"
command -v ${READELF} >/dev/null 2>&1 || die "${READELF} isn't installed"
@@ -112,7 +113,9 @@ __faddr2line() {
# section offsets.
local file_type=$(${READELF} --file-header $objfile |
${AWK} '$1 == "Type:" { print $2; exit }')
- [[ $file_type = "EXEC" ]] && is_vmlinux=1
+ if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then
+ is_vmlinux=1
+ fi
# Go through each of the object's symbols which match the func name.
# In rare cases there might be duplicates, in which case we print all
@@ -269,6 +272,8 @@ LIST=0
[[ ! -f $objfile ]] && die "can't find objfile $objfile"
shift
+${READELF} --section-headers --wide $objfile | ${GREP} -q '\.debug_info' || die "CONFIG_DEBUG_INFO not enabled"
+
DIR_PREFIX=supercalifragilisticexpialidocious
find_dir_prefix $objfile
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh
deleted file mode 100755
index 8b980fb2270a..000000000000
--- a/scripts/gcc-goto.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# Test for gcc 'asm goto' support
-# Copyright (C) 2010, Jason Baron <jbaron@redhat.com>
-
-cat << "END" | $@ -x c - -fno-PIE -c -o /dev/null
-int main(void)
-{
-#if defined(__arm__) || defined(__aarch64__)
- /*
- * Not related to asm goto, but used by jump label
- * and broken on some ARM GCC versions (see GCC Bug 48637).
- */
- static struct { int dummy; int state; } tp;
- asm (".long %c0" :: "i" (&tp.state));
-#endif
-
-entry:
- asm goto ("" :::: entry);
- return 0;
-}
-END
diff --git a/scripts/gcc-ld b/scripts/gcc-ld
deleted file mode 100755
index 997b818c3962..000000000000
--- a/scripts/gcc-ld
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# run gcc with ld options
-# used as a wrapper to execute link time optimizations
-# yes virginia, this is not pretty
-
-ARGS="-nostdlib"
-
-while [ "$1" != "" ] ; do
- case "$1" in
- -save-temps|-m32|-m64) N="$1" ;;
- -r) N="$1" ;;
- -[Wg]*) N="$1" ;;
- -[olv]|-[Ofd]*|-nostdlib) N="$1" ;;
- --end-group|--start-group)
- N="-Wl,$1" ;;
- -[RTFGhIezcbyYu]*|\
---script|--defsym|-init|-Map|--oformat|-rpath|\
--rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|\
---version-script|--dynamic-list|--version-exports-symbol|--wrap|-m)
- A="$1" ; shift ; N="-Wl,$A,$1" ;;
- -[m]*) N="$1" ;;
- -*) N="-Wl,$1" ;;
- *) N="$1" ;;
- esac
- ARGS="$ARGS $N"
- shift
-done
-
-exec $CC $ARGS
diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c
index 848918764174..39e86be60dd2 100644
--- a/scripts/gcc-plugins/latent_entropy_plugin.c
+++ b/scripts/gcc-plugins/latent_entropy_plugin.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2012-2016 by the PaX Team <pageexec@freemail.hu>
* Copyright 2016 by Emese Revfy <re.emese@gmail.com>
- * Licensed under the GPL v2
*
* Note: the choice of the license means that the compilation process is
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
index ff91885f9470..c5c2ce113c92 100644
--- a/scripts/gcc-plugins/stackleak_plugin.c
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2011-2017 by the PaX Team <pageexec@freemail.hu>
* Modified by Alexander Popov <alex.popov@linux.com>
- * Licensed under the GPL v2
*
* Note: the choice of the license means that the compilation process is
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index 8bc04068ed39..d8c744233832 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -1,6 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2013-2017 by PaX Team <pageexec@freemail.hu>
- * Licensed under the GPL v2
*
* Note: the choice of the license means that the compilation process is
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
index d5983cf3db7d..c771831eb077 100644
--- a/scripts/gdb/linux/dmesg.py
+++ b/scripts/gdb/linux/dmesg.py
@@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc")
prb_desc_ring_type = utils.CachedType("struct prb_desc_ring")
prb_data_ring_type = utils.CachedType("struct prb_data_ring")
printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer")
-atomic_long_type = utils.CachedType("atomic_long_t")
class LxDmesg(gdb.Command):
"""Print Linux kernel log buffer."""
@@ -68,8 +67,6 @@ class LxDmesg(gdb.Command):
off = prb_data_ring_type.get_type()['data'].bitpos // 8
text_data_addr = utils.read_ulong(text_data_ring, off)
- counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
-
sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8
off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8
@@ -89,9 +86,9 @@ class LxDmesg(gdb.Command):
# read in tail and head descriptor ids
off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8
- tail_id = utils.read_u64(desc_ring, off + counter_off)
+ tail_id = utils.read_atomic_long(desc_ring, off)
off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8
- head_id = utils.read_u64(desc_ring, off + counter_off)
+ head_id = utils.read_atomic_long(desc_ring, off)
did = tail_id
while True:
@@ -102,7 +99,7 @@ class LxDmesg(gdb.Command):
desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
# skip non-committed record
- state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
+ state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift)
if state != desc_committed and state != desc_finalized:
if did == head_id:
break
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
index 46f7542db08c..dc07b6d12e30 100644
--- a/scripts/gdb/linux/symbols.py
+++ b/scripts/gdb/linux/symbols.py
@@ -180,7 +180,7 @@ lx-symbols command."""
self.breakpoint.delete()
self.breakpoint = None
self.breakpoint = LoadModuleBreakpoint(
- "kernel/module.c:do_init_module", self)
+ "kernel/module/main.c:do_init_module", self)
else:
gdb.write("Note: symbol update on module loading not supported "
"with this gdb version\n")
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
index ff7c1799d588..1553f68716cc 100644
--- a/scripts/gdb/linux/utils.py
+++ b/scripts/gdb/linux/utils.py
@@ -35,13 +35,12 @@ class CachedType:
long_type = CachedType("long")
-
+atomic_long_type = CachedType("atomic_long_t")
def get_long_type():
global long_type
return long_type.get_type()
-
def offset_of(typeobj, field):
element = gdb.Value(0).cast(typeobj)
return int(str(element[field].address).split()[0], 16)
@@ -129,6 +128,17 @@ def read_ulong(buffer, offset):
else:
return read_u32(buffer, offset)
+atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
+atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
+
+def read_atomic_long(buffer, offset):
+ global atomic_long_counter_offset
+ global atomic_long_counter_sizeof
+
+ if atomic_long_counter_sizeof == 8:
+ return read_u64(buffer, offset + atomic_long_counter_offset)
+ else:
+ return read_u32(buffer, offset + atomic_long_counter_offset)
target_arch = None
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 4136dc2c59df..3e8d3669f0ce 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -13,7 +13,7 @@
import os
-sys.path.insert(0, os.path.dirname(__file__) + "/scripts/gdb")
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/scripts/gdb")
try:
gdb.parse_and_eval("0")
diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
new file mode 100755
index 000000000000..75bb611bd751
--- /dev/null
+++ b/scripts/generate_rust_analyzer.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""generate_rust_analyzer - Generates the `rust-project.json` file for `rust-analyzer`.
+"""
+
+import argparse
+import json
+import logging
+import pathlib
+import sys
+
+def generate_crates(srctree, objtree, sysroot_src):
+ # Generate the configuration list.
+ cfg = []
+ with open(objtree / "include" / "generated" / "rustc_cfg") as fd:
+ for line in fd:
+ line = line.replace("--cfg=", "")
+ line = line.replace("\n", "")
+ cfg.append(line)
+
+ # Now fill the crates list -- dependencies need to come first.
+ #
+ # Avoid O(n^2) iterations by keeping a map of indexes.
+ crates = []
+ crates_indexes = {}
+
+ def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False):
+ crates_indexes[display_name] = len(crates)
+ crates.append({
+ "display_name": display_name,
+ "root_module": str(root_module),
+ "is_workspace_member": is_workspace_member,
+ "is_proc_macro": is_proc_macro,
+ "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps],
+ "cfg": cfg,
+ "edition": "2021",
+ "env": {
+ "RUST_MODFILE": "This is only for rust-analyzer"
+ }
+ })
+
+ # First, the ones in `rust/` since they are a bit special.
+ append_crate(
+ "core",
+ sysroot_src / "core" / "src" / "lib.rs",
+ [],
+ is_workspace_member=False,
+ )
+
+ append_crate(
+ "compiler_builtins",
+ srctree / "rust" / "compiler_builtins.rs",
+ [],
+ )
+
+ append_crate(
+ "alloc",
+ srctree / "rust" / "alloc" / "lib.rs",
+ ["core", "compiler_builtins"],
+ )
+
+ append_crate(
+ "macros",
+ srctree / "rust" / "macros" / "lib.rs",
+ [],
+ is_proc_macro=True,
+ )
+ crates[-1]["proc_macro_dylib_path"] = "rust/libmacros.so"
+
+ append_crate(
+ "bindings",
+ srctree / "rust"/ "bindings" / "lib.rs",
+ ["core"],
+ cfg=cfg,
+ )
+ crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
+
+ append_crate(
+ "kernel",
+ srctree / "rust" / "kernel" / "lib.rs",
+ ["core", "alloc", "macros", "bindings"],
+ cfg=cfg,
+ )
+ crates[-1]["source"] = {
+ "include_dirs": [
+ str(srctree / "rust" / "kernel"),
+ str(objtree / "rust")
+ ],
+ "exclude_dirs": [],
+ }
+
+ # Then, the rest outside of `rust/`.
+ #
+ # We explicitly mention the top-level folders we want to cover.
+ for folder in ("samples", "drivers"):
+ for path in (srctree / folder).rglob("*.rs"):
+ logging.info("Checking %s", path)
+ name = path.name.replace(".rs", "")
+
+ # Skip those that are not crate roots.
+ if f"{name}.o" not in open(path.parent / "Makefile").read():
+ continue
+
+ logging.info("Adding %s", name)
+ append_crate(
+ name,
+ path,
+ ["core", "alloc", "kernel"],
+ cfg=cfg,
+ )
+
+ return crates
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--verbose', '-v', action='store_true')
+ parser.add_argument("srctree", type=pathlib.Path)
+ parser.add_argument("objtree", type=pathlib.Path)
+ parser.add_argument("sysroot_src", type=pathlib.Path)
+ args = parser.parse_args()
+
+ logging.basicConfig(
+ format="[%(asctime)s] [%(levelname)s] %(message)s",
+ level=logging.INFO if args.verbose else logging.WARNING
+ )
+
+ rust_project = {
+ "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src),
+ "sysroot_src": str(args.sysroot_src),
+ }
+
+ json.dump(rust_project, sys.stdout, sort_keys=True, indent=4)
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
new file mode 100644
index 000000000000..3c6cbe2b278d
--- /dev/null
+++ b/scripts/generate_rust_target.rs
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! The custom target specification file generator for `rustc`.
+//!
+//! To configure a target from scratch, a JSON-encoded file has to be passed
+//! to `rustc` (introduced in [RFC 131]). These options and the file itself are
+//! unstable. Eventually, `rustc` should provide a way to do this in a stable
+//! manner. For instance, via command-line arguments. Therefore, this file
+//! should avoid using keys which can be set via `-C` or `-Z` options.
+//!
+//! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html
+
+use std::{
+ collections::HashMap,
+ fmt::{Display, Formatter, Result},
+ io::BufRead,
+};
+
+enum Value {
+ Boolean(bool),
+ Number(i32),
+ String(String),
+ Object(Object),
+}
+
+type Object = Vec<(String, Value)>;
+
+/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
+/// enough for this purpose.
+impl Display for Value {
+ fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
+ match self {
+ Value::Boolean(boolean) => write!(formatter, "{}", boolean),
+ Value::Number(number) => write!(formatter, "{}", number),
+ Value::String(string) => write!(formatter, "\"{}\"", string),
+ Value::Object(object) => {
+ formatter.write_str("{")?;
+ if let [ref rest @ .., ref last] = object[..] {
+ for (key, value) in rest {
+ write!(formatter, "\"{}\": {},", key, value)?;
+ }
+ write!(formatter, "\"{}\": {}", last.0, last.1)?;
+ }
+ formatter.write_str("}")
+ }
+ }
+ }
+}
+
+struct TargetSpec(Object);
+
+impl TargetSpec {
+ fn new() -> TargetSpec {
+ TargetSpec(Vec::new())
+ }
+}
+
+trait Push<T> {
+ fn push(&mut self, key: &str, value: T);
+}
+
+impl Push<bool> for TargetSpec {
+ fn push(&mut self, key: &str, value: bool) {
+ self.0.push((key.to_string(), Value::Boolean(value)));
+ }
+}
+
+impl Push<i32> for TargetSpec {
+ fn push(&mut self, key: &str, value: i32) {
+ self.0.push((key.to_string(), Value::Number(value)));
+ }
+}
+
+impl Push<String> for TargetSpec {
+ fn push(&mut self, key: &str, value: String) {
+ self.0.push((key.to_string(), Value::String(value)));
+ }
+}
+
+impl Push<&str> for TargetSpec {
+ fn push(&mut self, key: &str, value: &str) {
+ self.push(key, value.to_string());
+ }
+}
+
+impl Push<Object> for TargetSpec {
+ fn push(&mut self, key: &str, value: Object) {
+ self.0.push((key.to_string(), Value::Object(value)));
+ }
+}
+
+impl Display for TargetSpec {
+ fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
+ // We add some newlines for clarity.
+ formatter.write_str("{\n")?;
+ if let [ref rest @ .., ref last] = self.0[..] {
+ for (key, value) in rest {
+ write!(formatter, " \"{}\": {},\n", key, value)?;
+ }
+ write!(formatter, " \"{}\": {}\n", last.0, last.1)?;
+ }
+ formatter.write_str("}")
+ }
+}
+
+struct KernelConfig(HashMap<String, String>);
+
+impl KernelConfig {
+ /// Parses `include/config/auto.conf` from `stdin`.
+ fn from_stdin() -> KernelConfig {
+ let mut result = HashMap::new();
+
+ let stdin = std::io::stdin();
+ let mut handle = stdin.lock();
+ let mut line = String::new();
+
+ loop {
+ line.clear();
+
+ if handle.read_line(&mut line).unwrap() == 0 {
+ break;
+ }
+
+ if line.starts_with('#') {
+ continue;
+ }
+
+ let (key, value) = line.split_once('=').expect("Missing `=` in line.");
+ result.insert(key.to_string(), value.trim_end_matches('\n').to_string());
+ }
+
+ KernelConfig(result)
+ }
+
+ /// Does the option exist in the configuration (any value)?
+ ///
+ /// The argument must be passed without the `CONFIG_` prefix.
+ /// This avoids repetition and it also avoids `fixdep` making us
+ /// depend on it.
+ fn has(&self, option: &str) -> bool {
+ let option = "CONFIG_".to_owned() + option;
+ self.0.contains_key(&option)
+ }
+}
+
+fn main() {
+ let cfg = KernelConfig::from_stdin();
+ let mut ts = TargetSpec::new();
+
+ // `llvm-target`s are taken from `scripts/Makefile.clang`.
+ if cfg.has("X86_64") {
+ ts.push("arch", "x86_64");
+ ts.push(
+ "data-layout",
+ "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
+ );
+ let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string();
+ if cfg.has("RETPOLINE") {
+ features += ",+retpoline-external-thunk";
+ }
+ ts.push("features", features);
+ ts.push("llvm-target", "x86_64-linux-gnu");
+ ts.push("target-pointer-width", "64");
+ } else {
+ panic!("Unsupported architecture");
+ }
+
+ ts.push("emit-debug-gdb-scripts", false);
+ ts.push("frame-pointer", "may-omit");
+ ts.push(
+ "stack-probes",
+ vec![("kind".to_string(), Value::String("none".to_string()))],
+ );
+
+ // Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not
+ // (e.g. x86). It is also `rustc`'s default.
+ if cfg.has("CPU_BIG_ENDIAN") {
+ ts.push("target-endian", "big");
+ }
+
+ println!("{}", ts);
+}
diff --git a/scripts/get_feat.pl b/scripts/get_feat.pl
index 76cfb96b59b6..5c5397eeb237 100755
--- a/scripts/get_feat.pl
+++ b/scripts/get_feat.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0
use strict;
diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
new file mode 100644
index 000000000000..b16326a92c45
--- /dev/null
+++ b/scripts/head-object-list.txt
@@ -0,0 +1,53 @@
+# Head objects
+#
+# The objects listed here are placed at the head of vmlinux. A typical use-case
+# is an object that contains the entry point. This is kept for compatibility
+# with head-y, which Kbuild used to support.
+#
+# A counter approach is to control the section placement by the linker script.
+# The code marked as __HEAD goes into the ".head.text" section, which is placed
+# before the normal ".text" section.
+#
+# If you can achieve the correct code ordering by linker script, please delete
+# the entry from this file.
+#
+arch/alpha/kernel/head.o
+arch/arc/kernel/head.o
+arch/arm/kernel/head-nommu.o
+arch/arm/kernel/head.o
+arch/arm64/kernel/head.o
+arch/csky/kernel/head.o
+arch/hexagon/kernel/head.o
+arch/ia64/kernel/head.o
+arch/loongarch/kernel/head.o
+arch/m68k/68000/head.o
+arch/m68k/coldfire/head.o
+arch/m68k/kernel/head.o
+arch/m68k/kernel/sun3-head.o
+arch/microblaze/kernel/head.o
+arch/mips/kernel/head.o
+arch/nios2/kernel/head.o
+arch/openrisc/kernel/head.o
+arch/parisc/kernel/head.o
+arch/powerpc/kernel/head_40x.o
+arch/powerpc/kernel/head_44x.o
+arch/powerpc/kernel/head_64.o
+arch/powerpc/kernel/head_8xx.o
+arch/powerpc/kernel/head_85xx.o
+arch/powerpc/kernel/head_book3s_32.o
+arch/powerpc/kernel/entry_64.o
+arch/powerpc/kernel/fpu.o
+arch/powerpc/kernel/vector.o
+arch/powerpc/kernel/prom_init.o
+arch/riscv/kernel/head.o
+arch/s390/kernel/head64.o
+arch/sh/kernel/head_32.o
+arch/sparc/kernel/head_32.o
+arch/sparc/kernel/head_64.o
+arch/x86/kernel/head_32.o
+arch/x86/kernel/head_64.o
+arch/x86/kernel/head32.o
+arch/x86/kernel/head64.o
+arch/x86/kernel/ebda.o
+arch/x86/kernel/platform-quirks.o
+arch/xtensa/kernel/head.o
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh
index dd554bd436cc..4041881746ad 100755
--- a/scripts/headers_install.sh
+++ b/scripts/headers_install.sh
@@ -70,7 +70,6 @@ configs=$(sed -e '
#
# The format is <file-name>:<CONFIG-option> in each line.
config_leak_ignores="
-arch/alpha/include/uapi/asm/setup.h:CONFIG_ALPHA_LEGACY_START_ADDRESS
arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_16K
arch/arc/include/uapi/asm/page.h:CONFIG_ARC_PAGE_SIZE_4K
arch/arc/include/uapi/asm/swab.h:CONFIG_ARC_HAS_SWAPE
@@ -84,7 +83,6 @@ arch/nios2/include/uapi/asm/swab.h:CONFIG_NIOS2_CI_SWAB_SUPPORT
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/eventpoll.h:CONFIG_PM_SLEEP
include/uapi/linux/hw_breakpoint.h:CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
diff --git a/scripts/is_rust_module.sh b/scripts/is_rust_module.sh
new file mode 100755
index 000000000000..28b3831a7593
--- /dev/null
+++ b/scripts/is_rust_module.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# is_rust_module.sh module.ko
+#
+# Returns `0` if `module.ko` is a Rust module, `1` otherwise.
+
+set -e
+
+# Using the `16_` prefix ensures other symbols with the same substring
+# are not picked up (even if it would be unlikely). The last part is
+# used just in case LLVM decides to use the `.` suffix.
+#
+# In the future, checking for the `.comment` section may be another
+# option, see https://github.com/rust-lang/rust/pull/97550.
+${NM} "$*" | grep -qE '^[0-9a-fA-F]+ r _R[^[:space:]]+16___IS_RUST_MODULE[^[:space:]]*$'
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index f18e6dfc68c5..03fa07ad45d9 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -18,6 +18,7 @@
*
*/
+#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,7 +28,23 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
-#define KSYM_NAME_LEN 128
+#define _stringify_1(x) #x
+#define _stringify(x) _stringify_1(x)
+
+#define KSYM_NAME_LEN 512
+
+/*
+ * A substantially bigger size than the current maximum.
+ *
+ * It cannot be defined as an expression because it gets stringified
+ * for the fscanf() format string. Therefore, a _Static_assert() is
+ * used instead to maintain the relationship with KSYM_NAME_LEN.
+ */
+#define KSYM_NAME_LEN_BUFFER 2048
+_Static_assert(
+ KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4,
+ "Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
+);
struct sym_entry {
unsigned long long addr;
@@ -71,7 +88,7 @@ static unsigned char best_table_len[256];
static void usage(void)
{
fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] "
- "[--base-relative] < in.map > out.S\n");
+ "[--base-relative] in.map > out.S\n");
exit(1);
}
@@ -107,9 +124,6 @@ static bool is_ignored_symbol(const char *name, char type)
/* Symbol names that begin with the following are ignored.*/
static const char * const ignored_prefixes[] = {
- "$", /* local symbols for ARM, MIPS, etc. */
- ".L", /* local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. */
- "__crc_", /* modversions */
"__efistub_", /* arm64 EFI stub namespace */
"__kvm_nvhe_$", /* arm64 local symbols in non-VHE KVM namespace */
"__kvm_nvhe_.L", /* arm64 local symbols in non-VHE KVM namespace */
@@ -119,6 +133,7 @@ static bool is_ignored_symbol(const char *name, char type)
"__ThumbV7PILongThunk_",
"__LA25Thunk_", /* mips lld */
"__microLA25Thunk_",
+ "__kcfi_typeid_", /* CFI type identifiers */
NULL
};
@@ -198,15 +213,15 @@ static void check_symbol_range(const char *sym, unsigned long long addr,
static struct sym_entry *read_symbol(FILE *in)
{
- char name[500], type;
+ char name[KSYM_NAME_LEN_BUFFER+1], type;
unsigned long long addr;
unsigned int len;
struct sym_entry *sym;
int rc;
- rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
+ rc = fscanf(in, "%llx %c %" _stringify(KSYM_NAME_LEN_BUFFER) "s\n", &addr, &type, name);
if (rc != 3) {
- if (rc != EOF && fgets(name, 500, in) == NULL)
+ if (rc != EOF && fgets(name, ARRAY_SIZE(name), in) == NULL)
fprintf(stderr, "Read error or end of file.\n");
return NULL;
}
@@ -313,12 +328,19 @@ static void shrink_table(void)
}
}
-static void read_map(FILE *in)
+static void read_map(const char *in)
{
+ FILE *fp;
struct sym_entry *sym;
- while (!feof(in)) {
- sym = read_symbol(in);
+ fp = fopen(in, "r");
+ if (!fp) {
+ perror(in);
+ exit(1);
+ }
+
+ while (!feof(fp)) {
+ sym = read_symbol(fp);
if (!sym)
continue;
@@ -329,12 +351,15 @@ static void read_map(FILE *in)
table = realloc(table, sizeof(*table) * table_size);
if (!table) {
fprintf(stderr, "out of memory\n");
+ fclose(fp);
exit (1);
}
}
table[table_cnt++] = sym;
}
+
+ fclose(fp);
}
static void output_label(const char *label)
@@ -471,12 +496,35 @@ static void write_src(void)
if ((i & 0xFF) == 0)
markers[i >> 8] = off;
- printf("\t.byte 0x%02x", table[i]->len);
+ /* There cannot be any symbol of length zero. */
+ if (table[i]->len == 0) {
+ fprintf(stderr, "kallsyms failure: "
+ "unexpected zero symbol length\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */
+ if (table[i]->len > 0x3FFF) {
+ fprintf(stderr, "kallsyms failure: "
+ "unexpected huge symbol length\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Encode length with ULEB128. */
+ if (table[i]->len <= 0x7F) {
+ /* Most symbols use a single byte for the length. */
+ printf("\t.byte 0x%02x", table[i]->len);
+ off += table[i]->len + 1;
+ } else {
+ /* "Big" symbols use two bytes. */
+ printf("\t.byte 0x%02x, 0x%02x",
+ (table[i]->len & 0x7F) | 0x80,
+ (table[i]->len >> 7) & 0x7F);
+ off += table[i]->len + 2;
+ }
for (k = 0; k < table[i]->len; k++)
printf(", 0x%02x", table[i]->sym[k]);
printf("\n");
-
- off += table[i]->len + 1;
}
printf("\n");
@@ -765,22 +813,26 @@ static void record_relative_base(void)
int main(int argc, char **argv)
{
- if (argc >= 2) {
- int i;
- for (i = 1; i < argc; i++) {
- if(strcmp(argv[i], "--all-symbols") == 0)
- all_symbols = 1;
- else if (strcmp(argv[i], "--absolute-percpu") == 0)
- absolute_percpu = 1;
- else if (strcmp(argv[i], "--base-relative") == 0)
- base_relative = 1;
- else
- usage();
- }
- } else if (argc != 1)
+ while (1) {
+ static struct option long_options[] = {
+ {"all-symbols", no_argument, &all_symbols, 1},
+ {"absolute-percpu", no_argument, &absolute_percpu, 1},
+ {"base-relative", no_argument, &base_relative, 1},
+ {},
+ };
+
+ int c = getopt_long(argc, argv, "", long_options, NULL);
+
+ if (c == -1)
+ break;
+ if (c != 0)
+ usage();
+ }
+
+ if (optind >= argc)
usage();
- read_map(stdin);
+ read_map(argv[optind]);
shrink_table();
if (absolute_percpu)
make_percpus_absolute();
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 4178065ca27f..33d19e419908 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -551,7 +551,7 @@ static int conf_choice(struct menu *menu)
print_help(child);
continue;
}
- sym_set_choice_value(sym, child->sym);
+ sym_set_tristate_value(child->sym, yes);
for (child = child->list; child; child = child->next) {
indent += 2;
conf(child);
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index c4340c90e172..b7c9f1dd5e42 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -216,6 +216,13 @@ static const char *conf_get_autoheader_name(void)
return name ? name : "include/generated/autoconf.h";
}
+static const char *conf_get_rustccfg_name(void)
+{
+ char *name = getenv("KCONFIG_RUSTCCFG");
+
+ return name ? name : "include/generated/rustc_cfg";
+}
+
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{
char *p2;
@@ -605,6 +612,9 @@ static const struct comment_style comment_style_c = {
static void conf_write_heading(FILE *fp, const struct comment_style *cs)
{
+ if (!cs)
+ return;
+
fprintf(fp, "%s\n", cs->prefix);
fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
@@ -745,6 +755,65 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym)
free(escaped);
}
+static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
+{
+ const char *val;
+ const char *val_prefix = "";
+ char *val_prefixed = NULL;
+ size_t val_prefixed_len;
+ char *escaped = NULL;
+
+ if (sym->type == S_UNKNOWN)
+ return;
+
+ val = sym_get_string_value(sym);
+
+ switch (sym->type) {
+ case S_BOOLEAN:
+ case S_TRISTATE:
+ /*
+ * We do not care about disabled ones, i.e. no need for
+ * what otherwise are "comments" in other printers.
+ */
+ if (*val == 'n')
+ return;
+
+ /*
+ * To have similar functionality to the C macro `IS_ENABLED()`
+ * we provide an empty `--cfg CONFIG_X` here in both `y`
+ * and `m` cases.
+ *
+ * Then, the common `fprintf()` below will also give us
+ * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
+ * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
+ */
+ fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
+ break;
+ case S_HEX:
+ if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
+ val_prefix = "0x";
+ break;
+ default:
+ break;
+ }
+
+ if (strlen(val_prefix) > 0) {
+ val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
+ val_prefixed = xmalloc(val_prefixed_len);
+ snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
+ val = val_prefixed;
+ }
+
+ /* All values get escaped: the `--cfg` option only takes strings */
+ escaped = escape_string_value(val);
+ val = escaped;
+
+ fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
+
+ free(escaped);
+ free(val_prefixed);
+}
+
/*
* Write out a minimal config.
* All values that has default values are skipped as this is redundant.
@@ -1132,6 +1201,12 @@ int conf_write_autoconf(int overwrite)
if (ret)
return ret;
+ ret = __conf_write_autoconf(conf_get_rustccfg_name(),
+ print_symbol_for_rustccfg,
+ NULL);
+ if (ret)
+ return ret;
+
/*
* Create include/config/auto.conf. This must be the last step because
* Kbuild has a dependency on auto.conf and this marks the successful
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index fa8c010aa683..6ac2eabe109d 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -98,7 +98,6 @@ 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);
@@ -124,11 +123,6 @@ static inline struct symbol *sym_get_choice_value(struct symbol *sym)
return (struct symbol *)sym->curr.val;
}
-static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
-{
- return sym_set_tristate_value(chval, yes);
-}
-
static inline bool sym_is_choice(struct symbol *sym)
{
return sym->flags & SYMBOL_CHOICE ? true : false;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 3d6f7cba8846..62b6313f51c8 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -661,11 +661,6 @@ const char *menu_get_prompt(struct menu *menu)
return NULL;
}
-struct menu *menu_get_root_menu(struct menu *menu)
-{
- return &rootmenu;
-}
-
struct menu *menu_get_parent_menu(struct menu *menu)
{
enum prop_type type;
diff --git a/scripts/kconfig/qconf-cfg.sh b/scripts/kconfig/qconf-cfg.sh
index 9b695e5cd9b3..ad652cb53947 100755
--- a/scripts/kconfig/qconf-cfg.sh
+++ b/scripts/kconfig/qconf-cfg.sh
@@ -20,5 +20,6 @@ fi
echo >&2 "*"
echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}."
echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
+echo >&2 "* You need $PKG"
echo >&2 "*"
exit 1
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 7516949bb049..aea04365bc69 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -427,6 +427,13 @@ sub print_lineno {
print ".. LINENO " . $lineno . "\n";
}
}
+
+sub emit_warning {
+ my $location = shift;
+ my $msg = shift;
+ print STDERR "$location: warning: $msg";
+ ++$warnings;
+}
##
# dumps section contents to arrays/hashes intended for that purpose.
#
@@ -451,8 +458,7 @@ sub dump_section {
if (defined($sections{$name}) && ($sections{$name} ne "")) {
# Only warn on user specified duplicate section names.
if ($name ne $section_default) {
- print STDERR "${file}:$.: warning: duplicate section name '$name'\n";
- ++$warnings;
+ emit_warning("${file}:$.", "duplicate section name '$name'\n");
}
$sections{$name} .= $contents;
} else {
@@ -1094,7 +1100,7 @@ sub dump_struct($$) {
if ($members) {
if ($identifier ne $declaration_name) {
- print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n";
+ emit_warning("${file}:$.", "expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n");
return;
}
@@ -1298,9 +1304,9 @@ sub dump_enum($$) {
if ($members) {
if ($identifier ne $declaration_name) {
if ($identifier eq "") {
- print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n";
+ emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n");
} else {
- print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n";
+ emit_warning("${file}:$.", "expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n");
}
return;
}
@@ -1316,7 +1322,7 @@ sub dump_enum($$) {
if (!$parameterdescs{$arg}) {
$parameterdescs{$arg} = $undescribed;
if (show_warnings("enum", $declaration_name)) {
- print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n";
+ emit_warning("${file}:$.", "Enum value '$arg' not described in enum '$declaration_name'\n");
}
}
$_members{$arg} = 1;
@@ -1325,7 +1331,7 @@ sub dump_enum($$) {
while (my ($k, $v) = each %parameterdescs) {
if (!exists($_members{$k})) {
if (show_warnings("enum", $declaration_name)) {
- print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n";
+ emit_warning("${file}:$.", "Excess enum value '$k' description in '$declaration_name'\n");
}
}
}
@@ -1367,7 +1373,7 @@ sub dump_typedef($$) {
$return_type =~ s/^\s+//;
if ($identifier ne $declaration_name) {
- print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n";
+ emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
return;
}
@@ -1398,7 +1404,7 @@ sub dump_typedef($$) {
$declaration_name = $1;
if ($identifier ne $declaration_name) {
- print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n";
+ emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
return;
}
@@ -1554,9 +1560,7 @@ sub push_parameter($$$$$) {
$parameterdescs{$param} = $undescribed;
if (show_warnings($type, $declaration_name) && $param !~ /\./) {
- print STDERR
- "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n";
- ++$warnings;
+ emit_warning("${file}:$.", "Function parameter or member '$param' not described in '$declaration_name'\n");
}
}
@@ -1604,11 +1608,10 @@ sub check_sections($$$$$) {
}
if ($err) {
if ($decl_type eq "function") {
- print STDERR "${file}:$.: warning: " .
+ emit_warning("${file}:$.",
"Excess function parameter " .
"'$sects[$sx]' " .
- "description in '$decl_name'\n";
- ++$warnings;
+ "description in '$decl_name'\n");
}
}
}
@@ -1629,10 +1632,9 @@ sub check_return_section {
if (!defined($sections{$section_return}) ||
$sections{$section_return} eq "") {
- print STDERR "${file}:$.: warning: " .
+ emit_warning("${file}:$.",
"No description found for return value of " .
- "'$declaration_name'\n";
- ++$warnings;
+ "'$declaration_name'\n");
}
}
@@ -1714,12 +1716,12 @@ sub dump_function($$) {
create_parameterlist($args, ',', $file, $declaration_name);
} else {
- print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n";
+ emit_warning("${file}:$.", "cannot understand function prototype: '$prototype'\n");
return;
}
if ($identifier ne $declaration_name) {
- print STDERR "${file}:$.: warning: expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n";
+ emit_warning("${file}:$.", "expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n");
return;
}
@@ -1801,8 +1803,8 @@ sub tracepoint_munge($) {
$tracepointargs = $1;
}
if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
- print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n".
- "$prototype\n";
+ emit_warning("${file}:$.", "Unrecognized tracepoint format: \n".
+ "$prototype\n");
} else {
$prototype = "static inline void trace_$tracepointname($tracepointargs)";
$identifier = "trace_$identifier";
@@ -2027,22 +2029,16 @@ sub process_name($$) {
}
if (!$is_kernel_comment) {
- print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n";
- print STDERR $_;
- ++$warnings;
+ emit_warning("${file}:$.", "This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n$_");
$state = STATE_NORMAL;
}
if (($declaration_purpose eq "") && $verbose) {
- print STDERR "${file}:$.: warning: missing initial short description on line:\n";
- print STDERR $_;
- ++$warnings;
+ emit_warning("${file}:$.", "missing initial short description on line:\n$_");
}
if ($identifier eq "" && $decl_type ne "enum") {
- print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n";
- print STDERR $_;
- ++$warnings;
+ emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n$_");
$state = STATE_NORMAL;
}
@@ -2050,9 +2046,7 @@ sub process_name($$) {
print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n";
}
} else {
- print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
- " - I thought it was a doc line\n";
- ++$warnings;
+ emit_warning("${file}:$.", "Cannot understand $_ on line $. - I thought it was a doc line\n");
$state = STATE_NORMAL;
}
}
@@ -2071,8 +2065,7 @@ sub process_body($$) {
$section =~ s/\.\.\.$//;
if ($verbose) {
- print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n";
- ++$warnings;
+ emit_warning("${file}:$.", "Variable macro arguments should be documented without dots\n");
}
}
@@ -2101,8 +2094,7 @@ sub process_body($$) {
if (($contents ne "") && ($contents ne "\n")) {
if (!$in_doc_sect && $verbose) {
- print STDERR "${file}:$.: warning: contents before sections\n";
- ++$warnings;
+ emit_warning("${file}:$.", "contents before sections\n");
}
dump_section($file, $section, $contents);
$section = $section_default;
@@ -2128,8 +2120,7 @@ sub process_body($$) {
}
# look for doc_com + <text> + doc_end:
if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
- print STDERR "${file}:$.: warning: suspicious ending line: $_";
- ++$warnings;
+ emit_warning("${file}:$.", "suspicious ending line: $_");
}
$prototype = "";
@@ -2173,8 +2164,7 @@ sub process_body($$) {
}
} else {
# i dont know - bad line? ignore.
- print STDERR "${file}:$.: warning: bad line: $_";
- ++$warnings;
+ emit_warning("${file}:$.", "bad line: $_");
}
}
@@ -2268,9 +2258,7 @@ sub process_inline($$) {
}
} elsif ($inline_doc_state == STATE_INLINE_NAME) {
$inline_doc_state = STATE_INLINE_ERROR;
- print STDERR "${file}:$.: warning: ";
- print STDERR "Incorrect use of kernel-doc format: $_";
- ++$warnings;
+ emit_warning("${file}:$.", "Incorrect use of kernel-doc format: $_");
}
}
}
@@ -2319,11 +2307,11 @@ sub process_file($) {
if ($initial_section_counter == $section_counter && $
output_mode ne "none") {
if ($output_selection == OUTPUT_INCLUDE) {
- print STDERR "${file}:1: warning: '$_' not found\n"
+ emit_warning("${file}:1", "'$_' not found\n")
for keys %function_table;
}
else {
- print STDERR "${file}:1: warning: no structured comments found\n";
+ emit_warning("${file}:1", "no structured comments found\n");
}
}
close IN_FILE;
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index eecc1863e556..918470d768e9 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -3,17 +3,15 @@
#
# link vmlinux
#
-# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and
-# $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories
-# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
+# vmlinux is linked from the objects in vmlinux.a and $(KBUILD_VMLINUX_LIBS).
+# vmlinux.a contains objects that are linked unconditionally.
# $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally
# (not within --whole-archive), and do not require symbol indexes added.
#
# vmlinux
# ^
# |
-# +--< $(KBUILD_VMLINUX_OBJS)
-# | +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
+# +--< vmlinux.a
# |
# +--< $(KBUILD_VMLINUX_LIBS)
# | +--< lib/lib.a + more
@@ -67,7 +65,7 @@ vmlinux_link()
objs=vmlinux.o
libs=
else
- objs="${KBUILD_VMLINUX_OBJS}"
+ objs=vmlinux.a
libs="${KBUILD_VMLINUX_LIBS}"
fi
@@ -75,6 +73,8 @@ vmlinux_link()
objs="${objs} .vmlinux.export.o"
fi
+ objs="${objs} init/version-timestamp.o"
+
if [ "${SRCARCH}" = "um" ]; then
wl=-Wl,
ld="${CC}"
@@ -157,7 +157,7 @@ kallsyms()
fi
info KSYMS ${2}
- ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
+ scripts/kallsyms ${kallsymopt} ${1} > ${2}
}
# Perform one step in kallsyms generation, including temporary linking of
@@ -170,7 +170,8 @@ kallsyms_step()
kallsyms_S=${kallsyms_vmlinux}.S
vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
- kallsyms ${kallsyms_vmlinux} ${kallsyms_S}
+ mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms
+ kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
info AS ${kallsyms_S}
${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
@@ -182,6 +183,7 @@ kallsyms_step()
# See mksymap for additional details
mksysmap()
{
+ info NM ${2}
${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
}
@@ -197,8 +199,6 @@ cleanup()
rm -f System.map
rm -f vmlinux
rm -f vmlinux.map
- rm -f .vmlinux.objs
- rm -f .vmlinux.export.c
}
# Use "make V=1" to debug this script
@@ -213,52 +213,7 @@ if [ "$1" = "clean" ]; then
exit 0
fi
-# Update version
-info GEN .version
-if [ -r .version ]; then
- VERSION=$(expr 0$(cat .version) + 1)
- echo $VERSION > .version
-else
- rm -f .version
- echo 1 > .version
-fi;
-
-# final build of init/
-${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
-
-#link vmlinux.o
-${MAKE} -f "${srctree}/scripts/Makefile.vmlinux_o"
-
-# Generate the list of in-tree objects in vmlinux
-#
-# This is used to retrieve symbol versions generated by genksyms.
-for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
- case ${f} in
- *libgcc.a)
- # Some architectures do '$(CC) --print-libgcc-file-name' to
- # borrow libgcc.a from the toolchain.
- # There is no EXPORT_SYMBOL in external objects. Ignore this.
- ;;
- *.a)
- ${AR} t ${f} ;;
- *)
- echo ${f} ;;
- esac
-done > .vmlinux.objs
-
-# modpost vmlinux.o to check for section mismatches
-${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
-
-info MODINFO modules.builtin.modinfo
-${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
-info GEN modules.builtin
-# The second line aids cases where multiple modules share the same object.
-tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
- tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
-
-if is_enabled CONFIG_MODULES; then
- ${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o
-fi
+${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o
btf_vmlinux_bin_o=""
if is_enabled CONFIG_DEBUG_INFO_BTF; then
@@ -318,7 +273,6 @@ if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
${RESOLVE_BTFIDS} vmlinux
fi
-info SYSMAP System.map
mksysmap vmlinux System.map
if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then
@@ -331,9 +285,7 @@ fi
# step a (see comment above)
if is_enabled CONFIG_KALLSYMS; then
- mksysmap ${kallsyms_vmlinux} .tmp_System.map
-
- if ! cmp -s System.map .tmp_System.map; then
+ if ! cmp -s System.map ${kallsyms_vmlinux}.syms; then
echo >&2 Inconsistent kallsyms data
echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
exit 1
diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh
index 250925aab101..b6593eac5003 100755
--- a/scripts/min-tool-version.sh
+++ b/scripts/min-tool-version.sh
@@ -30,6 +30,12 @@ llvm)
echo 11.0.0
fi
;;
+rustc)
+ echo 1.62.0
+ ;;
+bindgen)
+ echo 0.56.0
+ ;;
*)
echo "$1: unknown tool" >&2
exit 1
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index ca40a5258c87..2596f78e52ef 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -1,33 +1,10 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
-TARGET=$1
-ARCH=$2
-SMP=$3
-PREEMPT=$4
-PREEMPT_DYNAMIC=$5
-PREEMPT_RT=$6
-CC_VERSION="$7"
-LD=$8
+UTS_MACHINE=$1
+CC_VERSION="$2"
+LD=$3
-# Do not expand names
-set -f
-
-# Fix the language to get consistent output
-LC_ALL=C
-export LC_ALL
-
-if [ -z "$KBUILD_BUILD_VERSION" ]; then
- VERSION=$(cat .version 2>/dev/null || echo 1)
-else
- VERSION=$KBUILD_BUILD_VERSION
-fi
-
-if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
- TIMESTAMP=`date`
-else
- TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
-fi
if test -z "$KBUILD_BUILD_USER"; then
LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
else
@@ -39,63 +16,12 @@ else
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
fi
-UTS_VERSION="#$VERSION"
-CONFIG_FLAGS=""
-if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi
-
-if [ -n "$PREEMPT_RT" ] ; then
- CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_RT"
-elif [ -n "$PREEMPT_DYNAMIC" ] ; then
- CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT_DYNAMIC"
-elif [ -n "$PREEMPT" ] ; then
- CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"
-fi
-
-# Truncate to maximum length
-UTS_LEN=64
-UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)"
-
-# Generate a temporary compile.h
+LD_VERSION=$(LC_ALL=C $LD -v | head -n1 |
+ sed -e 's/(compatible with [^)]*)//' -e 's/[[:space:]]*$//')
-{ echo /\* This file is auto generated, version $VERSION \*/
- if [ -n "$CONFIG_FLAGS" ] ; then echo "/* $CONFIG_FLAGS */"; fi
-
- echo \#define UTS_MACHINE \"$ARCH\"
-
- echo \#define UTS_VERSION \"$UTS_VERSION\"
-
- printf '#define LINUX_COMPILE_BY "%s"\n' "$LINUX_COMPILE_BY"
- echo \#define LINUX_COMPILE_HOST \"$LINUX_COMPILE_HOST\"
-
- LD_VERSION=$($LD -v | head -n1 | sed 's/(compatible with [^)]*)//' \
- | sed 's/[[:space:]]*$//')
- printf '#define LINUX_COMPILER "%s"\n' "$CC_VERSION, $LD_VERSION"
-} > .tmpcompile
-
-# Only replace the real compile.h if the new one is different,
-# in order to preserve the timestamp and avoid unnecessary
-# recompilations.
-# We don't consider the file changed if only the date/time changed,
-# unless KBUILD_BUILD_TIMESTAMP was explicitly set (e.g. for
-# reproducible builds with that value referring to a commit timestamp).
-# A kernel config change will increase the generation number, thus
-# causing compile.h to be updated (including date/time) due to the
-# changed comment in the
-# first line.
-
-if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
- IGNORE_PATTERN="UTS_VERSION"
-else
- IGNORE_PATTERN="NOT_A_PATTERN_TO_BE_MATCHED"
-fi
-
-if [ -r $TARGET ] && \
- grep -v $IGNORE_PATTERN $TARGET > .tmpver.1 && \
- grep -v $IGNORE_PATTERN .tmpcompile > .tmpver.2 && \
- cmp -s .tmpver.1 .tmpver.2; then
- rm -f .tmpcompile
-else
- echo " UPD $TARGET"
- mv -f .tmpcompile $TARGET
-fi
-rm -f .tmpver.1 .tmpver.2
+cat <<EOF
+#define UTS_MACHINE "${UTS_MACHINE}"
+#define LINUX_COMPILE_BY "${LINUX_COMPILE_BY}"
+#define LINUX_COMPILE_HOST "${LINUX_COMPILE_HOST}"
+#define LINUX_COMPILER "${CC_VERSION}, ${LD_VERSION}"
+EOF
diff --git a/scripts/mksysmap b/scripts/mksysmap
index 9aa23d15862a..16a08b8ef2f8 100755
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -37,8 +37,24 @@
# readprofile starts reading symbols when _stext is found, and
# continue until it finds a symbol which is not either of 'T', 't',
-# 'W' or 'w'. __crc_ are 'A' and placed in the middle
-# so we just ignore them to let readprofile continue to work.
-# (At least sparc64 has __crc_ in the middle).
+# 'W' or 'w'.
+#
+# Ignored prefixes:
+# $ - local symbols for ARM, MIPS, etc.
+# .L - local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc.
+# __crc_ - modversions
+# __kstrtab_ - EXPORT_SYMBOL (symbol name)
+# __kstrtabns_ - EXPORT_SYMBOL (namespace)
+#
+# Ignored symbols:
+# L0 - for LoongArch?
-$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)' > $2
+$NM -n $1 | grep -v \
+ -e ' [aNUw] ' \
+ -e ' \$' \
+ -e ' \.L' \
+ -e ' __crc_' \
+ -e ' __kstrtab_' \
+ -e ' __kstrtabns_' \
+ -e ' L0$' \
+> $2
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index cbd6b0f48b4e..80d973144fde 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1571,9 +1571,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
zeros = calloc(1, sym->st_size);
symval = zeros;
} else {
- symval = (void *)info->hdr
- + info->sechdrs[get_secindex(info, sym)].sh_offset
- + sym->st_value;
+ symval = sym_get_data(info, sym);
}
/* First handle the "special" cases */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 620dc8c4c814..2c80da0220c3 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -321,13 +321,10 @@ static void *sym_get_data_by_offset(const struct elf_info *info,
{
Elf_Shdr *sechdr = &info->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)
+void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
{
return sym_get_data_by_offset(info, get_secindex(info, sym),
sym->st_value);
@@ -339,8 +336,16 @@ static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
sechdr->sh_name);
}
-static const char *sec_name(const struct elf_info *info, int secindex)
+static const char *sec_name(const struct elf_info *info, unsigned int secindex)
{
+ /*
+ * If sym->st_shndx is a special section index, there is no
+ * corresponding section header.
+ * Return "" if the index is out of range of info->sechdrs[] array.
+ */
+ if (secindex >= info->num_sections)
+ return "";
+
return sech_name(info, &info->sechdrs[secindex]);
}
@@ -466,6 +471,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
sechdrs = (void *)hdr + hdr->e_shoff;
info->sechdrs = sechdrs;
+ /* modpost only works for relocatable objects */
+ if (hdr->e_type != ET_REL)
+ fatal("%s: not relocatable object.", 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=%zu\n",
@@ -737,12 +746,18 @@ static bool match(const char *string, const char *const patterns[])
return false;
}
+/* useful to pass patterns to match() directly */
+#define PATTERNS(...) \
+ ({ \
+ static const char *const patterns[] = {__VA_ARGS__, NULL}; \
+ patterns; \
+ })
+
/* sections that we do not want to do full section mismatch check on */
static const char *const section_white_list[] =
{
".comment*",
".debug*",
- ".cranges", /* sh64 */
".zdebug*", /* Compressed debug sections. */
".GCC.command.line", /* record-gcc-switches */
".mdebug*", /* alpha, score, mips etc. */
@@ -830,28 +845,12 @@ static const char *const init_data_sections[] =
/* all init sections */
static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
-/* All init and exit sections (code + data) */
-static const char *const init_exit_sections[] =
- {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
-
/* all text sections */
static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
/* data section */
static const char *const data_sections[] = { DATA_SECTIONS, NULL };
-
-/* symbols in .data that may refer to init/exit sections */
-#define DEFAULT_SYMBOL_WHITE_LIST \
- "*driver", \
- "*_template", /* scsi uses *_template a lot */ \
- "*_timer", /* arm uses ops structures named _timer a lot */ \
- "*_sht", /* scsi also used *_sht to some extent */ \
- "*_ops", \
- "*_probe", \
- "*_probe_one", \
- "*_console"
-
static const char *const head_sections[] = { ".head.text*", NULL };
static const char *const linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL };
@@ -883,9 +882,6 @@ enum mismatch {
*
* @mismatch: Type of mismatch.
*
- * @symbol_white_list: Do not match a relocation to a symbol in this list
- * even if it is targeting a section in @bad_to_sec.
- *
* @handler: Specific handler to call when a match is found. If NULL,
* default_mismatch_handler() will be called.
*
@@ -895,7 +891,6 @@ struct sectioncheck {
const char *bad_tosec[20];
const char *good_tosec[20];
enum mismatch mismatch;
- const char *symbol_white_list[20];
void (*handler)(const char *modname, struct elf_info *elf,
const struct sectioncheck* const mismatch,
Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
@@ -915,75 +910,61 @@ static const struct sectioncheck sectioncheck[] = {
.fromsec = { TEXT_SECTIONS, NULL },
.bad_tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = TEXT_TO_ANY_INIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { DATA_SECTIONS, NULL },
.bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_INIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { DATA_SECTIONS, NULL },
.bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_INIT,
- .symbol_white_list = {
- "*_template", "*_timer", "*_sht", "*_ops",
- "*_probe", "*_probe_one", "*_console", NULL
- },
},
{
.fromsec = { TEXT_SECTIONS, NULL },
.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = TEXT_TO_ANY_EXIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { DATA_SECTIONS, NULL },
.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_EXIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
/* Do not reference init code/data from meminit code/data */
{
.fromsec = { ALL_XXXINIT_SECTIONS, NULL },
.bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = XXXINIT_TO_SOME_INIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
/* Do not reference exit code/data from memexit code/data */
{
.fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
.bad_tosec = { EXIT_SECTIONS, NULL },
.mismatch = XXXEXIT_TO_SOME_EXIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
/* Do not use exit code/data from init code */
{
.fromsec = { ALL_INIT_SECTIONS, NULL },
.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = ANY_INIT_TO_ANY_EXIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
/* Do not use init code/data from exit code */
{
.fromsec = { ALL_EXIT_SECTIONS, NULL },
.bad_tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = ANY_EXIT_TO_ANY_INIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
.bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = ANY_INIT_TO_ANY_EXIT,
- .symbol_white_list = { NULL },
},
/* Do not export init/exit functions or data */
{
.fromsec = { "___ksymtab*", NULL },
.bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
.mismatch = EXPORT_TO_INIT_EXIT,
- .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { "__ex_table", NULL },
@@ -1044,15 +1025,6 @@ static const struct sectioncheck *section_mismatch(
* fromsec = .data*
* atsym = __param_ops_*
*
- * Pattern 2:
- * Many drivers utilise a *driver container with references to
- * add, remove, probe functions etc.
- * the pattern is identified by:
- * tosec = init or exit section
- * fromsec = data section
- * atsym = *driver, *_template, *_sht, *_ops, *_probe,
- * *probe_one, *_console, *_timer
- *
* Pattern 3:
* Whitelist all references from .head.text to any init section
*
@@ -1101,10 +1073,22 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
strstarts(fromsym, "__param_ops_"))
return 0;
- /* Check for pattern 2 */
- if (match(tosec, init_exit_sections) &&
- match(fromsec, data_sections) &&
- match(fromsym, mismatch->symbol_white_list))
+ /* symbols in data sections that may refer to any init/exit sections */
+ if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
+ match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
+ match(fromsym, PATTERNS("*_template", // scsi uses *_template a lot
+ "*_timer", // arm uses ops structures named _timer a lot
+ "*_sht", // scsi also used *_sht to some extent
+ "*_ops",
+ "*_probe",
+ "*_probe_one",
+ "*_console")))
+ return 0;
+
+ /* symbols in data sections that may refer to meminit/exit sections */
+ if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
+ match(tosec, PATTERNS(ALL_XXXINIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
+ match(fromsym, PATTERNS("*driver")))
return 0;
/* Check for pattern 3 */
@@ -1230,42 +1214,6 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
return near;
}
-/*
- * Convert a section name to the function/data attribute
- * .init.text => __init
- * .memexitconst => __memconst
- * etc.
- *
- * The memory of returned value has been allocated on a heap. The user of this
- * method should free it after usage.
-*/
-static char *sec2annotation(const char *s)
-{
- if (match(s, init_exit_sections)) {
- char *p = NOFAIL(malloc(20));
- char *r = p;
-
- *p++ = '_';
- *p++ = '_';
- if (*s == '.')
- s++;
- while (*s && *s != '.')
- *p++ = *s++;
- *p = '\0';
- if (*s == '.')
- s++;
- if (strstr(s, "rodata") != NULL)
- strcat(p, "const ");
- else if (strstr(s, "data") != NULL)
- strcat(p, "data ");
- else
- strcat(p, " ");
- return r;
- } else {
- return NOFAIL(strdup(""));
- }
-}
-
static int is_function(Elf_Sym *sym)
{
if (sym)
@@ -1274,19 +1222,6 @@ static int is_function(Elf_Sym *sym)
return -1;
}
-static void print_section_list(const char * const list[20])
-{
- const char *const *s = list;
-
- while (*s) {
- fprintf(stderr, "%s", *s);
- s++;
- if (*s)
- fprintf(stderr, ", ");
- }
- fprintf(stderr, "\n");
-}
-
static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
{
switch (is_func) {
@@ -1304,141 +1239,31 @@ static inline void get_pretty_name(int is_func, const char** name, const char**
static void report_sec_mismatch(const char *modname,
const struct sectioncheck *mismatch,
const char *fromsec,
- unsigned long long fromaddr,
const char *fromsym,
- int from_is_func,
- const char *tosec, const char *tosym,
- int to_is_func)
+ const char *tosec, const char *tosym)
{
- const char *from, *from_p;
- const char *to, *to_p;
- char *prl_from;
- char *prl_to;
-
sec_mismatch_count++;
- get_pretty_name(from_is_func, &from, &from_p);
- get_pretty_name(to_is_func, &to, &to_p);
-
- warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
- "to the %s %s:%s%s\n",
- modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
- tosym, to_p);
-
switch (mismatch->mismatch) {
case TEXT_TO_ANY_INIT:
- prl_from = sec2annotation(fromsec);
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The function %s%s() references\n"
- "the %s %s%s%s.\n"
- "This is often because %s lacks a %s\n"
- "annotation or the annotation of %s is wrong.\n",
- prl_from, fromsym,
- to, prl_to, tosym, to_p,
- fromsym, prl_to, tosym);
- free(prl_from);
- free(prl_to);
- break;
- case DATA_TO_ANY_INIT: {
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The variable %s references\n"
- "the %s %s%s%s\n"
- "If the reference is valid then annotate the\n"
- "variable with __init* or __refdata (see linux/init.h) "
- "or name the variable:\n",
- fromsym, to, prl_to, tosym, to_p);
- print_section_list(mismatch->symbol_white_list);
- free(prl_to);
- break;
- }
+ case DATA_TO_ANY_INIT:
case TEXT_TO_ANY_EXIT:
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The function %s() references a %s in an exit section.\n"
- "Often the %s %s%s has valid usage outside the exit section\n"
- "and the fix is to remove the %sannotation of %s.\n",
- fromsym, to, to, tosym, to_p, prl_to, tosym);
- free(prl_to);
- break;
- case DATA_TO_ANY_EXIT: {
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The variable %s references\n"
- "the %s %s%s%s\n"
- "If the reference is valid then annotate the\n"
- "variable with __exit* (see linux/init.h) or "
- "name the variable:\n",
- fromsym, to, prl_to, tosym, to_p);
- print_section_list(mismatch->symbol_white_list);
- free(prl_to);
- break;
- }
+ case DATA_TO_ANY_EXIT:
case XXXINIT_TO_SOME_INIT:
case XXXEXIT_TO_SOME_EXIT:
- prl_from = sec2annotation(fromsec);
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The %s %s%s%s references\n"
- "a %s %s%s%s.\n"
- "If %s is only used by %s then\n"
- "annotate %s with a matching annotation.\n",
- from, prl_from, fromsym, from_p,
- to, prl_to, tosym, to_p,
- tosym, fromsym, tosym);
- free(prl_from);
- free(prl_to);
- break;
case ANY_INIT_TO_ANY_EXIT:
- prl_from = sec2annotation(fromsec);
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The %s %s%s%s references\n"
- "a %s %s%s%s.\n"
- "This is often seen when error handling "
- "in the init function\n"
- "uses functionality in the exit path.\n"
- "The fix is often to remove the %sannotation of\n"
- "%s%s so it may be used outside an exit section.\n",
- from, prl_from, fromsym, from_p,
- to, prl_to, tosym, to_p,
- prl_to, tosym, to_p);
- free(prl_from);
- free(prl_to);
- break;
case ANY_EXIT_TO_ANY_INIT:
- prl_from = sec2annotation(fromsec);
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The %s %s%s%s references\n"
- "a %s %s%s%s.\n"
- "This is often seen when error handling "
- "in the exit function\n"
- "uses functionality in the init path.\n"
- "The fix is often to remove the %sannotation of\n"
- "%s%s so it may be used outside an init section.\n",
- from, prl_from, fromsym, from_p,
- to, prl_to, tosym, to_p,
- prl_to, tosym, to_p);
- free(prl_from);
- free(prl_to);
+ warn("%s: section mismatch in reference: %s (section: %s) -> %s (section: %s)\n",
+ modname, fromsym, fromsec, tosym, tosec);
break;
case EXPORT_TO_INIT_EXIT:
- prl_to = sec2annotation(tosec);
- fprintf(stderr,
- "The symbol %s is exported and annotated %s\n"
- "Fix this by removing the %sannotation of %s "
- "or drop the export.\n",
- tosym, prl_to, prl_to, tosym);
- free(prl_to);
+ warn("%s: EXPORT_SYMBOL used for init/exit symbol: %s (section: %s)\n",
+ modname, tosym, tosec);
break;
case EXTABLE_TO_NON_TEXT:
- fatal("There's a special handler for this mismatch type, "
- "we should never get here.");
+ fatal("There's a special handler for this mismatch type, we should never get here.\n");
break;
}
- fprintf(stderr, "\n");
}
static void default_mismatch_handler(const char *modname, struct elf_info *elf,
@@ -1454,9 +1279,6 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
from = find_elf_symbol2(elf, r->r_offset, fromsec);
fromsym = sym_name(elf, from);
- if (strstarts(fromsym, "reference___initcall"))
- return;
-
tosec = sec_name(elf, get_secindex(elf, sym));
to = find_elf_symbol(elf, r->r_addend, sym);
tosym = sym_name(elf, to);
@@ -1465,9 +1287,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
if (secref_whitelist(mismatch,
fromsec, fromsym, tosec, tosym)) {
report_sec_mismatch(modname, mismatch,
- fromsec, r->r_offset, fromsym,
- is_function(from), tosec, tosym,
- is_function(to));
+ fromsec, fromsym, tosec, tosym);
}
}
@@ -1623,9 +1443,6 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
break;
case R_386_PC32:
r->r_addend = TO_NATIVE(*location) + 4;
- /* For CONFIG_RELOCATABLE=y */
- if (elf->hdr->e_type == ET_EXEC)
- r->r_addend += r->r_offset;
break;
}
return 0;
@@ -1718,8 +1535,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
Elf_Rela *stop = (void *)start + sechdr->sh_size;
- fromsec = sech_name(elf, sechdr);
- fromsec += strlen(".rela");
+ fromsec = sec_name(elf, sechdr->sh_info);
/* if from section (name) is know good then skip it */
if (match(fromsec, section_white_list))
return;
@@ -1771,8 +1587,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
Elf_Rel *stop = (void *)start + sechdr->sh_size;
- fromsec = sech_name(elf, sechdr);
- fromsec += strlen(".rel");
+ fromsec = sec_name(elf, sechdr->sh_info);
/* if from section (name) is know good then skip it */
if (match(fromsec, section_white_list))
return;
@@ -2191,6 +2006,9 @@ static void add_header(struct buffer *b, struct module *mod)
if (strstarts(mod->name, "drivers/staging"))
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
+
+ if (strstarts(mod->name, "tools/testing"))
+ buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n");
}
static void add_exported_symbols(struct buffer *buf, struct module *mod)
@@ -2203,13 +2021,11 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
/* record CRCs for exported symbols */
buf_printf(buf, "\n");
list_for_each_entry(sym, &mod->exported_symbols, list) {
- if (!sym->crc_valid) {
+ if (!sym->crc_valid)
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
sym->name);
- continue;
- }
buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n",
sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : "");
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 044bdfb894b7..1178f40a73f3 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -26,7 +26,6 @@
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Addr Elf32_Addr
-#define Elf_Sword Elf64_Sword
#define Elf_Section Elf32_Half
#define ELF_ST_BIND ELF32_ST_BIND
#define ELF_ST_TYPE ELF32_ST_TYPE
@@ -41,7 +40,6 @@
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Addr Elf64_Addr
-#define Elf_Sword Elf64_Sxword
#define Elf_Section Elf64_Half
#define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE
@@ -158,22 +156,28 @@ static inline int is_shndx_special(unsigned int i)
return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
}
-/*
- * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
- * the way to -256..-1, to avoid conflicting with real section
- * indices.
- */
-#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
-
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
static inline unsigned int get_secindex(const struct elf_info *info,
const Elf_Sym *sym)
{
- if (is_shndx_special(sym->st_shndx))
- return SPECIAL(sym->st_shndx);
- if (sym->st_shndx != SHN_XINDEX)
- return sym->st_shndx;
- return info->symtab_shndx_start[sym - info->symtab_start];
+ unsigned int index = sym->st_shndx;
+
+ /*
+ * Elf{32,64}_Sym::st_shndx is 2 byte. Big section numbers are available
+ * in the .symtab_shndx section.
+ */
+ if (index == SHN_XINDEX)
+ return info->symtab_shndx_start[sym - info->symtab_start];
+
+ /*
+ * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
+ * the way to UINT_MAX-255..UINT_MAX, to avoid conflicting with real
+ * section indices.
+ */
+ if (index >= SHN_LORESERVE && index <= SHN_HIRESERVE)
+ return index - SHN_HIRESERVE - 1;
+
+ return index;
}
/* file2alias.c */
@@ -187,6 +191,7 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen);
/* from modpost.c */
char *read_text_file(const char *filename);
char *get_line(char **stringp);
+void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
enum loglevel {
LOG_WARN,
diff --git a/scripts/module.lds.S b/scripts/module.lds.S
index 1d0e1e4dc3d2..da4bddd26171 100644
--- a/scripts/module.lds.S
+++ b/scripts/module.lds.S
@@ -3,20 +3,10 @@
* Archs are free to supply their own linker scripts. ld will
* combine them automatically.
*/
-#ifdef CONFIG_CFI_CLANG
-# include <asm/page.h>
-# define ALIGN_CFI ALIGN(PAGE_SIZE)
-# define SANITIZER_DISCARDS *(.eh_frame)
-#else
-# define ALIGN_CFI
-# define SANITIZER_DISCARDS
-#endif
-
SECTIONS {
/DISCARD/ : {
*(.discard)
*(.discard.*)
- SANITIZER_DISCARDS
}
__ksymtab 0 : { *(SORT(___ksymtab+*)) }
@@ -27,10 +17,16 @@ SECTIONS {
.ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) }
.init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }
+ .altinstructions 0 : ALIGN(8) { KEEP(*(.altinstructions)) }
+ __bug_table 0 : ALIGN(8) { KEEP(*(__bug_table)) }
__jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) }
__patchable_function_entries : { *(__patchable_function_entries) }
+#ifdef CONFIG_ARCH_USES_CFI_TRAPS
+ __kcfi_traps : { KEEP(*(.kcfi_traps)) }
+#endif
+
#ifdef CONFIG_LTO_CLANG
/*
* With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
@@ -51,15 +47,6 @@ SECTIONS {
*(.rodata .rodata.[0-9a-zA-Z_]*)
*(.rodata..L*)
}
-
- /*
- * With CONFIG_CFI_CLANG, we assume __cfi_check is at the beginning
- * of the .text section, and is aligned to PAGE_SIZE.
- */
- .text : ALIGN_CFI {
- *(.text.__cfi_check)
- *(.text .text.[0-9a-zA-Z_]* .text..L.cfi*)
- }
#endif
}
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 7c477ca7dc98..c920c1b18e7a 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -49,6 +49,9 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF
URL: https://www.kernel.org
$S Source: kernel-$__KERNELRELEASE.tar.gz
Provides: $PROVIDES
+ # $UTS_MACHINE as a fallback of _arch in case
+ # /usr/lib/rpm/platform/*/macros was not included.
+ %define _arch %{?_arch:$UTS_MACHINE}
%define __spec_install_post /usr/lib/rpm/brp-compress || :
%define debug_package %{nil}
@@ -85,10 +88,10 @@ $S
mkdir -p %{buildroot}/boot
%ifarch ia64
mkdir -p %{buildroot}/boot/efi
- cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
+ cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/
%else
- cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
+ cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
%endif
$M $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install
$MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files
index 7adab4618035..ccadfa3afb2b 100755
--- a/scripts/remove-stale-files
+++ b/scripts/remove-stale-files
@@ -20,6 +20,8 @@ set -e
# yard. Stale files stay in this file for a while (for some release cycles?),
# then will be really dead and removed from the code base entirely.
+rm -f arch/powerpc/purgatory/kexec-purgatory.c
+
# These were previously generated source files. When you are building the kernel
# with O=, make sure to remove the stale files in the output tree. Otherwise,
# the build system wrongly compiles the stale ones.
@@ -40,4 +42,8 @@ if [ -n "${building_out_of_srctree}" ]; then
done
fi
+rm -f arch/riscv/purgatory/kexec-purgatory.c
+
rm -f scripts/extract-cert
+
+rm -f arch/x86/purgatory/kexec-purgatory.c
diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
new file mode 100755
index 000000000000..aebbf1913970
--- /dev/null
+++ b/scripts/rust_is_available.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Tests whether a suitable Rust toolchain is available.
+#
+# Pass `-v` for human output and more checks (as warnings).
+
+set -e
+
+min_tool_version=$(dirname $0)/min-tool-version.sh
+
+# Convert the version string x.y.z to a canonical up-to-7-digits form.
+#
+# Note that this function uses one more digit (compared to other
+# instances in other version scripts) to give a bit more space to
+# `rustc` since it will reach 1.100.0 in late 2026.
+get_canonical_version()
+{
+ IFS=.
+ set -- $1
+ echo $((100000 * $1 + 100 * $2 + $3))
+}
+
+# Check that the Rust compiler exists.
+if ! command -v "$RUSTC" >/dev/null; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust compiler '$RUSTC' could not be found."
+ echo >&2 "***"
+ fi
+ exit 1
+fi
+
+# Check that the Rust bindings generator exists.
+if ! command -v "$BINDGEN" >/dev/null; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found."
+ echo >&2 "***"
+ fi
+ exit 1
+fi
+
+# Check that the Rust compiler version is suitable.
+#
+# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
+rust_compiler_version=$( \
+ LC_ALL=C "$RUSTC" --version 2>/dev/null \
+ | head -n 1 \
+ | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+)
+rust_compiler_min_version=$($min_tool_version rustc)
+rust_compiler_cversion=$(get_canonical_version $rust_compiler_version)
+rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version)
+if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust compiler '$RUSTC' is too old."
+ echo >&2 "*** Your version: $rust_compiler_version"
+ echo >&2 "*** Minimum version: $rust_compiler_min_version"
+ echo >&2 "***"
+ fi
+ exit 1
+fi
+if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work."
+ echo >&2 "*** Your version: $rust_compiler_version"
+ echo >&2 "*** Expected version: $rust_compiler_min_version"
+ echo >&2 "***"
+fi
+
+# Check that the Rust bindings generator is suitable.
+#
+# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`.
+rust_bindings_generator_version=$( \
+ LC_ALL=C "$BINDGEN" --version 2>/dev/null \
+ | head -n 1 \
+ | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+)
+rust_bindings_generator_min_version=$($min_tool_version bindgen)
+rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version)
+rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version)
+if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust bindings generator '$BINDGEN' is too old."
+ echo >&2 "*** Your version: $rust_bindings_generator_version"
+ echo >&2 "*** Minimum version: $rust_bindings_generator_min_version"
+ echo >&2 "***"
+ fi
+ exit 1
+fi
+if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then
+ echo >&2 "***"
+ echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work."
+ echo >&2 "*** Your version: $rust_bindings_generator_version"
+ echo >&2 "*** Expected version: $rust_bindings_generator_min_version"
+ echo >&2 "***"
+fi
+
+# Check that the `libclang` used by the Rust bindings generator is suitable.
+bindgen_libclang_version=$( \
+ LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \
+ | grep -F 'clang version ' \
+ | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
+ | head -n 1 \
+)
+bindgen_libclang_min_version=$($min_tool_version llvm)
+bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version)
+bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version)
+if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old."
+ echo >&2 "*** Your version: $bindgen_libclang_version"
+ echo >&2 "*** Minimum version: $bindgen_libclang_min_version"
+ echo >&2 "***"
+ fi
+ exit 1
+fi
+
+# If the C compiler is Clang, then we can also check whether its version
+# matches the `libclang` version used by the Rust bindings generator.
+#
+# In the future, we might be able to perform a full version check, see
+# https://github.com/rust-lang/rust-bindgen/issues/2138.
+if [ "$1" = -v ]; then
+ cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ')
+ if [ "$cc_name" = Clang ]; then
+ clang_version=$( \
+ LC_ALL=C "$CC" --version 2>/dev/null \
+ | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p'
+ )
+ if [ "$clang_version" != "$bindgen_libclang_version" ]; then
+ echo >&2 "***"
+ echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')"
+ echo >&2 "*** version does not match Clang's. This may be a problem."
+ echo >&2 "*** libclang version: $bindgen_libclang_version"
+ echo >&2 "*** Clang version: $clang_version"
+ echo >&2 "***"
+ fi
+ fi
+fi
+
+# Check that the source code for the `core` standard library exists.
+#
+# `$KRUSTFLAGS` is passed in case the user added `--sysroot`.
+rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot)
+rustc_src=${RUST_LIB_SRC:-"$rustc_sysroot/lib/rustlib/src/rust/library"}
+rustc_src_core="$rustc_src/core/src/lib.rs"
+if [ ! -e "$rustc_src_core" ]; then
+ if [ "$1" = -v ]; then
+ echo >&2 "***"
+ echo >&2 "*** Source code for the 'core' standard library could not be found"
+ echo >&2 "*** at '$rustc_src_core'."
+ echo >&2 "***"
+ fi
+ exit 1
+fi
diff --git a/scripts/rust_is_available_bindgen_libclang.h b/scripts/rust_is_available_bindgen_libclang.h
new file mode 100644
index 000000000000..0ef6db10d674
--- /dev/null
+++ b/scripts/rust_is_available_bindgen_libclang.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#pragma message("clang version " __clang_version__)
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
index 2dccf141241d..24086793b0d8 100755
--- a/scripts/selinux/install_policy.sh
+++ b/scripts/selinux/install_policy.sh
@@ -31,8 +31,7 @@ fi
if selinuxenabled; then
echo "SELinux is already enabled"
echo "This prevents safely relabeling all files."
- echo "Boot with selinux=0 on the kernel command-line or"
- echo "SELINUX=disabled in /etc/selinux/config."
+ echo "Boot with selinux=0 on the kernel command-line."
exit 1
fi
@@ -78,7 +77,7 @@ cd /etc/selinux/dummy/contexts/files
$SF -F file_contexts /
mounts=`cat /proc/$$/mounts | \
- egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
+ grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
awk '{ print $2 '}`
$SF -F file_contexts $mounts
diff --git a/scripts/sign-file.c b/scripts/sign-file.c
index 7434e9ea926e..598ef5465f82 100644
--- a/scripts/sign-file.c
+++ b/scripts/sign-file.c
@@ -114,7 +114,7 @@ static void drain_openssl_errors(void)
bool __cond = (cond); \
display_openssl_errors(__LINE__); \
if (__cond) { \
- err(1, fmt, ## __VA_ARGS__); \
+ errx(1, fmt, ## __VA_ARGS__); \
} \
} while(0)
diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install
index f126ecbb0494..ec84fc62774e 100755
--- a/scripts/sphinx-pre-install
+++ b/scripts/sphinx-pre-install
@@ -25,6 +25,7 @@ my $need_sphinx = 0;
my $need_pip = 0;
my $need_virtualenv = 0;
my $rec_sphinx_upgrade = 0;
+my $verbose_warn_install = 1;
my $install = "";
my $virtenv_dir = "";
my $python_cmd = "";
@@ -103,10 +104,12 @@ sub check_missing(%)
next;
}
- if ($is_optional) {
- print "Warning: better to also install \"$prog\".\n";
- } else {
- print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
+ if ($verbose_warn_install) {
+ if ($is_optional) {
+ print "Warning: better to also install \"$prog\".\n";
+ } else {
+ print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
+ }
}
if (defined($map{$prog})) {
$install .= " " . $map{$prog};
@@ -386,7 +389,8 @@ sub give_debian_hints()
check_missing(\%map);
return if (!$need && !$optional);
- printf("You should run:\n\n\tsudo apt-get install $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo apt-get install $install\n");
}
sub give_redhat_hints()
@@ -458,10 +462,12 @@ sub give_redhat_hints()
if (!$old) {
# dnf, for Fedora 18+
- printf("You should run:\n\n\tsudo dnf install -y $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo dnf install -y $install\n");
} else {
# yum, for RHEL (and clones) or Fedora version < 18
- printf("You should run:\n\n\tsudo yum install -y $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo yum install -y $install\n");
}
}
@@ -509,7 +515,8 @@ sub give_opensuse_hints()
check_missing(\%map);
return if (!$need && !$optional);
- printf("You should run:\n\n\tsudo zypper install --no-recommends $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo zypper install --no-recommends $install\n");
}
sub give_mageia_hints()
@@ -553,7 +560,8 @@ sub give_mageia_hints()
check_missing(\%map);
return if (!$need && !$optional);
- printf("You should run:\n\n\tsudo $packager_cmd $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo $packager_cmd $install\n");
}
sub give_arch_linux_hints()
@@ -583,7 +591,8 @@ sub give_arch_linux_hints()
check_missing(\%map);
return if (!$need && !$optional);
- printf("You should run:\n\n\tsudo pacman -S $install\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n\tsudo pacman -S $install\n");
}
sub give_gentoo_hints()
@@ -610,7 +619,8 @@ sub give_gentoo_hints()
return if (!$need && !$optional);
- printf("You should run:\n\n");
+ printf("You should run:\n") if ($verbose_warn_install);
+ printf("\n");
my $imagemagick = "media-gfx/imagemagick svg png";
my $cairo = "media-gfx/graphviz cairo pdf";
@@ -700,7 +710,7 @@ sub check_distros()
sub deactivate_help()
{
- printf "\nIf you want to exit the virtualenv, you can use:\n";
+ printf "\n If you want to exit the virtualenv, you can use:\n";
printf "\tdeactivate\n";
}
@@ -720,6 +730,12 @@ sub get_virtenv()
next if (! -f $sphinx_cmd);
my $ver = get_sphinx_version($sphinx_cmd);
+
+ if (!$ver) {
+ $f =~ s#/bin/activate##;
+ print("Warning: virtual environment $f is not working.\nPython version upgrade? Remove it with:\n\n\trm -rf $f\n\n");
+ }
+
if ($need_sphinx && ($ver ge $min_version)) {
return ($f, $ver);
} elsif ($ver gt $cur_version) {
@@ -741,7 +757,7 @@ sub recommend_sphinx_upgrade()
# Get the highest version from sphinx_*/bin/sphinx-build and the
# corresponding command to activate the venv/virtenv
- $activate_cmd = get_virtenv();
+ ($activate_cmd, $venv_ver) = get_virtenv();
# Store the highest version from Sphinx existing virtualenvs
if (($activate_cmd ne "") && ($venv_ver gt $cur_version)) {
@@ -759,10 +775,14 @@ sub recommend_sphinx_upgrade()
# Either there are already a virtual env or a new one should be created
$need_pip = 1;
+ return if (!$latest_avail_ver);
+
# Return if the reason is due to an upgrade or not
if ($latest_avail_ver lt $rec_version) {
$rec_sphinx_upgrade = 1;
}
+
+ return $latest_avail_ver;
}
#
@@ -775,12 +795,13 @@ sub recommend_sphinx_version($)
{
my $virtualenv_cmd = shift;
- if ($latest_avail_ver lt $min_pdf_version) {
- print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n";
- }
-
# Version is OK. Nothing to do.
- return if ($cur_version && ($cur_version ge $rec_version));
+ if ($cur_version && ($cur_version ge $rec_version)) {
+ if ($cur_version lt $min_pdf_version) {
+ print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n";
+ }
+ return;
+ };
if (!$need_sphinx) {
# sphinx-build is present and its version is >= $min_version
@@ -820,13 +841,17 @@ sub recommend_sphinx_version($)
}
# Suggest newer versions if current ones are too old
- if ($latest_avail_ver && $cur_version ge $min_version) {
+ if ($latest_avail_ver && $latest_avail_ver ge $min_version) {
# If there's a good enough version, ask the user to enable it
if ($latest_avail_ver ge $rec_version) {
printf "\nNeed to activate Sphinx (version $latest_avail_ver) on virtualenv with:\n";
printf "\t. $activate_cmd\n";
deactivate_help();
+ if ($latest_avail_ver lt $min_pdf_version) {
+ print "note: If you want pdf, you need at least Sphinx $min_pdf_version.\n";
+ }
+
return;
}
@@ -848,7 +873,7 @@ sub recommend_sphinx_version($)
print "To upgrade Sphinx, use:\n\n";
}
} else {
- print "Sphinx needs to be installed either as a package or via pip/pypi with:\n";
+ print "\nSphinx needs to be installed either:\n1) via pip/pypi with:\n\n";
}
$python_cmd = find_python_no_venv();
@@ -858,6 +883,29 @@ sub recommend_sphinx_version($)
printf "\t. $virtenv_dir/bin/activate\n";
printf "\tpip install -r $requirement_file\n";
deactivate_help();
+
+ printf "\n2) As a package with:\n";
+
+ my $old_need = $need;
+ my $old_optional = $optional;
+ %missing = ();
+ $pdf = 0;
+ $optional = 0;
+ $install = "";
+ $verbose_warn_install = 0;
+
+ add_package("python-sphinx", 0);
+ check_python_module("sphinx_rtd_theme", 1);
+
+ check_distros();
+
+ $need = $old_need;
+ $optional = $old_optional;
+
+ printf "\n Please note that Sphinx >= 3.0 will currently produce false-positive\n";
+ printf " warning when the same name is used for more than one type (functions,\n";
+ printf " structs, enums,...). This is known Sphinx bug. For more details, see:\n";
+ printf "\thttps://github.com/sphinx-doc/sphinx/pull/8313\n";
}
sub check_needs()
@@ -897,7 +945,7 @@ sub check_needs()
}
}
- recommend_sphinx_upgrade();
+ my $venv_ver = recommend_sphinx_upgrade();
my $virtualenv_cmd;
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 01fab3d4f90b..e137cf15aae9 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -25,13 +25,6 @@ else
tree=${srctree}/
fi
-# ignore userspace tools
-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
ALLSOURCE_ARCHS=${SRCARCH}
@@ -100,7 +93,7 @@ all_compiled_sources()
find $ignore -name "*.cmd" -exec \
grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ |
awk '!a[$0]++'
- } | xargs realpath -es $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) |
+ } | xargs realpath -esq $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) |
sort -u
}
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
index 7011fbe003ff..438516bdfb3c 100755
--- a/scripts/tracing/draw_functrace.py
+++ b/scripts/tracing/draw_functrace.py
@@ -8,7 +8,7 @@ This script parses a trace provided by the function tracer in
kernel/trace/trace_functions.c
The resulted trace is processed into a tree to produce a more human
view of the call stack by drawing textual but hierarchical tree of
-calls. Only the functions's names and the the call time are provided.
+calls. Only the functions's names and the call time are provided.
Usage:
Be sure that you have CONFIG_FUNCTION_TRACER