diff mbox series

[2/2] modules: use a list of supported arch for each module

Message ID 20210917012904.26544-3-jziviani@suse.de (mailing list archive)
State New, archived
Headers show
Series modules: Improve modinfo.c architecture support | expand

Commit Message

Jose R. Ziviani Sept. 17, 2021, 1:29 a.m. UTC
When compiling QEMU with more than one target, for instance,
--target-list=s390x-softmmu,x86_64-softmmu, modinfo.c will be
filled with modules available for both, with no specification
of what modules can/cannot be loaded for a particular target.

This will cause message errors when executing the target that
shouldn't be loading that module, such as:

$ qemu-system-s390x -nodefaults -display none -accel qtest -M none -device help
Failed to open module: /.../hw-display-virtio-vga.so: undefined symbol: vmstate_vga_common

This patch changes the module infrastructure to use a list of
architectures, obtained during the build time, to specify what
targets can load each module.

Signed-off-by: Jose R. Ziviani <jziviani@suse.de>
---
 include/qemu/module.h       |  2 +-
 meson.build                 | 18 +++++++++++++-----
 scripts/modinfo-collect.py  | 10 ++++++++++
 scripts/modinfo-generate.py |  7 +++----
 util/module.c               | 18 +++++++++++++-----
 5 files changed, 40 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/include/qemu/module.h b/include/qemu/module.h
index 3deac0078b..3b487c646c 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -144,7 +144,7 @@  void module_allow_arch(const char *arch);
 typedef struct QemuModinfo QemuModinfo;
 struct QemuModinfo {
     const char *name;
-    const char *arch;
+    const char **archs;
     const char **objs;
     const char **deps;
     const char **opts;
diff --git a/meson.build b/meson.build
index d1d3fd84ec..efba275092 100644
--- a/meson.build
+++ b/meson.build
@@ -2343,11 +2343,19 @@  foreach d, list : modules
         # unique when it comes to lookup in compile_commands.json.
         # Depnds on a mesion version with
         # https://github.com/mesonbuild/meson/pull/8900
-        modinfo_files += custom_target(d + '-' + m + '.modinfo',
-                                       output: d + '-' + m + '.modinfo',
-                                       input: module_ss.sources() + genh,
-                                       capture: true,
-                                       command: [modinfo_collect, module_ss.sources()])
+        if modules_arch.has_key(m)
+          modinfo_files += custom_target(d + '-' + m + '.modinfo',
+                                        output: d + '-' + m + '.modinfo',
+                                        input: module_ss.sources() + genh,
+                                        capture: true,
+                                        command: [modinfo_collect, module_ss.sources(), '--archs', modules_arch[m]])
+        else
+          modinfo_files += custom_target(d + '-' + m + '.modinfo',
+                                        output: d + '-' + m + '.modinfo',
+                                        input: module_ss.sources() + genh,
+                                        capture: true,
+                                        command: [modinfo_collect, module_ss.sources()])
+        endif
       endif
     else
       if d == 'block'
diff --git a/scripts/modinfo-collect.py b/scripts/modinfo-collect.py
index 4acb188c3e..739cd23e2f 100755
--- a/scripts/modinfo-collect.py
+++ b/scripts/modinfo-collect.py
@@ -50,6 +50,16 @@  def main(args):
         print("MODINFO_START arch \"%s\" MODINFO_END" % arch)
     with open('compile_commands.json') as f:
         compile_commands = json.load(f)
+
+    try:
+        arch_idx = args.index('--archs')
+        archs = args[arch_idx + 1:]
+        args = args[:arch_idx]
+        for arch in archs:
+            print("MODINFO_START arch \"%s\" MODINFO_END" % arch)
+    except ValueError:
+        pass
+
     for src in args:
         print("MODINFO_DEBUG src %s" % src)
         command = find_command(src, target, compile_commands)
diff --git a/scripts/modinfo-generate.py b/scripts/modinfo-generate.py
index f559eed007..e1d13acd92 100755
--- a/scripts/modinfo-generate.py
+++ b/scripts/modinfo-generate.py
@@ -33,7 +33,7 @@  def parse_line(line):
     return (kind, data)
 
 def generate(name, lines):
-    arch = ""
+    archs = []
     objs = []
     deps = []
     opts = []
@@ -47,14 +47,13 @@  def generate(name, lines):
             elif kind == 'opts':
                 opts.append(data)
             elif kind == 'arch':
-                arch = data;
+                archs.append(data);
             else:
                 print("unknown:", kind)
                 exit(1)
 
     print("    .name = \"%s\"," % name)
-    if arch != "":
-        print("    .arch = %s," % arch)
+    print_array("archs", archs)
     print_array("objs", objs)
     print_array("deps", deps)
     print_array("opts", opts)
diff --git a/util/module.c b/util/module.c
index 6bb4ad915a..7009143bfc 100644
--- a/util/module.c
+++ b/util/module.c
@@ -131,16 +131,24 @@  void module_allow_arch(const char *arch)
 
 static bool module_check_arch(const QemuModinfo *modinfo)
 {
-    if (modinfo->arch) {
+    const char **arch;
+
+    if (modinfo->archs) {
         if (!module_arch) {
             /* no arch set -> ignore all */
             return false;
         }
-        if (strcmp(module_arch, modinfo->arch) != 0) {
-            /* mismatch */
-            return false;
+
+        for (arch = modinfo->archs; *arch != NULL; arch++) {
+            if (strcmp(module_arch, *arch) == 0) {
+                return true;
+            }
         }
+
+        /* mismatch */
+        return false;
     }
+
     return true;
 }
 
@@ -245,7 +253,7 @@  bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
     g_hash_table_add(loaded_modules, module_name);
 
     for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
-        if (modinfo->arch) {
+        if (modinfo->archs) {
             if (strcmp(modinfo->name, module_name) == 0) {
                 if (!module_check_arch(modinfo)) {
                     return false;