qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Greg Manning" <gmanning@rapitasystems.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Alexandre Iooss" <erdnaxe@crans.org>,
	"Mahmoud Mandour" <ma.mandourr@gmail.com>
Subject: [PULL 14/23] plugins: make test/example plugins work on windows
Date: Tue,  7 Nov 2023 14:23:45 +0000	[thread overview]
Message-ID: <20231107142354.3151266-15-alex.bennee@linaro.org> (raw)
In-Reply-To: <20231107142354.3151266-1-alex.bennee@linaro.org>

From: Greg Manning <gmanning@rapitasystems.com>

Generate a qemu_plugin_api.lib delay import lib on windows, for
windows qemu plugins to link against.

Implement an example dll load fail hook to link up the API functions
correctly when a plugin is loaded on windows.

Update the build scripts for the test and example plugins to use these
things.

Signed-off-by: Greg Manning <gmanning@rapitasystems.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231102172053.17692-3-gmanning@rapitasystems.com>
[AJB: use find_program for dlltool, s/Windows/windows/]
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231106185112.2755262-15-alex.bennee@linaro.org>

diff --git a/configure b/configure
index cd6c521bd8..e50ec99fe2 100755
--- a/configure
+++ b/configure
@@ -1666,6 +1666,9 @@ fi
 if test "$targetos" = darwin; then
   echo "CONFIG_DARWIN=y" >> contrib/plugins/$config_host_mak
 fi
+if test "$targetos" = windows; then
+  echo "CONFIG_WIN32=y" >> contrib/plugins/$config_host_mak
+fi
 
 # tests/tcg configuration
 (config_host_mak=tests/tcg/config-host.mak
diff --git a/contrib/plugins/win32_linker.c b/contrib/plugins/win32_linker.c
new file mode 100644
index 0000000000..7534b2b8bf
--- /dev/null
+++ b/contrib/plugins/win32_linker.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023, Greg Manning <gmanning@rapitasystems.com>
+ *
+ * This hook, __pfnDliFailureHook2, is documented in the microsoft documentation here:
+ * https://learn.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification
+ * It gets called when a delay-loaded DLL encounters various errors.
+ * We handle the specific case of a DLL looking for a "qemu.exe",
+ * and give it the running executable (regardless of what it is named).
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include <windows.h>
+#include <delayimp.h>
+
+FARPROC WINAPI dll_failure_hook(unsigned dliNotify, PDelayLoadInfo pdli);
+
+
+PfnDliHook __pfnDliFailureHook2 = dll_failure_hook;
+
+FARPROC WINAPI dll_failure_hook(unsigned dliNotify, PDelayLoadInfo pdli) {
+    if (dliNotify == dliFailLoadLib) {
+        /* If the failing request was for qemu.exe, ... */
+        if (strcmp(pdli->szDll, "qemu.exe") == 0) {
+            /* Then pass back a pointer to the top level module. */
+            HMODULE top = GetModuleHandle(NULL);
+            return (FARPROC) top;
+        }
+    }
+    /* Otherwise we can't do anything special. */
+    return 0;
+}
+
diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
index 8ba78c7a32..751fa38619 100644
--- a/contrib/plugins/Makefile
+++ b/contrib/plugins/Makefile
@@ -22,7 +22,14 @@ NAMES += hwprofile
 NAMES += cache
 NAMES += drcov
 
-SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
+ifeq ($(CONFIG_WIN32),y)
+SO_SUFFIX := .dll
+LDLIBS += $(shell $(PKG_CONFIG) --libs glib-2.0)
+else
+SO_SUFFIX := .so
+endif
+
+SONAMES := $(addsuffix $(SO_SUFFIX),$(addprefix lib,$(NAMES)))
 
 # The main QEMU uses Glib extensively so it's perfectly fine to use it
 # in plugins (which many example do).
@@ -35,15 +42,20 @@ all: $(SONAMES)
 %.o: %.c
 	$(CC) $(CFLAGS) $(PLUGIN_CFLAGS) -c -o $@ $<
 
-lib%.so: %.o
-ifeq ($(CONFIG_DARWIN),y)
+ifeq ($(CONFIG_WIN32),y)
+lib%$(SO_SUFFIX): %.o win32_linker.o ../../plugins/qemu_plugin_api.lib
+	$(CC) -shared -o $@ $^ $(LDLIBS)
+else ifeq ($(CONFIG_DARWIN),y)
+lib%$(SO_SUFFIX): %.o
 	$(CC) -bundle -Wl,-undefined,dynamic_lookup -o $@ $^ $(LDLIBS)
 else
+lib%$(SO_SUFFIX): %.o
 	$(CC) -shared -o $@ $^ $(LDLIBS)
 endif
 
+
 clean:
-	rm -f *.o *.so *.d
+	rm -f *.o *$(SO_SUFFIX) *.d
 	rm -Rf .libs
 
 .PHONY: all clean
diff --git a/plugins/meson.build b/plugins/meson.build
index 71ed996ed3..40d24529c0 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -14,6 +14,25 @@ if not enable_modules
 endif
 
 if get_option('plugins')
+  if targetos == 'windows'
+    dlltool = find_program('dlltool', required: true)
+
+    # Generate a .lib file for plugins to link against.
+    # First, create a .def file listing all the symbols a plugin should expect to have
+    # available in qemu
+    win32_plugin_def = configure_file(
+      input: files('qemu-plugins.symbols'),
+      output: 'qemu_plugin_api.def',
+      capture: true,
+      command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
+    # then use dlltool to assemble a delaylib.
+    win32_qemu_plugin_api_lib = configure_file(
+      input: win32_plugin_def,
+      output: 'qemu_plugin_api.lib',
+      command: [dlltool, '--input-def', '@INPUT@',
+                '--output-delaylib', '@OUTPUT@', '--dllname', 'qemu.exe']
+    )
+  endif
   specific_ss.add(files(
     'loader.c',
     'core.c',
diff --git a/tests/plugin/meson.build b/tests/plugin/meson.build
index 322cafcdf6..528bb9d86c 100644
--- a/tests/plugin/meson.build
+++ b/tests/plugin/meson.build
@@ -1,9 +1,17 @@
 t = []
 if get_option('plugins')
   foreach i : ['bb', 'empty', 'insn', 'mem', 'syscall']
-    t += shared_module(i, files(i + '.c'),
-                       include_directories: '../../include/qemu',
-                       dependencies: glib)
+    if targetos == 'windows'
+      t += shared_module(i, files(i + '.c') + '../../contrib/plugins/win32_linker.c',
+                        include_directories: '../../include/qemu',
+                        objects: [win32_qemu_plugin_api_lib],
+                        dependencies: glib)
+
+    else
+      t += shared_module(i, files(i + '.c'),
+                        include_directories: '../../include/qemu',
+                        dependencies: glib)
+    endif
   endforeach
 endif
 if t.length() > 0
-- 
2.39.2



  parent reply	other threads:[~2023-11-07 14:29 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-07 14:23 [PULL 00/23] Final test, gdbstub, plugin and gitdm updates for 8.2 Alex Bennée
2023-11-07 14:23 ` [PULL 01/23] default-configs: Add TARGET_XML_FILES definition Alex Bennée
2023-11-07 14:23 ` [PULL 02/23] gdb-xml: fix duplicate register in arm-neon.xml Alex Bennée
2023-11-07 14:23 ` [PULL 03/23] target/arm: mark the 32bit alias of PAR when LPAE enabled Alex Bennée
2023-11-07 14:23 ` [PULL 04/23] target/arm: hide all versions of DBGD[RS]AR from gdbstub Alex Bennée
2023-11-07 14:23 ` [PULL 05/23] target/arm: hide aliased MIDR " Alex Bennée
2023-11-07 14:23 ` [PULL 06/23] tests/tcg: add an explicit gdbstub register tester Alex Bennée
2023-11-13 11:23   ` Nicholas Piggin
2023-11-15 20:56     ` Alex Bennée
2023-11-16  9:56       ` Luis Machado
2023-11-16 14:59         ` Alex Bennée
2023-11-07 14:23 ` [PULL 07/23] tests/avocado: update the tcg_plugins test Alex Bennée
2023-11-07 14:23 ` [PULL 08/23] gdbstub: Add num_regs member to GDBFeature Alex Bennée
2023-11-07 14:23 ` [PULL 09/23] gdbstub: Introduce gdb_find_static_feature() Alex Bennée
2023-11-07 14:23 ` [PULL 10/23] gdbstub: Introduce GDBFeatureBuilder Alex Bennée
2023-11-07 14:23 ` [PULL 11/23] cpu: Call plugin hooks only when ready Alex Bennée
2023-11-07 14:23 ` [PULL 12/23] configure: tell meson and contrib_plugins about DLLTOOL Alex Bennée
2023-11-07 14:23 ` [PULL 13/23] plugins: add dllexport and dllimport to api funcs Alex Bennée
2023-11-07 14:23 ` Alex Bennée [this message]
2023-11-07 14:23 ` [PULL 15/23] plugins: disable lockstep plugin on windows Alex Bennée
2023-11-07 14:23 ` [PULL 16/23] gitlab: add dlltool to Windows CI Alex Bennée
2023-11-07 14:23 ` [PULL 17/23] plugins: allow plugins to be enabled on windows Alex Bennée
2023-11-07 14:23 ` [PULL 18/23] contrib/gitdm: Add Rivos Inc to the domain map Alex Bennée
2023-11-07 14:23 ` [PULL 19/23] contrib/gitdm: add domain-map for Cestc Alex Bennée
2023-11-07 14:23 ` [PULL 20/23] contrib/gitdm: map HiSilicon to Huawei Alex Bennée
2023-11-07 14:23 ` [PULL 21/23] contrib/gitdm: add Daynix to domain-map Alex Bennée
2023-11-07 14:23 ` [PULL 22/23] mailmap: fixup some more corrupted author fields Alex Bennée
2023-11-07 14:23 ` [PULL 23/23] Revert "tests/tcg/nios2: Re-enable linux-user tests" Alex Bennée
2023-11-08 12:36 ` [PULL 00/23] Final test, gdbstub, plugin and gitdm updates for 8.2 Stefan Hajnoczi
2023-11-08 14:56   ` Alex Bennée
2023-11-08 15:54   ` Alex Bennée

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231107142354.3151266-15-alex.bennee@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=erdnaxe@crans.org \
    --cc=gmanning@rapitasystems.com \
    --cc=ma.mandourr@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).