diff options
Diffstat (limited to 'scripts')
56 files changed, 857 insertions, 503 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 2f331879816b..faf37bafa3f8 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -62,8 +62,7 @@ stringify = $(squote)$(quote)$1$(quote)$(squote) ### # The path to Kbuild or Makefile. Kbuild has precedence over Makefile. -kbuild-dir = $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) -kbuild-file = $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile) +kbuild-file = $(or $(wildcard $(src)/Kbuild),$(src)/Makefile) ### # Read a file, replacing newlines with spaces diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic index 8d01b37b7677..1486abf34c7c 100644 --- a/scripts/Makefile.asm-generic +++ b/scripts/Makefile.asm-generic @@ -9,7 +9,7 @@ PHONY := all all: -src := $(subst /generated,,$(obj)) +src := $(srctree)/$(subst /generated,,$(obj)) include $(srctree)/scripts/Kbuild.include -include $(kbuild-file) @@ -20,14 +20,14 @@ include $(srctree)/$(generic)/Kbuild endif redundant := $(filter $(mandatory-y) $(generated-y), $(generic-y)) -redundant += $(foreach f, $(generic-y), $(if $(wildcard $(srctree)/$(src)/$(f)),$(f))) +redundant += $(foreach f, $(generic-y), $(if $(wildcard $(src)/$(f)),$(f))) redundant := $(sort $(redundant)) $(if $(redundant),\ $(warning redundant generic-y found in $(src)/Kbuild: $(redundant))) # If arch does not implement mandatory headers, fallback to asm-generic ones. mandatory-y := $(filter-out $(generated-y), $(mandatory-y)) -generic-y += $(foreach f, $(mandatory-y), $(if $(wildcard $(srctree)/$(src)/$(f)),,$(f))) +generic-y += $(foreach f, $(mandatory-y), $(if $(wildcard $(src)/$(f)),,$(f))) generic-y := $(addprefix $(obj)/, $(generic-y)) generated-y := $(addprefix $(obj)/, $(generated-y)) diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf index 82377e470aed..2d6e5ed9081e 100644 --- a/scripts/Makefile.btf +++ b/scripts/Makefile.btf @@ -3,6 +3,8 @@ pahole-ver := $(CONFIG_PAHOLE_VERSION) pahole-flags-y := +ifeq ($(call test-le, $(pahole-ver), 125),y) + # pahole 1.18 through 1.21 can't handle zero-sized per-CPU vars ifeq ($(call test-le, $(pahole-ver), 121),y) pahole-flags-$(call test-ge, $(pahole-ver), 118) += --skip_encoding_btf_vars @@ -12,8 +14,17 @@ pahole-flags-$(call test-ge, $(pahole-ver), 121) += --btf_gen_floats pahole-flags-$(call test-ge, $(pahole-ver), 122) += -j -pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust +ifeq ($(pahole-ver), 125) +pahole-flags-y += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized +endif + +else -pahole-flags-$(call test-ge, $(pahole-ver), 125) += --skip_encoding_btf_inconsistent_proto --btf_gen_optimized +# Switch to using --btf_features for v1.26 and later. +pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func + +endif + +pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust export PAHOLE_FLAGS := $(pahole-flags-y) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 533a7799fdfe..efacca63c897 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -3,7 +3,7 @@ # Building # ========================================================================== -src := $(obj) +src := $(if $(VPATH),$(VPATH)/)$(obj) PHONY := $(obj)/ $(obj)/: @@ -113,13 +113,13 @@ endif quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< -$(obj)/%.s: $(src)/%.c FORCE +$(obj)/%.s: $(obj)/%.c FORCE $(call if_changed_dep,cc_s_c) quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< -$(obj)/%.i: $(src)/%.c FORCE +$(obj)/%.i: $(obj)/%.c FORCE $(call if_changed_dep,cpp_i_c) genksyms = scripts/genksyms/genksyms \ @@ -133,7 +133,7 @@ cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null -$(obj)/%.symtypes : $(src)/%.c FORCE +$(obj)/%.symtypes : $(obj)/%.c FORCE $(call cmd,cc_symtypes_c) # LLVM assembly @@ -141,7 +141,7 @@ $(obj)/%.symtypes : $(src)/%.c FORCE quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -fno-discard-value-names -o $@ $< -$(obj)/%.ll: $(src)/%.c FORCE +$(obj)/%.ll: $(obj)/%.c FORCE $(call if_changed_dep,cc_ll_c) # C (.c) files @@ -214,9 +214,9 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file -is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),y) +is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object)) -$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) +$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi))) @@ -240,7 +240,7 @@ define rule_as_o_S endef # Built-in and composite module parts -$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE +$(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) @@ -257,13 +257,13 @@ quiet_cmd_cc_lst_c = MKLST $@ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ System.map $(OBJDUMP) > $@ -$(obj)/%.lst: $(src)/%.c FORCE +$(obj)/%.lst: $(obj)/%.c FORCE $(call if_changed_dep,cc_lst_c) # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := new_uninit,offset_of +rust_allowed_features := new_uninit # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree @@ -290,7 +290,7 @@ rust_common_cmd = \ quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< -$(obj)/%.o: $(src)/%.rs FORCE +$(obj)/%.o: $(obj)/%.rs FORCE +$(call if_changed_dep,rustc_o_rs) quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ @@ -298,19 +298,19 @@ quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@ -$(obj)/%.rsi: $(src)/%.rs FORCE +$(obj)/%.rsi: $(obj)/%.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=asm=$@ $< -$(obj)/%.s: $(src)/%.rs FORCE +$(obj)/%.s: $(obj)/%.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=llvm-ir=$@ $< -$(obj)/%.ll: $(src)/%.rs FORCE +$(obj)/%.ll: $(obj)/%.rs FORCE +$(call if_changed_dep,rustc_ll_rs) # Compile assembler sources (.S) @@ -336,14 +336,14 @@ cmd_gensymtypes_S = \ quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null -$(obj)/%.symtypes : $(src)/%.S FORCE +$(obj)/%.symtypes : $(obj)/%.S FORCE $(call cmd,cc_symtypes_S) quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< -$(obj)/%.s: $(src)/%.S FORCE +$(obj)/%.s: $(obj)/%.S FORCE $(call if_changed_dep,cpp_s_S) quiet_cmd_as_o_S = AS $(quiet_modtag) $@ @@ -358,7 +358,7 @@ cmd_gen_symversions_S = $(call gen_symversions,S) endif -$(obj)/%.o: $(src)/%.S FORCE +$(obj)/%.o: $(obj)/%.S FORCE $(call if_changed_rule,as_o_S) targets += $(filter-out $(subdir-builtin), $(real-obj-y)) @@ -437,8 +437,8 @@ define rule_ld_multi_m $(call cmd,gen_objtooldep) endef -$(multi-obj-m): objtool-enabled := $(delay-objtool) -$(multi-obj-m): part-of-module := y +$(multi-obj-m): private objtool-enabled := $(delay-objtool) +$(multi-obj-m): private part-of-module := y $(multi-obj-m): %.o: %.mod FORCE $(call if_changed_rule,ld_multi_m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index f2cb4d7ffd96..4fcfab40ed61 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -3,7 +3,7 @@ # Cleaning up # ========================================================================== -src := $(obj) +src := $(if $(VPATH),$(VPATH)/)$(obj) PHONY := __clean __clean: diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug index 059ff38fe0cb..107db997ce38 100644 --- a/scripts/Makefile.debug +++ b/scripts/Makefile.debug @@ -17,6 +17,12 @@ endif DEBUG_CFLAGS += $(debug-flags-y) KBUILD_AFLAGS += $(debug-flags-y) +ifdef CONFIG_DEBUG_INFO_DWARF4 +DEBUG_RUSTFLAGS += -Zdwarf-version=4 +else ifdef CONFIG_DEBUG_INFO_DWARF5 +DEBUG_RUSTFLAGS += -Zdwarf-version=5 +endif + ifdef CONFIG_DEBUG_INFO_REDUCED DEBUG_CFLAGS += -fno-var-tracking DEBUG_RUSTFLAGS += -Cdebuginfo=1 @@ -29,10 +35,12 @@ endif ifdef CONFIG_DEBUG_INFO_COMPRESSED_ZLIB DEBUG_CFLAGS += -gz=zlib +DEBUG_RUSTFLAGS += -Zdebuginfo-compression=zlib KBUILD_AFLAGS += -gz=zlib KBUILD_LDFLAGS += --compress-debug-sections=zlib else ifdef CONFIG_DEBUG_INFO_COMPRESSED_ZSTD DEBUG_CFLAGS += -gz=zstd +DEBUG_RUSTFLAGS += -Zdebuginfo-compression=zstd KBUILD_AFLAGS += -gz=zstd KBUILD_LDFLAGS += --compress-debug-sections=zstd endif diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 3c17e6ba421c..d35f55e0d141 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -112,7 +112,7 @@ endif quiet_cmd_host-csingle = HOSTCC $@ cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(KBUILD_HOSTLDFLAGS) -o $@ $< \ $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) -$(host-csingle): $(obj)/%: $(src)/%.c FORCE +$(host-csingle): $(obj)/%: $(obj)/%.c FORCE $(call if_changed_dep,host-csingle) # Link an executable based on list of .o files, all plain c @@ -129,7 +129,7 @@ $(call multi_depend, $(host-cmulti), , -objs) # host-cobjs -> .o quiet_cmd_host-cobjs = HOSTCC $@ cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $< -$(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE +$(host-cobjs): $(obj)/%.o: $(obj)/%.c FORCE $(call if_changed_dep,host-cobjs) # Link an executable based on list of .o files, a mixture of .c and .cc diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3179747cbd2c..9f06f6aaf7fc 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -154,7 +154,7 @@ _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) # ifeq ($(CONFIG_GCOV_KERNEL),y) _c_flags += $(if $(patsubst n%,, \ - $(GCOV_PROFILE_$(target-stem).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \ + $(GCOV_PROFILE_$(target-stem).o)$(GCOV_PROFILE)$(if $(is-kernel-object),$(CONFIG_GCOV_PROFILE_ALL))), \ $(CFLAGS_GCOV)) endif @@ -165,32 +165,32 @@ endif ifeq ($(CONFIG_KASAN),y) ifneq ($(CONFIG_KASAN_HW_TAGS),y) _c_flags += $(if $(patsubst n%,, \ - $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)y), \ + $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) endif endif ifeq ($(CONFIG_KMSAN),y) _c_flags += $(if $(patsubst n%,, \ - $(KMSAN_SANITIZE_$(target-stem).o)$(KMSAN_SANITIZE)y), \ + $(KMSAN_SANITIZE_$(target-stem).o)$(KMSAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_KMSAN)) _c_flags += $(if $(patsubst n%,, \ - $(KMSAN_ENABLE_CHECKS_$(target-stem).o)$(KMSAN_ENABLE_CHECKS)y), \ + $(KMSAN_ENABLE_CHECKS_$(target-stem).o)$(KMSAN_ENABLE_CHECKS)$(is-kernel-object)), \ , -mllvm -msan-disable-checks=1) endif ifeq ($(CONFIG_UBSAN),y) _c_flags += $(if $(patsubst n%,, \ - $(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)y), \ + $(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_UBSAN)) _c_flags += $(if $(patsubst n%,, \ - $(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)y), \ + $(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_UBSAN_SIGNED_WRAP)) endif ifeq ($(CONFIG_KCOV),y) _c_flags += $(if $(patsubst n%,, \ - $(KCOV_INSTRUMENT_$(target-stem).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \ + $(KCOV_INSTRUMENT_$(target-stem).o)$(KCOV_INSTRUMENT)$(if $(is-kernel-object),$(CONFIG_KCOV_INSTRUMENT_ALL))), \ $(CFLAGS_KCOV)) endif @@ -200,7 +200,7 @@ endif # ifeq ($(CONFIG_KCSAN),y) _c_flags += $(if $(patsubst n%,, \ - $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)y), \ + $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_KCSAN)) # Some uninstrumented files provide implied barriers required to avoid false # positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only. @@ -209,16 +209,20 @@ _c_flags += $(if $(patsubst n%,, \ -D__KCSAN_INSTRUMENT_BARRIERS__) endif -# $(srctree)/$(src) for including checkin headers from generated source files -# $(objtree)/$(obj) for including generated headers from checkin source files +# $(src) for including checkin headers from generated source files +# $(obj) for including generated headers from checkin source files ifeq ($(KBUILD_EXTMOD),) ifdef building_out_of_srctree -_c_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) -_a_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) -_cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +_c_flags += $(addprefix -I, $(src) $(obj)) +_a_flags += $(addprefix -I, $(src) $(obj)) +_cpp_flags += $(addprefix -I, $(src) $(obj)) endif endif +# If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules +is-kernel-object = $(or $(part-of-builtin),$(part-of-module)) + +part-of-builtin = $(if $(filter $(basename $@).o, $(real-obj-y) $(lib-y)),y) part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) quiet_modtag = $(if $(part-of-module),[M], ) @@ -410,7 +414,7 @@ $(multi-dtb-y): FORCE $(call if_changed,fdtoverlay) $(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) -ifneq ($(CHECK_DTBS)$(CHECK_DT_BINDING),) +ifneq ($(CHECK_DTBS),) DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) DT_BINDING_DIR := Documentation/devicetree/bindings @@ -423,7 +427,7 @@ quiet_cmd_dtb = $(quiet_cmd_dtc) cmd_dtb = $(cmd_dtc) endif -$(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE +$(obj)/%.dtb: $(obj)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE $(call if_changed_dep,dtb) $(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE @@ -504,6 +508,22 @@ quiet_cmd_uimage = UIMAGE $@ -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ -n '$(UIMAGE_NAME)' -d $< $@ +# Flat Image Tree (FIT) +# This allows for packaging of a kernel and all devicetrees files, using +# compression. +# --------------------------------------------------------------------------- + +MAKE_FIT := $(srctree)/scripts/make_fit.py + +# Use this to override the compression algorithm +FIT_COMPRESSION ?= gzip + +quiet_cmd_fit = FIT $@ + cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ + --name '$(UIMAGE_NAME)' \ + $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ + --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) + # XZ # --------------------------------------------------------------------------- # Use xzkern to compress the kernel image and xzmisc to compress other things. diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 79fcf2731686..3bec9043e4f3 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -21,9 +21,11 @@ __modfinal: $(modules:%.o=%.ko) # modname and part-of-module are set to make c_flags define proper module flags modname = $(notdir $(@:.mod.o=)) part-of-module = y +GCOV_PROFILE := n +KCSAN_SANITIZE := n quiet_cmd_cc_o_c = CC [M] $@ - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI) $(CFLAGS_GCOV) $(CFLAGS_KCSAN), $(c_flags)) -c -o $@ $< + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< %.mod.o: %.mod.c FORCE $(call if_changed_dep,cc_o_c) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 739402f45509..44936ebad161 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -94,7 +94,7 @@ targets += .vmlinux.objs ifdef CONFIG_TRIM_UNUSED_KSYMS ksym-wl := $(CONFIG_UNUSED_KSYMS_WHITELIST) -ksym-wl := $(if $(filter-out /%, $(ksym-wl)),$(srctree)/)$(ksym-wl) +ksym-wl := $(if $(filter-out /%, $(ksym-wl)),$(if $(wildcard $(ksym-wl)),,$(srctree)/))$(ksym-wl) modpost-args += -t $(addprefix -u , $(ksym-wl)) modpost-deps += $(ksym-wl) endif @@ -112,7 +112,7 @@ else # set src + obj - they may be used in the modules's Makefile obj := $(KBUILD_EXTMOD) -src := $(obj) +src := $(if $(VPATH),$(VPATH)/)$(obj) # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS include $(kbuild-file) diff --git a/scripts/Makefile.vdsoinst b/scripts/Makefile.vdsoinst index c477d17b0aa5..bf72880c50d0 100644 --- a/scripts/Makefile.vdsoinst +++ b/scripts/Makefile.vdsoinst @@ -13,16 +13,15 @@ install-dir := $(MODLIB)/vdso define gen_install_rules -src := $$(firstword $$(subst :,$(space),$(1))) -dest := $(install-dir)/$$(or $$(word 2,$$(subst :,$(space),$(1))),$$(patsubst %.dbg,%,$$(notdir $(1)))) +dest := $(install-dir)/$$(patsubst %.dbg,%,$$(notdir $(1))) __default: $$(dest) -$$(dest): $$(src) FORCE +$$(dest): $(1) FORCE $$(call cmd,install) # Some architectures create .build-id symlinks ifneq ($(filter arm sparc x86, $(SRCARCH)),) -link := $(install-dir)/.build-id/$$(shell $(READELF) -n $$(src) | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p').debug +link := $(install-dir)/.build-id/$$(shell $(READELF) -n $(1) | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p').debug __default: $$(link) $$(link): $$(dest) FORCE diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index c9f3e03124d7..49946cb96844 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -18,9 +18,6 @@ quiet_cmd_cc_o_c = CC $@ $(call if_changed_dep,cc_o_c) ifdef CONFIG_MODULES -KASAN_SANITIZE_.vmlinux.export.o := n -KCSAN_SANITIZE_.vmlinux.export.o := n -GCOV_PROFILE_.vmlinux.export.o := n targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif diff --git a/scripts/check-variable-fonts.sh b/scripts/check-variable-fonts.sh new file mode 100755 index 000000000000..ce63f0acea5f --- /dev/null +++ b/scripts/check-variable-fonts.sh @@ -0,0 +1,115 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) Akira Yokosawa, 2024 +# +# For "make pdfdocs", reports of build errors of translations.pdf started +# arriving early 2024 [1, 2]. It turned out that Fedora and openSUSE +# tumbleweed have started deploying variable-font [3] format of "Noto CJK" +# fonts [4, 5]. For PDF, a LaTeX package named xeCJK is used for CJK +# (Chinese, Japanese, Korean) pages. xeCJK requires XeLaTeX/XeTeX, which +# does not (and likely never will) understand variable fonts for historical +# reasons. +# +# The build error happens even when both of variable- and non-variable-format +# fonts are found on the build system. To make matters worse, Fedora enlists +# variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_CN, +# -zh_TW, etc. Hence developers who have interest in CJK pages are more +# likely to encounter the build errors. +# +# This script is invoked from the error path of "make pdfdocs" and emits +# suggestions if variable-font files of "Noto CJK" fonts are in the list of +# fonts accessible from XeTeX. +# +# References: +# [1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/ +# [2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/ +# [3]: https://en.wikipedia.org/wiki/Variable_font +# [4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts +# [5]: https://build.opensuse.org/request/show/1157217 +# +#=========================================================================== +# Workarounds for building translations.pdf +#=========================================================================== +# +# * Denylist "variable font" Noto CJK fonts. +# - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with +# tweaks if necessary. Remove leading "# ". +# - Path of fontconfig/fonts.conf can be overridden by setting an env +# variable FONTS_CONF_DENY_VF. +# +# * Template: +# ----------------------------------------------------------------- +# <?xml version="1.0"?> +# <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> +# <fontconfig> +# <!-- +# Ignore variable-font glob (not to break xetex) +# --> +# <selectfont> +# <rejectfont> +# <!-- +# for Fedora +# --> +# <glob>/usr/share/fonts/google-noto-*-cjk-vf-fonts</glob> +# <!-- +# for openSUSE tumbleweed +# --> +# <glob>/usr/share/fonts/truetype/Noto*CJK*-VF.otf</glob> +# </rejectfont> +# </selectfont> +# </fontconfig> +# ----------------------------------------------------------------- +# +# The denylisting is activated for "make pdfdocs". +# +# * For skipping CJK pages in PDF +# - Uninstall texlive-xecjk. +# Denylisting is not needed in this case. +# +# * For printing CJK pages in PDF +# - Need non-variable "Noto CJK" fonts. +# * Fedora +# - google-noto-sans-cjk-fonts +# - google-noto-serif-cjk-fonts +# * openSUSE tumbleweed +# - Non-variable "Noto CJK" fonts are not available as distro packages +# as of April, 2024. Fetch a set of font files from upstream Noto +# CJK Font released at: +# https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc +# and at: +# https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc +# , then uncompress and deploy them. +# - Remember to update fontconfig cache by running fc-cache. +# +# !!! Caution !!! +# Uninstalling "variable font" packages can be dangerous. +# They might be depended upon by other packages important for your work. +# Denylisting should be less invasive, as it is effective only while +# XeLaTeX runs in "make pdfdocs". + +# Default per-user fontconfig path (overridden by env variable) +: ${FONTS_CONF_DENY_VF:=$HOME/deny-vf} + +export XDG_CONFIG_HOME=${FONTS_CONF_DENY_VF} + +notocjkvffonts=`fc-list : file family variable | \ + grep 'variable=True' | \ + grep -E -e 'Noto (Sans|Sans Mono|Serif) CJK' | \ + sed -e 's/^/ /' -e 's/: Noto S.*$//' | sort | uniq` + +if [ "x$notocjkvffonts" != "x" ] ; then + echo '=============================================================================' + echo 'XeTeX is confused by "variable font" files listed below:' + echo "$notocjkvffonts" + echo + echo 'For CJK pages in PDF, they need to be hidden from XeTeX by denylisting.' + echo 'Or, CJK pages can be skipped by uninstalling texlive-xecjk.' + echo + echo 'For more info on denylisting, other options, and variable font, see header' + echo 'comments of scripts/check-variable-fonts.sh.' + echo '=============================================================================' +fi + +# As this script is invoked from Makefile's error path, always error exit +# regardless of whether any variable font is discovered or not. +exit 1 diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9c4c4a61bc83..2b812210b412 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6040,6 +6040,12 @@ sub process { CHK("MACRO_ARG_PRECEDENCE", "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); } + +# check if this is an unused argument + if ($define_stmt !~ /\b$arg\b/) { + WARN("MACRO_ARG_UNUSED", + "Argument '$arg' is not used in function-like macro\n" . "$herectx"); + } } # check for macros with flow control, but without ## concatenation diff --git a/scripts/coccinelle/api/pm_runtime.cocci b/scripts/coccinelle/api/pm_runtime.cocci index 4b9778874453..2c931e748dda 100644 --- a/scripts/coccinelle/api/pm_runtime.cocci +++ b/scripts/coccinelle/api/pm_runtime.cocci @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/// Make sure pm_runtime_* calls does not use unnecessary IS_ERR_VALUE +/// Make sure pm_runtime_* calls do not unnecessarily use IS_ERR_VALUE /// // Keywords: pm_runtime // Confidence: Medium diff --git a/scripts/coccinelle/misc/minmax.cocci b/scripts/coccinelle/misc/minmax.cocci index fcf908b34f27..ca4830ae3042 100644 --- a/scripts/coccinelle/misc/minmax.cocci +++ b/scripts/coccinelle/misc/minmax.cocci @@ -50,11 +50,26 @@ func(...) ...> } +// Ignore errcode returns. +@errcode@ +position p; +identifier func; +expression x; +binary operator cmp = {<, <=}; +@@ + +func(...) +{ + <... + return ((x) cmp@p 0 ? (x) : 0); + ...> +} + @rmin depends on !patch@ identifier func; expression x, y; binary operator cmp = {<, <=}; -position p; +position p != errcode.p; @@ func(...) @@ -116,21 +131,6 @@ func(...) ...> } -// Don't generate patches for errcode returns. -@errcode depends on patch@ -position p; -identifier func; -expression x; -binary operator cmp = {<, <=}; -@@ - -func(...) -{ - <... - return ((x) cmp@p 0 ? (x) : 0); - ...> -} - @pmin depends on patch@ identifier func; expression x, y; diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 4d32b9497da9..a18657072541 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -16,12 +16,12 @@ libfdt = $(addprefix libfdt/,$(libfdt-objs)) fdtoverlay-objs := $(libfdt) fdtoverlay.o util.o # Source files need to get at the userspace version of libfdt_env.h to compile -HOST_EXTRACFLAGS += -I $(srctree)/$(src)/libfdt +HOST_EXTRACFLAGS += -I $(src)/libfdt HOST_EXTRACFLAGS += -DNO_YAML # Generated files need one more search path to include headers in source tree -HOSTCFLAGS_dtc-lexer.lex.o := -I $(srctree)/$(src) -HOSTCFLAGS_dtc-parser.tab.o := -I $(srctree)/$(src) +HOSTCFLAGS_dtc-lexer.lex.o := -I $(src) +HOSTCFLAGS_dtc-parser.tab.o := -I $(src) # dependencies on generated files need to be listed explicitly $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile index 48941faa6ea6..d77ad9079d0f 100644 --- a/scripts/gdb/linux/Makefile +++ b/scripts/gdb/linux/Makefile @@ -2,7 +2,7 @@ ifdef building_out_of_srctree -symlinks := $(patsubst $(srctree)/$(src)/%,%,$(wildcard $(srctree)/$(src)/*.py)) +symlinks := $(patsubst $(src)/%,%,$(wildcard $(src)/*.py)) quiet_cmd_symlink = SYMLINK $@ cmd_symlink = ln -fsn $(patsubst $(obj)/%,$(abspath $(srctree))/$(src)/%,$@) $@ diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py index cba589e5b57d..2f11c4f9c345 100644 --- a/scripts/gdb/linux/cpus.py +++ b/scripts/gdb/linux/cpus.py @@ -26,11 +26,7 @@ def get_current_cpu(): if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: return gdb.selected_thread().num - 1 elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: - tid = gdb.selected_thread().ptid[2] - if tid > (0x100000000 - MAX_CPUS - 2): - return 0x100000000 - tid - 2 - else: - return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu'] + return gdb.parse_and_eval("kgdb_active.counter") else: raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " "supported with this gdb server.") @@ -152,9 +148,8 @@ Note that VAR has to be quoted as string.""" def __init__(self): super(PerCpu, self).__init__("lx_per_cpu") - def invoke(self, var_name, cpu=-1): - var_ptr = gdb.parse_and_eval("&" + var_name.string()) - return per_cpu(var_ptr, cpu) + def invoke(self, var, cpu=-1): + return per_cpu(var.address, cpu) PerCpu() diff --git a/scripts/gdb/linux/interrupts.py b/scripts/gdb/linux/interrupts.py index 66ae5c7690cf..616a5f26377a 100644 --- a/scripts/gdb/linux/interrupts.py +++ b/scripts/gdb/linux/interrupts.py @@ -37,7 +37,7 @@ def show_irq_desc(prec, irq): any_count = 0 if desc['kstat_irqs']: for cpu in cpus.each_online_cpu(): - any_count += cpus.per_cpu(desc['kstat_irqs'], cpu) + any_count += cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt'] if (desc['action'] == 0 or irq_desc_is_chained(desc)) and any_count == 0: return text; @@ -45,7 +45,7 @@ def show_irq_desc(prec, irq): text += "%*d: " % (prec, irq) for cpu in cpus.each_online_cpu(): if desc['kstat_irqs']: - count = cpus.per_cpu(desc['kstat_irqs'], cpu) + count = cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt'] else: count = 0 text += "%10u" % (count) @@ -177,7 +177,7 @@ def arm_common_show_interrupts(prec): if desc == 0: continue for cpu in cpus.each_online_cpu(): - text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu)) + text += "%10u" % (cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt']) text += " %s" % (ipi_types[ipi].string()) text += "\n" return text diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 6793d6e86e77..62348397c1f5 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -85,7 +85,7 @@ thread_info_type = utils.CachedType("struct thread_info") def get_thread_info(task): thread_info_ptr_type = thread_info_type.get_type().pointer() - if task.type.fields()[0].type == thread_info_type.get_type(): + if task_type.get_type().fields()[0].type == thread_info_type.get_type(): return task['thread_info'] thread_info = task['stack'].cast(thread_info_ptr_type) return thread_info.dereference() diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 7d5278d815fa..245ab297ea84 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -196,7 +196,7 @@ def get_gdbserver_type(): def probe_kgdb(): try: thread_info = gdb.execute("info thread 2", to_string=True) - return "shadowCPU0" in thread_info + return "shadowCPU" in thread_info except gdb.error: return False diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index fc52bc41d3e7..f270c7b0cf34 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -66,7 +66,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): append_crate( "alloc", - srctree / "rust" / "alloc" / "lib.rs", + sysroot_src / "alloc" / "src" / "lib.rs", ["core", "compiler_builtins"], cfg=crates_cfgs.get("alloc", []), ) diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 54919cf48621..3fcbc3737b2e 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -154,7 +154,7 @@ fn main() { 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", + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", ); let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string(); if cfg.has("MITIGATION_RETPOLINE") { diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index d6a422a63b6a..312edccda736 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -23,8 +23,8 @@ $(obj)/pars%.tab.c $(obj)/pars%.tab.h: $(src)/pars%.y FORCE endif # -I needed for generated C source to include headers in source tree -HOSTCFLAGS_parse.tab.o := -I $(srctree)/$(src) -HOSTCFLAGS_lex.lex.o := -I $(srctree)/$(src) +HOSTCFLAGS_parse.tab.o := -I $(src) +HOSTCFLAGS_lex.lex.o := -I $(src) # dependencies on generated files need to be listed explicitly $(obj)/lex.lex.o: $(obj)/parse.tab.h diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 653b92f6d4c8..47978efe4797 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -204,6 +204,11 @@ static int symbol_in_range(const struct sym_entry *s, return 0; } +static bool string_starts_with(const char *s, const char *prefix) +{ + return strncmp(s, prefix, strlen(prefix)) == 0; +} + static int symbol_valid(const struct sym_entry *s) { const char *name = sym_name(s); @@ -211,6 +216,14 @@ static int symbol_valid(const struct sym_entry *s) /* if --all-symbols is not specified, then symbols outside the text * and inittext sections are discarded */ if (!all_symbols) { + /* + * Symbols starting with __start and __stop are used to denote + * section boundaries, and should always be included: + */ + if (string_starts_with(name, "__start_") || + string_starts_with(name, "__stop_")) + return 1; + if (symbol_in_range(s, text_ranges, ARRAY_SIZE(text_ranges)) == 0) return 0; diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index ea1bf3b3dbde..a0a0be38cbdc 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -57,7 +57,7 @@ $(foreach c, config menuconfig nconfig gconfig xconfig, $(eval $(call config_rul PHONY += localmodconfig localyesconfig localyesconfig localmodconfig: $(obj)/conf - $(Q)$(PERL) $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config + $(Q)$(PERL) $(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config $(Q)if [ -f .config ]; then \ cmp -s .tmp.config .config || \ (mv -f .config .config.old.1; \ @@ -118,7 +118,7 @@ tinyconfig: # CHECK: -o cache_dir=<path> working? PHONY += testconfig testconfig: $(obj)/conf - $(Q)$(PYTHON3) -B -m pytest $(srctree)/$(src)/tests \ + $(Q)$(PYTHON3) -B -m pytest $(src)/tests \ -o cache_dir=$(abspath $(obj)/tests/.cache) \ $(if $(findstring 1,$(KBUILD_VERBOSE)),--capture=no) clean-files += tests/.cache @@ -165,8 +165,8 @@ common-objs := confdata.o expr.o lexer.lex.o menu.o parser.tab.o \ preprocess.o symbol.o util.o $(obj)/lexer.lex.o: $(obj)/parser.tab.h -HOSTCFLAGS_lexer.lex.o := -I $(srctree)/$(src) -HOSTCFLAGS_parser.tab.o := -I $(srctree)/$(src) +HOSTCFLAGS_lexer.lex.o := -I $(src) +HOSTCFLAGS_parser.tab.o := -I $(src) # conf: Used for defconfig, oldconfig and related targets hostprogs += conf diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 965bb40c50e5..8ad2c52d9b1f 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -446,7 +446,7 @@ help: } } -static int conf_choice(struct menu *menu) +static void conf_choice(struct menu *menu) { struct symbol *sym, *def_sym; struct menu *child; @@ -459,19 +459,18 @@ static int conf_choice(struct menu *menu) sym_calc_value(sym); switch (sym_get_tristate_value(sym)) { case no: - return 1; case mod: - return 0; + return; case yes: break; } } else { switch (sym_get_tristate_value(sym)) { case no: - return 1; + return; case mod: printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); - return 0; + return; case yes: break; } @@ -497,9 +496,8 @@ static int conf_choice(struct menu *menu) printf("%*c", indent, '>'); } else printf("%*c", indent, ' '); - printf(" %d. %s", cnt, menu_get_prompt(child)); - if (child->sym->name) - printf(" (%s)", child->sym->name); + printf(" %d. %s (%s)", cnt, menu_get_prompt(child), + child->sym->name); if (!sym_has_value(child->sym)) printf(" (NEW)"); printf("\n"); @@ -552,7 +550,7 @@ static int conf_choice(struct menu *menu) continue; } sym_set_tristate_value(child->sym, yes); - return 1; + return; } } diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 0e35c4819cf1..387503daf0f7 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -502,7 +502,7 @@ int conf_read(const char *name) for_all_symbols(sym) { sym_calc_value(sym); - if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) + if (sym_is_choice(sym)) continue; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ @@ -793,59 +793,39 @@ int conf_write_defconfig(const char *filename) sym_clear_all_valid(); - /* Traverse all menus to find all relevant symbols */ - menu = rootmenu.list; + menu_for_each_entry(menu) { + struct menu *choice; - while (menu != NULL) - { sym = menu->sym; if (sym && !sym_is_choice(sym)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) - goto next_menu; + continue; sym->flags &= ~SYMBOL_WRITE; /* If we cannot change the symbol - skip */ if (!sym_is_changeable(sym)) - goto next_menu; + continue; /* If symbol equals to default value - skip */ if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) - goto next_menu; + continue; /* * If symbol is a choice value and equals to the * default for a choice - skip. - * But only if value is bool and equal to "y" and - * choice is not "optional". - * (If choice is "optional" then all values can be "n") */ - if (sym_is_choice_value(sym)) { - struct symbol *cs; + choice = sym_get_choice_menu(sym); + if (choice) { struct symbol *ds; - cs = prop_get_symbol(sym_get_choice_prop(sym)); - ds = sym_choice_default(cs); - if (!sym_is_optional(cs) && sym == ds) { + ds = sym_choice_default(choice->sym); + if (sym == ds) { if ((sym->type == S_BOOLEAN) && sym_get_tristate_value(sym) == yes) - goto next_menu; + continue; } } print_symbol_for_dotconfig(out, sym); } -next_menu: - if (menu->list != NULL) { - menu = menu->list; - } - else if (menu->next != NULL) { - menu = menu->next; - } else { - while ((menu = menu->parent)) { - if (menu->next != NULL) { - menu = menu->next; - break; - } - } - } } fclose(out); return 0; @@ -906,7 +886,7 @@ int conf_write(const char *name) "# %s\n" "#\n", str); need_newline = false; - } else if (!(sym->flags & SYMBOL_CHOICE) && + } else if (!sym_is_choice(sym) && !(sym->flags & SYMBOL_WRITTEN)) { sym_calc_value(sym); if (!(sym->flags & SYMBOL_WRITE)) @@ -1028,7 +1008,7 @@ static int conf_touch_deps(void) for_all_symbols(sym) { sym_calc_value(sym); - if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) + if (sym_is_choice(sym)) continue; if (sym->flags & SYMBOL_WRITE) { if (sym->flags & SYMBOL_DEF_AUTO) { diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 0158f5eac454..d965e427753e 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -72,8 +72,7 @@ enum { /* * Represents a configuration symbol. * - * Choices are represented as a special kind of symbol and have the - * SYMBOL_CHOICE bit set in 'flags'. + * Choices are represented as a special kind of symbol with null name. */ struct symbol { /* link node for the hash table */ @@ -131,14 +130,11 @@ struct symbol { #define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ -#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ -#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_CHANGED 0x0400 /* ? */ #define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ -#define SYMBOL_NO_WRITE 0x1000 /* Symbol for internal use only; it will not be written */ #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ #define SYMBOL_WARNED 0x8000 /* warning has been issued */ diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 9709aca3a30f..cc400ffe6615 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -18,8 +18,6 @@ #include <unistd.h> #include <time.h> -//#define DEBUG - enum { SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW }; @@ -71,39 +69,6 @@ static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); static gchar **fill_row(struct menu *menu); static void conf_changed(void); -/* Helping/Debugging Functions */ -#ifdef DEBUG -static const char *dbg_sym_flags(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val & SYMBOL_CONST) - strcat(buf, "const/"); - if (val & SYMBOL_CHECK) - strcat(buf, "check/"); - if (val & SYMBOL_CHOICE) - strcat(buf, "choice/"); - if (val & SYMBOL_CHOICEVAL) - strcat(buf, "choiceval/"); - if (val & SYMBOL_VALID) - strcat(buf, "valid/"); - if (val & SYMBOL_OPTIONAL) - strcat(buf, "optional/"); - if (val & SYMBOL_WRITE) - strcat(buf, "write/"); - if (val & SYMBOL_CHANGED) - strcat(buf, "changed/"); - if (val & SYMBOL_NO_WRITE) - strcat(buf, "no_write/"); - - buf[strlen(buf) - 1] = '\0'; - - return buf; -} -#endif - static void replace_button_icon(GladeXML *xml, GdkDrawable *window, GtkStyle *style, gchar *btn_name, gchar **xpm) { @@ -493,7 +458,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data) if (conf_read(fn)) text_insert_msg("Error", "Unable to load configuration !"); else - display_tree(&rootmenu); + display_tree_part(); } void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) @@ -1082,15 +1047,13 @@ static gchar **fill_row(struct menu *menu) row[COL_NAME] = g_strdup(sym->name); sym_calc_value(sym); - sym->flags &= ~SYMBOL_CHANGED; + menu->flags &= ~MENU_CHANGED; if (sym_is_choice(sym)) { // parse childs for getting final value struct menu *child; struct symbol *def_sym = sym_get_choice_value(sym); struct menu *def_menu = NULL; - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - for (child = menu->list; child; child = child->next) { if (menu_is_visible(child) && child->sym == def_sym) @@ -1100,6 +1063,11 @@ static gchar **fill_row(struct menu *menu) if (def_menu) row[COL_VALUE] = g_strdup(menu_get_prompt(def_menu)); + + if (sym_get_type(sym) == S_BOOLEAN) { + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + return row; + } } if (sym->flags & SYMBOL_CHOICEVAL) row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); @@ -1107,11 +1075,6 @@ static gchar **fill_row(struct menu *menu) stype = sym_get_type(sym); switch (stype) { case S_BOOLEAN: - if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) - row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); - if (sym_is_choice(sym)) - break; - /* fall through */ case S_TRISTATE: val = sym_get_tristate_value(sym); switch (val) { @@ -1268,12 +1231,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) else menu2 = NULL; // force adding of a first child -#ifdef DEBUG - printf("%*c%s | %s\n", indent, ' ', - menu1 ? menu_get_prompt(menu1) : "nil", - menu2 ? menu_get_prompt(menu2) : "nil"); -#endif - if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { @@ -1314,7 +1271,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) else goto reparse; // next child } - } else if (sym && (sym->flags & SYMBOL_CHANGED)) { + } else if (sym && (child1->flags & MENU_CHANGED)) { set_node(child2, menu1, fill_row(menu1)); } @@ -1330,7 +1287,6 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) /* Display the whole tree (single/split/full view) */ static void display_tree(struct menu *menu) { - struct symbol *sym; struct property *prop; struct menu *child; enum prop_type ptype; @@ -1342,11 +1298,9 @@ static void display_tree(struct menu *menu) for (child = menu->list; child; child = child->next) { prop = child->prompt; - sym = child->sym; ptype = prop ? prop->type : P_UNKNOWN; - if (sym) - sym->flags &= ~SYMBOL_CHANGED; + menu->flags &= ~MENU_CHANGED; if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) && (tree == tree1)) @@ -1360,19 +1314,7 @@ static void display_tree(struct menu *menu) (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || (opt_mode == OPT_ALL && menu_get_prompt(child))) place_node(child, fill_row(child)); -#ifdef DEBUG - printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); - printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); - printf("%s", prop_get_type_name(ptype)); - printf(" | "); - if (sym) { - printf("%s", sym_type_name(sym->type)); - printf(" | "); - printf("%s", dbg_sym_flags(sym->flags)); - printf("\n"); - } else - printf("\n"); -#endif + if ((view_mode != FULL_VIEW) && (ptype == P_MENU) && (tree == tree2)) continue; @@ -1405,6 +1347,8 @@ static void display_tree_part(void) display_tree(current); else if (view_mode == SPLIT_VIEW) display_tree(browsed); + else if (view_mode == FULL_VIEW) + display_tree(&rootmenu); gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); } diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l index 89544c3a1a29..8dd597c4710d 100644 --- a/scripts/kconfig/lexer.l +++ b/scripts/kconfig/lexer.l @@ -120,7 +120,6 @@ n [A-Za-z0-9_-] "menuconfig" return T_MENUCONFIG; "modules" return T_MODULES; "on" return T_ON; -"optional" return T_OPTIONAL; "prompt" return T_PROMPT; "range" return T_RANGE; "select" return T_SELECT; diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index e7cc9e985c4f..64dfc354dd5c 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -79,6 +79,11 @@ void str_printf(struct gstr *gs, const char *fmt, ...); char *str_get(struct gstr *gs); /* menu.c */ +struct menu *menu_next(struct menu *menu, struct menu *root); +#define menu_for_each_sub_entry(menu, root) \ + for (menu = menu_next(root, root); menu; menu = menu_next(menu, root)) +#define menu_for_each_entry(menu) \ + menu_for_each_sub_entry(menu, &rootmenu) void _menu_init(void); void menu_warn(struct menu *menu, const char *fmt, ...); struct menu *menu_add_menu(void); @@ -124,7 +129,8 @@ static inline struct symbol *sym_get_choice_value(struct symbol *sym) static inline bool sym_is_choice(struct symbol *sym) { - return sym->flags & SYMBOL_CHOICE ? true : false; + /* A choice is a symbol with no name */ + return sym->name == NULL; } static inline bool sym_is_choice_value(struct symbol *sym) @@ -132,11 +138,6 @@ static inline bool sym_is_choice_value(struct symbol *sym) return sym->flags & SYMBOL_CHOICEVAL ? true : false; } -static inline bool sym_is_optional(struct symbol *sym) -{ - return sym->flags & SYMBOL_OPTIONAL ? true : false; -} - static inline bool sym_has_value(struct symbol *sym) { return sym->flags & SYMBOL_DEF_USER ? true : false; diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 2807fa584c2b..d76aaf4ea117 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -34,6 +34,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str); bool sym_set_string_value(struct symbol *sym, const char *newval); bool sym_is_changeable(struct symbol *sym); struct property * sym_get_choice_prop(struct symbol *sym); +struct menu *sym_get_choice_menu(struct symbol *sym); const char * sym_get_string_value(struct symbol *sym); const char * prop_get_type_name(enum prop_type type); diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index f18e2a89f613..964139c87fcb 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c @@ -17,22 +17,13 @@ struct dialog_info dlg; static void set_mono_theme(void) { - dlg.screen.atr = A_NORMAL; - dlg.shadow.atr = A_NORMAL; - dlg.dialog.atr = A_NORMAL; dlg.title.atr = A_BOLD; - dlg.border.atr = A_NORMAL; dlg.button_active.atr = A_REVERSE; dlg.button_inactive.atr = A_DIM; dlg.button_key_active.atr = A_REVERSE; dlg.button_key_inactive.atr = A_BOLD; dlg.button_label_active.atr = A_REVERSE; - dlg.button_label_inactive.atr = A_NORMAL; - dlg.inputbox.atr = A_NORMAL; dlg.position_indicator.atr = A_BOLD; - dlg.menubox.atr = A_NORMAL; - dlg.menubox_border.atr = A_NORMAL; - dlg.item.atr = A_NORMAL; dlg.item_selected.atr = A_REVERSE; dlg.tag.atr = A_BOLD; dlg.tag_selected.atr = A_REVERSE; diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index c0969097447d..d6a61ca1a984 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -525,19 +525,12 @@ static void build_conf(struct menu *menu) val = sym_get_tristate_value(sym); if (sym_is_changeable(sym)) { - switch (type) { - case S_BOOLEAN: - item_make("[%c]", val == no ? ' ' : '*'); - break; - case S_TRISTATE: - switch (val) { - case yes: ch = '*'; break; - case mod: ch = 'M'; break; - default: ch = ' '; break; - } - item_make("<%c>", ch); - break; + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; } + item_make("<%c>", ch); item_set_tag('t'); item_set_data(menu); } else { @@ -548,15 +541,8 @@ static void build_conf(struct menu *menu) item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); if (val == yes) { - if (def_menu) { - item_add_str(" (%s)", menu_get_prompt(def_menu)); - item_add_str(" --->"); - if (def_menu->list) { - indent += 2; - build_conf(def_menu); - indent -= 2; - } - } + if (def_menu) + item_add_str(" (%s) --->", menu_get_prompt(def_menu)); return; } } else { @@ -568,49 +554,43 @@ static void build_conf(struct menu *menu) } child_count++; val = sym_get_tristate_value(sym); - if (sym_is_choice_value(sym) && val == yes) { - item_make(" "); - item_set_tag(':'); + switch (type) { + case S_BOOLEAN: + if (sym_is_changeable(sym)) + item_make("[%c]", val == no ? ' ' : '*'); + else + item_make("-%c-", val == no ? ' ' : '*'); + item_set_tag('t'); item_set_data(menu); - } else { - switch (type) { - case S_BOOLEAN: - if (sym_is_changeable(sym)) - item_make("[%c]", val == no ? ' ' : '*'); - else - item_make("-%c-", val == no ? ' ' : '*'); - item_set_tag('t'); - item_set_data(menu); - break; - case S_TRISTATE: - switch (val) { - case yes: ch = '*'; break; - case mod: ch = 'M'; break; - default: ch = ' '; break; - } - if (sym_is_changeable(sym)) { - if (sym->rev_dep.tri == mod) - item_make("{%c}", ch); - else - item_make("<%c>", ch); - } else - item_make("-%c-", ch); - item_set_tag('t'); - item_set_data(menu); - break; - default: - tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ - item_make("(%s)", sym_get_string_value(sym)); - tmp = indent - tmp + 4; - if (tmp < 0) - tmp = 0; - item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), - (sym_has_value(sym) || !sym_is_changeable(sym)) ? - "" : " (NEW)"); - item_set_tag('s'); - item_set_data(menu); - goto conf_childs; + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; } + if (sym_is_changeable(sym)) { + if (sym->rev_dep.tri == mod) + item_make("{%c}", ch); + else + item_make("<%c>", ch); + } else + item_make("-%c-", ch); + item_set_tag('t'); + item_set_data(menu); + break; + default: + tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ + item_make("(%s)", sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changeable(sym)) ? + "" : " (NEW)"); + item_set_tag('s'); + item_set_data(menu); + goto conf_childs; } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), (sym_has_value(sym) || !sym_is_changeable(sym)) ? diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 3b822cd110f4..53151c5a6028 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -17,6 +17,27 @@ static const char nohelp_text[] = "There is no help available for this option."; struct menu rootmenu; static struct menu **last_entry_ptr; +/** + * menu_next - return the next menu entry with depth-first traversal + * @menu: pointer to the current menu + * @root: root of the sub-tree to traverse. If NULL is given, the traveral + * continues until it reaches the end of the entire menu tree. + * return: the menu to visit next, or NULL when it reaches the end. + */ +struct menu *menu_next(struct menu *menu, struct menu *root) +{ + if (menu->list) + return menu->list; + + while (menu != root && !menu->next) + menu = menu->parent; + + if (menu == root) + return NULL; + + return menu->next; +} + void menu_warn(struct menu *menu, const char *fmt, ...) { va_list ap; @@ -242,11 +263,9 @@ static void sym_check_prop(struct symbol *sym) sym->name); } if (sym_is_choice(sym)) { - struct property *choice_prop = - sym_get_choice_prop(sym2); + struct menu *choice = sym_get_choice_menu(sym2); - if (!choice_prop || - prop_get_symbol(choice_prop) != sym) + if (!choice || choice->sym != sym) prop_warn(prop, "choice default symbol '%s' is not contained in the choice", sym2->name); @@ -486,18 +505,6 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) menu->sym && !sym_is_choice_value(menu->sym)) { current_entry = menu; menu->sym->flags |= SYMBOL_CHOICEVAL; - if (!menu->prompt) - menu_warn(menu, "choice value must have a prompt"); - for (prop = menu->sym->prop; prop; prop = prop->next) { - if (prop->type == P_DEFAULT) - prop_warn(prop, "defaults for choice " - "values not supported"); - if (prop->menu == menu) - continue; - if (prop->type == P_PROMPT && - prop->menu->parent->sym != sym) - prop_warn(prop, "choice value used outside its choice group"); - } /* Non-tristate choice values of tristate choices must * depend on the choice being set to Y. The choice * values' dependencies were propagated to their @@ -572,15 +579,11 @@ static void _menu_finalize(struct menu *parent, bool inside_choice) } /* - * For non-optional choices, add a reverse dependency (corresponding to - * a select) of '<visibility> && m'. This prevents the user from - * setting the choice mode to 'n' when the choice is visible. - * - * This would also work for non-choice symbols, but only non-optional - * choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented - * as a type of symbol. + * For choices, add a reverse dependency (corresponding to a select) of + * '<visibility> && m'. This prevents the user from setting the choice + * mode to 'n' when the choice is visible. */ - if (sym && !sym_is_optional(sym) && parent->prompt) { + if (sym && sym_is_choice(sym) && parent->prompt) { sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, expr_alloc_and(parent->prompt->visible.expr, expr_alloc_symbol(&symbol_mod))); diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 9d22b0f3197b..e1cb09418cbe 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -826,26 +826,18 @@ static void build_conf(struct menu *menu) val = sym_get_tristate_value(sym); if (sym_is_changeable(sym)) { - switch (type) { - case S_BOOLEAN: - item_make(menu, 't', "[%c]", - val == no ? ' ' : '*'); + switch (val) { + case yes: + ch = '*'; break; - case S_TRISTATE: - switch (val) { - case yes: - ch = '*'; - break; - case mod: - ch = 'M'; - break; - default: - ch = ' '; - break; - } - item_make(menu, 't', "<%c>", ch); + case mod: + ch = 'M'; + break; + default: + ch = ' '; break; } + item_make(menu, 't', "<%c>", ch); } else { item_make(menu, def_menu ? 't' : ':', " "); } @@ -853,16 +845,8 @@ static void build_conf(struct menu *menu) item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); if (val == yes) { - if (def_menu) { - item_add_str(" (%s)", - menu_get_prompt(def_menu)); - item_add_str(" --->"); - if (def_menu->list) { - indent += 2; - build_conf(def_menu); - indent -= 2; - } - } + if (def_menu) + item_add_str(" (%s) --->", menu_get_prompt(def_menu)); return; } } else { @@ -874,54 +858,46 @@ static void build_conf(struct menu *menu) } child_count++; val = sym_get_tristate_value(sym); - if (sym_is_choice_value(sym) && val == yes) { - item_make(menu, ':', " "); - } else { - switch (type) { - case S_BOOLEAN: - if (sym_is_changeable(sym)) - item_make(menu, 't', "[%c]", - val == no ? ' ' : '*'); - else - item_make(menu, 't', "-%c-", - val == no ? ' ' : '*'); + switch (type) { + case S_BOOLEAN: + if (sym_is_changeable(sym)) + item_make(menu, 't', "[%c]", + val == no ? ' ' : '*'); + else + item_make(menu, 't', "-%c-", + val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: + ch = '*'; break; - case S_TRISTATE: - switch (val) { - case yes: - ch = '*'; - break; - case mod: - ch = 'M'; - break; - default: - ch = ' '; - break; - } - if (sym_is_changeable(sym)) { - if (sym->rev_dep.tri == mod) - item_make(menu, - 't', "{%c}", ch); - else - item_make(menu, - 't', "<%c>", ch); - } else - item_make(menu, 't', "-%c-", ch); + case mod: + ch = 'M'; break; default: - tmp = 2 + strlen(sym_get_string_value(sym)); - item_make(menu, 's', " (%s)", - sym_get_string_value(sym)); - tmp = indent - tmp + 4; - if (tmp < 0) - tmp = 0; - item_add_str("%*c%s%s", tmp, ' ', - menu_get_prompt(menu), - (sym_has_value(sym) || - !sym_is_changeable(sym)) ? "" : - " (NEW)"); - goto conf_childs; + ch = ' '; + break; } + if (sym_is_changeable(sym)) { + if (sym->rev_dep.tri == mod) + item_make(menu, 't', "{%c}", ch); + else + item_make(menu, 't', "<%c>", ch); + } else + item_make(menu, 't', "-%c-", ch); + break; + default: + tmp = 2 + strlen(sym_get_string_value(sym)); + item_make(menu, 's', " (%s)", + sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || + !sym_is_changeable(sym)) ? "" : " (NEW)"); + goto conf_childs; } item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 7fb996612c96..ff709001b1f0 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -30,6 +30,8 @@ static bool zconf_endtoken(const char *tokenname, struct menu *current_menu, *current_entry; +static bool inside_choice = false; + %} %union @@ -69,7 +71,6 @@ struct menu *current_menu, *current_entry; %token T_MODULES %token T_ON %token T_OPEN_PAREN -%token T_OPTIONAL %token T_PLUS_EQUAL %token T_PROMPT %token T_RANGE @@ -140,19 +141,25 @@ stmt_list_in_choice: config_entry_start: T_CONFIG nonconst_symbol T_EOL { - $2->flags |= SYMBOL_OPTIONAL; menu_add_entry($2); printd(DEBUG_PARSE, "%s:%d:config %s\n", cur_filename, cur_lineno, $2->name); }; config_stmt: config_entry_start config_option_list { + if (inside_choice) { + if (!current_entry->prompt) { + fprintf(stderr, "%s:%d: error: choice member must have a prompt\n", + current_entry->filename, current_entry->lineno); + yynerrs++; + } + } + printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); }; menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL { - $2->flags |= SYMBOL_OPTIONAL; menu_add_entry($2); printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", cur_filename, cur_lineno, $2->name); }; @@ -224,8 +231,8 @@ config_option: T_MODULES T_EOL choice: T_CHOICE T_EOL { - struct symbol *sym = sym_lookup(NULL, SYMBOL_CHOICE); - sym->flags |= SYMBOL_NO_WRITE; + struct symbol *sym = sym_lookup(NULL, 0); + menu_add_entry(sym); menu_add_expr(P_CHOICE, NULL, NULL); printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno); @@ -240,10 +247,14 @@ choice_entry: choice choice_option_list } $$ = menu_add_menu(); + + inside_choice = true; }; choice_end: end { + inside_choice = false; + if (zconf_endtoken($1, "choice")) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", cur_filename, cur_lineno); @@ -272,12 +283,6 @@ choice_option: logic_type prompt_stmt_opt T_EOL printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1); }; -choice_option: T_OPTIONAL T_EOL -{ - current_entry->sym->flags |= SYMBOL_OPTIONAL; - printd(DEBUG_PARSE, "%s:%d:optional\n", cur_filename, cur_lineno); -}; - choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL { menu_add_symbol(P_DEFAULT, $2, $3); @@ -471,6 +476,38 @@ assign_val: %% +/** + * choice_check_sanity - check sanity of a choice member + * + * @menu: menu of the choice member + * + * Return: -1 if an error is found, 0 otherwise. + */ +static int choice_check_sanity(struct menu *menu) +{ + struct property *prop; + int ret = 0; + + for (prop = menu->sym->prop; prop; prop = prop->next) { + if (prop->type == P_DEFAULT) { + fprintf(stderr, "%s:%d: error: %s", + prop->filename, prop->lineno, + "defaults for choice values not supported\n"); + ret = -1; + } + + if (prop->menu != menu && prop->type == P_PROMPT && + prop->menu->parent != menu->parent) { + fprintf(stderr, "%s:%d: error: %s", + prop->filename, prop->lineno, + "choice value has a prompt outside its choice group\n"); + ret = -1; + } + } + + return ret; +} + void conf_parse(const char *name) { struct menu *menu; @@ -517,20 +554,17 @@ void conf_parse(const char *name) menu_finalize(); - menu = &rootmenu; - while (menu) { + menu_for_each_entry(menu) { + struct menu *child; + if (menu->sym && sym_check_deps(menu->sym)) yynerrs++; - if (menu->list) { - menu = menu->list; - continue; + if (menu->sym && sym_is_choice(menu->sym)) { + menu_for_each_sub_entry(child, menu) + if (child->sym && choice_check_sanity(child)) + yynerrs++; } - - while (!menu->next && menu->parent) - menu = menu->parent; - - menu = menu->next; } if (yynerrs) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 81fe1884ef8a..aa0e25ee5119 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -78,6 +78,41 @@ struct property *sym_get_choice_prop(struct symbol *sym) return NULL; } +/** + * sym_get_choice_menu - get the parent choice menu if present + * + * @sym: a symbol pointer + * + * Return: a choice menu if this function is called against a choice member. + */ +struct menu *sym_get_choice_menu(struct symbol *sym) +{ + struct menu *menu = NULL; + struct menu *m; + + /* + * Choice members must have a prompt. Find a menu entry with a prompt, + * and assume it resides inside a choice block. + */ + list_for_each_entry(m, &sym->menus, link) + if (m->prompt) { + menu = m; + break; + } + + if (!menu) + return NULL; + + do { + menu = menu->parent; + } while (menu && !menu->sym); + + if (menu && menu->sym && sym_is_choice(menu->sym)) + return menu; + + return NULL; +} + static struct property *sym_get_default_prop(struct symbol *sym) { struct property *prop; @@ -152,13 +187,11 @@ static void sym_validate_range(struct symbol *sym) static void sym_set_changed(struct symbol *sym) { - struct property *prop; + struct menu *menu; sym->flags |= SYMBOL_CHANGED; - for (prop = sym->prop; prop; prop = prop->next) { - if (prop->menu) - prop->menu->flags |= MENU_CHANGED; - } + list_for_each_entry(menu, &sym->menus, link) + menu->flags |= MENU_CHANGED; } static void sym_set_all_changed(void) @@ -466,10 +499,9 @@ void sym_calc_value(struct symbol *sym) if (sym->flags & SYMBOL_CHANGED) sym_set_changed(choice_sym); } - } - if (sym->flags & SYMBOL_NO_WRITE) sym->flags &= ~SYMBOL_WRITE; + } if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) set_all_choice_values(sym); @@ -827,7 +859,7 @@ struct symbol *sym_lookup(const char *name, int flags) if (symbol->name && !strcmp(symbol->name, name) && (flags ? symbol->flags & flags - : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) + : !(symbol->flags & SYMBOL_CONST))) return symbol; } new_name = xstrdup(name); @@ -1172,16 +1204,18 @@ out: static struct symbol *sym_check_choice_deps(struct symbol *choice) { - struct symbol *sym, *sym2; - struct property *prop; - struct expr *e; + struct menu *choice_menu, *menu; + struct symbol *sym2; struct dep_stack stack; dep_stack_insert(&stack, choice); - prop = sym_get_choice_prop(choice); - expr_list_for_each_sym(prop->expr, e, sym) - sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); + choice_menu = list_first_entry(&choice->menus, struct menu, link); + + menu_for_each_sub_entry(menu, choice_menu) { + if (menu->sym) + menu->sym->flags |= SYMBOL_CHECK | SYMBOL_CHECKED; + } choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); sym2 = sym_check_sym_deps(choice); @@ -1189,14 +1223,17 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice) if (sym2) goto out; - expr_list_for_each_sym(prop->expr, e, sym) { - sym2 = sym_check_sym_deps(sym); + menu_for_each_sub_entry(menu, choice_menu) { + if (!menu->sym) + continue; + sym2 = sym_check_sym_deps(menu->sym); if (sym2) break; } out: - expr_list_for_each_sym(prop->expr, e, sym) - sym->flags &= ~SYMBOL_CHECK; + menu_for_each_sub_entry(menu, choice_menu) + if (menu->sym) + menu->sym->flags &= ~SYMBOL_CHECK; if (sym2 && sym_is_choice_value(sym2) && prop_get_symbol(sym_get_choice_prop(sym2)) == choice) diff --git a/scripts/kconfig/tests/choice/Kconfig b/scripts/kconfig/tests/choice/Kconfig index 0930eb65e932..8cdda40868a1 100644 --- a/scripts/kconfig/tests/choice/Kconfig +++ b/scripts/kconfig/tests/choice/Kconfig @@ -18,19 +18,6 @@ config BOOL_CHOICE1 endchoice choice - prompt "optional boolean choice" - optional - default OPT_BOOL_CHOICE1 - -config OPT_BOOL_CHOICE0 - bool "choice 0" - -config OPT_BOOL_CHOICE1 - bool "choice 1" - -endchoice - -choice prompt "tristate choice" default TRI_CHOICE1 @@ -41,16 +28,3 @@ config TRI_CHOICE1 tristate "choice 1" endchoice - -choice - prompt "optional tristate choice" - optional - default OPT_TRI_CHOICE1 - -config OPT_TRI_CHOICE0 - tristate "choice 0" - -config OPT_TRI_CHOICE1 - tristate "choice 1" - -endchoice diff --git a/scripts/kconfig/tests/choice/__init__.py b/scripts/kconfig/tests/choice/__init__.py index 4318fce05912..05e162220085 100644 --- a/scripts/kconfig/tests/choice/__init__.py +++ b/scripts/kconfig/tests/choice/__init__.py @@ -6,8 +6,6 @@ The handling of 'choice' is a bit complicated part in Kconfig. The behavior of 'y' choice is intuitive. If choice values are tristate, the choice can be 'm' where each value can be enabled independently. -Also, if a choice is marked as 'optional', the whole choice can be -invisible. """ diff --git a/scripts/kconfig/tests/choice/allmod_expected_config b/scripts/kconfig/tests/choice/allmod_expected_config index f1f5dcdb7923..d1f51651740c 100644 --- a/scripts/kconfig/tests/choice/allmod_expected_config +++ b/scripts/kconfig/tests/choice/allmod_expected_config @@ -1,9 +1,5 @@ CONFIG_MODULES=y # CONFIG_BOOL_CHOICE0 is not set CONFIG_BOOL_CHOICE1=y -# CONFIG_OPT_BOOL_CHOICE0 is not set -CONFIG_OPT_BOOL_CHOICE1=y CONFIG_TRI_CHOICE0=m CONFIG_TRI_CHOICE1=m -CONFIG_OPT_TRI_CHOICE0=m -CONFIG_OPT_TRI_CHOICE1=m diff --git a/scripts/kconfig/tests/choice/allyes_expected_config b/scripts/kconfig/tests/choice/allyes_expected_config index e5a062a1157c..8a76c1816893 100644 --- a/scripts/kconfig/tests/choice/allyes_expected_config +++ b/scripts/kconfig/tests/choice/allyes_expected_config @@ -1,9 +1,5 @@ CONFIG_MODULES=y # CONFIG_BOOL_CHOICE0 is not set CONFIG_BOOL_CHOICE1=y -# CONFIG_OPT_BOOL_CHOICE0 is not set -CONFIG_OPT_BOOL_CHOICE1=y # CONFIG_TRI_CHOICE0 is not set CONFIG_TRI_CHOICE1=y -# CONFIG_OPT_TRI_CHOICE0 is not set -CONFIG_OPT_TRI_CHOICE1=y diff --git a/scripts/kconfig/tests/choice/oldask0_expected_stdout b/scripts/kconfig/tests/choice/oldask0_expected_stdout index b251bba9698b..d2257db46423 100644 --- a/scripts/kconfig/tests/choice/oldask0_expected_stdout +++ b/scripts/kconfig/tests/choice/oldask0_expected_stdout @@ -3,8 +3,6 @@ boolean choice 1. choice 0 (BOOL_CHOICE0) (NEW) > 2. choice 1 (BOOL_CHOICE1) (NEW) choice[1-2?]: -optional boolean choice [N/y/?] (NEW) tristate choice [M/y/?] (NEW) choice 0 (TRI_CHOICE0) [N/m/?] (NEW) choice 1 (TRI_CHOICE1) [N/m/?] (NEW) -optional tristate choice [N/m/y/?] (NEW) diff --git a/scripts/kconfig/tests/choice/oldask1_config b/scripts/kconfig/tests/choice/oldask1_config index b67bfe3c641f..0f417856c81c 100644 --- a/scripts/kconfig/tests/choice/oldask1_config +++ b/scripts/kconfig/tests/choice/oldask1_config @@ -1,2 +1 @@ # CONFIG_MODULES is not set -CONFIG_OPT_BOOL_CHOICE0=y diff --git a/scripts/kconfig/tests/choice/oldask1_expected_stdout b/scripts/kconfig/tests/choice/oldask1_expected_stdout index c2125e9bf96a..ffa20ad7f38e 100644 --- a/scripts/kconfig/tests/choice/oldask1_expected_stdout +++ b/scripts/kconfig/tests/choice/oldask1_expected_stdout @@ -3,13 +3,7 @@ boolean choice 1. choice 0 (BOOL_CHOICE0) (NEW) > 2. choice 1 (BOOL_CHOICE1) (NEW) choice[1-2?]: -optional boolean choice [Y/n/?] (NEW) -optional boolean choice -> 1. choice 0 (OPT_BOOL_CHOICE0) - 2. choice 1 (OPT_BOOL_CHOICE1) (NEW) -choice[1-2?]: tristate choice 1. choice 0 (TRI_CHOICE0) (NEW) > 2. choice 1 (TRI_CHOICE1) (NEW) choice[1-2?]: -optional tristate choice [N/y/?] diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cb1be22afc65..95a59ac78f82 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -62,7 +62,7 @@ my $anon_struct_union = 0; # match expressions used to find embedded type information my $type_constant = '\b``([^\`]+)``\b'; -my $type_constant2 = '\%([-_\w]+)'; +my $type_constant2 = '\%([-_*\w]+)'; my $type_func = '(\w+)\(\)'; my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; my $type_param_ref = '([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; @@ -1143,6 +1143,7 @@ sub dump_struct($$) { $members =~ s/\s*$attribute/ /gi; $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos; $members =~ s/\s*__counted_by\s*\([^;]*\)/ /gos; + $members =~ s/\s*__counted_by_(le|be)\s*\([^;]*\)/ /gos; $members =~ s/\s*__packed\s*/ /gos; $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos; $members =~ s/\s*____cacheline_aligned_in_smp/ /gos; @@ -1151,7 +1152,8 @@ sub dump_struct($$) { # - first eat non-declaration parameters and rewrite for final match # - then remove macro, outer parens, and trailing semicolon $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos; - $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos; + $members =~ s/\bstruct_group_attr\s*\(([^,]*,){2}/STRUCT_GROUP(/gos; + $members =~ s/\bstruct_group_tagged\s*\(([^,]*),([^,]*),/struct $1 $2; STRUCT_GROUP(/gos; $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos; $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos; @@ -1723,6 +1725,7 @@ sub dump_function($$) { $prototype =~ s/__must_check +//; $prototype =~ s/__weak +//; $prototype =~ s/__sched +//; + $prototype =~ s/_noprof//; $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; $prototype =~ s/__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//; $prototype =~ s/__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +//; diff --git a/scripts/make_fit.py b/scripts/make_fit.py new file mode 100755 index 000000000000..3de90c5a094b --- /dev/null +++ b/scripts/make_fit.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2024 Google LLC +# Written by Simon Glass <sjg@chromium.org> +# + +"""Build a FIT containing a lot of devicetree files + +Usage: + make_fit.py -A arm64 -n 'Linux-6.6' -O linux + -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk + @arch/arm64/boot/dts/dtbs-list -E -c gzip + +Creates a FIT containing the supplied kernel and a set of devicetree files, +either specified individually or listed in a file (with an '@' prefix). + +Use -E to generate an external FIT (where the data is placed after the +FIT data structure). This allows parsing of the data without loading +the entire FIT. + +Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and +zstd algorithms. + +The resulting FIT can be booted by bootloaders which support FIT, such +as U-Boot, Linuxboot, Tianocore, etc. + +Note that this tool does not yet support adding a ramdisk / initrd. +""" + +import argparse +import collections +import os +import subprocess +import sys +import tempfile +import time + +import libfdt + + +# Tool extension and the name of the command-line tools +CompTool = collections.namedtuple('CompTool', 'ext,tools') + +COMP_TOOLS = { + 'bzip2': CompTool('.bz2', 'bzip2'), + 'gzip': CompTool('.gz', 'pigz,gzip'), + 'lz4': CompTool('.lz4', 'lz4'), + 'lzma': CompTool('.lzma', 'lzma'), + 'lzo': CompTool('.lzo', 'lzop'), + 'zstd': CompTool('.zstd', 'zstd'), +} + + +def parse_args(): + """Parse the program ArgumentParser + + Returns: + Namespace object containing the arguments + """ + epilog = 'Build a FIT from a directory tree containing .dtb files' + parser = argparse.ArgumentParser(epilog=epilog, fromfile_prefix_chars='@') + parser.add_argument('-A', '--arch', type=str, required=True, + help='Specifies the architecture') + parser.add_argument('-c', '--compress', type=str, default='none', + help='Specifies the compression') + parser.add_argument('-E', '--external', action='store_true', + help='Convert the FIT to use external data') + parser.add_argument('-n', '--name', type=str, required=True, + help='Specifies the name') + parser.add_argument('-o', '--output', type=str, required=True, + help='Specifies the output file (.fit)') + parser.add_argument('-O', '--os', type=str, required=True, + help='Specifies the operating system') + parser.add_argument('-k', '--kernel', type=str, required=True, + help='Specifies the (uncompressed) kernel input file (.itk)') + parser.add_argument('-v', '--verbose', action='store_true', + help='Enable verbose output') + parser.add_argument('dtbs', type=str, nargs='*', + help='Specifies the devicetree files to process') + + return parser.parse_args() + + +def setup_fit(fsw, name): + """Make a start on writing the FIT + + Outputs the root properties and the 'images' node + + Args: + fsw (libfdt.FdtSw): Object to use for writing + name (str): Name of kernel image + """ + fsw.INC_SIZE = 65536 + fsw.finish_reservemap() + fsw.begin_node('') + fsw.property_string('description', f'{name} with devicetree set') + fsw.property_u32('#address-cells', 1) + + fsw.property_u32('timestamp', int(time.time())) + fsw.begin_node('images') + + +def write_kernel(fsw, data, args): + """Write out the kernel image + + Writes a kernel node along with the required properties + + Args: + fsw (libfdt.FdtSw): Object to use for writing + data (bytes): Data to write (possibly compressed) + args (Namespace): Contains necessary strings: + arch: FIT architecture, e.g. 'arm64' + fit_os: Operating Systems, e.g. 'linux' + name: Name of OS, e.g. 'Linux-6.6.0-rc7' + compress: Compression algorithm to use, e.g. 'gzip' + """ + with fsw.add_node('kernel'): + fsw.property_string('description', args.name) + fsw.property_string('type', 'kernel_noload') + fsw.property_string('arch', args.arch) + fsw.property_string('os', args.os) + fsw.property_string('compression', args.compress) + fsw.property('data', data) + fsw.property_u32('load', 0) + fsw.property_u32('entry', 0) + + +def finish_fit(fsw, entries): + """Finish the FIT ready for use + + Writes the /configurations node and subnodes + + Args: + fsw (libfdt.FdtSw): Object to use for writing + entries (list of tuple): List of configurations: + str: Description of model + str: Compatible stringlist + """ + fsw.end_node() + seq = 0 + with fsw.add_node('configurations'): + for model, compat in entries: + seq += 1 + with fsw.add_node(f'conf-{seq}'): + fsw.property('compatible', bytes(compat)) + fsw.property_string('description', model) + fsw.property_string('fdt', f'fdt-{seq}') + fsw.property_string('kernel', 'kernel') + fsw.end_node() + + +def compress_data(inf, compress): + """Compress data using a selected algorithm + + Args: + inf (IOBase): Filename containing the data to compress + compress (str): Compression algorithm, e.g. 'gzip' + + Return: + bytes: Compressed data + """ + if compress == 'none': + return inf.read() + + comp = COMP_TOOLS.get(compress) + if not comp: + raise ValueError(f"Unknown compression algorithm '{compress}'") + + with tempfile.NamedTemporaryFile() as comp_fname: + with open(comp_fname.name, 'wb') as outf: + done = False + for tool in comp.tools.split(','): + try: + subprocess.call([tool, '-c'], stdin=inf, stdout=outf) + done = True + break + except FileNotFoundError: + pass + if not done: + raise ValueError(f'Missing tool(s): {comp.tools}\n') + with open(comp_fname.name, 'rb') as compf: + comp_data = compf.read() + return comp_data + + +def output_dtb(fsw, seq, fname, arch, compress): + """Write out a single devicetree to the FIT + + Args: + fsw (libfdt.FdtSw): Object to use for writing + seq (int): Sequence number (1 for first) + fmame (str): Filename containing the DTB + arch: FIT architecture, e.g. 'arm64' + compress (str): Compressed algorithm, e.g. 'gzip' + + Returns: + tuple: + str: Model name + bytes: Compatible stringlist + """ + with fsw.add_node(f'fdt-{seq}'): + # Get the compatible / model information + with open(fname, 'rb') as inf: + data = inf.read() + fdt = libfdt.FdtRo(data) + model = fdt.getprop(0, 'model').as_str() + compat = fdt.getprop(0, 'compatible') + + fsw.property_string('description', model) + fsw.property_string('type', 'flat_dt') + fsw.property_string('arch', arch) + fsw.property_string('compression', compress) + fsw.property('compatible', bytes(compat)) + + with open(fname, 'rb') as inf: + compressed = compress_data(inf, compress) + fsw.property('data', compressed) + return model, compat + + +def build_fit(args): + """Build the FIT from the provided files and arguments + + Args: + args (Namespace): Program arguments + + Returns: + tuple: + bytes: FIT data + int: Number of configurations generated + size: Total uncompressed size of data + """ + seq = 0 + size = 0 + fsw = libfdt.FdtSw() + setup_fit(fsw, args.name) + entries = [] + + # Handle the kernel + with open(args.kernel, 'rb') as inf: + comp_data = compress_data(inf, args.compress) + size += os.path.getsize(args.kernel) + write_kernel(fsw, comp_data, args) + + for fname in args.dtbs: + # Ignore overlay (.dtbo) files + if os.path.splitext(fname)[1] == '.dtb': + seq += 1 + size += os.path.getsize(fname) + model, compat = output_dtb(fsw, seq, fname, args.arch, args.compress) + entries.append([model, compat]) + + finish_fit(fsw, entries) + + # Include the kernel itself in the returned file count + return fsw.as_fdt().as_bytearray(), seq + 1, size + + +def run_make_fit(): + """Run the tool's main logic""" + args = parse_args() + + out_data, count, size = build_fit(args) + with open(args.output, 'wb') as outf: + outf.write(out_data) + + ext_fit_size = None + if args.external: + mkimage = os.environ.get('MKIMAGE', 'mkimage') + subprocess.check_call([mkimage, '-E', '-F', args.output], + stdout=subprocess.DEVNULL) + + with open(args.output, 'rb') as inf: + data = inf.read() + ext_fit = libfdt.FdtRo(data) + ext_fit_size = ext_fit.totalsize() + + if args.verbose: + comp_size = len(out_data) + print(f'FIT size {comp_size:#x}/{comp_size / 1024 / 1024:.1f} MB', + end='') + if ext_fit_size: + print(f', header {ext_fit_size:#x}/{ext_fit_size / 1024:.1f} KB', + end='') + print(f', {count} files, uncompressed {size / 1024 / 1024:.1f} MB') + + +if __name__ == "__main__": + sys.exit(run_make_fit()) diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh index 5927cc6b7de3..91c91201212c 100755 --- a/scripts/min-tool-version.sh +++ b/scripts/min-tool-version.sh @@ -33,7 +33,7 @@ llvm) fi ;; rustc) - echo 1.76.0 + echo 1.78.0 ;; bindgen) echo 0.65.1 diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 3c54125eb373..c729bc936bae 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -OBJECT_FILES_NON_STANDARD := y CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) hostprogs-always-y += modpost mk_elfconfig diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2f5b91da5afa..937294ff164f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -601,11 +601,6 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) strstarts(symname, "_savevr_") || strcmp(symname, ".TOC.") == 0) return 1; - - if (info->hdr->e_machine == EM_S390) - /* Expoline thunks are linked on all kernel modules during final link of .ko */ - if (strstarts(symname, "__s390_indirect_jump_r")) - return 1; /* Do not ignore this symbol */ return 0; } diff --git a/scripts/module.lds.S b/scripts/module.lds.S index bf5bcf2836d8..3f43edef813c 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -9,10 +9,13 @@ #define DISCARD_EH_FRAME *(.eh_frame) #endif +#include <asm-generic/codetag.lds.h> + SECTIONS { /DISCARD/ : { *(.discard) *(.discard.*) + *(.export_symbol) } __ksymtab 0 : { *(SORT(___ksymtab+*)) } @@ -47,12 +50,17 @@ SECTIONS { .data : { *(.data .data.[0-9a-zA-Z_]*) *(.data..L*) + CODETAG_SECTIONS() } .rodata : { *(.rodata .rodata.[0-9a-zA-Z_]*) *(.rodata..L*) } +#else + .data : { + CODETAG_SECTIONS() + } #endif } diff --git a/scripts/package/buildtar b/scripts/package/buildtar index 72c91a1b832f..eb67787f8673 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -53,18 +53,20 @@ cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" # # Install arch-specific kernel image(s) # +# Note: +# mips and arm64 copy the first image found. This may not produce the desired +# outcome because it may pick up a stale file remaining in the build tree. +# case "${ARCH}" in - x86|i386|x86_64) - [ -f "${objtree}/arch/x86/boot/bzImage" ] && cp -v -- "${objtree}/arch/x86/boot/bzImage" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" - ;; alpha) - [ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" + cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" ;; parisc*) - [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" + cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" [ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}" ;; mips) + # Please note the following code may copy a stale file. if [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.bin" ]; then cp -v -- "${objtree}/arch/mips/boot/compressed/vmlinux.bin" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" elif [ -f "${objtree}/arch/mips/boot/compressed/vmlinux.ecoff" ]; then @@ -86,6 +88,7 @@ case "${ARCH}" in fi ;; arm64) + # Please note the following code may copy a stale file. for i in Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo vmlinuz.efi ; do if [ -f "${objtree}/arch/arm64/boot/${i}" ] ; then cp -v -- "${objtree}/arch/arm64/boot/${i}" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" @@ -94,21 +97,14 @@ case "${ARCH}" in done ;; riscv) - for i in Image.bz2 Image.gz Image; do - if [ -f "${objtree}/arch/riscv/boot/${i}" ] ; then - cp -v -- "${objtree}/arch/riscv/boot/${i}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" - break - fi - done + case "${KBUILD_IMAGE##*/}" in + Image.*|vmlinuz.efi) + cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}";; + *) + cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}";; + esac ;; *) - [ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}" - echo "" >&2 - echo '** ** ** WARNING ** ** **' >&2 - echo "" >&2 - echo "Your architecture did not define any architecture-dependent files" >&2 - echo "to be placed into the tarball. Please add those to ${0} ..." >&2 - echo "" >&2 - sleep 5 + cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" ;; esac diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install index 4c781617ffe6..c1121f098542 100755 --- a/scripts/sphinx-pre-install +++ b/scripts/sphinx-pre-install @@ -514,6 +514,7 @@ sub give_mageia_hints() { my %map = ( "python-sphinx" => "python3-sphinx", + "yaml" => "python3-yaml", "virtualenv" => "python3-virtualenv", "dot" => "graphviz", "convert" => "ImageMagick", @@ -557,10 +558,11 @@ sub give_mageia_hints() sub give_arch_linux_hints() { my %map = ( + "yaml" => "python-yaml", "virtualenv" => "python-virtualenv", "dot" => "graphviz", "convert" => "imagemagick", - "xelatex" => "texlive-bin", + "xelatex" => "texlive-xetex", "latexmk" => "texlive-core", "rsvg-convert" => "extra/librsvg", ); @@ -587,6 +589,7 @@ sub give_arch_linux_hints() sub give_gentoo_hints() { my %map = ( + "yaml" => "dev-python/pyyaml", "virtualenv" => "dev-python/virtualenv", "dot" => "media-gfx/graphviz", "convert" => "media-gfx/imagemagick", diff --git a/scripts/unifdef.c b/scripts/unifdef.c index db00e3e30a59..ff15efd6e7d7 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c @@ -203,7 +203,7 @@ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ static unsigned blankcount; /* count of blank lines */ static unsigned blankmax; /* maximum recent blankcount */ -static bool constexpr; /* constant #if expression */ +static bool constexpression; /* constant #if expression */ static bool zerosyms = true; /* to format symdepth output */ static bool firstsym; /* ditto */ @@ -819,7 +819,7 @@ static const struct ops { /* * Function for evaluating the innermost parts of expressions, * viz. !expr (expr) number defined(symbol) symbol - * We reset the constexpr flag in the last two cases. + * We reset the constexpression flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -877,7 +877,7 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) cp = skipcomment(cp); if (defparen && *cp++ != ')') return (LT_ERROR); - constexpr = false; + constexpression = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); @@ -895,7 +895,7 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) lt = *valp ? LT_TRUE : LT_FALSE; cp = skipargs(cp); } - constexpr = false; + constexpression = false; } else { debug("eval%d bad expr", ops - eval_ops); return (LT_ERROR); @@ -955,10 +955,10 @@ ifeval(const char **cpp) int val = 0; debug("eval %s", *cpp); - constexpr = killconsts ? false : true; + constexpression = killconsts ? false : true; ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); + return (constexpression ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* |