Skip to content

Commit 5ab23c7

Browse files
legionusnathanchance
authored andcommitted
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 <[email protected]> Signed-off-by: Alexey Gladkov <[email protected]> Tested-by: Stephen Rothwell <[email protected]> Reviewed-by: Nicolas Schier <[email protected]> Link: https://patch.msgid.link/28d4da3b0e3fc8474142746bcf469e03752c3208.1758182101.git.legion@kernel.org Signed-off-by: Nathan Chancellor <[email protected]>
1 parent 83fb493 commit 5ab23c7

File tree

6 files changed

+41
-6
lines changed

6 files changed

+41
-6
lines changed

include/linux/module.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,10 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name);
256256
__PASTE(type, \
257257
__PASTE(__, name)))))
258258

259-
#ifdef MODULE
260259
/* Creates an alias so file2alias.c can find device table. */
261260
#define MODULE_DEVICE_TABLE(type, name) \
262261
static typeof(name) __mod_device_table(type, name) \
263262
__attribute__ ((used, alias(__stringify(name))))
264-
#else /* !MODULE */
265-
#define MODULE_DEVICE_TABLE(type, name)
266-
#endif
267263

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

scripts/Makefile.vmlinux

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,13 @@ endif
8989
remove-section-y := .modinfo
9090
remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*'
9191

92+
remove-symbols := -w --strip-symbol='__mod_device_table__*'
93+
9294
# To avoid warnings: "empty loadable segment detected at ..." from GNU objcopy,
9395
# it is necessary to remove the PT_LOAD flag from the segment.
9496
quiet_cmd_strip_relocs = OBJCOPY $@
9597
cmd_strip_relocs = $(OBJCOPY) $(patsubst %,--set-section-flags %=noload,$(remove-section-y)) $< $@; \
96-
$(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $@
98+
$(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $(remove-symbols) $@
9799

98100
targets += vmlinux
99101
vmlinux: vmlinux.unstripped FORCE

scripts/mksysmap

Lines changed: 3 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)

scripts/mod/file2alias.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
14771477
void *symval;
14781478
char *zeros = NULL;
14791479
const char *type, *name, *modname;
1480-
size_t typelen;
1480+
size_t typelen, modnamelen;
14811481
static const char *prefix = "__mod_device_table__";
14821482

14831483
/* We're looking for a section relative symbol */
@@ -1500,6 +1500,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
15001500
type = strstr(modname, "__");
15011501
if (!type)
15021502
return;
1503+
modnamelen = type - modname;
15031504
type += strlen("__");
15041505

15051506
name = strstr(type, "__");
@@ -1526,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
15261527
}
15271528
}
15281529

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+
15291546
free(zeros);
15301547
}

scripts/mod/modpost.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname)
20672067
static void write_vmlinux_export_c_file(struct module *mod)
20682068
{
20692069
struct buffer buf = { };
2070+
struct module_alias *alias, *next;
20702071

20712072
buf_printf(&buf,
20722073
"#include <linux/export-internal.h>\n");
20732074

20742075
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+
20752090
write_if_changed(&buf, ".vmlinux.export.c");
20762091
free(buf.p);
20772092
}

scripts/mod/modpost.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len);
9999
* struct module_alias - auto-generated MODULE_ALIAS()
100100
*
101101
* @node: linked to module::aliases
102+
* @modname: name of the builtin module (only for vmlinux)
102103
* @str: a string for MODULE_ALIAS()
103104
*/
104105
struct module_alias {
105106
struct list_head node;
107+
char *builtin_modname;
106108
char str[];
107109
};
108110

0 commit comments

Comments
 (0)