Skip to content

Configure option `--enable-plugins` makes modules in shared library not loadable on macOS

Host environment

  • Operating system: macOS 10.15.7
  • OS/kernel version: Darwin MacBook-Pro.local 19.6.0 Darwin Kernel Version 19.6.0: Thu Oct 29 22:56:45 PDT 2020; root:xnu-6153.141.2.2~1/RELEASE_X86_64 x86_64
  • Architecture: x86_64
  • QEMU flavor: qemu-system-*
  • QEMU version: QEMU emulator version 6.0.92 (v6.1.0-rc2-15-gca92f162)
  • QEMU command line:
    qemu-system-x86_64 -device qxl
    or
    qemu-system-x86_64 -spice port=5901

Emulated/Virtualized environment

N/A

Description of problem

The title mentions --enable-plugins option, however as it's enabled by default, not providing --disable-plugins would also cause this to happen.

If TCG plugin support is enabled, symbols in qemu-system-* binaries will be missing, and module libraries would fail to load as they expect those symbols to exist in the main binary.

Configure options used: STRIP="strip -x" ./configure --enable-user --enable-tools --enable-parallels --enable-libxml2 --enable-spice --enable-hvf --enable-cocoa --enable-guest-agent --enable-curses --enable-plugins --enable-modules --objcc=gcc --enable-libusb --enable-usb-redir

After inspecting the compiler command line, I've found the linker option -Wl,-exported_symbols_list,qemu-plugins-ld64.symbols is causing this to happen: only symbols listed in qemu-plugins-ld64.symbols would be kept in qemu-system-* binaries and all other symbols will be hidden.

Note that this is not caused by stripping (although I had to use custom strip command line on macOS to successfully compile qemu); the option -exported_symbols_list works by only exposing the provided symbols and treating all other symbols as visibility=hidden.

Replacing --enable-plugins to --disable-plugins in the above configure command line would "fix" it, although it means TCG plugins will not be supported.

Steps to reproduce

  1. Build QEMU on macOS with plugin support enabled
  2. Try to use modules in shared library like qxl

Additional information

Some examples:

$ qemu-system-x86_64 -device qxl
Failed to open module: dlopen(/usr/local/bin/../lib/qemu/ui-spice-core.dylib, 10): Symbol not found: __TRACE_QEMU_SPICE_ADD_MEMSLOT_DSTATE
  Referenced from: /usr/local/bin/../lib/qemu/ui-spice-core.dylib
  Expected in: flat namespace
 in /usr/local/bin/../lib/qemu/ui-spice-core.dylib
Failed to open module: dlopen(/usr/local/bin/../lib/qemu/hw-display-qxl.dylib, 2): Symbol not found: __TRACE_QXL_CLIENT_MONITORS_CONFIG_CAPPED_DSTATE
  Referenced from: /usr/local/bin/../lib/qemu/hw-display-qxl.dylib
  Expected in: flat namespace
 in /usr/local/bin/../lib/qemu/hw-display-qxl.dylib
qemu-system-x86_64: -device qxl: 'qxl' is not a valid device model name
$ qemu-system-x86_64 -spice port=5901
Failed to open module: dlopen(/usr/local/bin/../lib/qemu/ui-spice-core.dylib, 10): Symbol not found: __TRACE_QEMU_SPICE_ADD_MEMSLOT_DSTATE
  Referenced from: /usr/local/bin/../lib/qemu/ui-spice-core.dylib
  Expected in: flat namespace
 in /usr/local/bin/../lib/qemu/ui-spice-core.dylib
qemu-system-x86_64: -spice port=5901: spice support is disabled

After disabling plugin support I could run virtual machines locally through libvirt with full spice and qxl video support.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information