modpost: traverse modules in order
authorMasahiro Yamada <masahiroy@kernel.org>
Sun, 1 May 2022 08:40:10 +0000 (17:40 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Sat, 7 May 2022 18:17:00 +0000 (03:17 +0900)
Currently, modpost manages modules in a singly linked list; it adds
a new node to the head, and traverses the list from new to old.

It works, but the error messages are shown in the reverse order.

If you have a Makefile like this:

  obj-m += foo.o bar.o

then, modpost shows error messages in bar.o, foo.o, in this order.

Use a doubly linked list to keep the order in modules.order; use
list_add_tail() for the node addition and list_for_each_entry() for
the list traverse.

Now that the kernel's list macros have been imported to modpost, I will
use them actively going forward.

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

index 25066dc..1b9dcb4 100644 (file)
@@ -165,16 +165,17 @@ char *get_line(char **stringp)
 }
 
 /* A list of all modules we processed */
-static struct module *modules;
+LIST_HEAD(modules);
 
 static struct module *find_module(const char *modname)
 {
        struct module *mod;
 
-       for (mod = modules; mod; mod = mod->next)
+       list_for_each_entry(mod, &modules, list) {
                if (strcmp(mod->name, modname) == 0)
-                       break;
-       return mod;
+                       return mod;
+       }
+       return NULL;
 }
 
 static struct module *new_module(const char *modname)
@@ -184,7 +185,6 @@ static struct module *new_module(const char *modname)
        mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
        memset(mod, 0, sizeof(*mod));
 
-       /* add to list */
        strcpy(mod->name, modname);
        mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
 
@@ -195,8 +195,7 @@ static struct module *new_module(const char *modname)
         */
        mod->is_gpl_compatible = true;
 
-       mod->next = modules;
-       modules = mod;
+       list_add_tail(&mod->list, &modules);
 
        return mod;
 }
@@ -2477,7 +2476,7 @@ static void write_namespace_deps_files(const char *fname)
        struct namespace_list *ns;
        struct buffer ns_deps_buf = {};
 
-       for (mod = modules; mod; mod = mod->next) {
+       list_for_each_entry(mod, &modules, list) {
 
                if (mod->from_dump || !mod->missing_namespaces)
                        continue;
@@ -2568,7 +2567,7 @@ int main(int argc, char **argv)
        if (files_source)
                read_symbols_from_files(files_source);
 
-       for (mod = modules; mod; mod = mod->next) {
+       list_for_each_entry(mod, &modules, list) {
                char fname[PATH_MAX];
                int ret;
 
index 73c36df..69601f3 100644 (file)
@@ -11,6 +11,7 @@
 #include <unistd.h>
 #include <elf.h>
 
+#include "list.h"
 #include "elfconfig.h"
 
 /* On BSD-alike OSes elf.h defines these according to host's word size */
@@ -111,7 +112,7 @@ void
 buf_write(struct buffer *buf, const char *s, int len);
 
 struct module {
-       struct module *next;
+       struct list_head list;
        bool is_gpl_compatible;
        struct symbol *unres;
        bool from_dump;         /* true if module was loaded from *.symvers */