summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-30 13:41:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-30 13:41:50 -0800
commit6a34dfa15d6edf7e78b8118d862d2db0889cf669 (patch)
treef5bc36ccaa5251fa660cf2efdb00d6ffa3ace36b /scripts
parent0e287d31b62bb53ad81d5e59778384a40f8b6f56 (diff)
parente6064da6461f989a357f2e280d7f8d4155267c4c (diff)
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() ...
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Kbuild.include2
-rw-r--r--scripts/Makefile.autofdo24
-rw-r--r--scripts/Makefile.build59
-rw-r--r--scripts/Makefile.clean2
-rw-r--r--scripts/Makefile.compiler2
-rw-r--r--scripts/Makefile.host8
-rw-r--r--scripts/Makefile.lib62
-rw-r--r--scripts/Makefile.modfinal31
-rw-r--r--scripts/Makefile.modinst8
-rw-r--r--scripts/Makefile.modpost24
-rw-r--r--scripts/Makefile.propeller39
-rw-r--r--scripts/Makefile.vmlinux51
-rwxr-xr-xscripts/coccicheck6
-rwxr-xr-xscripts/depmod.sh4
-rw-r--r--scripts/genksyms/genksyms.c73
-rw-r--r--scripts/head-object-list.txt1
-rw-r--r--scripts/kconfig/conf.c5
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/nconf.c2
-rw-r--r--scripts/kconfig/nconf.gui.c9
-rw-r--r--scripts/kconfig/parser.y28
-rw-r--r--scripts/kconfig/qconf.cc204
-rw-r--r--scripts/kconfig/qconf.h19
-rwxr-xr-xscripts/kconfig/streamline_config.pl18
-rw-r--r--scripts/kconfig/symbol.c26
-rwxr-xr-xscripts/link-vmlinux.sh16
-rw-r--r--scripts/mod/file2alias.c779
-rw-r--r--scripts/mod/modpost.c31
-rw-r--r--scripts/mod/modpost.h21
-rw-r--r--scripts/nsdeps10
-rwxr-xr-xscripts/package/builddeb22
-rwxr-xr-xscripts/package/install-extmod-build7
-rwxr-xr-xscripts/package/mkdebian2
-rwxr-xr-xscripts/setlocalversion58
34 files changed, 793 insertions, 861 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index ed8a7493524b..8c311b997e24 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -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)
diff --git a/scripts/Makefile.autofdo b/scripts/Makefile.autofdo
new file mode 100644
index 000000000000..1caf2457e585
--- /dev/null
+++ b/scripts/Makefile.autofdo
@@ -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
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index f483a54380e7..c16e4cf54d77 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -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
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 4fcfab40ed61..6ead00ec7313 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -3,7 +3,7 @@
# Cleaning up
# ==========================================================================
-src := $(if $(VPATH),$(VPATH)/)$(obj)
+src := $(srcroot)/$(obj)
PHONY := __clean
__clean:
diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler
index e0842496d26e..8c1029687e2e 100644
--- a/scripts/Makefile.compiler
+++ b/scripts/Makefile.compiler
@@ -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)
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index e01c13a588dd..c1dedf646a39 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -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
#####
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 01a9f567d5af..7395200538da 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -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
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index 1482884ec3ca..542ba462ed3e 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -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.
# ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index d97720943189..f97c9926ed31 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -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)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 44936ebad161..ab0e94ea6249 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -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))
diff --git a/scripts/Makefile.propeller b/scripts/Makefile.propeller
new file mode 100644
index 000000000000..48a660128e25
--- /dev/null
+++ b/scripts/Makefile.propeller
@@ -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
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux
index dddad554e912..873caaa55313 100644
--- a/scripts/Makefile.vmlinux
+++ b/scripts/Makefile.vmlinux
@@ -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
# ---------------------------------------------------------------------------
diff --git a/scripts/coccicheck b/scripts/coccicheck
index e52cb43fede6..0e6bc5a10320 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -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:]")
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index e22da27fe13e..3c34fecacbc8 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -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
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index f3901c55df23..07f9b8cfb233 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -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;
+ return;
+ }
- if (flag_dump_defs)
- fprintf(debugfile, "Export %s == <", name);
+ if (flag_dump_defs)
+ fprintf(debugfile, "Export %s == <", name);
- expansion_trail = (struct symbol *)-1L;
+ expansion_trail = (struct symbol *)-1L;
- sym->expansion_trail = expansion_trail;
- expansion_trail = sym;
- crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
+ 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;
+ 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++;
+ 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, ", ");
}
- sym->expansion_trail = 0;
- sym = n;
+ print_type_name(sym->type, sym->name);
+ if (sym->status == STATUS_DEFINED)
+ fprintf(stderr, " (became defined)");
+ has_changed = 1;
+ if (flag_preserve)
+ errors++;
}
- if (has_changed)
- fprintf(stderr, "\n");
+ sym->expansion_trail = 0;
+ sym = n;
+ }
+ if (has_changed)
+ fprintf(stderr, "\n");
- if (flag_dump_defs)
- fputs(">\n", debugfile);
+ if (flag_dump_defs)
+ fputs(">\n", debugfile);
- printf("#SYMVER %s 0x%08lx\n", name, crc);
- }
+ printf("#SYMVER %s 0x%08lx\n", name, crc);
}
/*----------------------------------------------------------------------*/
diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
index fd5d00bac447..f12b4a7b8406 100644
--- a/scripts/head-object-list.txt
+++ b/scripts/head-object-list.txt
@@ -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
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 3d7d454c54da..8abe57041955 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -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)
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 63519cd24bc7..8914b4e8f2a8 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -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);
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 063b4f7ccbdb..c0b2dabf6c89 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -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;
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 72b605efe549..4bfdf8ac2a9a 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -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 ' ':
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index bc43fb67c7c4..68372d3ff325 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -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;
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index e260cab1c2af..6c92ef1e16ef 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -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['<'] = "&lt;";
+ patterns['>'] = "&gt;";
+ patterns['&'] = "&amp;";
+ patterns['"'] = "&quot;";
+ patterns['\n'] = "<br>";
+
for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
- switch (res[i].toLatin1()) {
- case '<':
- res.replace(i, 1, "&lt;");
- i += 4;
- break;
- case '>':
- res.replace(i, 1, "&gt;");
- i += 4;
- break;
- case '&':
- res.replace(i, 1, "&amp;");
- i += 5;
- break;
- case '"':
- res.replace(i, 1, "&quot;");
- 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;
-
- 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;
- }
+ struct menu *m;
- 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);
- split1->setChildrenCollapsible(false);
-
- menuList = new ConfigList(widget, "menu");
+ QVBoxLayout *layout = new QVBoxLayout(widget);
- split2 = new QSplitter(widget);
+ split2 = new QSplitter(Qt::Vertical, widget);
+ layout->addWidget(split2);
split2->setChildrenCollapsible(false);
- split2->setOrientation(Qt::Vertical);
- // create config tree
- configList = new ConfigList(widget, "config");
+ split1 = new QSplitter(Qt::Horizontal, split2);
+ split1->setChildrenCollapsible(false);
- helpText = new ConfigInfoView(widget, "help");
+ configList = new ConfigList(split1, "config");
- 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();
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 53373064d90a..62ab3286d04f 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -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:
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index d51cd7ac15d2..8e23faab5d22 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -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;
}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index a3af93aaaf32..89b84bf8e21f 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -71,6 +71,24 @@ const char *sym_type_name(enum symbol_type type)
}
/**
+ * 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
*
* @sym: a symbol pointer
@@ -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;
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index a3c634b2f348..d853ddb3b28c 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -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
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index c4cc11aa558f..5b5745f00eb3 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -10,6 +10,12 @@
* of the GNU General Public License, incorporated herein by reference.
*/
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "list.h"
+#include "xalloc.h"
+
#include "modpost.h"
#include "devicetable-offsets.h"
@@ -31,6 +37,66 @@ typedef Elf64_Addr kernel_ulong_t;
#include <ctype.h>
#include <stdbool.h>
+/**
+ * module_alias_printf - add auto-generated MODULE_ALIAS()
+ *
+ * @mod: module
+ * @append_wildcard: append '*' for future extension if not exist yet
+ * @fmt: printf(3)-like format
+ */
+static void __attribute__((format (printf, 3, 4)))
+module_alias_printf(struct module *mod, bool append_wildcard,
+ const char *fmt, ...)
+{
+ struct module_alias *new, *als;
+ size_t len;
+ int n;
+ va_list ap;
+
+ /* Determine required size. */
+ va_start(ap, fmt);
+ n = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (n < 0) {
+ error("vsnprintf failed\n");
+ return;
+ }
+
+ len = n + 1; /* extra byte for '\0' */
+
+ if (append_wildcard)
+ len++; /* extra byte for '*' */
+
+ new = xmalloc(sizeof(*new) + len);
+
+ /* Now, really print it to the allocated buffer */
+ va_start(ap, fmt);
+ n = vsnprintf(new->str, len, fmt, ap);
+ va_end(ap);
+
+ if (n < 0) {
+ error("vsnprintf failed\n");
+ free(new);
+ return;
+ }
+
+ if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) {
+ new->str[n] = '*';
+ new->str[n + 1] = '\0';
+ }
+
+ /* avoid duplication */
+ list_for_each_entry(als, &mod->aliases, node) {
+ if (!strcmp(als->str, new->str)) {
+ free(new);
+ return;
+ }
+ }
+
+ list_add_tail(&new->node, &mod->aliases);
+}
+
typedef uint32_t __u32;
typedef uint16_t __u16;
typedef unsigned char __u8;
@@ -56,35 +122,24 @@ typedef struct {
* we handle those differences explicitly below */
#include "../../include/linux/mod_devicetable.h"
-/* This array collects all instances that use the generic do_table */
struct devtable {
- const char *device_id; /* name of table, __mod_<name>__*_device_table. */
+ const char *device_id;
unsigned long id_size;
- int (*do_entry)(const char *filename, void *symval, char *alias);
+ void (*do_entry)(struct module *mod, void *symval);
};
-/* Size of alias provided to do_entry functions */
-#define ALIAS_SIZE 500
-
/* Define a variable f that holds the value of field f of struct devid
* based at address m.
*/
#define DEF_FIELD(m, devid, f) \
typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f))
-/* Define a variable v that holds the address of field f of struct devid
- * based at address m. Due to the way typeof works, for a field of type
- * T[N] the variable has type T(*)[N], _not_ T*.
- */
-#define DEF_FIELD_ADDR_VAR(m, devid, f, v) \
- typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f)
-
/* Define a variable f that holds the address of field f of struct devid
* based at address m. Due to the way typeof works, for a field of type
* T[N] the variable has type T(*)[N], _not_ T*.
*/
#define DEF_FIELD_ADDR(m, devid, f) \
- DEF_FIELD_ADDR_VAR(m, devid, f, f)
+ typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f)
#define ADD(str, sep, cond, field) \
do { \
@@ -99,15 +154,6 @@ do { \
sprintf(str + strlen(str), "*"); \
} while(0)
-/* End in a wildcard, for future extension */
-static inline void add_wildcard(char *str)
-{
- int len = strlen(str);
-
- if (str[len - 1] != '*')
- strcat(str + len, "*");
-}
-
static inline void add_uuid(char *str, uuid_le uuid)
{
int len = strlen(str);
@@ -130,40 +176,6 @@ static inline void add_guid(char *str, guid_t guid)
guid.b[12], guid.b[13], guid.b[14], guid.b[15]);
}
-/**
- * Check that sizeof(device_id type) are consistent with size of section
- * in .o file. If in-consistent then userspace and kernel does not agree
- * on actual size which is a bug.
- * Also verify that the final entry in the table is all zeros.
- * Ignore both checks if build host differ from target host and size differs.
- **/
-static void device_id_check(const char *modname, const char *device_id,
- unsigned long size, unsigned long id_size,
- void *symval)
-{
- int i;
-
- if (size % id_size || size < id_size) {
- fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_%s__<identifier>_device_table=%lu.\n"
- "Fix definition of struct %s_device_id in mod_devicetable.h\n",
- modname, device_id, id_size, device_id, size, device_id);
- }
- /* Verify last one is a terminator */
- for (i = 0; i < id_size; i++ ) {
- if (*(uint8_t*)(symval+size-id_size+i)) {
- fprintf(stderr,
- "%s: struct %s_device_id is %lu bytes. The last of %lu is:\n",
- modname, device_id, id_size, size / id_size);
- for (i = 0; i < id_size; i++ )
- fprintf(stderr,"0x%02x ",
- *(uint8_t*)(symval+size-id_size+i) );
- fprintf(stderr,"\n");
- fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n",
- modname, device_id);
- }
- }
-}
-
/* USB is special because the bcdDevice can be matched against a numeric range */
/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
static void do_usb_entry(void *symval,
@@ -229,9 +241,7 @@ static void do_usb_entry(void *symval,
ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
bInterfaceNumber);
- add_wildcard(alias);
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"%s\");\n", alias);
+ module_alias_printf(mod, true, "%s", alias);
}
/* Handles increment/decrement of BCD formatted integers */
@@ -273,7 +283,7 @@ static unsigned int incbcd(unsigned int *bcd,
return init;
}
-static void do_usb_entry_multi(void *symval, struct module *mod)
+static void do_usb_entry_multi(struct module *mod, void *symval)
{
unsigned int devlo, devhi;
unsigned char chi, clo, max;
@@ -338,22 +348,7 @@ static void do_usb_entry_multi(void *symval, struct module *mod)
}
}
-static void do_usb_table(void *symval, unsigned long size,
- struct module *mod)
-{
- unsigned int i;
- const unsigned long id_size = SIZE_usb_device_id;
-
- device_id_check(mod->name, "usb", size, id_size, symval);
-
- /* Leave last one: it's the terminator. */
- size -= id_size;
-
- for (i = 0; i < size; i += id_size)
- do_usb_entry_multi(symval + i, mod);
-}
-
-static void do_of_entry_multi(void *symval, struct module *mod)
+static void do_of_entry(struct module *mod, void *symval)
{
char alias[500];
int len;
@@ -375,56 +370,39 @@ static void do_of_entry_multi(void *symval, struct module *mod)
if (isspace(*tmp))
*tmp = '_';
- buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
- strcat(alias, "C");
- add_wildcard(alias);
- buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
-}
-
-static void do_of_table(void *symval, unsigned long size,
- struct module *mod)
-{
- unsigned int i;
- const unsigned long id_size = SIZE_of_device_id;
-
- device_id_check(mod->name, "of", size, id_size, symval);
-
- /* Leave last one: it's the terminator. */
- size -= id_size;
-
- for (i = 0; i < size; i += id_size)
- do_of_entry_multi(symval + i, mod);
+ module_alias_printf(mod, false, "%s", alias);
+ module_alias_printf(mod, false, "%sC*", alias);
}
/* Looks like: hid:bNvNpN */
-static int do_hid_entry(const char *filename,
- void *symval, char *alias)
+static void do_hid_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, hid_device_id, bus);
DEF_FIELD(symval, hid_device_id, group);
DEF_FIELD(symval, hid_device_id, vendor);
DEF_FIELD(symval, hid_device_id, product);
- sprintf(alias, "hid:");
ADD(alias, "b", bus != HID_BUS_ANY, bus);
ADD(alias, "g", group != HID_GROUP_ANY, group);
ADD(alias, "v", vendor != HID_ANY_ID, vendor);
ADD(alias, "p", product != HID_ANY_ID, product);
- return 1;
+ module_alias_printf(mod, false, "hid:%s", alias);
}
/* Looks like: ieee1394:venNmoNspNverN */
-static int do_ieee1394_entry(const char *filename,
- void *symval, char *alias)
+static void do_ieee1394_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, ieee1394_device_id, match_flags);
DEF_FIELD(symval, ieee1394_device_id, vendor_id);
DEF_FIELD(symval, ieee1394_device_id, model_id);
DEF_FIELD(symval, ieee1394_device_id, specifier_id);
DEF_FIELD(symval, ieee1394_device_id, version);
- strcpy(alias, "ieee1394:");
ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID,
vendor_id);
ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID,
@@ -434,14 +412,13 @@ static int do_ieee1394_entry(const char *filename,
ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION,
version);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "ieee1394:%s", alias);
}
/* Looks like: pci:vNdNsvNsdNbcNscNiN or <prefix>_pci:vNdNsvNsdNbcNscNiN. */
-static int do_pci_entry(const char *filename,
- void *symval, char *alias)
+static void do_pci_entry(struct module *mod, void *symval)
{
+ char alias[256];
/* Class field can be divided into these three. */
unsigned char baseclass, subclass, interface,
baseclass_mask, subclass_mask, interface_mask;
@@ -464,7 +441,6 @@ static int do_pci_entry(const char *filename,
default:
warn("Unknown PCI driver_override alias %08X\n",
override_only);
- return 0;
}
ADD(alias, "v", vendor != PCI_ANY_ID, vendor);
@@ -483,28 +459,28 @@ static int do_pci_entry(const char *filename,
|| (subclass_mask != 0 && subclass_mask != 0xFF)
|| (interface_mask != 0 && interface_mask != 0xFF)) {
warn("Can't handle masks in %s:%04X\n",
- filename, class_mask);
- return 0;
+ mod->name, class_mask);
+ return;
}
ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
ADD(alias, "sc", subclass_mask == 0xFF, subclass);
ADD(alias, "i", interface_mask == 0xFF, interface);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "%s", alias);
}
/* looks like: "ccw:tNmNdtNdmN" */
-static int do_ccw_entry(const char *filename,
- void *symval, char *alias)
+static void do_ccw_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, ccw_device_id, match_flags);
DEF_FIELD(symval, ccw_device_id, cu_type);
DEF_FIELD(symval, ccw_device_id, cu_model);
DEF_FIELD(symval, ccw_device_id, dev_type);
DEF_FIELD(symval, ccw_device_id, dev_model);
- strcpy(alias, "ccw:");
ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE,
cu_type);
ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL,
@@ -513,47 +489,42 @@ static int do_ccw_entry(const char *filename,
dev_type);
ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL,
dev_model);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "ccw:%s", alias);
}
/* looks like: "ap:tN" */
-static int do_ap_entry(const char *filename,
- void *symval, char *alias)
+static void do_ap_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, ap_device_id, dev_type);
- sprintf(alias, "ap:t%02X*", dev_type);
- return 1;
+ module_alias_printf(mod, false, "ap:t%02X*", dev_type);
}
/* looks like: "css:tN" */
-static int do_css_entry(const char *filename,
- void *symval, char *alias)
+static void do_css_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, css_device_id, type);
- sprintf(alias, "css:t%01X", type);
- return 1;
+ module_alias_printf(mod, false, "css:t%01X", type);
}
/* Looks like: "serio:tyNprNidNexN" */
-static int do_serio_entry(const char *filename,
- void *symval, char *alias)
+static void do_serio_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, serio_device_id, type);
DEF_FIELD(symval, serio_device_id, proto);
DEF_FIELD(symval, serio_device_id, id);
DEF_FIELD(symval, serio_device_id, extra);
- strcpy(alias, "serio:");
ADD(alias, "ty", type != SERIO_ANY, type);
ADD(alias, "pr", proto != SERIO_ANY, proto);
ADD(alias, "id", id != SERIO_ANY, id);
ADD(alias, "ex", extra != SERIO_ANY, extra);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "serio:%s", alias);
}
/* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or
@@ -563,21 +534,19 @@ static int do_serio_entry(const char *filename,
* or _CLS. Also, bb, ss, and pp can be substituted with ??
* as don't care byte.
*/
-static int do_acpi_entry(const char *filename,
- void *symval, char *alias)
+static void do_acpi_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, acpi_device_id, id);
DEF_FIELD(symval, acpi_device_id, cls);
DEF_FIELD(symval, acpi_device_id, cls_msk);
- if (id && strlen((const char *)*id))
- sprintf(alias, "acpi*:%s:*", *id);
+ if ((*id)[0])
+ module_alias_printf(mod, false, "acpi*:%s:*", *id);
else {
+ char alias[256];
int i, byte_shift, cnt = 0;
unsigned int msk;
- sprintf(&alias[cnt], "acpi*:");
- cnt = 6;
for (i = 1; i <= 3; i++) {
byte_shift = 8 * (3-i);
msk = (cls_msk >> byte_shift) & 0xFF;
@@ -588,101 +557,49 @@ static int do_acpi_entry(const char *filename,
sprintf(&alias[cnt], "??");
cnt += 2;
}
- sprintf(&alias[cnt], ":*");
+ module_alias_printf(mod, false, "acpi*:%s:*", alias);
}
- return 1;
}
/* looks like: "pnp:dD" */
-static void do_pnp_device_entry(void *symval, unsigned long size,
- struct module *mod)
+static void do_pnp_device_entry(struct module *mod, void *symval)
{
- const unsigned long id_size = SIZE_pnp_device_id;
- const unsigned int count = (size / id_size)-1;
- unsigned int i;
-
- device_id_check(mod->name, "pnp", size, id_size, symval);
+ DEF_FIELD_ADDR(symval, pnp_device_id, id);
+ char acpi_id[sizeof(*id)];
- for (i = 0; i < count; i++) {
- DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id);
- char acpi_id[sizeof(*id)];
- int j;
-
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"pnp:d%s*\");\n", *id);
-
- /* fix broken pnp bus lowercasing */
- for (j = 0; j < sizeof(acpi_id); j++)
- acpi_id[j] = toupper((*id)[j]);
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
- }
+ /* fix broken pnp bus lowercasing */
+ for (unsigned int i = 0; i < sizeof(acpi_id); i++)
+ acpi_id[i] = toupper((*id)[i]);
+ module_alias_printf(mod, false, "pnp:d%s*", *id);
+ module_alias_printf(mod, false, "acpi*:%s:*", acpi_id);
}
/* looks like: "pnp:dD" for every device of the card */
-static void do_pnp_card_entries(void *symval, unsigned long size,
- struct module *mod)
+static void do_pnp_card_entry(struct module *mod, void *symval)
{
- const unsigned long id_size = SIZE_pnp_card_device_id;
- const unsigned int count = (size / id_size)-1;
- unsigned int i;
-
- device_id_check(mod->name, "pnp", size, id_size, symval);
-
- for (i = 0; i < count; i++) {
- unsigned int j;
- DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs);
-
- for (j = 0; j < PNP_MAX_DEVICES; j++) {
- const char *id = (char *)(*devs)[j].id;
- int i2, j2;
- int dup = 0;
-
- if (!id[0])
- break;
+ DEF_FIELD_ADDR(symval, pnp_card_device_id, devs);
- /* find duplicate, already added value */
- for (i2 = 0; i2 < i && !dup; i2++) {
- DEF_FIELD_ADDR_VAR(symval + i2 * id_size,
- pnp_card_device_id,
- devs, devs_dup);
+ for (unsigned int i = 0; i < PNP_MAX_DEVICES; i++) {
+ const char *id = (char *)(*devs)[i].id;
+ char acpi_id[PNP_ID_LEN];
- for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) {
- const char *id2 =
- (char *)(*devs_dup)[j2].id;
-
- if (!id2[0])
- break;
-
- if (!strcmp(id, id2)) {
- dup = 1;
- break;
- }
- }
- }
-
- /* add an individual alias for every device entry */
- if (!dup) {
- char acpi_id[PNP_ID_LEN];
- int k;
+ if (!id[0])
+ break;
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+ /* fix broken pnp bus lowercasing */
+ for (unsigned int j = 0; j < sizeof(acpi_id); j++)
+ acpi_id[j] = toupper(id[j]);
- /* fix broken pnp bus lowercasing */
- for (k = 0; k < sizeof(acpi_id); k++)
- acpi_id[k] = toupper(id[k]);
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
- }
- }
+ /* add an individual alias for every device entry */
+ module_alias_printf(mod, false, "pnp:d%s*", id);
+ module_alias_printf(mod, false, "acpi*:%s:*", acpi_id);
}
}
/* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
-static int do_pcmcia_entry(const char *filename,
- void *symval, char *alias)
+static void do_pcmcia_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
unsigned int i;
DEF_FIELD(symval, pcmcia_device_id, match_flags);
DEF_FIELD(symval, pcmcia_device_id, manf_id);
@@ -696,7 +613,6 @@ static int do_pcmcia_entry(const char *filename,
(*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]);
}
- strcpy(alias, "pcmcia:");
ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID,
manf_id);
ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID,
@@ -712,13 +628,12 @@ static int do_pcmcia_entry(const char *filename,
ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]);
ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "pcmcia:%s", alias);
}
-static int do_vio_entry(const char *filename, void *symval,
- char *alias)
+static void do_vio_entry(struct module *mod, void *symval)
{
+ char alias[256];
char *tmp;
DEF_FIELD_ADDR(symval, vio_device_id, type);
DEF_FIELD_ADDR(symval, vio_device_id, compat);
@@ -731,8 +646,7 @@ static int do_vio_entry(const char *filename, void *symval,
if (isspace (*tmp))
*tmp = '_';
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "%s", alias);
}
static void do_input(char *alias,
@@ -748,9 +662,10 @@ static void do_input(char *alias,
}
/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
-static int do_input_entry(const char *filename, void *symval,
- char *alias)
+static void do_input_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, input_device_id, flags);
DEF_FIELD(symval, input_device_id, bustype);
DEF_FIELD(symval, input_device_id, vendor);
@@ -766,8 +681,6 @@ static int do_input_entry(const char *filename, void *symval,
DEF_FIELD_ADDR(symval, input_device_id, ffbit);
DEF_FIELD_ADDR(symval, input_device_id, swbit);
- sprintf(alias, "input:");
-
ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype);
ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor);
ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product);
@@ -802,102 +715,96 @@ static int do_input_entry(const char *filename, void *symval,
sprintf(alias + strlen(alias), "w*");
if (flags & INPUT_DEVICE_ID_MATCH_SWBIT)
do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX);
- return 1;
+
+ module_alias_printf(mod, false, "input:%s", alias);
}
-static int do_eisa_entry(const char *filename, void *symval,
- char *alias)
+static void do_eisa_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, eisa_device_id, sig);
- if (sig[0])
- sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig);
- else
- strcat(alias, "*");
- return 1;
+ module_alias_printf(mod, false, EISA_DEVICE_MODALIAS_FMT "*", *sig);
}
/* Looks like: parisc:tNhvNrevNsvN */
-static int do_parisc_entry(const char *filename, void *symval,
- char *alias)
+static void do_parisc_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, parisc_device_id, hw_type);
DEF_FIELD(symval, parisc_device_id, hversion);
DEF_FIELD(symval, parisc_device_id, hversion_rev);
DEF_FIELD(symval, parisc_device_id, sversion);
- strcpy(alias, "parisc:");
ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type);
ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion);
ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev);
ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "parisc:%s", alias);
}
/* Looks like: sdio:cNvNdN. */
-static int do_sdio_entry(const char *filename,
- void *symval, char *alias)
+static void do_sdio_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, sdio_device_id, class);
DEF_FIELD(symval, sdio_device_id, vendor);
DEF_FIELD(symval, sdio_device_id, device);
- strcpy(alias, "sdio:");
ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class);
ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor);
ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "sdio:%s", alias);
}
/* Looks like: ssb:vNidNrevN. */
-static int do_ssb_entry(const char *filename,
- void *symval, char *alias)
+static void do_ssb_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, ssb_device_id, vendor);
DEF_FIELD(symval, ssb_device_id, coreid);
DEF_FIELD(symval, ssb_device_id, revision);
- strcpy(alias, "ssb:");
ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor);
ADD(alias, "id", coreid != SSB_ANY_ID, coreid);
ADD(alias, "rev", revision != SSB_ANY_REV, revision);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "ssb:%s", alias);
}
/* Looks like: bcma:mNidNrevNclN. */
-static int do_bcma_entry(const char *filename,
- void *symval, char *alias)
+static void do_bcma_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, bcma_device_id, manuf);
DEF_FIELD(symval, bcma_device_id, id);
DEF_FIELD(symval, bcma_device_id, rev);
DEF_FIELD(symval, bcma_device_id, class);
- strcpy(alias, "bcma:");
ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf);
ADD(alias, "id", id != BCMA_ANY_ID, id);
ADD(alias, "rev", rev != BCMA_ANY_REV, rev);
ADD(alias, "cl", class != BCMA_ANY_CLASS, class);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "bcma:%s", alias);
}
/* Looks like: virtio:dNvN */
-static int do_virtio_entry(const char *filename, void *symval,
- char *alias)
+static void do_virtio_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, virtio_device_id, device);
DEF_FIELD(symval, virtio_device_id, vendor);
- strcpy(alias, "virtio:");
ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device);
ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "virtio:%s", alias);
}
/*
@@ -906,8 +813,7 @@ static int do_virtio_entry(const char *filename, void *symval,
* in the name.
*/
-static int do_vmbus_entry(const char *filename, void *symval,
- char *alias)
+static void do_vmbus_entry(struct module *mod, void *symval)
{
int i;
DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid);
@@ -916,68 +822,57 @@ static int do_vmbus_entry(const char *filename, void *symval,
for (i = 0; i < (sizeof(*guid) * 2); i += 2)
sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2]));
- strcpy(alias, "vmbus:");
- strcat(alias, guid_name);
-
- return 1;
+ module_alias_printf(mod, false, "vmbus:%s", guid_name);
}
/* Looks like: rpmsg:S */
-static int do_rpmsg_entry(const char *filename, void *symval,
- char *alias)
+static void do_rpmsg_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, rpmsg_device_id, name);
- sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name);
- return 1;
+ module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name);
}
/* Looks like: i2c:S */
-static int do_i2c_entry(const char *filename, void *symval,
- char *alias)
+static void do_i2c_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, i2c_device_id, name);
- sprintf(alias, I2C_MODULE_PREFIX "%s", *name);
- return 1;
+ module_alias_printf(mod, false, I2C_MODULE_PREFIX "%s", *name);
}
-static int do_i3c_entry(const char *filename, void *symval,
- char *alias)
+static void do_i3c_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, i3c_device_id, match_flags);
DEF_FIELD(symval, i3c_device_id, dcr);
DEF_FIELD(symval, i3c_device_id, manuf_id);
DEF_FIELD(symval, i3c_device_id, part_id);
DEF_FIELD(symval, i3c_device_id, extra_info);
- strcpy(alias, "i3c:");
ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr);
ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id);
ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id);
ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info);
- return 1;
+ module_alias_printf(mod, false, "i3c:%s", alias);
}
-static int do_slim_entry(const char *filename, void *symval, char *alias)
+static void do_slim_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, slim_device_id, manf_id);
DEF_FIELD(symval, slim_device_id, prod_code);
- sprintf(alias, "slim:%x:%x:*", manf_id, prod_code);
-
- return 1;
+ module_alias_printf(mod, false, "slim:%x:%x:*", manf_id, prod_code);
}
/* Looks like: spi:S */
-static int do_spi_entry(const char *filename, void *symval,
- char *alias)
+static void do_spi_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, spi_device_id, name);
- sprintf(alias, SPI_MODULE_PREFIX "%s", *name);
- return 1;
+ module_alias_printf(mod, false, SPI_MODULE_PREFIX "%s", *name);
}
static const struct dmifield {
@@ -1012,12 +907,11 @@ static void dmi_ascii_filter(char *d, const char *s)
}
-static int do_dmi_entry(const char *filename, void *symval,
- char *alias)
+static void do_dmi_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
int i, j;
DEF_FIELD_ADDR(symval, dmi_system_id, matches);
- sprintf(alias, "dmi*");
for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
for (j = 0; j < 4; j++) {
@@ -1032,80 +926,75 @@ static int do_dmi_entry(const char *filename, void *symval,
}
}
- strcat(alias, ":");
- return 1;
+ module_alias_printf(mod, false, "dmi*%s:", alias);
}
-static int do_platform_entry(const char *filename,
- void *symval, char *alias)
+static void do_platform_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, platform_device_id, name);
- sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name);
- return 1;
+
+ module_alias_printf(mod, false, PLATFORM_MODULE_PREFIX "%s", *name);
}
-static int do_mdio_entry(const char *filename,
- void *symval, char *alias)
+static void do_mdio_entry(struct module *mod, void *symval)
{
+ char id[33];
int i;
DEF_FIELD(symval, mdio_device_id, phy_id);
DEF_FIELD(symval, mdio_device_id, phy_id_mask);
- alias += sprintf(alias, MDIO_MODULE_PREFIX);
-
for (i = 0; i < 32; i++) {
if (!((phy_id_mask >> (31-i)) & 1))
- *(alias++) = '?';
+ id[i] = '?';
else if ((phy_id >> (31-i)) & 1)
- *(alias++) = '1';
+ id[i] = '1';
else
- *(alias++) = '0';
+ id[i] = '0';
}
/* Terminate the string */
- *alias = 0;
+ id[32] = '\0';
- return 1;
+ module_alias_printf(mod, false, MDIO_MODULE_PREFIX "%s", id);
}
/* Looks like: zorro:iN. */
-static int do_zorro_entry(const char *filename, void *symval,
- char *alias)
+static void do_zorro_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
DEF_FIELD(symval, zorro_device_id, id);
- strcpy(alias, "zorro:");
+
ADD(alias, "i", id != ZORRO_WILDCARD, id);
- return 1;
+
+ module_alias_printf(mod, false, "zorro:%s", alias);
}
/* looks like: "pnp:dD" */
-static int do_isapnp_entry(const char *filename,
- void *symval, char *alias)
+static void do_isapnp_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, isapnp_device_id, vendor);
DEF_FIELD(symval, isapnp_device_id, function);
- sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
+ module_alias_printf(mod, false, "pnp:d%c%c%c%x%x%x%x*",
'A' + ((vendor >> 2) & 0x3f) - 1,
'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
'A' + ((vendor >> 8) & 0x1f) - 1,
(function >> 4) & 0x0f, function & 0x0f,
(function >> 12) & 0x0f, (function >> 8) & 0x0f);
- return 1;
}
/* Looks like: "ipack:fNvNdN". */
-static int do_ipack_entry(const char *filename,
- void *symval, char *alias)
+static void do_ipack_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
DEF_FIELD(symval, ipack_device_id, format);
DEF_FIELD(symval, ipack_device_id, vendor);
DEF_FIELD(symval, ipack_device_id, device);
- strcpy(alias, "ipack:");
+
ADD(alias, "f", format != IPACK_ANY_FORMAT, format);
ADD(alias, "v", vendor != IPACK_ANY_ID, vendor);
ADD(alias, "d", device != IPACK_ANY_ID, device);
- add_wildcard(alias);
- return 1;
+
+ module_alias_printf(mod, true, "ipack:%s", alias);
}
/*
@@ -1156,9 +1045,9 @@ static void append_nibble_mask(char **outp,
* N is exactly 8 digits, where each is an upper-case hex digit, or
* a ? or [] pattern matching exactly one digit.
*/
-static int do_amba_entry(const char *filename,
- void *symval, char *alias)
+static void do_amba_entry(struct module *mod, void *symval)
{
+ char alias[256];
unsigned int digit;
char *p = alias;
DEF_FIELD(symval, amba_id, id);
@@ -1166,15 +1055,14 @@ static int do_amba_entry(const char *filename,
if ((id & mask) != id)
fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n",
- filename, id, mask);
+ mod->name, id, mask);
- p += sprintf(alias, "amba:d");
for (digit = 0; digit < 8; digit++)
append_nibble_mask(&p,
(id >> (4 * (7 - digit))) & 0xf,
(mask >> (4 * (7 - digit))) & 0xf);
- return 1;
+ module_alias_printf(mod, false, "amba:d%s", alias);
}
/*
@@ -1183,13 +1071,11 @@ static int do_amba_entry(const char *filename,
* N is exactly 2 digits, where each is an upper-case hex digit, or
* a ? or [] pattern matching exactly one digit.
*/
-static int do_mips_cdmm_entry(const char *filename,
- void *symval, char *alias)
+static void do_mips_cdmm_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, mips_cdmm_device_id, type);
- sprintf(alias, "mipscdmm:t%02X*", type);
- return 1;
+ module_alias_printf(mod, false, "mipscdmm:t%02X*", type);
}
/* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*
@@ -1198,137 +1084,130 @@ static int do_mips_cdmm_entry(const char *filename,
* complicated.
*/
-static int do_x86cpu_entry(const char *filename, void *symval,
- char *alias)
+static void do_x86cpu_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, x86_cpu_id, feature);
DEF_FIELD(symval, x86_cpu_id, family);
DEF_FIELD(symval, x86_cpu_id, model);
DEF_FIELD(symval, x86_cpu_id, vendor);
- strcpy(alias, "cpu:type:x86,");
ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor);
ADD(alias, "fam", family != X86_FAMILY_ANY, family);
ADD(alias, "mod", model != X86_MODEL_ANY, model);
strcat(alias, ":feature:*");
if (feature != X86_FEATURE_ANY)
sprintf(alias + strlen(alias), "%04X*", feature);
- return 1;
+
+ module_alias_printf(mod, false, "cpu:type:x86,%s", alias);
}
/* LOOKS like cpu:type:*:feature:*FEAT* */
-static int do_cpu_entry(const char *filename, void *symval, char *alias)
+static void do_cpu_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, cpu_feature, feature);
- sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
- return 1;
+ module_alias_printf(mod, false, "cpu:type:*:feature:*%04X*", feature);
}
/* Looks like: mei:S:uuid:N:* */
-static int do_mei_entry(const char *filename, void *symval,
- char *alias)
+static void do_mei_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD_ADDR(symval, mei_cl_device_id, name);
DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid);
DEF_FIELD(symval, mei_cl_device_id, version);
- sprintf(alias, MEI_CL_MODULE_PREFIX);
- sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*");
add_uuid(alias, *uuid);
ADD(alias, ":", version != MEI_CL_VERSION_ANY, version);
- strcat(alias, ":*");
-
- return 1;
+ module_alias_printf(mod, false, MEI_CL_MODULE_PREFIX "%s:%s:*",
+ (*name)[0] ? *name : "*", alias);
}
/* Looks like: rapidio:vNdNavNadN */
-static int do_rio_entry(const char *filename,
- void *symval, char *alias)
+static void do_rio_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, rio_device_id, did);
DEF_FIELD(symval, rio_device_id, vid);
DEF_FIELD(symval, rio_device_id, asm_did);
DEF_FIELD(symval, rio_device_id, asm_vid);
- strcpy(alias, "rapidio:");
ADD(alias, "v", vid != RIO_ANY_ID, vid);
ADD(alias, "d", did != RIO_ANY_ID, did);
ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid);
ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "rapidio:%s", alias);
}
/* Looks like: ulpi:vNpN */
-static int do_ulpi_entry(const char *filename, void *symval,
- char *alias)
+static void do_ulpi_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, ulpi_device_id, vendor);
DEF_FIELD(symval, ulpi_device_id, product);
- sprintf(alias, "ulpi:v%04xp%04x", vendor, product);
-
- return 1;
+ module_alias_printf(mod, false, "ulpi:v%04xp%04x", vendor, product);
}
/* Looks like: hdaudio:vNrNaN */
-static int do_hda_entry(const char *filename, void *symval, char *alias)
+static void do_hda_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, hda_device_id, vendor_id);
DEF_FIELD(symval, hda_device_id, rev_id);
DEF_FIELD(symval, hda_device_id, api_version);
- strcpy(alias, "hdaudio:");
ADD(alias, "v", vendor_id != 0, vendor_id);
ADD(alias, "r", rev_id != 0, rev_id);
ADD(alias, "a", api_version != 0, api_version);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "hdaudio:%s", alias);
}
/* Looks like: sdw:mNpNvNcN */
-static int do_sdw_entry(const char *filename, void *symval, char *alias)
+static void do_sdw_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, sdw_device_id, mfg_id);
DEF_FIELD(symval, sdw_device_id, part_id);
DEF_FIELD(symval, sdw_device_id, sdw_version);
DEF_FIELD(symval, sdw_device_id, class_id);
- strcpy(alias, "sdw:");
ADD(alias, "m", mfg_id != 0, mfg_id);
ADD(alias, "p", part_id != 0, part_id);
ADD(alias, "v", sdw_version != 0, sdw_version);
ADD(alias, "c", class_id != 0, class_id);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "sdw:%s", alias);
}
/* Looks like: fsl-mc:vNdN */
-static int do_fsl_mc_entry(const char *filename, void *symval,
- char *alias)
+static void do_fsl_mc_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, fsl_mc_device_id, vendor);
DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type);
- sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type);
- return 1;
+ module_alias_printf(mod, false, "fsl-mc:v%08Xd%s", vendor, *obj_type);
}
/* Looks like: tbsvc:kSpNvNrN */
-static int do_tbsvc_entry(const char *filename, void *symval, char *alias)
+static void do_tbsvc_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, tb_service_id, match_flags);
DEF_FIELD_ADDR(symval, tb_service_id, protocol_key);
DEF_FIELD(symval, tb_service_id, protocol_id);
DEF_FIELD(symval, tb_service_id, protocol_version);
DEF_FIELD(symval, tb_service_id, protocol_revision);
- strcpy(alias, "tbsvc:");
if (match_flags & TBSVC_MATCH_PROTOCOL_KEY)
sprintf(alias + strlen(alias), "k%s", *protocol_key);
else
@@ -1339,93 +1218,80 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias)
ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION,
protocol_revision);
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "tbsvc:%s", alias);
}
/* Looks like: typec:idNmN */
-static int do_typec_entry(const char *filename, void *symval, char *alias)
+static void do_typec_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, typec_device_id, svid);
DEF_FIELD(symval, typec_device_id, mode);
- sprintf(alias, "typec:id%04X", svid);
ADD(alias, "m", mode != TYPEC_ANY_MODE, mode);
- return 1;
+ module_alias_printf(mod, false, "typec:id%04X%s", svid, alias);
}
/* Looks like: tee:uuid */
-static int do_tee_entry(const char *filename, void *symval, char *alias)
+static void do_tee_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, tee_client_device_id, uuid);
- sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ module_alias_printf(mod, true,
+ "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4],
uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9],
uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14],
uuid->b[15]);
-
- add_wildcard(alias);
- return 1;
}
/* Looks like: wmi:guid */
-static int do_wmi_entry(const char *filename, void *symval, char *alias)
+static void do_wmi_entry(struct module *mod, void *symval)
{
- int len;
DEF_FIELD_ADDR(symval, wmi_device_id, guid_string);
if (strlen(*guid_string) != UUID_STRING_LEN) {
warn("Invalid WMI device id 'wmi:%s' in '%s'\n",
- *guid_string, filename);
- return 0;
+ *guid_string, mod->name);
+ return;
}
- len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string);
- if (len < 0 || len >= ALIAS_SIZE) {
- warn("Could not generate all MODULE_ALIAS's in '%s'\n",
- filename);
- return 0;
- }
- return 1;
+ module_alias_printf(mod, false, WMI_MODULE_PREFIX "%s", *guid_string);
}
/* Looks like: mhi:S */
-static int do_mhi_entry(const char *filename, void *symval, char *alias)
+static void do_mhi_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, mhi_device_id, chan);
- sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan);
- return 1;
+ module_alias_printf(mod, false, MHI_DEVICE_MODALIAS_FMT, *chan);
}
/* Looks like: mhi_ep:S */
-static int do_mhi_ep_entry(const char *filename, void *symval, char *alias)
+static void do_mhi_ep_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, mhi_device_id, chan);
- sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan);
- return 1;
+ module_alias_printf(mod, false, MHI_EP_DEVICE_MODALIAS_FMT, *chan);
}
/* Looks like: ishtp:{guid} */
-static int do_ishtp_entry(const char *filename, void *symval, char *alias)
+static void do_ishtp_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
DEF_FIELD_ADDR(symval, ishtp_device_id, guid);
- strcpy(alias, ISHTP_MODULE_PREFIX "{");
add_guid(alias, *guid);
- strcat(alias, "}");
- return 1;
+ module_alias_printf(mod, false, ISHTP_MODULE_PREFIX "{%s}", alias);
}
-static int do_auxiliary_entry(const char *filename, void *symval, char *alias)
+static void do_auxiliary_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, auxiliary_device_id, name);
- sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name);
- return 1;
+ module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name);
}
/*
@@ -1433,8 +1299,10 @@ static int do_auxiliary_entry(const char *filename, void *symval, char *alias)
*
* N is exactly 2 digits, where each is an upper-case hex digit.
*/
-static int do_ssam_entry(const char *filename, void *symval, char *alias)
+static void do_ssam_entry(struct module *mod, void *symval)
{
+ char alias[256] = {};
+
DEF_FIELD(symval, ssam_device_id, match_flags);
DEF_FIELD(symval, ssam_device_id, domain);
DEF_FIELD(symval, ssam_device_id, category);
@@ -1442,30 +1310,28 @@ static int do_ssam_entry(const char *filename, void *symval, char *alias)
DEF_FIELD(symval, ssam_device_id, instance);
DEF_FIELD(symval, ssam_device_id, function);
- sprintf(alias, "ssam:d%02Xc%02X", domain, category);
ADD(alias, "t", match_flags & SSAM_MATCH_TARGET, target);
ADD(alias, "i", match_flags & SSAM_MATCH_INSTANCE, instance);
ADD(alias, "f", match_flags & SSAM_MATCH_FUNCTION, function);
- return 1;
+ module_alias_printf(mod, false, "ssam:d%02Xc%02X%s",
+ domain, category, alias);
}
/* Looks like: dfl:tNfN */
-static int do_dfl_entry(const char *filename, void *symval, char *alias)
+static void do_dfl_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, dfl_device_id, type);
DEF_FIELD(symval, dfl_device_id, feature_id);
- sprintf(alias, "dfl:t%04Xf%04X", type, feature_id);
-
- add_wildcard(alias);
- return 1;
+ module_alias_printf(mod, true, "dfl:t%04Xf%04X", type, feature_id);
}
/* Looks like: cdx:vNdN */
-static int do_cdx_entry(const char *filename, void *symval,
- char *alias)
+static void do_cdx_entry(struct module *mod, void *symval)
{
+ char alias[256];
+
DEF_FIELD(symval, cdx_device_id, vendor);
DEF_FIELD(symval, cdx_device_id, device);
DEF_FIELD(symval, cdx_device_id, subvendor);
@@ -1484,7 +1350,7 @@ static int do_cdx_entry(const char *filename, void *symval,
default:
warn("Unknown CDX driver_override alias %08X\n",
override_only);
- return 0;
+ return;
}
ADD(alias, "v", vendor != CDX_ANY_ID, vendor);
@@ -1493,24 +1359,22 @@ static int do_cdx_entry(const char *filename, void *symval,
ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice);
ADD(alias, "c", class_mask == 0xFFFFFF, class);
- return 1;
+ module_alias_printf(mod, false, "%s", alias);
}
-static int do_vchiq_entry(const char *filename, void *symval, char *alias)
+static void do_vchiq_entry(struct module *mod, void *symval)
{
DEF_FIELD_ADDR(symval, vchiq_device_id, name);
- sprintf(alias, "vchiq:%s", *name);
- return 1;
+ module_alias_printf(mod, false, "vchiq:%s", *name);
}
/* Looks like: coreboot:tN */
-static int do_coreboot_entry(const char *filename, void *symval, char *alias)
+static void do_coreboot_entry(struct module *mod, void *symval)
{
DEF_FIELD(symval, coreboot_device_id, tag);
- sprintf(alias, "coreboot:t%08X", tag);
- return 1;
+ module_alias_printf(mod, false, "coreboot:t%08X", tag);
}
/* Does namelen bytes of name exactly match the symbol? */
@@ -1522,25 +1386,34 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol)
return memcmp(name, symbol, namelen) == 0;
}
-static void do_table(void *symval, unsigned long size,
+static void do_table(const char *name, void *symval, unsigned long size,
unsigned long id_size,
const char *device_id,
- int (*do_entry)(const char *filename, void *symval, char *alias),
+ void (*do_entry)(struct module *mod, void *symval),
struct module *mod)
{
unsigned int i;
- char alias[ALIAS_SIZE];
- device_id_check(mod->name, device_id, size, id_size, symval);
- /* Leave last one: it's the terminator. */
- size -= id_size;
+ if (size % id_size || size < id_size) {
+ error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n",
+ mod->name, name, device_id);
+ return;
+ }
- for (i = 0; i < size; i += id_size) {
- if (do_entry(mod->name, symval+i, alias)) {
- buf_printf(&mod->dev_table_buf,
- "MODULE_ALIAS(\"%s\");\n", alias);
+ /* Verify the last entry is a terminator */
+ for (i = size - id_size; i < size; i++) {
+ if (*(uint8_t *)(symval + i)) {
+ error("%s: %s[] is not terminated with a NULL entry\n",
+ mod->name, name);
+ return;
}
}
+
+ /* Leave last one: it's the terminator. */
+ size -= id_size;
+
+ for (i = 0; i < size; i += id_size)
+ do_entry(mod, symval + i);
}
static const struct devtable devtable[] = {
@@ -1596,6 +1469,10 @@ static const struct devtable devtable[] = {
{"cdx", SIZE_cdx_device_id, do_cdx_entry},
{"vchiq", SIZE_vchiq_device_id, do_vchiq_entry},
{"coreboot", SIZE_coreboot_device_id, do_coreboot_entry},
+ {"of", SIZE_of_device_id, do_of_entry},
+ {"usb", SIZE_usb_device_id, do_usb_entry_multi},
+ {"pnp", SIZE_pnp_device_id, do_pnp_device_entry},
+ {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry},
};
/* Create MODULE_ALIAS() statements.
@@ -1606,8 +1483,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
{
void *symval;
char *zeros = NULL;
- const char *name, *identifier;
- unsigned int namelen;
+ const char *type, *name;
+ size_t typelen;
+ static const char *prefix = "__mod_device_table__";
/* We're looking for a section relative symbol */
if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
@@ -1617,19 +1495,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
return;
- /* All our symbols are of form __mod_<name>__<identifier>_device_table. */
- if (strncmp(symname, "__mod_", strlen("__mod_")))
- return;
- name = symname + strlen("__mod_");
- namelen = strlen(name);
- if (namelen < strlen("_device_table"))
- return;
- if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
+ /* All our symbols are of form __mod_device_table__<type>__<name>. */
+ if (!strstarts(symname, prefix))
return;
- identifier = strstr(name, "__");
- if (!identifier)
+ type = symname + strlen(prefix);
+
+ name = strstr(type, "__");
+ if (!name)
return;
- namelen = identifier - name;
+ typelen = name - type;
+ name += strlen("__");
/* Handle all-NULL symbols allocated into .bss */
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
@@ -1639,35 +1514,15 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
symval = sym_get_data(info, sym);
}
- /* First handle the "special" cases */
- if (sym_is(name, namelen, "usb"))
- do_usb_table(symval, sym->st_size, mod);
- else if (sym_is(name, namelen, "of"))
- do_of_table(symval, sym->st_size, mod);
- else if (sym_is(name, namelen, "pnp"))
- do_pnp_device_entry(symval, sym->st_size, mod);
- else if (sym_is(name, namelen, "pnp_card"))
- do_pnp_card_entries(symval, sym->st_size, mod);
- else {
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devtable); i++) {
- const struct devtable *p = &devtable[i];
+ for (int i = 0; i < ARRAY_SIZE(devtable); i++) {
+ const struct devtable *p = &devtable[i];
- if (sym_is(name, namelen, p->device_id)) {
- do_table(symval, sym->st_size, p->id_size,
- p->device_id, p->do_entry, mod);
- break;
- }
+ if (sym_is(type, typelen, p->device_id)) {
+ do_table(name, symval, sym->st_size, p->id_size,
+ p->device_id, p->do_entry, mod);
+ break;
}
}
- free(zeros);
-}
-/* Now add out buffered information to the generated C source */
-void add_moddevtable(struct buffer *buf, struct module *mod)
-{
- buf_printf(buf, "\n");
- buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
- free(mod->dev_table_buf.p);
+ free(zeros);
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 107393a8c48a..0584cbcdbd2d 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -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);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index ada3a36cc4bc..49848fcbe2a1 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -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);
diff --git a/scripts/nsdeps b/scripts/nsdeps
index f1718cc0d700..bab4ec870e50 100644
--- a/scripts/nsdeps
+++ b/scripts/nsdeps
@@ -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
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 441b0bb66e0d..fb686fd3266f 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -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"
-
- mkdir -p "${dbg%/*}" "${link%/*}"
- "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
- ln -sf --relative "${dbg}" "${link}"
- done < modules.order
+ 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
+ fi
# Build debug package
# Different tools want the image in different locations
diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build
index 7ec1f061a519..64d958ee45f3 100755
--- a/scripts/package/install-extmod-build
+++ b/scripts/package/install-extmod-build
@@ -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
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
index fc3b7fa709fc..4ffcc70f8e31 100755
--- a/scripts/package/mkdebian
+++ b/scripts/package/mkdebian
@@ -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
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 38b96c6797f4..28169d7e143b 100755
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -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