@@ -42,6 +42,7 @@
*.so.dbg
*.su
*.symtypes
+*.symver.lds
*.symversions
*.tab.[ch]
*.tar
@@ -1867,6 +1867,7 @@ clean: $(clean-dirs)
-o -name '*.c.[012]*.*' \
-o -name '*.ll' \
-o -name '*.gcno' \
+ -o -name '*.symver.lds' \
-o -name '*.*.symversions' \) -type f -print | xargs rm -f
# Generate tags for editors
@@ -46,6 +46,7 @@ include $(srctree)/scripts/Makefile.lib
MODPOST = scripts/mod/modpost \
$(if $(CONFIG_MODVERSIONS),-m) \
+ $(if $(CONFIG_MODULE_REL_CRCS),-r) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
-o $@
@@ -24,6 +24,8 @@
/* Are we using CONFIG_MODVERSIONS? */
static bool modversions;
+/* Is CONFIG_MODULE_REL_CRCS enabled? */
+static bool modversions_rel_crcs;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static bool all_versions;
/* If we are modposting external module set to 1 */
@@ -2554,9 +2556,21 @@ static void write_dump(const char *fname)
free(buf.p);
}
-static void check_symversions(struct module *mod)
+static void write_symversions_lds(struct module *mod)
{
+ struct buffer buf = { };
struct symbol *sym;
+ char lds_file[PATH_MAX];
+ int ret;
+
+ ret = snprintf(lds_file, sizeof(lds_file), "%s.symver.lds", mod->name);
+ if (ret >= sizeof(lds_file)) {
+ error("%s: too long path was truncated\n", lds_file);
+ return;
+ }
+
+ if (modversions_rel_crcs)
+ buf_printf(&buf, "SECTIONS { .rodata : ALIGN(4) {\n");
list_for_each_entry(sym, &mod->exported_symbols, list) {
if (!sym->crc_valid) {
@@ -2564,8 +2578,22 @@ static void check_symversions(struct module *mod)
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
sym->name);
+ continue;
}
+
+ if (modversions_rel_crcs)
+ buf_printf(&buf, "__crc_%s = .; LONG(0x%08x);\n",
+ sym->name, sym->crc);
+ else
+ buf_printf(&buf, "__crc_%s = 0x%08x;\n",
+ sym->name, sym->crc);
}
+
+ if (modversions_rel_crcs)
+ buf_printf(&buf, "} }\n");
+
+ write_if_changed(&buf, lds_file);
+ free(buf.p);
}
static void write_namespace_deps_files(const char *fname)
@@ -2606,7 +2634,7 @@ int main(int argc, char **argv)
LIST_HEAD(dump_lists);
struct dump_list *dl, *dl2;
- while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
+ while ((opt = getopt(argc, argv, "ei:mrnT:o:awENd:")) != -1) {
switch (opt) {
case 'e':
external_module = true;
@@ -2619,6 +2647,9 @@ int main(int argc, char **argv)
case 'm':
modversions = true;
break;
+ case 'r':
+ modversions_rel_crcs = true;
+ break;
case 'n':
ignore_missing_files = true;
break;
@@ -2665,7 +2696,7 @@ int main(int argc, char **argv)
int ret;
if (modversions && !mod->from_dump)
- check_symversions(mod);
+ write_symversions_lds(mod);
if (mod->is_vmlinux || mod->from_dump)
continue;
Merge version CRCs per vmlinux or per module. These linker scripts will be fed to the final link stage. Add the new option, -r, to modpost. This is needed to output the linker scripts in a different format when CONFIG_MODULE_REL_CRCS=y. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> --- Changes in v2: - Fix CONFIG_MODULE_REL_CRCS=y case .gitignore | 1 + Makefile | 1 + scripts/Makefile.modpost | 1 + scripts/mod/modpost.c | 37 ++++++++++++++++++++++++++++++++++--- 4 files changed, 37 insertions(+), 3 deletions(-)