Skip to content

Commit fc7d5e3

Browse files
maurermasahir0y
authored andcommitted
modpost: Produce extended MODVERSIONS information
Generate both the existing modversions format and the new extended one when running modpost. Presence of this metadata in the final .ko is guarded by CONFIG_EXTENDED_MODVERSIONS. We no longer generate an error on long symbols in modpost if CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately encoded in the extended section. These symbols will be skipped in the previous encoding. An error will still be generated if CONFIG_EXTENDED_MODVERSIONS is not set. Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Matthew Maurer <mmaurer@google.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
1 parent 54ac1ac commit fc7d5e3

3 files changed

Lines changed: 69 additions & 4 deletions

File tree

kernel/module/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ config ASM_MODVERSIONS
207207
assembly. This can be enabled only when the target architecture
208208
supports it.
209209

210+
config EXTENDED_MODVERSIONS
211+
bool "Extended Module Versioning Support"
212+
depends on MODVERSIONS
213+
help
214+
This enables extended MODVERSIONs support, allowing long symbol
215+
names to be versioned.
216+
217+
The most likely reason you would enable this is to enable Rust
218+
support. If unsure, say N.
219+
210220
config MODULE_SRCVERSION_ALL
211221
bool "Source checksum for all modules"
212222
help

scripts/Makefile.modpost

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ MODPOST = $(objtree)/scripts/mod/modpost
4343
modpost-args = \
4444
$(if $(CONFIG_MODULES),-M) \
4545
$(if $(CONFIG_MODVERSIONS),-m) \
46+
$(if $(CONFIG_EXTENDED_MODVERSIONS),-x) \
4647
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
4748
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
4849
$(if $(KBUILD_MODPOST_WARN),-w) \

scripts/mod/modpost.c

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ static bool module_enabled;
3333
static bool modversions;
3434
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
3535
static bool all_versions;
36+
/* Is CONFIG_EXTENDED_MODVERSIONS set? */
37+
static bool extended_modversions;
3638
/* If we are modposting external module set to 1 */
3739
static bool external_module;
3840
/* Only warn about unresolved symbols */
@@ -1805,6 +1807,49 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
18051807
}
18061808
}
18071809

1810+
/**
1811+
* Record CRCs for unresolved symbols, supporting long names
1812+
*/
1813+
static void add_extended_versions(struct buffer *b, struct module *mod)
1814+
{
1815+
struct symbol *s;
1816+
1817+
if (!extended_modversions)
1818+
return;
1819+
1820+
buf_printf(b, "\n");
1821+
buf_printf(b, "static const u32 ____version_ext_crcs[]\n");
1822+
buf_printf(b, "__used __section(\"__version_ext_crcs\") = {\n");
1823+
list_for_each_entry(s, &mod->unresolved_symbols, list) {
1824+
if (!s->module)
1825+
continue;
1826+
if (!s->crc_valid) {
1827+
warn("\"%s\" [%s.ko] has no CRC!\n",
1828+
s->name, mod->name);
1829+
continue;
1830+
}
1831+
buf_printf(b, "\t0x%08x,\n", s->crc);
1832+
}
1833+
buf_printf(b, "};\n");
1834+
1835+
buf_printf(b, "static const char ____version_ext_names[]\n");
1836+
buf_printf(b, "__used __section(\"__version_ext_names\") =\n");
1837+
list_for_each_entry(s, &mod->unresolved_symbols, list) {
1838+
if (!s->module)
1839+
continue;
1840+
if (!s->crc_valid)
1841+
/*
1842+
* We already warned on this when producing the crc
1843+
* table.
1844+
* We need to skip its name too, as the indexes in
1845+
* both tables need to align.
1846+
*/
1847+
continue;
1848+
buf_printf(b, "\t\"%s\\0\"\n", s->name);
1849+
}
1850+
buf_printf(b, ";\n");
1851+
}
1852+
18081853
/**
18091854
* Record CRCs for unresolved symbols
18101855
**/
@@ -1828,9 +1873,14 @@ static void add_versions(struct buffer *b, struct module *mod)
18281873
continue;
18291874
}
18301875
if (strlen(s->name) >= MODULE_NAME_LEN) {
1831-
error("too long symbol \"%s\" [%s.ko]\n",
1832-
s->name, mod->name);
1833-
break;
1876+
if (extended_modversions) {
1877+
/* this symbol will only be in the extended info */
1878+
continue;
1879+
} else {
1880+
error("too long symbol \"%s\" [%s.ko]\n",
1881+
s->name, mod->name);
1882+
break;
1883+
}
18341884
}
18351885
buf_printf(b, "\t{ 0x%08x, \"%s\" },\n",
18361886
s->crc, s->name);
@@ -1961,6 +2011,7 @@ static void write_mod_c_file(struct module *mod)
19612011
add_header(&buf, mod);
19622012
add_exported_symbols(&buf, mod);
19632013
add_versions(&buf, mod);
2014+
add_extended_versions(&buf, mod);
19642015
add_depends(&buf, mod);
19652016

19662017
buf_printf(&buf, "\n");
@@ -2126,7 +2177,7 @@ int main(int argc, char **argv)
21262177
LIST_HEAD(dump_lists);
21272178
struct dump_list *dl, *dl2;
21282179

2129-
while ((opt = getopt(argc, argv, "ei:MmnT:to:au:WwENd:")) != -1) {
2180+
while ((opt = getopt(argc, argv, "ei:MmnT:to:au:WwENd:x")) != -1) {
21302181
switch (opt) {
21312182
case 'e':
21322183
external_module = true;
@@ -2175,6 +2226,9 @@ int main(int argc, char **argv)
21752226
case 'd':
21762227
missing_namespace_deps = optarg;
21772228
break;
2229+
case 'x':
2230+
extended_modversions = true;
2231+
break;
21782232
default:
21792233
exit(1);
21802234
}

0 commit comments

Comments
 (0)