modpost: dump Module.symvers in the same order of modules.order
authorMasahiro Yamada <masahiroy@kernel.org>
Sun, 1 May 2022 08:40:15 +0000 (17:40 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Sat, 7 May 2022 18:17:01 +0000 (03:17 +0900)
modpost dumps the exported symbols into Module.symvers, but currently
in random order because it iterates in the hash table.

Add a linked list of exported symbols in struct module, so we can
iterate on symbols per module.

This commit makes Module.symvers much more readable; the outer loop in
write_dump() iterates over the modules in the order of modules.order,
and the inner loop dumps symbols in each module.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
scripts/mod/modpost.c
scripts/mod/modpost.h

index 8bdde738803fd33d4306b7d68d0565faeafbce49..cdd9098b603533f86e5fe1fb3c696feb2af70815 100644 (file)
@@ -185,6 +185,7 @@ static struct module *new_module(const char *modname)
        mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
        memset(mod, 0, sizeof(*mod));
 
+       INIT_LIST_HEAD(&mod->exported_symbols);
        INIT_LIST_HEAD(&mod->unresolved_symbols);
        INIT_LIST_HEAD(&mod->missing_namespaces);
        INIT_LIST_HEAD(&mod->imported_namespaces);
@@ -211,7 +212,7 @@ static struct module *new_module(const char *modname)
 
 struct symbol {
        struct symbol *next;
-       struct list_head list;  /* link to module::unresolved_symbols */
+       struct list_head list;  /* link to module::exported_symbols or module::unresolved_symbols */
        struct module *module;
        char *namespace;
        unsigned int crc;
@@ -413,6 +414,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
 
        if (!s) {
                s = new_symbol(name, mod, export);
+               list_add_tail(&s->list, &mod->exported_symbols);
        } else if (!external_module || s->module->is_vmlinux ||
                   s->module == mod) {
                warn("%s: '%s' exported twice. Previous export was in %s%s\n",
@@ -2456,22 +2458,17 @@ fail:
 static void write_dump(const char *fname)
 {
        struct buffer buf = { };
-       struct symbol *symbol;
-       const char *namespace;
-       int n;
+       struct module *mod;
+       struct symbol *sym;
 
-       for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
-               symbol = symbolhash[n];
-               while (symbol) {
-                       if (!symbol->module->from_dump) {
-                               namespace = symbol->namespace;
-                               buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
-                                          symbol->crc, symbol->name,
-                                          symbol->module->name,
-                                          export_str(symbol->export),
-                                          namespace ? namespace : "");
-                       }
-                       symbol = symbol->next;
+       list_for_each_entry(mod, &modules, list) {
+               if (mod->from_dump)
+                       continue;
+               list_for_each_entry(sym, &mod->exported_symbols, list) {
+                       buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
+                                  sym->crc, sym->name, mod->name,
+                                  export_str(sym->export),
+                                  sym->namespace ?: "");
                }
        }
        write_buf(&buf, fname);
index 2e13a736ab38a6934d25edfc3eae4c7df529ae90..cfa127d2bb8f2fee035249e77f8acfe39f83c001 100644 (file)
@@ -113,6 +113,7 @@ buf_write(struct buffer *buf, const char *s, int len);
 
 struct module {
        struct list_head list;
+       struct list_head exported_symbols;
        struct list_head unresolved_symbols;
        bool is_gpl_compatible;
        bool from_dump;         /* true if module was loaded from *.symvers */