From 8d18ef04f940a8d336fe7915b5ea419c3eb0c0a6 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Thu, 18 Sep 2025 10:05:45 +0200 Subject: [PATCH 1/8] s390: vmlinux.lds.S: Reorder sections In the upcoming changes, the ELF_DETAILS macro will be extended with the ".modinfo" section, which will cause an error: >> s390x-linux-ld: .tmp_vmlinux1: warning: allocated section `.modinfo' not in segment >> s390x-linux-ld: .tmp_vmlinux2: warning: allocated section `.modinfo' not in segment >> s390x-linux-ld: vmlinux.unstripped: warning: allocated section `.modinfo' not in segment This happens because the .vmlinux.info use :NONE to override the default segment and tell the linker to not put the section in any segment at all. To avoid this, we need to change the sections order that will be placed in the default segment. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Cc: linux-s390@vger.kernel.org Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506062053.zbkFBEnJ-lkp@intel.com/ Signed-off-by: Alexey Gladkov Acked-by: Heiko Carstens Link: https://patch.msgid.link/20d40a7a3a053ba06a54155e777dcde7fdada1db.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- arch/s390/kernel/vmlinux.lds.S | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 1c606dfa595d..feecf1a6ddb4 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -209,6 +209,11 @@ SECTIONS . = ALIGN(PAGE_SIZE); _end = . ; + /* Debugging sections. */ + STABS_DEBUG + DWARF_DEBUG + ELF_DETAILS + /* * uncompressed image info used by the decompressor * it should match struct vmlinux_info @@ -239,11 +244,6 @@ SECTIONS #endif } :NONE - /* Debugging sections. */ - STABS_DEBUG - DWARF_DEBUG - ELF_DETAILS - /* * Make sure that the .got.plt is either completely empty or it * contains only the three reserved double words. From 0ce5139fd96e9d415d3faaef1c575e238f9bbd67 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 18 Sep 2025 10:05:46 +0200 Subject: [PATCH 2/8] kbuild: always create intermediate vmlinux.unstripped Generate the intermediate vmlinux.unstripped regardless of CONFIG_ARCH_VMLINUX_NEEDS_RELOCS. If CONFIG_ARCH_VMLINUX_NEEDS_RELOCS is unset, vmlinux.unstripped and vmlinux are identiacal. This simplifies the build rule, and allows to strip more sections by adding them to remove-section-y. Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/a48ca543fa2305bd17324f41606dcaed9b19f2d4.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- scripts/Makefile.vmlinux | 45 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index b64862dc6f08..4f2d4c3fb737 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -9,20 +9,6 @@ include $(srctree)/scripts/Makefile.lib targets := -ifdef CONFIG_ARCH_VMLINUX_NEEDS_RELOCS -vmlinux-final := vmlinux.unstripped - -quiet_cmd_strip_relocs = RSTRIP $@ - cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' --remove-section=!'.rel*.dyn' $< $@ - -vmlinux: $(vmlinux-final) FORCE - $(call if_changed,strip_relocs) - -targets += vmlinux -else -vmlinux-final := vmlinux -endif - %.o: %.c FORCE $(call if_changed_rule,cc_o_c) @@ -61,19 +47,19 @@ targets += .builtin-dtbs-list ifdef CONFIG_GENERIC_BUILTIN_DTB targets += .builtin-dtbs.S .builtin-dtbs.o -$(vmlinux-final): .builtin-dtbs.o +vmlinux.unstripped: .builtin-dtbs.o endif -# vmlinux +# vmlinux.unstripped # --------------------------------------------------------------------------- ifdef CONFIG_MODULES targets += .vmlinux.export.o -$(vmlinux-final): .vmlinux.export.o +vmlinux.unstripped: .vmlinux.export.o endif ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX -$(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o +vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@ @@ -86,17 +72,30 @@ cmd_link_vmlinux = \ $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -targets += $(vmlinux-final) -$(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +targets += vmlinux.unstripped +vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) ifdef CONFIG_DEBUG_INFO_BTF -$(vmlinux-final): $(RESOLVE_BTFIDS) +vmlinux.unstripped: $(RESOLVE_BTFIDS) endif ifdef CONFIG_BUILDTIME_TABLE_SORT -$(vmlinux-final): scripts/sorttable +vmlinux.unstripped: scripts/sorttable endif +# vmlinux +# --------------------------------------------------------------------------- + +remove-section-y := +remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' + +quiet_cmd_strip_relocs = OBJCOPY $@ + cmd_strip_relocs = $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $< $@ + +targets += vmlinux +vmlinux: vmlinux.unstripped FORCE + $(call if_changed,strip_relocs) + # modules.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES @@ -110,7 +109,7 @@ modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \ modules.builtin vmlinux.map vmlinux.o.map FORCE $(call if_changed,modules_builtin_ranges) -vmlinux.map: $(vmlinux-final) +vmlinux.map: vmlinux.unstripped @: endif From 3e86e4d74c0490e5fc5a7f8de8f29e7579c9ffe5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 18 Sep 2025 10:05:47 +0200 Subject: [PATCH 3/8] kbuild: keep .modinfo section in vmlinux.unstripped Keep the .modinfo section during linking, but strip it from the final vmlinux. Adjust scripts/mksysmap to exclude modinfo symbols from kallsyms. This change will allow the next commit to extract the .modinfo section from the vmlinux.unstripped intermediate. Signed-off-by: Masahiro Yamada Signed-off-by: Alexey Gladkov Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/aaf67c07447215463300fccaa758904bac42f992.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- include/asm-generic/vmlinux.lds.h | 2 +- scripts/Makefile.vmlinux | 7 +++++-- scripts/mksysmap | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index ae2d2359b79e..cfa63860dfd4 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -831,6 +831,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) /* Required sections not related to debugging. */ #define ELF_DETAILS \ + .modinfo : { *(.modinfo) } \ .comment 0 : { *(.comment) } \ .symtab 0 : { *(.symtab) } \ .strtab 0 : { *(.strtab) } \ @@ -1044,7 +1045,6 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) *(.discard.*) \ *(.export_symbol) \ *(.no_trim_symbol) \ - *(.modinfo) \ /* ld.bfd warns about .gnu.version* even when not emitted */ \ *(.gnu.version*) \ diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 4f2d4c3fb737..70856dab0f54 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -86,11 +86,14 @@ endif # vmlinux # --------------------------------------------------------------------------- -remove-section-y := +remove-section-y := .modinfo remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' +# To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy, +# it is necessary to remove the PT_LOAD flag from the segment. quiet_cmd_strip_relocs = OBJCOPY $@ - cmd_strip_relocs = $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $< $@ + cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \ + $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $@ targets += vmlinux vmlinux: vmlinux.unstripped FORCE diff --git a/scripts/mksysmap b/scripts/mksysmap index 3accbdb269ac..a607a0059d11 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -79,6 +79,9 @@ / _SDA_BASE_$/d / _SDA2_BASE_$/d +# MODULE_INFO() +/ __UNIQUE_ID_modinfo[0-9]*$/d + # --------------------------------------------------------------------------- # Ignored patterns # (symbols that contain the pattern are ignored) From 39cfd5b12160be4f57df1c3ba60139741c827616 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 18 Sep 2025 10:05:48 +0200 Subject: [PATCH 4/8] kbuild: extract modules.builtin.modinfo from vmlinux.unstripped Currently, we assume all the data for modules.builtin.modinfo are available in vmlinux.o. This makes it impossible for modpost, which is invoked after vmlinux.o, to add additional module info. This commit moves the modules.builtin.modinfo rule after modpost. Signed-off-by: Masahiro Yamada Signed-off-by: Alexey Gladkov Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/cdb3e5b9a739666b755cd0097dc34ab69c350e51.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- scripts/Makefile.vmlinux | 26 ++++++++++++++++++++++++++ scripts/Makefile.vmlinux_o | 26 +------------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 70856dab0f54..ce7946171497 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -99,6 +99,32 @@ targets += vmlinux vmlinux: vmlinux.unstripped FORCE $(call if_changed,strip_relocs) +# modules.builtin.modinfo +# --------------------------------------------------------------------------- + +OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary + +targets += modules.builtin.modinfo +modules.builtin.modinfo: vmlinux.unstripped FORCE + $(call if_changed,objcopy) + +# modules.builtin +# --------------------------------------------------------------------------- + +__default: modules.builtin + +# The second line aids cases where multiple modules share the same object. + +quiet_cmd_modules_builtin = GEN $@ + cmd_modules_builtin = \ + tr '\0' '\n' < $< | \ + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ + +targets += modules.builtin +modules.builtin: modules.builtin.modinfo FORCE + $(call if_changed,modules_builtin) + # modules.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index b024ffb3e201..23c8751285d7 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only PHONY := __default -__default: vmlinux.o modules.builtin.modinfo modules.builtin +__default: vmlinux.o include include/config/auto.conf include $(srctree)/scripts/Kbuild.include @@ -73,30 +73,6 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE targets += vmlinux.o -# modules.builtin.modinfo -# --------------------------------------------------------------------------- - -OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary - -targets += modules.builtin.modinfo -modules.builtin.modinfo: vmlinux.o FORCE - $(call if_changed,objcopy) - -# modules.builtin -# --------------------------------------------------------------------------- - -# The second line aids cases where multiple modules share the same object. - -quiet_cmd_modules_builtin = GEN $@ - cmd_modules_builtin = \ - tr '\0' '\n' < $< | \ - sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ - tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ - -targets += modules.builtin -modules.builtin: modules.builtin.modinfo FORCE - $(call if_changed,modules_builtin) - # Add FORCE to the prerequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- From b88f88c26705ad436ff9675258f76082dd43996a Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Thu, 18 Sep 2025 10:05:49 +0200 Subject: [PATCH 5/8] scsi: Always define blogic_pci_tbl structure The blogic_pci_tbl structure is used by the MODULE_DEVICE_TABLE macro. There is no longer a need to protect it with the MODULE condition, since this no longer causes the compiler to warn about an unused variable. To avoid warnings when -Wunused-const-variable option is used, mark it as __maybe_unused for such configuration. Cc: Khalid Aziz Cc: Martin K. Petersen Cc: linux-scsi@vger.kernel.org Suggested-by: James Bottomley Signed-off-by: Alexey Gladkov Signed-off-by: Arnd Bergmann Reviewed-by: Damien Le Moal Acked-by: Martin K. Petersen Link: https://patch.msgid.link/fd8e30de07de79a4923ae967eaee5ba2f2fcef00.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- drivers/scsi/BusLogic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 1f100270cd38..82597bd96525 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3715,7 +3715,6 @@ static void __exit blogic_exit(void) __setup("BusLogic=", blogic_setup); -#ifdef MODULE /*static const struct pci_device_id blogic_pci_tbl[] = { { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -3725,13 +3724,12 @@ __setup("BusLogic=", blogic_setup); PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } };*/ -static const struct pci_device_id blogic_pci_tbl[] = { +static const struct pci_device_id blogic_pci_tbl[] __maybe_unused = { {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)}, {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)}, {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)}, {0, }, }; -#endif MODULE_DEVICE_TABLE(pci, blogic_pci_tbl); module_init(blogic_init); From 83fb49389bbe07defb85b063f7ff0fd016f06b35 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Thu, 18 Sep 2025 10:05:50 +0200 Subject: [PATCH 6/8] modpost: Add modname to mod_device_table alias At this point, if a symbol is compiled as part of the kernel, information about which module the symbol belongs to is lost. To save this it is possible to add the module name to the alias name. It's not very pretty, but it's possible for now. Cc: Miguel Ojeda Cc: Andreas Hindborg Cc: Danilo Krummrich Cc: Alex Gaynor Cc: rust-for-linux@vger.kernel.org Signed-off-by: Alexey Gladkov Acked-by: Danilo Krummrich Acked-by: Nicolas Schier Link: https://patch.msgid.link/1a0d0bd87a4981d465b9ed21e14f4e78eaa03ded.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- include/linux/module.h | 14 +++++++++++++- rust/kernel/device_id.rs | 8 ++++---- scripts/mod/file2alias.c | 15 ++++++++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 3319a5269d28..e31ee29fac6b 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -244,10 +244,22 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); /* What your module does. */ #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) +/* + * Format: __mod_device_table__kmod_____ + * Parts of the string `__kmod_` and `__` are used as delimiters when parsing + * a symbol in file2alias.c + */ +#define __mod_device_table(type, name) \ + __PASTE(__mod_device_table__, \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __PASTE(type, \ + __PASTE(__, name))))) + #ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ -static typeof(name) __mod_device_table__##type##__##name \ +static typeof(name) __mod_device_table(type, name) \ __attribute__ ((used, alias(__stringify(name)))) #else /* !MODULE */ #define MODULE_DEVICE_TABLE(type, name) diff --git a/rust/kernel/device_id.rs b/rust/kernel/device_id.rs index 70d57814ff79..62c42da12e9d 100644 --- a/rust/kernel/device_id.rs +++ b/rust/kernel/device_id.rs @@ -195,10 +195,10 @@ macro_rules! module_device_table { ($table_type: literal, $module_table_name:ident, $table_name:ident) => { #[rustfmt::skip] #[export_name = - concat!("__mod_device_table__", $table_type, - "__", module_path!(), - "_", line!(), - "_", stringify!($table_name)) + concat!("__mod_device_table__", line!(), + "__kmod_", module_path!(), + "__", $table_type, + "__", stringify!($table_name)) ] static $module_table_name: [::core::mem::MaybeUninit; $table_name.raw_ids().size()] = unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) }; diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 00586119a25b..1260bc2287fb 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1476,7 +1476,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; - const char *type, *name; + const char *type, *name, *modname; size_t typelen; static const char *prefix = "__mod_device_table__"; @@ -1488,10 +1488,19 @@ 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_device_table____. */ + /* All our symbols are of form __mod_device_table__kmod_____. */ if (!strstarts(symname, prefix)) return; - type = symname + strlen(prefix); + + modname = strstr(symname, "__kmod_"); + if (!modname) + return; + modname += strlen("__kmod_"); + + type = strstr(modname, "__"); + if (!type) + return; + type += strlen("__"); name = strstr(type, "__"); if (!name) From 5ab23c7923a1d2ae1890026866a2d8506b010a4a Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Thu, 18 Sep 2025 10:05:51 +0200 Subject: [PATCH 7/8] modpost: Create modalias for builtin modules For some modules, modalias is generated using the modpost utility and the section is added to the module file. When a module is added inside vmlinux, modpost does not generate modalias for such modules and the information is lost. As a result kmod (which uses modules.builtin.modinfo in userspace) cannot determine that modalias is handled by a builtin kernel module. $ cat /sys/devices/pci0000:00/0000:00:14.0/modalias pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 $ modinfo xhci_pci name: xhci_pci filename: (builtin) license: GPL file: drivers/usb/host/xhci-pci description: xHCI PCI Host Controller Driver Missing modalias "pci:v*d*sv*sd*bc0Csc03i30*" which will be generated by modpost if the module is built separately. To fix this it is necessary to generate the same modalias for vmlinux as for the individual modules. Fortunately '.vmlinux.export.o' is already generated from which '.modinfo' can be extracted in the same way as for vmlinux.o. Signed-off-by: Masahiro Yamada Signed-off-by: Alexey Gladkov Tested-by: Stephen Rothwell Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/28d4da3b0e3fc8474142746bcf469e03752c3208.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- include/linux/module.h | 4 ---- scripts/Makefile.vmlinux | 4 +++- scripts/mksysmap | 3 +++ scripts/mod/file2alias.c | 19 ++++++++++++++++++- scripts/mod/modpost.c | 15 +++++++++++++++ scripts/mod/modpost.h | 2 ++ 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index e31ee29fac6b..e135cc79acee 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -256,14 +256,10 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); __PASTE(type, \ __PASTE(__, name))))) -#ifdef MODULE /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ static typeof(name) __mod_device_table(type, name) \ __attribute__ ((used, alias(__stringify(name)))) -#else /* !MODULE */ -#define MODULE_DEVICE_TABLE(type, name) -#endif /* Version of form [:][-]. * Or for CVS/RCS ID version, everything but the number is stripped. diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index ce7946171497..1e5e37aadcd0 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -89,11 +89,13 @@ endif remove-section-y := .modinfo remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' +remove-symbols := -w --strip-symbol='__mod_device_table__*' + # To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy, # it is necessary to remove the PT_LOAD flag from the segment. quiet_cmd_strip_relocs = OBJCOPY $@ cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \ - $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $@ + $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@ targets += vmlinux vmlinux: vmlinux.unstripped FORCE diff --git a/scripts/mksysmap b/scripts/mksysmap index a607a0059d11..c4531eacde20 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -59,6 +59,9 @@ # EXPORT_SYMBOL (namespace) / __kstrtabns_/d +# MODULE_DEVICE_TABLE (symbol name) +/ __mod_device_table__/d + # --------------------------------------------------------------------------- # Ignored suffixes # (do not forget '$' after each pattern) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 1260bc2287fb..7da9735e7ab3 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1477,7 +1477,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, void *symval; char *zeros = NULL; const char *type, *name, *modname; - size_t typelen; + size_t typelen, modnamelen; static const char *prefix = "__mod_device_table__"; /* We're looking for a section relative symbol */ @@ -1500,6 +1500,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, type = strstr(modname, "__"); if (!type) return; + modnamelen = type - modname; type += strlen("__"); name = strstr(type, "__"); @@ -1526,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, } } + if (mod->is_vmlinux) { + struct module_alias *alias; + + /* + * If this is vmlinux, record the name of the builtin module. + * Traverse the linked list in the reverse order, and set the + * builtin_modname unless it has already been set in the + * previous call. + */ + list_for_each_entry_reverse(alias, &mod->aliases, node) { + if (alias->builtin_modname) + break; + alias->builtin_modname = xstrndup(modname, modnamelen); + } + } + free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5ca7c268294e..47c8aa2a6939 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname) static void write_vmlinux_export_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; buf_printf(&buf, "#include \n"); add_exported_symbols(&buf, mod); + + buf_printf(&buf, + "#include \n" + "#undef __MODULE_INFO_PREFIX\n" + "#define __MODULE_INFO_PREFIX\n"); + + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n", + alias->builtin_modname, alias->str); + list_del(&alias->node); + free(alias->builtin_modname); + free(alias); + } + write_if_changed(&buf, ".vmlinux.export.c"); free(buf.p); } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9133e4c3803f..2aecb8f25c87 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len); * struct module_alias - auto-generated MODULE_ALIAS() * * @node: linked to module::aliases + * @modname: name of the builtin module (only for vmlinux) * @str: a string for MODULE_ALIAS() */ struct module_alias { struct list_head node; + char *builtin_modname; char str[]; }; From 3328d39a8dca2d6ed27197a0025df7540b99adf2 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Thu, 18 Sep 2025 10:05:52 +0200 Subject: [PATCH 8/8] kbuild: vmlinux.unstripped should always depend on .vmlinux.export.o Since .vmlinux.export.c is used to add generated by modpost modaliases for builtin modules the .vmlinux.export.o is no longer optional and should always be created. The generation of this file is not dependent on CONFIG_MODULES. Signed-off-by: Alexey Gladkov Reviewed-by: Nicolas Schier Link: https://patch.msgid.link/0e63a9c7741fe8217e4fd7c60afcf057ffa2ef5a.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor --- scripts/Makefile.vmlinux | 9 ++------- scripts/link-vmlinux.sh | 5 +---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 1e5e37aadcd0..7c6ae9886f8f 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -53,11 +53,6 @@ endif # vmlinux.unstripped # --------------------------------------------------------------------------- -ifdef CONFIG_MODULES -targets += .vmlinux.export.o -vmlinux.unstripped: .vmlinux.export.o -endif - ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o @@ -72,8 +67,8 @@ cmd_link_vmlinux = \ $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -targets += vmlinux.unstripped -vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +targets += vmlinux.unstripped .vmlinux.export.o +vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) ifdef CONFIG_DEBUG_INFO_BTF vmlinux.unstripped: $(RESOLVE_BTFIDS) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 51367c2bfc21..433849ff7529 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -73,10 +73,7 @@ vmlinux_link() objs="${objs} .builtin-dtbs.o" fi - if is_enabled CONFIG_MODULES; then - objs="${objs} .vmlinux.export.o" - fi - + objs="${objs} .vmlinux.export.o" objs="${objs} init/version-timestamp.o" if [ "${SRCARCH}" = "um" ]; then