Skip to content

Commit c7d3dd9

Browse files
committed
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/[email protected] Signed-off-by: Nathan Chancellor <[email protected]>
2 parents 95ee336 + 3328d39 commit c7d3dd9

File tree

12 files changed

+131
-78
lines changed

12 files changed

+131
-78
lines changed

arch/s390/kernel/vmlinux.lds.S

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ SECTIONS
209209
. = ALIGN(PAGE_SIZE);
210210
_end = . ;
211211

212+
/* Debugging sections. */
213+
STABS_DEBUG
214+
DWARF_DEBUG
215+
ELF_DETAILS
216+
212217
/*
213218
* uncompressed image info used by the decompressor
214219
* it should match struct vmlinux_info
@@ -239,11 +244,6 @@ SECTIONS
239244
#endif
240245
} :NONE
241246

242-
/* Debugging sections. */
243-
STABS_DEBUG
244-
DWARF_DEBUG
245-
ELF_DETAILS
246-
247247
/*
248248
* Make sure that the .got.plt is either completely empty or it
249249
* contains only the three reserved double words.

drivers/scsi/BusLogic.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3715,7 +3715,6 @@ static void __exit blogic_exit(void)
37153715

37163716
__setup("BusLogic=", blogic_setup);
37173717

3718-
#ifdef MODULE
37193718
/*static const struct pci_device_id blogic_pci_tbl[] = {
37203719
{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
37213720
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -3725,13 +3724,12 @@ __setup("BusLogic=", blogic_setup);
37253724
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
37263725
{ }
37273726
};*/
3728-
static const struct pci_device_id blogic_pci_tbl[] = {
3727+
static const struct pci_device_id blogic_pci_tbl[] __maybe_unused = {
37293728
{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
37303729
{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
37313730
{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
37323731
{0, },
37333732
};
3734-
#endif
37353733
MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
37363734

37373735
module_init(blogic_init);

include/asm-generic/vmlinux.lds.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
831831

832832
/* Required sections not related to debugging. */
833833
#define ELF_DETAILS \
834+
.modinfo : { *(.modinfo) } \
834835
.comment 0 : { *(.comment) } \
835836
.symtab 0 : { *(.symtab) } \
836837
.strtab 0 : { *(.strtab) } \
@@ -1044,7 +1045,6 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
10441045
*(.discard.*) \
10451046
*(.export_symbol) \
10461047
*(.no_trim_symbol) \
1047-
*(.modinfo) \
10481048
/* ld.bfd warns about .gnu.version* even when not emitted */ \
10491049
*(.gnu.version*) \
10501050

include/linux/module.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,22 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name);
244244
/* What your module does. */
245245
#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
246246

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+
248259
/* Creates an alias so file2alias.c can find device table. */
249260
#define MODULE_DEVICE_TABLE(type, name) \
250-
static typeof(name) __mod_device_table__##type##__##name \
261+
static typeof(name) __mod_device_table(type, name) \
251262
__attribute__ ((used, alias(__stringify(name))))
252-
#else /* !MODULE */
253-
#define MODULE_DEVICE_TABLE(type, name)
254-
#endif
255263

256264
/* Version of form [<epoch>:]<version>[-<extra-version>].
257265
* Or for CVS/RCS ID version, everything but the number is stripped.

rust/kernel/device_id.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ macro_rules! module_device_table {
195195
($table_type: literal, $module_table_name:ident, $table_name:ident) => {
196196
#[rustfmt::skip]
197197
#[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))
202202
]
203203
static $module_table_name: [::core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] =
204204
unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) };

scripts/Makefile.vmlinux

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,6 @@ include $(srctree)/scripts/Makefile.lib
99

1010
targets :=
1111

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-
2612
%.o: %.c FORCE
2713
$(call if_changed_rule,cc_o_c)
2814

@@ -61,19 +47,14 @@ targets += .builtin-dtbs-list
6147

6248
ifdef CONFIG_GENERIC_BUILTIN_DTB
6349
targets += .builtin-dtbs.S .builtin-dtbs.o
64-
$(vmlinux-final): .builtin-dtbs.o
50+
vmlinux.unstripped: .builtin-dtbs.o
6551
endif
6652

67-
# vmlinux
53+
# vmlinux.unstripped
6854
# ---------------------------------------------------------------------------
6955

70-
ifdef CONFIG_MODULES
71-
targets += .vmlinux.export.o
72-
$(vmlinux-final): .vmlinux.export.o
73-
endif
74-
7556
ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
76-
$(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o
57+
vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o
7758

7859
arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE
7960
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@
@@ -86,17 +67,61 @@ cmd_link_vmlinux = \
8667
$< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \
8768
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
8869

89-
targets += $(vmlinux-final)
90-
$(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
70+
targets += vmlinux.unstripped .vmlinux.export.o
71+
vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE
9172
+$(call if_changed_dep,link_vmlinux)
9273
ifdef CONFIG_DEBUG_INFO_BTF
93-
$(vmlinux-final): $(RESOLVE_BTFIDS)
74+
vmlinux.unstripped: $(RESOLVE_BTFIDS)
9475
endif
9576

9677
ifdef CONFIG_BUILDTIME_TABLE_SORT
97-
$(vmlinux-final): scripts/sorttable
78+
vmlinux.unstripped: scripts/sorttable
9879
endif
9980

81+
# vmlinux
82+
# ---------------------------------------------------------------------------
83+
84+
remove-section-y := .modinfo
85+
remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*'
86+
87+
remove-symbols := -w --strip-symbol='__mod_device_table__*'
88+
89+
# To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
90+
# it is necessary to remove the PT_LOAD flag from the segment.
91+
quiet_cmd_strip_relocs = OBJCOPY $@
92+
cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
93+
$(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@
94+
95+
targets += vmlinux
96+
vmlinux: vmlinux.unstripped FORCE
97+
$(call if_changed,strip_relocs)
98+
99+
# modules.builtin.modinfo
100+
# ---------------------------------------------------------------------------
101+
102+
OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary
103+
104+
targets += modules.builtin.modinfo
105+
modules.builtin.modinfo: vmlinux.unstripped FORCE
106+
$(call if_changed,objcopy)
107+
108+
# modules.builtin
109+
# ---------------------------------------------------------------------------
110+
111+
__default: modules.builtin
112+
113+
# The second line aids cases where multiple modules share the same object.
114+
115+
quiet_cmd_modules_builtin = GEN $@
116+
cmd_modules_builtin = \
117+
tr '\0' '\n' < $< | \
118+
sed -n 's/^[[:alnum:]:_]*\.file=//p' | \
119+
tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@
120+
121+
targets += modules.builtin
122+
modules.builtin: modules.builtin.modinfo FORCE
123+
$(call if_changed,modules_builtin)
124+
100125
# modules.builtin.ranges
101126
# ---------------------------------------------------------------------------
102127
ifdef CONFIG_BUILTIN_MODULE_RANGES
@@ -110,7 +135,7 @@ modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
110135
modules.builtin vmlinux.map vmlinux.o.map FORCE
111136
$(call if_changed,modules_builtin_ranges)
112137

113-
vmlinux.map: $(vmlinux-final)
138+
vmlinux.map: vmlinux.unstripped
114139
@:
115140

116141
endif

scripts/Makefile.vmlinux_o

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22

33
PHONY := __default
4-
__default: vmlinux.o modules.builtin.modinfo modules.builtin
4+
__default: vmlinux.o
55

66
include include/config/auto.conf
77
include $(srctree)/scripts/Kbuild.include
@@ -73,30 +73,6 @@ vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
7373

7474
targets += vmlinux.o
7575

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-
10076
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
10177
# ---------------------------------------------------------------------------
10278

scripts/link-vmlinux.sh

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ vmlinux_link()
7373
objs="${objs} .builtin-dtbs.o"
7474
fi
7575

76-
if is_enabled CONFIG_MODULES; then
77-
objs="${objs} .vmlinux.export.o"
78-
fi
79-
76+
objs="${objs} .vmlinux.export.o"
8077
objs="${objs} init/version-timestamp.o"
8178

8279
if [ "${SRCARCH}" = "um" ]; then

scripts/mksysmap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
# EXPORT_SYMBOL (namespace)
6060
/ __kstrtabns_/d
6161

62+
# MODULE_DEVICE_TABLE (symbol name)
63+
/ __mod_device_table__/d
64+
6265
# ---------------------------------------------------------------------------
6366
# Ignored suffixes
6467
# (do not forget '$' after each pattern)
@@ -79,6 +82,9 @@
7982
/ _SDA_BASE_$/d
8083
/ _SDA2_BASE_$/d
8184

85+
# MODULE_INFO()
86+
/ __UNIQUE_ID_modinfo[0-9]*$/d
87+
8288
# ---------------------------------------------------------------------------
8389
# Ignored patterns
8490
# (symbols that contain the pattern are ignored)

scripts/mod/file2alias.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
14761476
{
14771477
void *symval;
14781478
char *zeros = NULL;
1479-
const char *type, *name;
1480-
size_t typelen;
1479+
const char *type, *name, *modname;
1480+
size_t typelen, modnamelen;
14811481
static const char *prefix = "__mod_device_table__";
14821482

14831483
/* We're looking for a section relative symbol */
@@ -1488,10 +1488,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
14881488
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
14891489
return;
14901490

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>. */
14921492
if (!strstarts(symname, prefix))
14931493
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("__");
14951505

14961506
name = strstr(type, "__");
14971507
if (!name)
@@ -1517,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
15171527
}
15181528
}
15191529

1530+
if (mod->is_vmlinux) {
1531+
struct module_alias *alias;
1532+
1533+
/*
1534+
* If this is vmlinux, record the name of the builtin module.
1535+
* Traverse the linked list in the reverse order, and set the
1536+
* builtin_modname unless it has already been set in the
1537+
* previous call.
1538+
*/
1539+
list_for_each_entry_reverse(alias, &mod->aliases, node) {
1540+
if (alias->builtin_modname)
1541+
break;
1542+
alias->builtin_modname = xstrndup(modname, modnamelen);
1543+
}
1544+
}
1545+
15201546
free(zeros);
15211547
}

0 commit comments

Comments
 (0)