Merge tag 'kbuild-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild
Pull Kbuild updates from Masahiro Yamada: - Add generic support for built-in boot DTB files - Enable TAB cycling for dialog buttons in nconfig - Fix issues in streamline_config.pl - Refactor Kconfig - Add support for Clang's AutoFDO (Automatic Feedback-Directed Optimization) - Add support for Clang's Propeller, a profile-guided optimization. - Change the working directory to the external module directory for M= builds - Support building external modules in a separate output directory - Enable objtool for *.mod.o and additional kernel objects - Use lz4 instead of deprecated lz4c - Work around a performance issue with "git describe" - Refactor modpost * tag 'kbuild-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (85 commits) kbuild: rename .tmp_vmlinux.kallsyms0.syms to .tmp_vmlinux0.syms gitignore: Don't ignore 'tags' directory kbuild: add dependency from vmlinux to resolve_btfids modpost: replace tdb_hash() with hash_str() kbuild: deb-pkg: add python3:native to build dependency genksyms: reduce indentation in export_symbol() modpost: improve error messages in device_id_check() modpost: rename alias symbol for MODULE_DEVICE_TABLE() modpost: rename variables in handle_moddevtable() modpost: move strstarts() to modpost.h modpost: convert do_usb_table() to a generic handler modpost: convert do_of_table() to a generic handler modpost: convert do_pnp_device_entry() to a generic handler modpost: convert do_pnp_card_entries() to a generic handler modpost: call module_alias_printf() from all do_*_entry() functions modpost: pass (struct module *) to do_*_entry() functions modpost: remove DEF_FIELD_ADDR_VAR() macro modpost: deduplicate MODULE_ALIAS() for all drivers modpost: introduce module_alias_printf() helper modpost: remove unnecessary check in do_acpi_entry() ...
This commit is contained in:
@@ -205,7 +205,7 @@ if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:)
|
||||
|
||||
cmd_and_fixdep = \
|
||||
$(cmd); \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
|
||||
$(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
|
||||
rm -f $(depfile)
|
||||
|
||||
# Usage: $(call if_changed_rule,foo)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# Enable available and selected Clang AutoFDO features.
|
||||
|
||||
CFLAGS_AUTOFDO_CLANG := -fdebug-info-for-profiling -mllvm -enable-fs-discriminator=true -mllvm -improved-fs-discriminator=true
|
||||
|
||||
ifndef CONFIG_DEBUG_INFO
|
||||
CFLAGS_AUTOFDO_CLANG += -gmlt
|
||||
endif
|
||||
|
||||
ifdef CLANG_AUTOFDO_PROFILE
|
||||
CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections
|
||||
CFLAGS_AUTOFDO_CLANG += -fsplit-machine-functions
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO_CLANG_THIN
|
||||
ifdef CLANG_AUTOFDO_PROFILE
|
||||
KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE)
|
||||
endif
|
||||
KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto
|
||||
KBUILD_LDFLAGS += -plugin-opt=-split-machine-functions
|
||||
endif
|
||||
|
||||
export CFLAGS_AUTOFDO_CLANG
|
||||
+7
-52
@@ -3,7 +3,7 @@
|
||||
# Building
|
||||
# ==========================================================================
|
||||
|
||||
src := $(if $(VPATH),$(VPATH)/)$(obj)
|
||||
src := $(srcroot)/$(obj)
|
||||
|
||||
PHONY := $(obj)/
|
||||
$(obj)/:
|
||||
@@ -34,7 +34,7 @@ subdir-asflags-y :=
|
||||
subdir-ccflags-y :=
|
||||
|
||||
# Read auto.conf if it exists, otherwise ignore
|
||||
-include include/config/auto.conf
|
||||
-include $(objtree)/include/config/auto.conf
|
||||
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
include $(srctree)/scripts/Makefile.compiler
|
||||
@@ -107,20 +107,14 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
|
||||
$(obj)/%.i: $(obj)/%.c FORCE
|
||||
$(call if_changed_dep,cpp_i_c)
|
||||
|
||||
genksyms = scripts/genksyms/genksyms \
|
||||
$(if $(1), -T $(2)) \
|
||||
$(if $(KBUILD_PRESERVE), -p) \
|
||||
-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null)
|
||||
genksyms = $(objtree)/scripts/genksyms/genksyms \
|
||||
$(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \
|
||||
$(if $(KBUILD_PRESERVE), -p) \
|
||||
$(addprefix -r , $(wildcard $(@:.o=.symref)))
|
||||
|
||||
# These mirror gensymtypes_S and co below, keep them in synch.
|
||||
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 : $(obj)/%.c FORCE
|
||||
$(call cmd,cc_symtypes_c)
|
||||
|
||||
# LLVM assembly
|
||||
# Generate .ll files from .c
|
||||
quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@
|
||||
@@ -135,17 +129,6 @@ $(obj)/%.ll: $(obj)/%.c FORCE
|
||||
|
||||
is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y)
|
||||
|
||||
# When a module consists of a single object, there is no reason to keep LLVM IR.
|
||||
# Make $(LD) covert LLVM IR to ELF here.
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
|
||||
endif
|
||||
|
||||
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
|
||||
$(cmd_ld_single_m) \
|
||||
$(cmd_objtool)
|
||||
|
||||
ifdef CONFIG_MODVERSIONS
|
||||
# When module versioning is enabled the following steps are executed:
|
||||
# o compile a <file>.o from <file>.c
|
||||
@@ -158,8 +141,7 @@ ifdef CONFIG_MODVERSIONS
|
||||
|
||||
gen_symversions = \
|
||||
if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \
|
||||
$(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
>> $(dot-target).cmd; \
|
||||
$(cmd_gensymtypes_$1) >> $(dot-target).cmd; \
|
||||
fi
|
||||
|
||||
cmd_gen_symversions_c = $(call gen_symversions,c)
|
||||
@@ -207,23 +189,6 @@ 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)))
|
||||
endif
|
||||
|
||||
define rule_cc_o_c
|
||||
$(call cmd_and_fixdep,cc_o_c)
|
||||
$(call cmd,checksrc)
|
||||
$(call cmd,checkdoc)
|
||||
$(call cmd,gen_objtooldep)
|
||||
$(call cmd,gen_symversions_c)
|
||||
$(call cmd,record_mcount)
|
||||
$(call cmd,warn_shared_object)
|
||||
endef
|
||||
|
||||
define rule_as_o_S
|
||||
$(call cmd_and_fixdep,as_o_S)
|
||||
$(call cmd,gen_objtooldep)
|
||||
$(call cmd,gen_symversions_S)
|
||||
$(call cmd,warn_shared_object)
|
||||
endef
|
||||
|
||||
# Built-in and composite module parts
|
||||
$(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
@@ -330,22 +295,12 @@ cmd_gensymtypes_S = \
|
||||
$(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms)
|
||||
|
||||
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
|
||||
cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null
|
||||
|
||||
$(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: $(obj)/%.S FORCE
|
||||
$(call if_changed_dep,cpp_s_S)
|
||||
|
||||
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
|
||||
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool)
|
||||
|
||||
ifdef CONFIG_ASM_MODVERSIONS
|
||||
|
||||
# versioning matches the C process described above, with difference that
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Cleaning up
|
||||
# ==========================================================================
|
||||
|
||||
src := $(if $(VPATH),$(VPATH)/)$(obj)
|
||||
src := $(srcroot)/$(obj)
|
||||
|
||||
PHONY := __clean
|
||||
__clean:
|
||||
|
||||
@@ -13,7 +13,7 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \
|
||||
$(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
|
||||
|
||||
# output directory for tests below
|
||||
TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
|
||||
TMPOUT = .tmp_$$$$
|
||||
|
||||
# try-run
|
||||
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
|
||||
|
||||
@@ -96,12 +96,10 @@ hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \
|
||||
$(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
|
||||
$(HOSTRUSTFLAGS_$(target-stem))
|
||||
|
||||
# $(objtree)/$(obj) for including generated headers from checkin source files
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# $(obj) for including generated headers from checkin source files
|
||||
ifdef building_out_of_srctree
|
||||
hostc_flags += -I $(objtree)/$(obj)
|
||||
hostcxx_flags += -I $(objtree)/$(obj)
|
||||
endif
|
||||
hostc_flags += -I $(obj)
|
||||
hostcxx_flags += -I $(obj)
|
||||
endif
|
||||
|
||||
#####
|
||||
|
||||
+58
-4
@@ -191,15 +191,33 @@ _c_flags += $(if $(patsubst n%,, \
|
||||
-D__KCSAN_INSTRUMENT_BARRIERS__)
|
||||
endif
|
||||
|
||||
#
|
||||
# Enable AutoFDO build flags except some files or directories we don't want to
|
||||
# enable (depends on variables AUTOFDO_PROFILE_obj.o and AUTOFDO_PROFILE).
|
||||
#
|
||||
ifeq ($(CONFIG_AUTOFDO_CLANG),y)
|
||||
_c_flags += $(if $(patsubst n%,, \
|
||||
$(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(is-kernel-object)), \
|
||||
$(CFLAGS_AUTOFDO_CLANG))
|
||||
endif
|
||||
|
||||
#
|
||||
# Enable Propeller build flags except some files or directories we don't want to
|
||||
# enable (depends on variables AUTOFDO_PROPELLER_obj.o and PROPELLER_PROFILE).
|
||||
#
|
||||
ifdef CONFIG_PROPELLER_CLANG
|
||||
_c_flags += $(if $(patsubst n%,, \
|
||||
$(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(PROPELLER_PROFILE))$(is-kernel-object), \
|
||||
$(CFLAGS_PROPELLER_CLANG))
|
||||
endif
|
||||
|
||||
# $(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 += $(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))
|
||||
@@ -280,6 +298,42 @@ $(foreach m, $1, \
|
||||
$(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3))))
|
||||
endef
|
||||
|
||||
# Build commands
|
||||
# ===========================================================================
|
||||
# These are shared by some Makefile.* files.
|
||||
|
||||
objtool-enabled := y
|
||||
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
# objtool cannot process LLVM IR. Make $(LD) covert LLVM IR to ELF here.
|
||||
cmd_ld_single = $(if $(objtool-enabled), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
|
||||
endif
|
||||
|
||||
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
|
||||
$(cmd_ld_single) \
|
||||
$(cmd_objtool)
|
||||
|
||||
define rule_cc_o_c
|
||||
$(call cmd_and_fixdep,cc_o_c)
|
||||
$(call cmd,checksrc)
|
||||
$(call cmd,checkdoc)
|
||||
$(call cmd,gen_objtooldep)
|
||||
$(call cmd,gen_symversions_c)
|
||||
$(call cmd,record_mcount)
|
||||
$(call cmd,warn_shared_object)
|
||||
endef
|
||||
|
||||
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
|
||||
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool)
|
||||
|
||||
define rule_as_o_S
|
||||
$(call cmd_and_fixdep,as_o_S)
|
||||
$(call cmd,gen_objtooldep)
|
||||
$(call cmd,gen_symversions_S)
|
||||
$(call cmd,warn_shared_object)
|
||||
endef
|
||||
|
||||
# Copy a file
|
||||
# ===========================================================================
|
||||
# 'cp' preserves permissions. If you use it to copy a file in read-only srctree,
|
||||
@@ -371,10 +425,10 @@ quiet_cmd_lzo_with_size = LZO $@
|
||||
cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
|
||||
|
||||
quiet_cmd_lz4 = LZ4 $@
|
||||
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@
|
||||
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@
|
||||
|
||||
quiet_cmd_lz4_with_size = LZ4 $@
|
||||
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \
|
||||
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \
|
||||
$(size_append); } > $@
|
||||
|
||||
# U-Boot mkimage
|
||||
|
||||
+13
-18
@@ -6,14 +6,12 @@
|
||||
PHONY := __modfinal
|
||||
__modfinal:
|
||||
|
||||
include include/config/auto.conf
|
||||
include $(objtree)/include/config/auto.conf
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
# for c_flags
|
||||
include $(srctree)/scripts/Makefile.lib
|
||||
|
||||
# find all modules listed in modules.order
|
||||
modules := $(call read-file, $(MODORDER))
|
||||
modules := $(call read-file, modules.order)
|
||||
|
||||
__modfinal: $(modules:%.o=%.ko)
|
||||
@:
|
||||
@@ -22,30 +20,27 @@ __modfinal: $(modules:%.o=%.ko)
|
||||
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), $(c_flags)) -c -o $@ $<
|
||||
ccflags-remove-y := $(CC_FLAGS_CFI)
|
||||
|
||||
%.mod.o: %.mod.c FORCE
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
$(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
.module-common.o: $(srctree)/scripts/module-common.c FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
quiet_cmd_ld_ko_o = LD [M] $@
|
||||
cmd_ld_ko_o = \
|
||||
$(LD) -r $(KBUILD_LDFLAGS) \
|
||||
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
|
||||
-T scripts/module.lds -o $@ $(filter %.o, $^)
|
||||
-T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^)
|
||||
|
||||
quiet_cmd_btf_ko = BTF [M] $@
|
||||
cmd_btf_ko = \
|
||||
if [ ! -f vmlinux ]; then \
|
||||
if [ ! -f $(objtree)/vmlinux ]; then \
|
||||
printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
|
||||
else \
|
||||
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \
|
||||
$(RESOLVE_BTFIDS) -b vmlinux $@; \
|
||||
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \
|
||||
$(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \
|
||||
fi;
|
||||
|
||||
# Same as newer-prereqs, but allows to exclude specified extra dependencies
|
||||
@@ -57,13 +52,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
|
||||
printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
|
||||
|
||||
# Re-generate module BTFs if either module's .ko or vmlinux changed
|
||||
%.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
|
||||
+$(call if_changed_except,ld_ko_o,vmlinux)
|
||||
%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE
|
||||
+$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux)
|
||||
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
|
||||
+$(if $(newer-prereqs),$(call cmd,btf_ko))
|
||||
endif
|
||||
|
||||
targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o
|
||||
targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o
|
||||
|
||||
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
PHONY := __modinst
|
||||
__modinst:
|
||||
|
||||
include include/config/auto.conf
|
||||
include $(objtree)/include/config/auto.conf
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
install-y :=
|
||||
@@ -40,7 +40,7 @@ $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin.
|
||||
|
||||
endif
|
||||
|
||||
modules := $(call read-file, $(MODORDER))
|
||||
modules := $(call read-file, modules.order)
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
dst := $(MODLIB)/kernel
|
||||
@@ -59,7 +59,7 @@ suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
|
||||
suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
|
||||
endif
|
||||
|
||||
modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
|
||||
modules := $(patsubst %.o, $(dst)/%.ko$(suffix-y), $(modules))
|
||||
install-$(CONFIG_MODULES) += $(modules)
|
||||
|
||||
__modinst: $(install-y)
|
||||
@@ -119,7 +119,7 @@ endif
|
||||
# Create necessary directories
|
||||
$(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir)))
|
||||
|
||||
$(dst)/%.ko: $(extmod_prefix)%.ko FORCE
|
||||
$(dst)/%.ko: %.ko FORCE
|
||||
$(call cmd,install)
|
||||
$(call cmd,strip)
|
||||
$(call cmd,sign)
|
||||
|
||||
+12
-12
@@ -35,10 +35,10 @@
|
||||
PHONY := __modpost
|
||||
__modpost:
|
||||
|
||||
include include/config/auto.conf
|
||||
include $(objtree)/include/config/auto.conf
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
MODPOST = scripts/mod/modpost
|
||||
MODPOST = $(objtree)/scripts/mod/modpost
|
||||
|
||||
modpost-args = \
|
||||
$(if $(CONFIG_MODULES),-M) \
|
||||
@@ -46,7 +46,7 @@ modpost-args = \
|
||||
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
|
||||
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
|
||||
$(if $(KBUILD_MODPOST_WARN),-w) \
|
||||
$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
|
||||
$(if $(KBUILD_NSDEPS),-d modules.nsdeps) \
|
||||
$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \
|
||||
$(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \
|
||||
-o $@
|
||||
@@ -61,8 +61,8 @@ endif
|
||||
# Read out modules.order to pass in modpost.
|
||||
# Otherwise, allmodconfig would fail with "Argument list too long".
|
||||
ifdef KBUILD_MODULES
|
||||
modpost-args += -T $(MODORDER)
|
||||
modpost-deps += $(MODORDER)
|
||||
modpost-args += -T modules.order
|
||||
modpost-deps += modules.order
|
||||
endif
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
@@ -111,19 +111,19 @@ endif
|
||||
else
|
||||
|
||||
# set src + obj - they may be used in the modules's Makefile
|
||||
obj := $(KBUILD_EXTMOD)
|
||||
src := $(if $(VPATH),$(VPATH)/)$(obj)
|
||||
obj := .
|
||||
src := $(srcroot)
|
||||
|
||||
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
|
||||
include $(kbuild-file)
|
||||
|
||||
output-symdump := $(KBUILD_EXTMOD)/Module.symvers
|
||||
output-symdump := Module.symvers
|
||||
|
||||
ifeq ($(wildcard Module.symvers),)
|
||||
missing-input := Module.symvers
|
||||
ifeq ($(wildcard $(objtree)/Module.symvers),)
|
||||
missing-input := $(objtree)/Module.symvers
|
||||
else
|
||||
modpost-args += -i Module.symvers
|
||||
modpost-deps += Module.symvers
|
||||
modpost-args += -i $(objtree)/Module.symvers
|
||||
modpost-deps += $(objtree)/Module.symvers
|
||||
endif
|
||||
|
||||
modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS))
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# Enable available and selected Clang Propeller features.
|
||||
ifdef CLANG_PROPELLER_PROFILE_PREFIX
|
||||
CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections
|
||||
KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering
|
||||
else
|
||||
# Starting with Clang v20, the '-fbasic-block-sections=labels' option is
|
||||
# deprecated. Use the recommended '-fbasic-block-address-map' option.
|
||||
# Link: https://github.com/llvm/llvm-project/pull/110039
|
||||
ifeq ($(call clang-min-version, 200000),y)
|
||||
CFLAGS_PROPELLER_CLANG := -fbasic-block-address-map
|
||||
else
|
||||
CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels
|
||||
endif
|
||||
endif
|
||||
|
||||
# Propeller requires debug information to embed module names in the profiles.
|
||||
# If CONFIG_DEBUG_INFO is not enabled, set -gmlt option. Skip this for AutoFDO,
|
||||
# as the option should already be set.
|
||||
ifndef CONFIG_DEBUG_INFO
|
||||
ifndef CONFIG_AUTOFDO_CLANG
|
||||
CFLAGS_PROPELLER_CLANG += -gmlt
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LTO_CLANG_THIN
|
||||
ifdef CLANG_PROPELLER_PROFILE_PREFIX
|
||||
KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt
|
||||
else
|
||||
ifeq ($(call test-ge, $(CONFIG_LLD_VERSION), 200000),y)
|
||||
KBUILD_LDFLAGS += --lto-basic-block-address-map
|
||||
else
|
||||
KBUILD_LDFLAGS += --lto-basic-block-sections=labels
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
export CFLAGS_PROPELLER_CLANG
|
||||
@@ -5,17 +5,53 @@ __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)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
%.o: %.S FORCE
|
||||
$(call if_changed_rule,as_o_S)
|
||||
|
||||
# Built-in dtb
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
quiet_cmd_wrap_dtbs = WRAP $@
|
||||
cmd_wrap_dtbs = { \
|
||||
echo '\#include <asm-generic/vmlinux.lds.h>'; \
|
||||
echo '.section .dtb.init.rodata,"a"'; \
|
||||
while read dtb; do \
|
||||
symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \
|
||||
echo '.balign STRUCT_ALIGNMENT'; \
|
||||
echo ".global $${symbase}_begin"; \
|
||||
echo "$${symbase}_begin:"; \
|
||||
echo '.incbin "'$$dtb'" '; \
|
||||
echo ".global $${symbase}_end"; \
|
||||
echo "$${symbase}_end:"; \
|
||||
done < $<; \
|
||||
} > $@
|
||||
|
||||
.builtin-dtbs.S: .builtin-dtbs-list FORCE
|
||||
$(call if_changed,wrap_dtbs)
|
||||
|
||||
quiet_cmd_gen_dtbs_list = GEN $@
|
||||
cmd_gen_dtbs_list = \
|
||||
$(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@
|
||||
|
||||
.builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE
|
||||
$(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list))
|
||||
|
||||
targets += .builtin-dtbs-list
|
||||
|
||||
ifdef CONFIG_GENERIC_BUILTIN_DTB
|
||||
targets += .builtin-dtbs.S .builtin-dtbs.o
|
||||
vmlinux: .builtin-dtbs.o
|
||||
endif
|
||||
|
||||
# vmlinux
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ifdef CONFIG_MODULES
|
||||
targets += .vmlinux.export.o
|
||||
@@ -39,6 +75,9 @@ cmd_link_vmlinux = \
|
||||
targets += vmlinux
|
||||
vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
|
||||
+$(call if_changed_dep,link_vmlinux)
|
||||
ifdef CONFIG_DEBUG_INFO_BTF
|
||||
vmlinux: $(RESOLVE_BTFIDS)
|
||||
endif
|
||||
|
||||
# module.builtin.ranges
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
+1
-5
@@ -80,11 +80,7 @@ command results in a shift count error.'
|
||||
NPROC=1
|
||||
else
|
||||
ONLINE=0
|
||||
if [ "$KBUILD_EXTMOD" = "" ] ; then
|
||||
OPTIONS="--dir $srctree $COCCIINCLUDE"
|
||||
else
|
||||
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
|
||||
fi
|
||||
OPTIONS="--dir $srcroot $COCCIINCLUDE"
|
||||
|
||||
# Use only one thread per core by default if hyperthreading is enabled
|
||||
THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ KERNELRELEASE=$1
|
||||
|
||||
: ${DEPMOD:=depmod}
|
||||
|
||||
if ! test -r System.map ; then
|
||||
if ! test -r "${objtree}/System.map" ; then
|
||||
echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2
|
||||
exit 0
|
||||
fi
|
||||
@@ -25,7 +25,7 @@ if [ -z $(command -v $DEPMOD) ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set -- -ae -F System.map
|
||||
set -- -ae -F "${objtree}/System.map"
|
||||
if test -n "$INSTALL_MOD_PATH"; then
|
||||
set -- "$@" -b "$INSTALL_MOD_PATH"
|
||||
fi
|
||||
|
||||
+45
-44
@@ -632,54 +632,55 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
|
||||
void export_symbol(const char *name)
|
||||
{
|
||||
struct symbol *sym;
|
||||
unsigned long crc;
|
||||
int has_changed = 0;
|
||||
|
||||
sym = find_symbol(name, SYM_NORMAL, 0);
|
||||
if (!sym)
|
||||
if (!sym) {
|
||||
error_with_pos("export undefined symbol %s", name);
|
||||
else {
|
||||
unsigned long crc;
|
||||
int has_changed = 0;
|
||||
|
||||
if (flag_dump_defs)
|
||||
fprintf(debugfile, "Export %s == <", name);
|
||||
|
||||
expansion_trail = (struct symbol *)-1L;
|
||||
|
||||
sym->expansion_trail = expansion_trail;
|
||||
expansion_trail = sym;
|
||||
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
|
||||
|
||||
sym = expansion_trail;
|
||||
while (sym != (struct symbol *)-1L) {
|
||||
struct symbol *n = sym->expansion_trail;
|
||||
|
||||
if (sym->status != STATUS_UNCHANGED) {
|
||||
if (!has_changed) {
|
||||
print_location();
|
||||
fprintf(stderr, "%s: %s: modversion "
|
||||
"changed because of changes "
|
||||
"in ", flag_preserve ? "error" :
|
||||
"warning", name);
|
||||
} else
|
||||
fprintf(stderr, ", ");
|
||||
print_type_name(sym->type, sym->name);
|
||||
if (sym->status == STATUS_DEFINED)
|
||||
fprintf(stderr, " (became defined)");
|
||||
has_changed = 1;
|
||||
if (flag_preserve)
|
||||
errors++;
|
||||
}
|
||||
sym->expansion_trail = 0;
|
||||
sym = n;
|
||||
}
|
||||
if (has_changed)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (flag_dump_defs)
|
||||
fputs(">\n", debugfile);
|
||||
|
||||
printf("#SYMVER %s 0x%08lx\n", name, crc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag_dump_defs)
|
||||
fprintf(debugfile, "Export %s == <", name);
|
||||
|
||||
expansion_trail = (struct symbol *)-1L;
|
||||
|
||||
sym->expansion_trail = expansion_trail;
|
||||
expansion_trail = sym;
|
||||
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
|
||||
|
||||
sym = expansion_trail;
|
||||
while (sym != (struct symbol *)-1L) {
|
||||
struct symbol *n = sym->expansion_trail;
|
||||
|
||||
if (sym->status != STATUS_UNCHANGED) {
|
||||
if (!has_changed) {
|
||||
print_location();
|
||||
fprintf(stderr,
|
||||
"%s: %s: modversion changed because of changes in ",
|
||||
flag_preserve ? "error" : "warning",
|
||||
name);
|
||||
} else {
|
||||
fprintf(stderr, ", ");
|
||||
}
|
||||
print_type_name(sym->type, sym->name);
|
||||
if (sym->status == STATUS_DEFINED)
|
||||
fprintf(stderr, " (became defined)");
|
||||
has_changed = 1;
|
||||
if (flag_preserve)
|
||||
errors++;
|
||||
}
|
||||
sym->expansion_trail = 0;
|
||||
sym = n;
|
||||
}
|
||||
if (has_changed)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (flag_dump_defs)
|
||||
fputs(">\n", debugfile);
|
||||
|
||||
printf("#SYMVER %s 0x%08lx\n", name, crc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
@@ -23,7 +23,6 @@ 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
|
||||
|
||||
@@ -628,7 +628,7 @@ static const struct option long_opts[] = {
|
||||
|
||||
static void conf_usage(const char *progname)
|
||||
{
|
||||
printf("Usage: %s [options] <kconfig-file>\n", progname);
|
||||
printf("Usage: %s [options] kconfig_file\n", progname);
|
||||
printf("\n");
|
||||
printf("Generic options:\n");
|
||||
printf(" -h, --help Print this message and exit.\n");
|
||||
@@ -653,6 +653,9 @@ static void conf_usage(const char *progname)
|
||||
printf(" --mod2yesconfig Change answers from mod to yes if possible\n");
|
||||
printf(" --mod2noconfig Change answers from mod to no if possible\n");
|
||||
printf(" (If none of the above is given, --oldaskconfig is the default)\n");
|
||||
printf("\n");
|
||||
printf("Arguments:\n");
|
||||
printf(" kconfig_file Top-level Kconfig file.\n");
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
|
||||
@@ -34,6 +34,7 @@ bool sym_string_valid(struct symbol *sym, const char *newval);
|
||||
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(const struct symbol *sym);
|
||||
struct menu *sym_get_prompt_menu(const struct symbol *sym);
|
||||
struct menu *sym_get_choice_menu(const struct symbol *sym);
|
||||
const char * sym_get_string_value(struct symbol *sym);
|
||||
|
||||
|
||||
@@ -467,7 +467,7 @@ static void handle_f9(int *key, struct menu *current_item)
|
||||
return;
|
||||
}
|
||||
|
||||
/* return != 0 to indicate the key was handles */
|
||||
/* return != 0 to indicate the key was handled */
|
||||
static int process_special_keys(int *key, struct menu *menu)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -277,6 +277,15 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
|
||||
case KEY_RIGHT:
|
||||
menu_driver(menu, REQ_RIGHT_ITEM);
|
||||
break;
|
||||
case 9: /* TAB */
|
||||
if (btn_num > 1) {
|
||||
/* cycle through buttons */
|
||||
if (item_index(current_item(menu)) == btn_num - 1)
|
||||
menu_driver(menu, REQ_FIRST_ITEM);
|
||||
else
|
||||
menu_driver(menu, REQ_NEXT_ITEM);
|
||||
}
|
||||
break;
|
||||
case 10: /* ENTER */
|
||||
case 27: /* ESCAPE */
|
||||
case ' ':
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
int cdebug = PRINTD;
|
||||
|
||||
static void yyerror(const char *err);
|
||||
static void zconfprint(const char *err, ...);
|
||||
static void zconf_error(const char *err, ...);
|
||||
static bool zconf_endtoken(const char *tokenname,
|
||||
const char *expected_tokenname);
|
||||
@@ -183,7 +182,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
|
||||
if (current_entry->prompt)
|
||||
current_entry->prompt->type = P_MENU;
|
||||
else
|
||||
zconfprint("warning: menuconfig statement without prompt");
|
||||
zconf_error("menuconfig statement without prompt");
|
||||
printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
|
||||
};
|
||||
|
||||
@@ -293,12 +292,6 @@ choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
|
||||
printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
|
||||
};
|
||||
|
||||
choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL
|
||||
{
|
||||
menu_add_prompt(P_PROMPT, $2, $3);
|
||||
printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno);
|
||||
};
|
||||
|
||||
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
|
||||
{
|
||||
menu_add_symbol(P_DEFAULT, $2, $3);
|
||||
@@ -408,14 +401,14 @@ help: help_start T_HELPTEXT
|
||||
{
|
||||
if (current_entry->help) {
|
||||
free(current_entry->help);
|
||||
zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
|
||||
current_entry->sym->name ?: "<choice>");
|
||||
zconf_error("'%s' defined with more than one help text",
|
||||
current_entry->sym->name ?: "<choice>");
|
||||
}
|
||||
|
||||
/* Is the help text empty or all whitespace? */
|
||||
if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
|
||||
zconfprint("warning: '%s' defined with blank help text",
|
||||
current_entry->sym->name ?: "<choice>");
|
||||
zconf_error("'%s' defined with blank help text",
|
||||
current_entry->sym->name ?: "<choice>");
|
||||
|
||||
current_entry->help = $2;
|
||||
};
|
||||
@@ -598,17 +591,6 @@ static bool zconf_endtoken(const char *tokenname,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void zconfprint(const char *err, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
|
||||
va_start(ap, err);
|
||||
vfprintf(stderr, err, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void zconf_error(const char *err, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
+63
-145
@@ -110,7 +110,7 @@ void ConfigItem::updateMenu(void)
|
||||
|
||||
if (prop) switch (prop->type) {
|
||||
case P_MENU:
|
||||
if (list->mode == singleMode || list->mode == symbolMode) {
|
||||
if (list->mode == singleMode) {
|
||||
/* a menuconfig entry is displayed differently
|
||||
* depending whether it's at the view root or a child.
|
||||
*/
|
||||
@@ -159,7 +159,7 @@ void ConfigItem::updateMenu(void)
|
||||
ch = 'M';
|
||||
break;
|
||||
default:
|
||||
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
|
||||
if (sym_is_choice_value(sym))
|
||||
setIcon(promptColIdx, choiceNoIcon);
|
||||
else
|
||||
setIcon(promptColIdx, symbolNoIcon);
|
||||
@@ -175,17 +175,16 @@ void ConfigItem::updateMenu(void)
|
||||
setText(dataColIdx, sym_get_string_value(sym));
|
||||
break;
|
||||
}
|
||||
if (!sym_has_value(sym) && visible)
|
||||
if (!sym_has_value(sym))
|
||||
prompt += " (NEW)";
|
||||
set_prompt:
|
||||
setText(promptColIdx, prompt);
|
||||
}
|
||||
|
||||
void ConfigItem::testUpdateMenu(bool v)
|
||||
void ConfigItem::testUpdateMenu(void)
|
||||
{
|
||||
ConfigItem* i;
|
||||
|
||||
visible = v;
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
@@ -307,7 +306,6 @@ ConfigList::ConfigList(QWidget *parent, const char *name)
|
||||
{
|
||||
setObjectName(name);
|
||||
setSortingEnabled(false);
|
||||
setRootIsDecorated(true);
|
||||
|
||||
setVerticalScrollMode(ScrollPerPixel);
|
||||
setHorizontalScrollMode(ScrollPerPixel);
|
||||
@@ -430,27 +428,26 @@ void ConfigList::updateList()
|
||||
item = (ConfigItem*)(*it);
|
||||
if (!item->menu)
|
||||
continue;
|
||||
item->testUpdateMenu(menu_is_visible(item->menu));
|
||||
item->testUpdateMenu();
|
||||
|
||||
++it;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (rootEntry != &rootmenu && (mode == singleMode ||
|
||||
(mode == symbolMode && rootEntry->parent != &rootmenu))) {
|
||||
if (rootEntry != &rootmenu && mode == singleMode) {
|
||||
item = (ConfigItem *)topLevelItem(0);
|
||||
if (!item)
|
||||
item = new ConfigItem(this, 0, true);
|
||||
item = new ConfigItem(this, 0);
|
||||
last = item;
|
||||
}
|
||||
if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
|
||||
rootEntry->sym && rootEntry->prompt) {
|
||||
item = last ? last->nextSibling() : nullptr;
|
||||
if (!item)
|
||||
item = new ConfigItem(this, last, rootEntry, true);
|
||||
item = new ConfigItem(this, last, rootEntry);
|
||||
else
|
||||
item->testUpdateMenu(true);
|
||||
item->testUpdateMenu();
|
||||
|
||||
updateMenuList(item, rootEntry);
|
||||
update();
|
||||
@@ -599,7 +596,6 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
|
||||
struct menu* child;
|
||||
ConfigItem* item;
|
||||
ConfigItem* last;
|
||||
bool visible;
|
||||
enum prop_type type;
|
||||
|
||||
if (!menu) {
|
||||
@@ -631,14 +627,13 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
|
||||
break;
|
||||
}
|
||||
|
||||
visible = menu_is_visible(child);
|
||||
if (!menuSkip(child)) {
|
||||
if (!child->sym && !child->list && !child->prompt)
|
||||
continue;
|
||||
if (!item || item->menu != child)
|
||||
item = new ConfigItem(parent, last, child, visible);
|
||||
item = new ConfigItem(parent, last, child);
|
||||
else
|
||||
item->testUpdateMenu(visible);
|
||||
item->testUpdateMenu();
|
||||
|
||||
if (mode == fullMode || mode == menuMode || type != P_MENU)
|
||||
updateMenuList(item, child);
|
||||
@@ -664,7 +659,6 @@ void ConfigList::updateMenuList(struct menu *menu)
|
||||
struct menu* child;
|
||||
ConfigItem* item;
|
||||
ConfigItem* last;
|
||||
bool visible;
|
||||
enum prop_type type;
|
||||
|
||||
if (!menu) {
|
||||
@@ -696,14 +690,13 @@ void ConfigList::updateMenuList(struct menu *menu)
|
||||
break;
|
||||
}
|
||||
|
||||
visible = menu_is_visible(child);
|
||||
if (!menuSkip(child)) {
|
||||
if (!child->sym && !child->list && !child->prompt)
|
||||
continue;
|
||||
if (!item || item->menu != child)
|
||||
item = new ConfigItem(this, last, child, visible);
|
||||
item = new ConfigItem(this, last, child);
|
||||
else
|
||||
item->testUpdateMenu(visible);
|
||||
item->testUpdateMenu();
|
||||
|
||||
if (mode == fullMode || mode == menuMode || type != P_MENU)
|
||||
updateMenuList(item, child);
|
||||
@@ -731,7 +724,7 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
|
||||
struct menu *menu;
|
||||
enum prop_type type;
|
||||
|
||||
if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
|
||||
if (ev->key() == Qt::Key_Escape && mode == singleMode) {
|
||||
emit parentSelected();
|
||||
ev->accept();
|
||||
return;
|
||||
@@ -781,13 +774,6 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
|
||||
ev->accept();
|
||||
}
|
||||
|
||||
void ConfigList::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
//QPoint p(contentsToViewport(e->pos()));
|
||||
//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
|
||||
Parent::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void ConfigList::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
QPoint p = e->pos();
|
||||
@@ -834,13 +820,6 @@ skip:
|
||||
Parent::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void ConfigList::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
//QPoint p(contentsToViewport(e->pos()));
|
||||
//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
|
||||
Parent::mouseMoveEvent(e);
|
||||
}
|
||||
|
||||
void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
|
||||
{
|
||||
QPoint p = e->pos();
|
||||
@@ -1022,7 +1001,7 @@ void ConfigInfoView::menuInfo(void)
|
||||
if (sym->name) {
|
||||
stream << " (";
|
||||
if (showDebug())
|
||||
stream << "<a href=\"s" << sym->name << "\">";
|
||||
stream << "<a href=\"" << sym->name << "\">";
|
||||
stream << print_filter(sym->name);
|
||||
if (showDebug())
|
||||
stream << "</a>";
|
||||
@@ -1031,7 +1010,7 @@ void ConfigInfoView::menuInfo(void)
|
||||
} else if (sym->name) {
|
||||
stream << "<big><b>";
|
||||
if (showDebug())
|
||||
stream << "<a href=\"s" << sym->name << "\">";
|
||||
stream << "<a href=\"" << sym->name << "\">";
|
||||
stream << print_filter(sym->name);
|
||||
if (showDebug())
|
||||
stream << "</a>";
|
||||
@@ -1086,9 +1065,9 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
|
||||
switch (prop->type) {
|
||||
case P_PROMPT:
|
||||
case P_MENU:
|
||||
stream << "prompt: <a href=\"m" << sym->name << "\">";
|
||||
stream << "prompt: ";
|
||||
stream << print_filter(prop->text);
|
||||
stream << "</a><br>";
|
||||
stream << "<br>";
|
||||
break;
|
||||
case P_DEFAULT:
|
||||
case P_SELECT:
|
||||
@@ -1122,28 +1101,19 @@ QString ConfigInfoView::print_filter(const QString &str)
|
||||
{
|
||||
QRegularExpression re("[<>&\"\\n]");
|
||||
QString res = str;
|
||||
|
||||
QHash<QChar, QString> patterns;
|
||||
patterns['<'] = "<";
|
||||
patterns['>'] = ">";
|
||||
patterns['&'] = "&";
|
||||
patterns['"'] = """;
|
||||
patterns['\n'] = "<br>";
|
||||
|
||||
for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
|
||||
switch (res[i].toLatin1()) {
|
||||
case '<':
|
||||
res.replace(i, 1, "<");
|
||||
i += 4;
|
||||
break;
|
||||
case '>':
|
||||
res.replace(i, 1, ">");
|
||||
i += 4;
|
||||
break;
|
||||
case '&':
|
||||
res.replace(i, 1, "&");
|
||||
i += 5;
|
||||
break;
|
||||
case '"':
|
||||
res.replace(i, 1, """);
|
||||
i += 6;
|
||||
break;
|
||||
case '\n':
|
||||
res.replace(i, 1, "<br>");
|
||||
i += 4;
|
||||
break;
|
||||
const QString n = patterns.value(res[i], QString());
|
||||
if (!n.isEmpty()) {
|
||||
res.replace(i, 1, n);
|
||||
i += n.length();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@@ -1154,7 +1124,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
|
||||
QTextStream *stream = reinterpret_cast<QTextStream *>(data);
|
||||
|
||||
if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
|
||||
*stream << "<a href=\"s" << sym->name << "\">";
|
||||
*stream << "<a href=\"" << sym->name << "\">";
|
||||
*stream << print_filter(str);
|
||||
*stream << "</a>";
|
||||
} else {
|
||||
@@ -1164,39 +1134,11 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
|
||||
|
||||
void ConfigInfoView::clicked(const QUrl &url)
|
||||
{
|
||||
QByteArray str = url.toEncoded();
|
||||
const std::size_t count = str.size();
|
||||
char *data = new char[count + 2]; // '$' + '\0'
|
||||
struct symbol **result;
|
||||
struct menu *m = NULL;
|
||||
struct menu *m;
|
||||
|
||||
if (count < 1) {
|
||||
delete[] data;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(data, str.constData(), count);
|
||||
data[count] = '\0';
|
||||
|
||||
/* Seek for exact match */
|
||||
data[0] = '^';
|
||||
strcat(data, "$");
|
||||
result = sym_re_search(data);
|
||||
if (!result) {
|
||||
delete[] data;
|
||||
return;
|
||||
}
|
||||
|
||||
sym = *result;
|
||||
|
||||
/* Seek for the menu which holds the symbol */
|
||||
for (struct property *prop = sym->prop; prop; prop = prop->next) {
|
||||
if (prop->type != P_PROMPT && prop->type != P_MENU)
|
||||
continue;
|
||||
m = prop->menu;
|
||||
break;
|
||||
}
|
||||
sym = sym_find(url.toEncoded().constData());
|
||||
|
||||
m = sym_get_prompt_menu(sym);
|
||||
if (!m) {
|
||||
/* Symbol is not visible as a menu */
|
||||
symbolInfo();
|
||||
@@ -1204,9 +1146,6 @@ void ConfigInfoView::clicked(const QUrl &url)
|
||||
} else {
|
||||
emit menuSelected(m);
|
||||
}
|
||||
|
||||
free(result);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
|
||||
@@ -1240,8 +1179,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
|
||||
layout2->addWidget(searchButton);
|
||||
layout1->addLayout(layout2);
|
||||
|
||||
split = new QSplitter(this);
|
||||
split->setOrientation(Qt::Vertical);
|
||||
split = new QSplitter(Qt::Vertical, this);
|
||||
list = new ConfigList(split, "search");
|
||||
list->mode = listMode;
|
||||
info = new ConfigInfoView(split, "search");
|
||||
@@ -1300,8 +1238,7 @@ void ConfigSearchWindow::search(void)
|
||||
return;
|
||||
for (p = result; *p; p++) {
|
||||
for_all_prompts((*p), prop)
|
||||
lastItem = new ConfigItem(list, lastItem, prop->menu,
|
||||
menu_is_visible(prop->menu));
|
||||
lastItem = new ConfigItem(list, lastItem, prop->menu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1341,61 +1278,56 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
|
||||
|
||||
QWidget *widget = new QWidget(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||
setCentralWidget(widget);
|
||||
|
||||
split1 = new QSplitter(widget);
|
||||
split1->setOrientation(Qt::Horizontal);
|
||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||
|
||||
split2 = new QSplitter(Qt::Vertical, widget);
|
||||
layout->addWidget(split2);
|
||||
split2->setChildrenCollapsible(false);
|
||||
|
||||
split1 = new QSplitter(Qt::Horizontal, split2);
|
||||
split1->setChildrenCollapsible(false);
|
||||
|
||||
menuList = new ConfigList(widget, "menu");
|
||||
configList = new ConfigList(split1, "config");
|
||||
|
||||
split2 = new QSplitter(widget);
|
||||
split2->setChildrenCollapsible(false);
|
||||
split2->setOrientation(Qt::Vertical);
|
||||
|
||||
// create config tree
|
||||
configList = new ConfigList(widget, "config");
|
||||
|
||||
helpText = new ConfigInfoView(widget, "help");
|
||||
|
||||
layout->addWidget(split2);
|
||||
split2->addWidget(split1);
|
||||
split1->addWidget(configList);
|
||||
split1->addWidget(menuList);
|
||||
split2->addWidget(helpText);
|
||||
menuList = new ConfigList(split1, "menu");
|
||||
|
||||
helpText = new ConfigInfoView(split2, "help");
|
||||
setTabOrder(configList, helpText);
|
||||
|
||||
configList->setFocus();
|
||||
|
||||
backAction = new QAction(QPixmap(xpm_back), "Back", this);
|
||||
backAction->setShortcut(QKeySequence::Back);
|
||||
connect(backAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::goBack);
|
||||
|
||||
QAction *quitAction = new QAction("&Quit", this);
|
||||
quitAction->setShortcut(Qt::CTRL | Qt::Key_Q);
|
||||
quitAction->setShortcut(QKeySequence::Quit);
|
||||
connect(quitAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::close);
|
||||
|
||||
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
|
||||
loadAction->setShortcut(Qt::CTRL | Qt::Key_L);
|
||||
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this);
|
||||
loadAction->setShortcut(QKeySequence::Open);
|
||||
connect(loadAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::loadConfig);
|
||||
|
||||
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
|
||||
saveAction->setShortcut(Qt::CTRL | Qt::Key_S);
|
||||
saveAction->setShortcut(QKeySequence::Save);
|
||||
connect(saveAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::saveConfig);
|
||||
|
||||
conf_set_changed_callback(conf_changed);
|
||||
|
||||
configname = xstrdup(conf_get_configname());
|
||||
configname = conf_get_configname();
|
||||
|
||||
QAction *saveAsAction = new QAction("Save &As...", this);
|
||||
saveAsAction->setShortcut(QKeySequence::SaveAs);
|
||||
connect(saveAsAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::saveConfigAs);
|
||||
QAction *searchAction = new QAction("&Find", this);
|
||||
searchAction->setShortcut(Qt::CTRL | Qt::Key_F);
|
||||
searchAction->setShortcut(QKeySequence::Find);
|
||||
connect(searchAction, &QAction::triggered,
|
||||
this, &ConfigMainWindow::searchConfig);
|
||||
singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
|
||||
@@ -1505,6 +1437,9 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
connect(helpText, &ConfigInfoView::menuSelected,
|
||||
this, &ConfigMainWindow::setMenuLink);
|
||||
|
||||
connect(configApp, &QApplication::aboutToQuit,
|
||||
this, &ConfigMainWindow::saveSettings);
|
||||
|
||||
conf_read(NULL);
|
||||
|
||||
QString listMode = configSettings->value("/listMode", "symbol").toString();
|
||||
@@ -1528,28 +1463,22 @@ ConfigMainWindow::ConfigMainWindow(void)
|
||||
void ConfigMainWindow::loadConfig(void)
|
||||
{
|
||||
QString str;
|
||||
QByteArray ba;
|
||||
const char *name;
|
||||
|
||||
str = QFileDialog::getOpenFileName(this, "", configname);
|
||||
if (str.isNull())
|
||||
return;
|
||||
|
||||
ba = str.toLocal8Bit();
|
||||
name = ba.data();
|
||||
|
||||
if (conf_read(name))
|
||||
if (conf_read(str.toLocal8Bit().constData()))
|
||||
QMessageBox::information(this, "qconf", "Unable to load configuration!");
|
||||
|
||||
free(configname);
|
||||
configname = xstrdup(name);
|
||||
configname = str;
|
||||
|
||||
ConfigList::updateListAllForAll();
|
||||
}
|
||||
|
||||
bool ConfigMainWindow::saveConfig(void)
|
||||
{
|
||||
if (conf_write(configname)) {
|
||||
if (conf_write(configname.toLocal8Bit().constData())) {
|
||||
QMessageBox::information(this, "qconf", "Unable to save configuration!");
|
||||
return false;
|
||||
}
|
||||
@@ -1561,23 +1490,17 @@ bool ConfigMainWindow::saveConfig(void)
|
||||
void ConfigMainWindow::saveConfigAs(void)
|
||||
{
|
||||
QString str;
|
||||
QByteArray ba;
|
||||
const char *name;
|
||||
|
||||
str = QFileDialog::getSaveFileName(this, "", configname);
|
||||
if (str.isNull())
|
||||
return;
|
||||
|
||||
ba = str.toLocal8Bit();
|
||||
name = ba.data();
|
||||
|
||||
if (conf_write(name)) {
|
||||
if (conf_write(str.toLocal8Bit().constData())) {
|
||||
QMessageBox::information(this, "qconf", "Unable to save configuration!");
|
||||
}
|
||||
conf_write_autoconf(0);
|
||||
|
||||
free(configname);
|
||||
configname = xstrdup(name);
|
||||
configname = str;
|
||||
}
|
||||
|
||||
void ConfigMainWindow::searchConfig(void)
|
||||
@@ -1662,9 +1585,6 @@ void ConfigMainWindow::listFocusChanged(void)
|
||||
|
||||
void ConfigMainWindow::goBack(void)
|
||||
{
|
||||
if (configList->rootEntry == &rootmenu)
|
||||
return;
|
||||
|
||||
configList->setParentMenu();
|
||||
}
|
||||
|
||||
@@ -1905,8 +1825,6 @@ int main(int ac, char** av)
|
||||
v = new ConfigMainWindow();
|
||||
|
||||
//zconfdump(stdout);
|
||||
configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
|
||||
configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
|
||||
|
||||
v->show();
|
||||
configApp->exec();
|
||||
|
||||
+8
-11
@@ -55,9 +55,7 @@ public:
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
void focusInEvent(QFocusEvent *e);
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
@@ -116,25 +114,25 @@ public:
|
||||
class ConfigItem : public QTreeWidgetItem {
|
||||
typedef class QTreeWidgetItem Parent;
|
||||
public:
|
||||
ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
|
||||
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
|
||||
ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m)
|
||||
: Parent(parent, after), nextItem(0), menu(m), goParent(false)
|
||||
{
|
||||
init();
|
||||
}
|
||||
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
|
||||
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
|
||||
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m)
|
||||
: Parent(parent, after), nextItem(0), menu(m), goParent(false)
|
||||
{
|
||||
init();
|
||||
}
|
||||
ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
|
||||
: Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
|
||||
ConfigItem(ConfigList *parent, ConfigItem *after)
|
||||
: Parent(parent, after), nextItem(0), menu(0), goParent(true)
|
||||
{
|
||||
init();
|
||||
}
|
||||
~ConfigItem(void);
|
||||
void init(void);
|
||||
void updateMenu(void);
|
||||
void testUpdateMenu(bool v);
|
||||
void testUpdateMenu(void);
|
||||
ConfigList* listView() const
|
||||
{
|
||||
return (ConfigList*)Parent::treeWidget();
|
||||
@@ -161,7 +159,6 @@ public:
|
||||
|
||||
ConfigItem* nextItem;
|
||||
struct menu *menu;
|
||||
bool visible;
|
||||
bool goParent;
|
||||
|
||||
static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon;
|
||||
@@ -237,7 +234,7 @@ protected:
|
||||
class ConfigMainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
char *configname;
|
||||
QString configname;
|
||||
static QAction *saveAction;
|
||||
static void conf_changed(bool);
|
||||
public:
|
||||
|
||||
@@ -144,6 +144,7 @@ my %selects;
|
||||
my %prompts;
|
||||
my %objects;
|
||||
my %config2kfile;
|
||||
my %defaults;
|
||||
my $var;
|
||||
my $iflevel = 0;
|
||||
my @ifdeps;
|
||||
@@ -220,8 +221,9 @@ sub read_kconfig {
|
||||
$depends{$config} = $1;
|
||||
} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
|
||||
$depends{$config} .= " " . $1;
|
||||
} elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
|
||||
} elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
|
||||
my $dep = $3;
|
||||
$defaults{$config} = 1;
|
||||
if ($dep !~ /^\s*(y|m|n)\s*$/) {
|
||||
$dep =~ s/.*\sif\s+//;
|
||||
$depends{$config} .= " " . $dep;
|
||||
@@ -503,7 +505,7 @@ sub parse_config_selects
|
||||
|
||||
# Check if something other than a module selects this config
|
||||
if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") {
|
||||
dprint "$conf (non module) selects config, we are good\n";
|
||||
dprint "$conf (non module) selects $config, we are good\n";
|
||||
# we are good with this
|
||||
return;
|
||||
}
|
||||
@@ -523,8 +525,16 @@ sub parse_config_selects
|
||||
|
||||
# If no possible config selected this, then something happened.
|
||||
if (!defined($next_config)) {
|
||||
print STDERR "WARNING: $config is required, but nothing in the\n";
|
||||
print STDERR " current config selects it.\n";
|
||||
|
||||
# Some config options have no prompt, and nothing selects them, but
|
||||
# they stay turned on once the final checks for the configs
|
||||
# are done. These configs have a default option, so turn off the
|
||||
# warnings for configs with default options.
|
||||
if (!defined($defaults{$config})) {
|
||||
print STDERR "WARNING: $config is required, but nothing in the\n";
|
||||
print STDERR " current config selects it.\n";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,24 @@ const char *sym_type_name(enum symbol_type type)
|
||||
return "???";
|
||||
}
|
||||
|
||||
/**
|
||||
* sym_get_prompt_menu - get the menu entry with a prompt
|
||||
*
|
||||
* @sym: a symbol pointer
|
||||
*
|
||||
* Return: the menu entry with a prompt.
|
||||
*/
|
||||
struct menu *sym_get_prompt_menu(const struct symbol *sym)
|
||||
{
|
||||
struct menu *m;
|
||||
|
||||
list_for_each_entry(m, &sym->menus, link)
|
||||
if (m->prompt)
|
||||
return m;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* sym_get_choice_menu - get the parent choice menu if present
|
||||
*
|
||||
@@ -80,18 +98,12 @@ const char *sym_type_name(enum symbol_type type)
|
||||
struct menu *sym_get_choice_menu(const 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;
|
||||
}
|
||||
|
||||
menu = sym_get_prompt_menu(sym);
|
||||
if (!menu)
|
||||
return NULL;
|
||||
|
||||
|
||||
+10
-6
@@ -68,6 +68,10 @@ vmlinux_link()
|
||||
libs="${KBUILD_VMLINUX_LIBS}"
|
||||
fi
|
||||
|
||||
if is_enabled CONFIG_GENERIC_BUILTIN_DTB; then
|
||||
objs="${objs} .builtin-dtbs.o"
|
||||
fi
|
||||
|
||||
if is_enabled CONFIG_MODULES; then
|
||||
objs="${objs} .vmlinux.export.o"
|
||||
fi
|
||||
@@ -208,8 +212,8 @@ kallsymso=
|
||||
strip_debug=
|
||||
|
||||
if is_enabled CONFIG_KALLSYMS; then
|
||||
true > .tmp_vmlinux.kallsyms0.syms
|
||||
kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms
|
||||
true > .tmp_vmlinux0.syms
|
||||
kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms
|
||||
fi
|
||||
|
||||
if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then
|
||||
@@ -236,14 +240,14 @@ if is_enabled CONFIG_KALLSYMS; then
|
||||
# Generate section listing all symbols and add it into vmlinux
|
||||
# It's a four step process:
|
||||
# 0) Generate a dummy __kallsyms with empty symbol list.
|
||||
# 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections,
|
||||
# 1) Link .tmp_vmlinux1.kallsyms so it has all symbols and sections,
|
||||
# with a dummy __kallsyms.
|
||||
# Running kallsyms on that gives us .tmp_kallsyms1.o with
|
||||
# Running kallsyms on that gives us .tmp_vmlinux1.kallsyms.o with
|
||||
# the right size
|
||||
# 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of
|
||||
# 2) Link .tmp_vmlinux2.kallsyms so it now has a __kallsyms section of
|
||||
# the right size, but due to the added section, some
|
||||
# addresses have shifted.
|
||||
# From here, we generate a correct .tmp_vmlinux.kallsyms2.o
|
||||
# From here, we generate a correct .tmp_vmlinux2.kallsyms.o
|
||||
# 3) That link may have expanded the kernel image enough that
|
||||
# more linker branch stubs / trampolines had to be added, which
|
||||
# introduces new names, which further expands kallsyms. Do another
|
||||
|
||||
+317
-462
File diff suppressed because it is too large
Load Diff
+13
-18
@@ -21,6 +21,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <hash.h>
|
||||
#include <hashtable.h>
|
||||
#include <list.h>
|
||||
#include <xalloc.h>
|
||||
@@ -176,6 +177,7 @@ static struct module *new_module(const char *name, size_t namelen)
|
||||
INIT_LIST_HEAD(&mod->unresolved_symbols);
|
||||
INIT_LIST_HEAD(&mod->missing_namespaces);
|
||||
INIT_LIST_HEAD(&mod->imported_namespaces);
|
||||
INIT_LIST_HEAD(&mod->aliases);
|
||||
|
||||
memcpy(mod->name, name, namelen);
|
||||
mod->name[namelen] = '\0';
|
||||
@@ -209,19 +211,6 @@ struct symbol {
|
||||
|
||||
static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10);
|
||||
|
||||
/* This is based on the hash algorithm from gdbm, via tdb */
|
||||
static inline unsigned int tdb_hash(const char *name)
|
||||
{
|
||||
unsigned value; /* Used to compute the hash value. */
|
||||
unsigned i; /* Used to cycle through random values. */
|
||||
|
||||
/* Set the initial value from the key size. */
|
||||
for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
|
||||
value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
|
||||
|
||||
return (1103515243 * value + 12345);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new symbols for use in the hash of exported symbols or
|
||||
* the list of unresolved symbols per module
|
||||
@@ -239,7 +228,7 @@ static struct symbol *alloc_symbol(const char *name)
|
||||
/* For the hash of exported symbols */
|
||||
static void hash_add_symbol(struct symbol *sym)
|
||||
{
|
||||
hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name));
|
||||
hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name));
|
||||
}
|
||||
|
||||
static void sym_add_unresolved(const char *name, struct module *mod, bool weak)
|
||||
@@ -260,7 +249,7 @@ static struct symbol *sym_find_with_module(const char *name, struct module *mod)
|
||||
if (name[0] == '.')
|
||||
name++;
|
||||
|
||||
hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) {
|
||||
hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) {
|
||||
if (strcmp(s->name, name) == 0 && (!mod || s->module == mod))
|
||||
return s;
|
||||
}
|
||||
@@ -340,8 +329,6 @@ static const char *sec_name(const struct elf_info *info, unsigned int secindex)
|
||||
return sech_name(info, &info->sechdrs[secindex]);
|
||||
}
|
||||
|
||||
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
|
||||
|
||||
static struct symbol *sym_add_exported(const char *name, struct module *mod,
|
||||
bool gpl_only, const char *namespace)
|
||||
{
|
||||
@@ -1966,6 +1953,7 @@ static void write_vmlinux_export_c_file(struct module *mod)
|
||||
static void write_mod_c_file(struct module *mod)
|
||||
{
|
||||
struct buffer buf = { };
|
||||
struct module_alias *alias, *next;
|
||||
char fname[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
@@ -1973,7 +1961,14 @@ static void write_mod_c_file(struct module *mod)
|
||||
add_exported_symbols(&buf, mod);
|
||||
add_versions(&buf, mod);
|
||||
add_depends(&buf, mod);
|
||||
add_moddevtable(&buf, mod);
|
||||
|
||||
buf_printf(&buf, "\n");
|
||||
list_for_each_entry_safe(alias, next, &mod->aliases, node) {
|
||||
buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str);
|
||||
list_del(&alias->node);
|
||||
free(alias);
|
||||
}
|
||||
|
||||
add_srcversion(&buf, mod);
|
||||
|
||||
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
|
||||
|
||||
+19
-2
@@ -67,6 +67,8 @@
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
|
||||
|
||||
struct buffer {
|
||||
char *p;
|
||||
int pos;
|
||||
@@ -79,6 +81,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...);
|
||||
void
|
||||
buf_write(struct buffer *buf, const char *s, int len);
|
||||
|
||||
/**
|
||||
* struct module_alias - auto-generated MODULE_ALIAS()
|
||||
*
|
||||
* @node: linked to module::aliases
|
||||
* @str: a string for MODULE_ALIAS()
|
||||
*/
|
||||
struct module_alias {
|
||||
struct list_head node;
|
||||
char str[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct module - represent a module (vmlinux or *.ko)
|
||||
*
|
||||
* @aliases: list head for module_aliases
|
||||
*/
|
||||
struct module {
|
||||
struct list_head list;
|
||||
struct list_head exported_symbols;
|
||||
@@ -89,12 +107,12 @@ struct module {
|
||||
bool seen;
|
||||
bool has_init;
|
||||
bool has_cleanup;
|
||||
struct buffer dev_table_buf;
|
||||
char srcversion[25];
|
||||
// Missing namespace dependencies
|
||||
struct list_head missing_namespaces;
|
||||
// Actual imported namespaces
|
||||
struct list_head imported_namespaces;
|
||||
struct list_head aliases;
|
||||
char name[];
|
||||
};
|
||||
|
||||
@@ -170,7 +188,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr,
|
||||
/* file2alias.c */
|
||||
void handle_moddevtable(struct module *mod, struct elf_info *info,
|
||||
Elf_Sym *sym, const char *symname);
|
||||
void add_moddevtable(struct buffer *buf, struct module *mod);
|
||||
|
||||
/* sumversion.c */
|
||||
void get_src_version(const char *modname, char sum[], unsigned sumlen);
|
||||
|
||||
+2
-8
@@ -19,12 +19,6 @@ if ! { echo "$SPATCH_REQ_VERSION"; echo "$SPATCH_VERSION"; } | sort -CV ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$KBUILD_EXTMOD" ]; then
|
||||
src_prefix=
|
||||
else
|
||||
src_prefix=$srctree/
|
||||
fi
|
||||
|
||||
generate_deps_for_ns() {
|
||||
$SPATCH --very-quiet --in-place --sp-file \
|
||||
$srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2
|
||||
@@ -34,7 +28,7 @@ generate_deps() {
|
||||
local mod=${1%.ko:}
|
||||
shift
|
||||
local namespaces="$*"
|
||||
local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod)
|
||||
local mod_source_files=$(sed "s|^\(.*\)\.o$|${srcroot}/\1.c|" $mod.mod)
|
||||
|
||||
for ns in $namespaces; do
|
||||
echo "Adding namespace $ns to module $mod.ko."
|
||||
@@ -57,4 +51,4 @@ generate_deps() {
|
||||
while read line
|
||||
do
|
||||
generate_deps $line
|
||||
done < $MODULES_NSDEPS
|
||||
done < modules.nsdeps
|
||||
|
||||
@@ -96,16 +96,18 @@ install_linux_image_dbg () {
|
||||
|
||||
# Parse modules.order directly because 'make modules_install' may sign,
|
||||
# compress modules, and then run unneeded depmod.
|
||||
while read -r mod; do
|
||||
mod="${mod%.o}.ko"
|
||||
dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}"
|
||||
buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
|
||||
link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug"
|
||||
if is_enabled CONFIG_MODULES; then
|
||||
while read -r mod; do
|
||||
mod="${mod%.o}.ko"
|
||||
dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}"
|
||||
buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
|
||||
link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug"
|
||||
|
||||
mkdir -p "${dbg%/*}" "${link%/*}"
|
||||
"${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
|
||||
ln -sf --relative "${dbg}" "${link}"
|
||||
done < modules.order
|
||||
mkdir -p "${dbg%/*}" "${link%/*}"
|
||||
"${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
|
||||
ln -sf --relative "${dbg}" "${link}"
|
||||
done < modules.order
|
||||
fi
|
||||
|
||||
# Build debug package
|
||||
# Different tools want the image in different locations
|
||||
|
||||
@@ -51,6 +51,13 @@ mkdir -p "${destdir}"
|
||||
if [ "${CC}" != "${HOSTCC}" ]; then
|
||||
echo "Rebuilding host programs with ${CC}..."
|
||||
|
||||
# This leverages external module building.
|
||||
# - Clear sub_make_done to allow the top-level Makefile to redo sub-make.
|
||||
# - Filter out --no-print-directory to print "Entering directory" logs
|
||||
# when Make changes the working directory.
|
||||
unset sub_make_done
|
||||
MAKEFLAGS=$(echo "${MAKEFLAGS}" | sed s/--no-print-directory//)
|
||||
|
||||
cat <<-'EOF' > "${destdir}/Kbuild"
|
||||
subdir-y := scripts
|
||||
EOF
|
||||
|
||||
@@ -202,7 +202,7 @@ Build-Depends-Arch: bc, bison, cpio, flex,
|
||||
gcc-${host_gnu} <!pkg.${sourcename}.nokernelheaders>,
|
||||
kmod, libelf-dev:native,
|
||||
libssl-dev:native, libssl-dev <!pkg.${sourcename}.nokernelheaders>,
|
||||
rsync
|
||||
python3:native, rsync
|
||||
Homepage: https://www.kernel.org/
|
||||
|
||||
Package: $packagename-$version
|
||||
|
||||
+42
-16
@@ -10,6 +10,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [--no-local] [srctree]" >&2
|
||||
exit 1
|
||||
@@ -30,6 +32,29 @@ if test $# -gt 0 -o ! -d "$srctree"; then
|
||||
usage
|
||||
fi
|
||||
|
||||
try_tag() {
|
||||
tag="$1"
|
||||
|
||||
# Is $tag an annotated tag?
|
||||
if [ "$(git cat-file -t "$tag" 2> /dev/null)" != tag ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD?
|
||||
# shellcheck disable=SC2046 # word splitting is the point here
|
||||
set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null)
|
||||
|
||||
# $1 is 0 if and only if $tag is an ancestor of HEAD. Use
|
||||
# string comparison, because $1 is empty if the 'git rev-list'
|
||||
# command somehow failed.
|
||||
if [ "$1" != 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# $2 is the number of commits in the range $tag..HEAD, possibly 0.
|
||||
count="$2"
|
||||
}
|
||||
|
||||
scm_version()
|
||||
{
|
||||
local short=false
|
||||
@@ -61,33 +86,33 @@ scm_version()
|
||||
# stable kernel: 6.1.7 -> v6.1.7
|
||||
version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/')
|
||||
|
||||
# try_tag initializes count if the tag is usable.
|
||||
count=
|
||||
|
||||
# If a localversion* file exists, and the corresponding
|
||||
# annotated tag exists and is an ancestor of HEAD, use
|
||||
# it. This is the case in linux-next.
|
||||
tag=${file_localversion#-}
|
||||
desc=
|
||||
if [ -n "${tag}" ]; then
|
||||
desc=$(git describe --match=$tag 2>/dev/null)
|
||||
if [ -n "${file_localversion#-}" ] ; then
|
||||
try_tag "${file_localversion#-}"
|
||||
fi
|
||||
|
||||
# Otherwise, if a localversion* file exists, and the tag
|
||||
# obtained by appending it to the tag derived from
|
||||
# KERNELVERSION exists and is an ancestor of HEAD, use
|
||||
# it. This is e.g. the case in linux-rt.
|
||||
if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then
|
||||
tag="${version_tag}${file_localversion}"
|
||||
desc=$(git describe --match=$tag 2>/dev/null)
|
||||
if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then
|
||||
try_tag "${version_tag}${file_localversion}"
|
||||
fi
|
||||
|
||||
# Otherwise, default to the annotated tag derived from KERNELVERSION.
|
||||
if [ -z "${desc}" ]; then
|
||||
tag="${version_tag}"
|
||||
desc=$(git describe --match=$tag 2>/dev/null)
|
||||
if [ -z "${count}" ]; then
|
||||
try_tag "${version_tag}"
|
||||
fi
|
||||
|
||||
# If we are at the tagged commit, we ignore it because the version is
|
||||
# well-defined.
|
||||
if [ "${tag}" != "${desc}" ]; then
|
||||
# If we are at the tagged commit, we ignore it because the
|
||||
# version is well-defined. If none of the attempted tags exist
|
||||
# or were usable, $count is still empty.
|
||||
if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then
|
||||
|
||||
# If only the short version is requested, don't bother
|
||||
# running further git commands
|
||||
@@ -95,14 +120,15 @@ scm_version()
|
||||
echo "+"
|
||||
return
|
||||
fi
|
||||
|
||||
# If we are past the tagged commit, we pretty print it.
|
||||
# (like 6.1.0-14595-g292a089d78d3)
|
||||
if [ -n "${desc}" ]; then
|
||||
echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}'
|
||||
if [ -n "${count}" ]; then
|
||||
printf "%s%05d" "-" "${count}"
|
||||
fi
|
||||
|
||||
# Add -g and exactly 12 hex chars.
|
||||
printf '%s%s' -g "$(echo $head | cut -c1-12)"
|
||||
printf '%s%.12s' -g "$head"
|
||||
fi
|
||||
|
||||
if ${no_dirty}; then
|
||||
|
||||
Reference in New Issue
Block a user