Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "Add generated modalias to modules.builtin.modinfo"

Alexey Gladkov says:

The modules.builtin.modinfo file is used by userspace (kmod to be specific) to
get information about builtin modules. Among other information about the module,
information about module aliases is stored. This is very important to determine
that a particular modalias will be handled by a module that is inside the
kernel.

There are several mechanisms for creating modalias for modules:

The first is to explicitly specify the MODULE_ALIAS of the macro. In this case,
the aliases go into the '.modinfo' section of the module if it is compiled
separately or into vmlinux.o if it is builtin into the kernel.

The second is the use of MODULE_DEVICE_TABLE followed by the use of the
modpost utility. In this case, vmlinux.o no longer has this information and
does not get it into modules.builtin.modinfo.

For example:

$ modinfo pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30
modinfo: ERROR: Module pci:v00008086d0000A36Dsv00001043sd00008694bc0Csc03i30 not found.

$ modinfo xhci_pci
name: xhci_pci
filename: (builtin)
license: GPL
file: drivers/usb/host/xhci-pci
description: xHCI PCI Host Controller Driver

The builtin module is missing alias "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 add the generated by modpost modalias to
modules.builtin.modinfo. Fortunately modpost already generates .vmlinux.export.c
for exported symbols. It is possible to add `.modinfo` for builtin modules and
modify the build system so that `.modinfo` section is extracted from the
intermediate vmlinux after modpost is executed.

Link: https://patch.msgid.link/cover.1758182101.git.legion@kernel.org
Signed-off-by: Nathan Chancellor <nathan@kernel.org>

+131 -78
+5 -5
arch/s390/kernel/vmlinux.lds.S
··· 209 209 . = ALIGN(PAGE_SIZE); 210 210 _end = . ; 211 211 212 + /* Debugging sections. */ 213 + STABS_DEBUG 214 + DWARF_DEBUG 215 + ELF_DETAILS 216 + 212 217 /* 213 218 * uncompressed image info used by the decompressor 214 219 * it should match struct vmlinux_info ··· 243 238 QUAD(kasan_early_shadow_p4d) 244 239 #endif 245 240 } :NONE 246 - 247 - /* Debugging sections. */ 248 - STABS_DEBUG 249 - DWARF_DEBUG 250 - ELF_DETAILS 251 241 252 242 /* 253 243 * Make sure that the .got.plt is either completely empty or it
+1 -3
drivers/scsi/BusLogic.c
··· 3715 3715 3716 3716 __setup("BusLogic=", blogic_setup); 3717 3717 3718 - #ifdef MODULE 3719 3718 /*static const struct pci_device_id blogic_pci_tbl[] = { 3720 3719 { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, 3721 3720 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ··· 3724 3725 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 3725 3726 { } 3726 3727 };*/ 3727 - static const struct pci_device_id blogic_pci_tbl[] = { 3728 + static const struct pci_device_id blogic_pci_tbl[] __maybe_unused = { 3728 3729 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)}, 3729 3730 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)}, 3730 3731 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)}, 3731 3732 {0, }, 3732 3733 }; 3733 - #endif 3734 3734 MODULE_DEVICE_TABLE(pci, blogic_pci_tbl); 3735 3735 3736 3736 module_init(blogic_init);
+1 -1
include/asm-generic/vmlinux.lds.h
··· 831 831 832 832 /* Required sections not related to debugging. */ 833 833 #define ELF_DETAILS \ 834 + .modinfo : { *(.modinfo) } \ 834 835 .comment 0 : { *(.comment) } \ 835 836 .symtab 0 : { *(.symtab) } \ 836 837 .strtab 0 : { *(.strtab) } \ ··· 1045 1044 *(.discard.*) \ 1046 1045 *(.export_symbol) \ 1047 1046 *(.no_trim_symbol) \ 1048 - *(.modinfo) \ 1049 1047 /* ld.bfd warns about .gnu.version* even when not emitted */ \ 1050 1048 *(.gnu.version*) \ 1051 1049
+13 -5
include/linux/module.h
··· 244 244 /* What your module does. */ 245 245 #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) 246 246 247 - #ifdef MODULE 247 + /* 248 + * Format: __mod_device_table__kmod_<modname>__<type>__<name> 249 + * Parts of the string `__kmod_` and `__` are used as delimiters when parsing 250 + * a symbol in file2alias.c 251 + */ 252 + #define __mod_device_table(type, name) \ 253 + __PASTE(__mod_device_table__, \ 254 + __PASTE(__KBUILD_MODNAME, \ 255 + __PASTE(__, \ 256 + __PASTE(type, \ 257 + __PASTE(__, name))))) 258 + 248 259 /* Creates an alias so file2alias.c can find device table. */ 249 260 #define MODULE_DEVICE_TABLE(type, name) \ 250 - static typeof(name) __mod_device_table__##type##__##name \ 261 + static typeof(name) __mod_device_table(type, name) \ 251 262 __attribute__ ((used, alias(__stringify(name)))) 252 - #else /* !MODULE */ 253 - #define MODULE_DEVICE_TABLE(type, name) 254 - #endif 255 263 256 264 /* Version of form [<epoch>:]<version>[-<extra-version>]. 257 265 * Or for CVS/RCS ID version, everything but the number is stripped.
+4 -4
rust/kernel/device_id.rs
··· 195 195 ($table_type: literal, $module_table_name:ident, $table_name:ident) => { 196 196 #[rustfmt::skip] 197 197 #[export_name = 198 - concat!("__mod_device_table__", $table_type, 199 - "__", module_path!(), 200 - "_", line!(), 201 - "_", stringify!($table_name)) 198 + concat!("__mod_device_table__", line!(), 199 + "__kmod_", module_path!(), 200 + "__", $table_type, 201 + "__", stringify!($table_name)) 202 202 ] 203 203 static $module_table_name: [::core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] = 204 204 unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) };
+52 -27
scripts/Makefile.vmlinux
··· 9 9 10 10 targets := 11 11 12 - ifdef CONFIG_ARCH_VMLINUX_NEEDS_RELOCS 13 - vmlinux-final := vmlinux.unstripped 14 - 15 - quiet_cmd_strip_relocs = RSTRIP $@ 16 - cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' --remove-section=!'.rel*.dyn' $< $@ 17 - 18 - vmlinux: $(vmlinux-final) FORCE 19 - $(call if_changed,strip_relocs) 20 - 21 - targets += vmlinux 22 - else 23 - vmlinux-final := vmlinux 24 - endif 25 - 26 12 %.o: %.c FORCE 27 13 $(call if_changed_rule,cc_o_c) 28 14 ··· 47 61 48 62 ifdef CONFIG_GENERIC_BUILTIN_DTB 49 63 targets += .builtin-dtbs.S .builtin-dtbs.o 50 - $(vmlinux-final): .builtin-dtbs.o 64 + vmlinux.unstripped: .builtin-dtbs.o 51 65 endif 52 66 53 - # vmlinux 67 + # vmlinux.unstripped 54 68 # --------------------------------------------------------------------------- 55 69 56 - ifdef CONFIG_MODULES 57 - targets += .vmlinux.export.o 58 - $(vmlinux-final): .vmlinux.export.o 59 - endif 60 - 61 70 ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX 62 - $(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o 71 + vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o 63 72 64 73 arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE 65 74 $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@ ··· 67 86 $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ 68 87 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) 69 88 70 - targets += $(vmlinux-final) 71 - $(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE 89 + targets += vmlinux.unstripped .vmlinux.export.o 90 + vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE 72 91 +$(call if_changed_dep,link_vmlinux) 73 92 ifdef CONFIG_DEBUG_INFO_BTF 74 - $(vmlinux-final): $(RESOLVE_BTFIDS) 93 + vmlinux.unstripped: $(RESOLVE_BTFIDS) 75 94 endif 76 95 77 96 ifdef CONFIG_BUILDTIME_TABLE_SORT 78 - $(vmlinux-final): scripts/sorttable 97 + vmlinux.unstripped: scripts/sorttable 79 98 endif 99 + 100 + # vmlinux 101 + # --------------------------------------------------------------------------- 102 + 103 + remove-section-y := .modinfo 104 + remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' 105 + 106 + remove-symbols := -w --strip-symbol='__mod_device_table__*' 107 + 108 + # To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy, 109 + # it is necessary to remove the PT_LOAD flag from the segment. 110 + quiet_cmd_strip_relocs = OBJCOPY $@ 111 + cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \ 112 + $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@ 113 + 114 + targets += vmlinux 115 + vmlinux: vmlinux.unstripped FORCE 116 + $(call if_changed,strip_relocs) 117 + 118 + # modules.builtin.modinfo 119 + # --------------------------------------------------------------------------- 120 + 121 + OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary 122 + 123 + targets += modules.builtin.modinfo 124 + modules.builtin.modinfo: vmlinux.unstripped FORCE 125 + $(call if_changed,objcopy) 126 + 127 + # modules.builtin 128 + # --------------------------------------------------------------------------- 129 + 130 + __default: modules.builtin 131 + 132 + # The second line aids cases where multiple modules share the same object. 133 + 134 + quiet_cmd_modules_builtin = GEN $@ 135 + cmd_modules_builtin = \ 136 + tr '\0' '\n' < $< | \ 137 + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ 138 + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ 139 + 140 + targets += modules.builtin 141 + modules.builtin: modules.builtin.modinfo FORCE 142 + $(call if_changed,modules_builtin) 80 143 81 144 # modules.builtin.ranges 82 145 # --------------------------------------------------------------------------- ··· 135 110 modules.builtin vmlinux.map vmlinux.o.map FORCE 136 111 $(call if_changed,modules_builtin_ranges) 137 112 138 - vmlinux.map: $(vmlinux-final) 113 + vmlinux.map: vmlinux.unstripped 139 114 @: 140 115 141 116 endif
+1 -25
scripts/Makefile.vmlinux_o
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 PHONY := __default 4 - __default: vmlinux.o modules.builtin.modinfo modules.builtin 4 + __default: vmlinux.o 5 5 6 6 include include/config/auto.conf 7 7 include $(srctree)/scripts/Kbuild.include ··· 72 72 $(call if_changed_rule,ld_vmlinux.o) 73 73 74 74 targets += vmlinux.o 75 - 76 - # modules.builtin.modinfo 77 - # --------------------------------------------------------------------------- 78 - 79 - OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary 80 - 81 - targets += modules.builtin.modinfo 82 - modules.builtin.modinfo: vmlinux.o FORCE 83 - $(call if_changed,objcopy) 84 - 85 - # modules.builtin 86 - # --------------------------------------------------------------------------- 87 - 88 - # The second line aids cases where multiple modules share the same object. 89 - 90 - quiet_cmd_modules_builtin = GEN $@ 91 - cmd_modules_builtin = \ 92 - tr '\0' '\n' < $< | \ 93 - sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ 94 - tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ 95 - 96 - targets += modules.builtin 97 - modules.builtin: modules.builtin.modinfo FORCE 98 - $(call if_changed,modules_builtin) 99 75 100 76 # Add FORCE to the prerequisites of a target to force it to be always rebuilt. 101 77 # ---------------------------------------------------------------------------
+6
scripts/mksysmap
··· 59 59 # EXPORT_SYMBOL (namespace) 60 60 / __kstrtabns_/d 61 61 62 + # MODULE_DEVICE_TABLE (symbol name) 63 + / __mod_device_table__/d 64 + 62 65 # --------------------------------------------------------------------------- 63 66 # Ignored suffixes 64 67 # (do not forget '$' after each pattern) ··· 81 78 # ppc 82 79 / _SDA_BASE_$/d 83 80 / _SDA2_BASE_$/d 81 + 82 + # MODULE_INFO() 83 + / __UNIQUE_ID_modinfo[0-9]*$/d 84 84 85 85 # --------------------------------------------------------------------------- 86 86 # Ignored patterns
+30 -4
scripts/mod/file2alias.c
··· 1476 1476 { 1477 1477 void *symval; 1478 1478 char *zeros = NULL; 1479 - const char *type, *name; 1480 - size_t typelen; 1479 + const char *type, *name, *modname; 1480 + size_t typelen, modnamelen; 1481 1481 static const char *prefix = "__mod_device_table__"; 1482 1482 1483 1483 /* We're looking for a section relative symbol */ ··· 1488 1488 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) 1489 1489 return; 1490 1490 1491 - /* All our symbols are of form __mod_device_table__<type>__<name>. */ 1491 + /* All our symbols are of form __mod_device_table__kmod_<modname>__<type>__<name>. */ 1492 1492 if (!strstarts(symname, prefix)) 1493 1493 return; 1494 - type = symname + strlen(prefix); 1494 + 1495 + modname = strstr(symname, "__kmod_"); 1496 + if (!modname) 1497 + return; 1498 + modname += strlen("__kmod_"); 1499 + 1500 + type = strstr(modname, "__"); 1501 + if (!type) 1502 + return; 1503 + modnamelen = type - modname; 1504 + type += strlen("__"); 1495 1505 1496 1506 name = strstr(type, "__"); 1497 1507 if (!name) ··· 1524 1514 do_table(name, symval, sym->st_size, p->id_size, 1525 1515 p->device_id, p->do_entry, mod); 1526 1516 break; 1517 + } 1518 + } 1519 + 1520 + if (mod->is_vmlinux) { 1521 + struct module_alias *alias; 1522 + 1523 + /* 1524 + * If this is vmlinux, record the name of the builtin module. 1525 + * Traverse the linked list in the reverse order, and set the 1526 + * builtin_modname unless it has already been set in the 1527 + * previous call. 1528 + */ 1529 + list_for_each_entry_reverse(alias, &mod->aliases, node) { 1530 + if (alias->builtin_modname) 1531 + break; 1532 + alias->builtin_modname = xstrndup(modname, modnamelen); 1527 1533 } 1528 1534 } 1529 1535
+15
scripts/mod/modpost.c
··· 2067 2067 static void write_vmlinux_export_c_file(struct module *mod) 2068 2068 { 2069 2069 struct buffer buf = { }; 2070 + struct module_alias *alias, *next; 2070 2071 2071 2072 buf_printf(&buf, 2072 2073 "#include <linux/export-internal.h>\n"); 2073 2074 2074 2075 add_exported_symbols(&buf, mod); 2076 + 2077 + buf_printf(&buf, 2078 + "#include <linux/module.h>\n" 2079 + "#undef __MODULE_INFO_PREFIX\n" 2080 + "#define __MODULE_INFO_PREFIX\n"); 2081 + 2082 + list_for_each_entry_safe(alias, next, &mod->aliases, node) { 2083 + buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n", 2084 + alias->builtin_modname, alias->str); 2085 + list_del(&alias->node); 2086 + free(alias->builtin_modname); 2087 + free(alias); 2088 + } 2089 + 2075 2090 write_if_changed(&buf, ".vmlinux.export.c"); 2076 2091 free(buf.p); 2077 2092 }
+2
scripts/mod/modpost.h
··· 99 99 * struct module_alias - auto-generated MODULE_ALIAS() 100 100 * 101 101 * @node: linked to module::aliases 102 + * @modname: name of the builtin module (only for vmlinux) 102 103 * @str: a string for MODULE_ALIAS() 103 104 */ 104 105 struct module_alias { 105 106 struct list_head node; 107 + char *builtin_modname; 106 108 char str[]; 107 109 }; 108 110