All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/6] Enable plugin support on msys2/mingw
@ 2020-10-01 16:34 Yonggang Luo
  2020-10-01 16:34 ` [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed Yonggang Luo
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson

V2-V3
Split following patches out

V1-V2
1. Fixes review comments
2. Increase QEMU_PLUGIN_VERSION to 1 for compat  QEMU_PLUGIN_VERSION 0
3. Revise the loader to support for version 0 and 1
4. By export function qemu_plugin_initialize in plugin, and call it in loader=
, so
  we have no need call it in every plugin. And also provide a standard implem=
entation,
  anyway, use can also override it.

Add this feature on msys2/mingw by using glib provided cross-platform dlsym f=
unctional.

Yonggang Luo (6):
  plugins: Fixes a issue when dlsym failed, the handle not closed
  plugin: Fixes compiling errors on msys2/mingw
  cirrus: Enable plugin in cirrus for windows
  plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first
  plugin: getting qemu_plugin_get_hwaddr only expose one function
    prototype
  plugin: Getting qemu-plugin works under win32.

 .cirrus.yml                  |   3 +-
 Makefile                     |   1 -
 configure                    |  71 -------------
 contrib/plugins/hotblocks.c  |   3 +-
 contrib/plugins/hotpages.c   |   1 +
 contrib/plugins/howvec.c     |   1 +
 contrib/plugins/lockstep.c   |   1 +
 include/qemu/qemu-plugin.h   | 197 +++++++++++++++++++++++++++--------
 meson.build                  |   6 +-
 plugins/api.c                |  71 +++++++------
 plugins/core.c               |  11 +-
 plugins/loader.c             |  51 ++++++++-
 plugins/meson.build          |  10 +-
 plugins/plugin.h             |   1 +
 plugins/qemu-plugins.symbols |  40 -------
 tests/plugin/bb.c            |   5 +-
 tests/plugin/empty.c         |   1 +
 tests/plugin/insn.c          |   1 +
 tests/plugin/mem.c           |   1 +
 19 files changed, 262 insertions(+), 214 deletions(-)
 delete mode 100644 plugins/qemu-plugins.symbols

--=20
2.28.0.windows.1



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-05  9:59   ` Alex Bennée
  2020-10-01 16:34 ` [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw Yonggang Luo
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson,
	Philippe Mathieu-Daudé

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 plugins/loader.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/plugins/loader.c b/plugins/loader.c
index 685d334e1a..8ac5dbc20f 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -235,6 +235,7 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
     return rc;
 
  err_symbol:
+    g_module_close(ctx->handle);
  err_dlopen:
     qemu_vfree(ctx);
     return 1;
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
  2020-10-01 16:34 ` [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-05 10:00   ` Alex Bennée
  2020-10-01 16:34 ` [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows Yonggang Luo
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson,
	Philippe Mathieu-Daudé

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 contrib/plugins/hotblocks.c | 2 +-
 tests/plugin/bb.c           | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/plugins/hotblocks.c b/contrib/plugins/hotblocks.c
index 3942a2ca54..37435a3fc7 100644
--- a/contrib/plugins/hotblocks.c
+++ b/contrib/plugins/hotblocks.c
@@ -102,7 +102,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
 {
     ExecCount *cnt;
     uint64_t pc = qemu_plugin_tb_vaddr(tb);
-    unsigned long insns = qemu_plugin_tb_n_insns(tb);
+    size_t insns = qemu_plugin_tb_n_insns(tb);
     uint64_t hash = pc ^ insns;
 
     g_mutex_lock(&lock);
diff --git a/tests/plugin/bb.c b/tests/plugin/bb.c
index e4cc7fdd6e..de09bdde4e 100644
--- a/tests/plugin/bb.c
+++ b/tests/plugin/bb.c
@@ -72,7 +72,7 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata)
     CPUCount *count = max_cpus ?
         g_ptr_array_index(counts, cpu_index) : &inline_count;
 
-    unsigned long n_insns = (unsigned long)udata;
+    uintptr_t n_insns = (uintptr_t)udata;
     g_mutex_lock(&count->lock);
     count->insn_count += n_insns;
     count->bb_count++;
@@ -81,7 +81,7 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata)
 
 static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
 {
-    unsigned long n_insns = qemu_plugin_tb_n_insns(tb);
+    size_t n_insns = qemu_plugin_tb_n_insns(tb);
 
     if (do_inline) {
         qemu_plugin_register_vcpu_tb_exec_inline(tb, QEMU_PLUGIN_INLINE_ADD_U64,
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
  2020-10-01 16:34 ` [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed Yonggang Luo
  2020-10-01 16:34 ` [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-05 10:17   ` Alex Bennée
  2020-10-01 16:34 ` [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first Yonggang Luo
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 .cirrus.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.cirrus.yml b/.cirrus.yml
index 86ea33926a..5363142373 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -104,7 +104,8 @@ windows_msys2_task:
     - C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build"
     - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure
       --python=python3 --ninja=ninja
-      --target-list-exclude=i386-softmmu,arm-softmmu,ppc-softmmu,mips-softmmu"
+      --target-list-exclude=i386-softmmu,arm-softmmu,ppc-softmmu,mips-softmmu
+      --enable-plugins"
     - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make -j$NUMBER_OF_PROCESSORS"
   test_script:
     - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check"
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
                   ` (2 preceding siblings ...)
  2020-10-01 16:34 ` [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-05 10:44   ` Alex Bennée
  2020-10-01 16:34 ` [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype Yonggang Luo
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson

This is used to distinguish from the qemu and plugin in
header qemu-plugin.h

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 plugins/api.c  | 1 +
 plugins/core.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/plugins/api.c b/plugins/api.c
index bbdc5a4eb4..f16922ca8b 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -35,6 +35,7 @@
  */
 
 #include "qemu/osdep.h"
+#define QEMU_PLUGIN_API_IMPLEMENTATION
 #include "qemu/plugin.h"
 #include "cpu.h"
 #include "sysemu/sysemu.h"
diff --git a/plugins/core.c b/plugins/core.c
index 51bfc94787..7a79ea4179 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -12,6 +12,7 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 #include "qemu/osdep.h"
+#define QEMU_PLUGIN_API_IMPLEMENTATION
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 #include "qapi/error.h"
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
                   ` (3 preceding siblings ...)
  2020-10-01 16:34 ` [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-05 10:48   ` Alex Bennée
  2020-10-01 16:34 ` [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32 Yonggang Luo
  2020-10-06 11:35 ` [PATCH v3 0/6] Enable plugin support on msys2/mingw Alex Bennée
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson

This is used for counting how much function are export to qemu plugin.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 plugins/api.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/plugins/api.c b/plugins/api.c
index f16922ca8b..d325084385 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -252,10 +252,12 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
 
 #ifdef CONFIG_SOFTMMU
 static __thread struct qemu_plugin_hwaddr hwaddr_info;
+#endif
 
 struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
                                                   uint64_t vaddr)
 {
+#ifdef CONFIG_SOFTMMU
     CPUState *cpu = current_cpu;
     unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
     hwaddr_info.is_store = info & TRACE_MEM_ST;
@@ -267,14 +269,10 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
     }
 
     return &hwaddr_info;
-}
 #else
-struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
-                                                  uint64_t vaddr)
-{
     return NULL;
-}
 #endif
+}
 
 bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
 {
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32.
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
                   ` (4 preceding siblings ...)
  2020-10-01 16:34 ` [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype Yonggang Luo
@ 2020-10-01 16:34 ` Yonggang Luo
  2020-10-06 11:29   ` Alex Bennée
  2020-10-06 11:35 ` [PATCH v3 0/6] Enable plugin support on msys2/mingw Alex Bennée
  6 siblings, 1 reply; 20+ messages in thread
From: Yonggang Luo @ 2020-10-01 16:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Paolo Bonzini, Yonggang Luo, Richard Henderson

We removed the need of .symbols file, so is the
configure script, if we one expose a function to qemu-plugin
just need prefix the function with QEMU_PLUGIN_EXPORT

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 Makefile                     |   1 -
 configure                    |  71 -------------
 contrib/plugins/hotblocks.c  |   1 +
 contrib/plugins/hotpages.c   |   1 +
 contrib/plugins/howvec.c     |   1 +
 contrib/plugins/lockstep.c   |   1 +
 include/qemu/qemu-plugin.h   | 197 +++++++++++++++++++++++++++--------
 meson.build                  |   6 +-
 plugins/api.c                |  62 +++++------
 plugins/core.c               |  10 +-
 plugins/loader.c             |  50 ++++++++-
 plugins/meson.build          |  10 +-
 plugins/plugin.h             |   1 +
 plugins/qemu-plugins.symbols |  40 -------
 tests/plugin/bb.c            |   1 +
 tests/plugin/empty.c         |   1 +
 tests/plugin/insn.c          |   1 +
 tests/plugin/mem.c           |   1 +
 18 files changed, 251 insertions(+), 205 deletions(-)
 delete mode 100644 plugins/qemu-plugins.symbols

diff --git a/Makefile b/Makefile
index 54fc1a9d10..9981dd5209 100644
--- a/Makefile
+++ b/Makefile
@@ -105,7 +105,6 @@ config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
 
 # Force configure to re-run if the API symbols are updated
 ifeq ($(CONFIG_PLUGIN),y)
-config-host.mak: $(SRC_PATH)/plugins/qemu-plugins.symbols
 
 .PHONY: plugins
 plugins:
diff --git a/configure b/configure
index 1c21a73c3b..ea447919fc 100755
--- a/configure
+++ b/configure
@@ -5435,61 +5435,6 @@ if compile_prog "" "" ; then
   atomic64=yes
 fi
 
-#########################################
-# See if --dynamic-list is supported by the linker
-ld_dynamic_list="no"
-if test "$static" = "no" ; then
-    cat > $TMPTXT <<EOF
-{
-  foo;
-};
-EOF
-
-    cat > $TMPC <<EOF
-#include <stdio.h>
-void foo(void);
-
-void foo(void)
-{
-  printf("foo\n");
-}
-
-int main(void)
-{
-  foo();
-  return 0;
-}
-EOF
-
-    if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
-        ld_dynamic_list="yes"
-    fi
-fi
-
-#########################################
-# See if -exported_symbols_list is supported by the linker
-
-ld_exported_symbols_list="no"
-if test "$static" = "no" ; then
-    cat > $TMPTXT <<EOF
-  _foo
-EOF
-
-    if compile_prog "" "-Wl,-exported_symbols_list,$TMPTXT" ; then
-        ld_exported_symbols_list="yes"
-    fi
-fi
-
-if  test "$plugins" = "yes" &&
-    test "$ld_dynamic_list" = "no" &&
-    test "$ld_exported_symbols_list" = "no" ; then
-  error_exit \
-      "Plugin support requires dynamic linking and specifying a set of symbols " \
-      "that are exported to plugins. Unfortunately your linker doesn't " \
-      "support the flag (--dynamic-list or -exported_symbols_list) used " \
-      "for this purpose. You can't build with --static."
-fi
-
 ########################################
 # See if __attribute__((alias)) is supported.
 # This false for Xcode 9, but has been remedied for Xcode 10.
@@ -7074,22 +7019,6 @@ fi
 
 if test "$plugins" = "yes" ; then
     echo "CONFIG_PLUGIN=y" >> $config_host_mak
-    # Copy the export object list to the build dir
-    if test "$ld_dynamic_list" = "yes" ; then
-	echo "CONFIG_HAS_LD_DYNAMIC_LIST=yes" >> $config_host_mak
-	ld_symbols=qemu-plugins-ld.symbols
-	cp "$source_path/plugins/qemu-plugins.symbols" $ld_symbols
-    elif test "$ld_exported_symbols_list" = "yes" ; then
-	echo "CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST=yes" >> $config_host_mak
-	ld64_symbols=qemu-plugins-ld64.symbols
-	echo "# Automatically generated by configure - do not modify" > $ld64_symbols
-	grep 'qemu_' "$source_path/plugins/qemu-plugins.symbols" | sed 's/;//g' | \
-	    sed -E 's/^[[:space:]]*(.*)/_\1/' >> $ld64_symbols
-    else
-	error_exit \
-	    "If \$plugins=yes, either \$ld_dynamic_list or " \
-	    "\$ld_exported_symbols_list should have been set to 'yes'."
-    fi
 fi
 
 if test -n "$gdb_bin" ; then
diff --git a/contrib/plugins/hotblocks.c b/contrib/plugins/hotblocks.c
index 37435a3fc7..39e77d2980 100644
--- a/contrib/plugins/hotblocks.c
+++ b/contrib/plugins/hotblocks.c
@@ -13,6 +13,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/contrib/plugins/hotpages.c b/contrib/plugins/hotpages.c
index ecd6c18732..1ae3f44aed 100644
--- a/contrib/plugins/hotpages.c
+++ b/contrib/plugins/hotpages.c
@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/contrib/plugins/howvec.c b/contrib/plugins/howvec.c
index 3b9a6939f2..db1b4e5780 100644
--- a/contrib/plugins/howvec.c
+++ b/contrib/plugins/howvec.c
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/contrib/plugins/lockstep.c b/contrib/plugins/lockstep.c
index a696673dff..7173b2910d 100644
--- a/contrib/plugins/lockstep.c
+++ b/contrib/plugins/lockstep.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <errno.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index bab8b0d4b3..8d08f52f7f 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -21,11 +21,7 @@
  *   https://gcc.gnu.org/wiki/Visibility
  */
 #if defined _WIN32 || defined __CYGWIN__
-  #ifdef BUILDING_DLL
-    #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
-  #else
-    #define QEMU_PLUGIN_EXPORT __declspec(dllimport)
-  #endif
+  #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
   #define QEMU_PLUGIN_LOCAL
 #else
   #if __GNUC__ >= 4
@@ -52,7 +48,9 @@ typedef uint64_t qemu_plugin_id_t;
 
 extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
 
-#define QEMU_PLUGIN_VERSION 0
+#define QEMU_PLUGIN_VERSION 1
+
+typedef void *(*qemu_plugin_global_dlsym_t)(void* context, const char *name);
 
 typedef struct {
     /* string describing architecture */
@@ -73,8 +71,23 @@ typedef struct {
             int max_vcpus;
         } system;
     };
+    void *context;
+    qemu_plugin_global_dlsym_t dlsym;
 } qemu_info_t;
 
+/**
+ * qemu_plugin_initialize() - Initialize a plugin before install
+ * @info: a block describing some details about the guest
+ *
+ * All plugins must export this symbol, and in most case using qemu-plugin.h
+ * provided implementation directly.
+ * For plugin provide this function, the QEMU_PLUGIN_VERSION should >= 1
+ *
+ * Note: This function only used to loading qemu's exported functions, nothing
+ * else should doding in this function.
+ */
+QEMU_PLUGIN_EXPORT int qemu_plugin_initialize(const qemu_info_t *info);
+
 /**
  * qemu_plugin_install() - Install a plugin
  * @id: this plugin's opaque ID
@@ -121,7 +134,7 @@ typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
  *
  * Note: Calling this function from qemu_plugin_install() is a bug.
  */
-void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
+typedef void (*qemu_plugin_uninstall_t)(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
 
 /**
  * qemu_plugin_reset() - Reset a plugin
@@ -134,7 +147,7 @@ void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
  * Plugins are reset asynchronously, and therefore the given plugin receives
  * callbacks until @cb is called.
  */
-void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
+typedef void (*qemu_plugin_reset_t)(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
 
 /**
  * qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback
@@ -145,7 +158,7 @@ void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
  *
  * See also: qemu_plugin_register_vcpu_exit_cb()
  */
-void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_init_cb_t)(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb);
 
 /**
@@ -157,7 +170,7 @@ void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
  *
  * See also: qemu_plugin_register_vcpu_init_cb()
  */
-void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_exit_cb_t)(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb);
 
 /**
@@ -167,7 +180,7 @@ void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
  *
  * The @cb function is called every time a vCPU idles.
  */
-void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_idle_cb_t)(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb);
 
 /**
@@ -177,7 +190,7 @@ void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
  *
  * The @cb function is called every time a vCPU resumes execution.
  */
-void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_resume_cb_t)(qemu_plugin_id_t id,
                                          qemu_plugin_vcpu_simple_cb_t cb);
 
 /*
@@ -214,11 +227,11 @@ enum qemu_plugin_mem_rw {
 typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
                                                struct qemu_plugin_tb *tb);
 
-void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
                                            qemu_plugin_vcpu_tb_trans_cb_t cb);
 
 /**
- * qemu_plugin_register_vcpu_tb_trans_exec_cb() - register execution callback
+ * qemu_plugin_register_vcpu_tb_exec_cb() - register execution callback
  * @tb: the opaque qemu_plugin_tb handle for the translation
  * @cb: callback function
  * @flags: does the plugin read or write the CPU's registers?
@@ -226,7 +239,7 @@ void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
  *
  * The @cb function is called every time a translated unit executes.
  */
-void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
+typedef void (*qemu_plugin_register_vcpu_tb_exec_cb_t)(struct qemu_plugin_tb *tb,
                                           qemu_plugin_vcpu_udata_cb_t cb,
                                           enum qemu_plugin_cb_flags flags,
                                           void *userdata);
@@ -236,7 +249,7 @@ enum qemu_plugin_op {
 };
 
 /**
- * qemu_plugin_register_vcpu_tb_trans_exec_inline() - execution inline op
+ * qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op
  * @tb: the opaque qemu_plugin_tb handle for the translation
  * @op: the type of qemu_plugin_op (e.g. ADD_U64)
  * @ptr: the target memory location for the op
@@ -246,7 +259,7 @@ enum qemu_plugin_op {
  * Useful if you just want to increment a single counter somewhere in
  * memory.
  */
-void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
+typedef void (*qemu_plugin_register_vcpu_tb_exec_inline_t)(struct qemu_plugin_tb *tb,
                                               enum qemu_plugin_op op,
                                               void *ptr, uint64_t imm);
 
@@ -259,7 +272,7 @@ void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
  *
  * The @cb function is called every time an instruction is executed
  */
-void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
+typedef void (*qemu_plugin_register_vcpu_insn_exec_cb_t)(struct qemu_plugin_insn *insn,
                                             qemu_plugin_vcpu_udata_cb_t cb,
                                             enum qemu_plugin_cb_flags flags,
                                             void *userdata);
@@ -275,26 +288,26 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
  * Insert an inline op to every time an instruction executes. Useful
  * if you just want to increment a single counter somewhere in memory.
  */
-void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
+typedef void (*qemu_plugin_register_vcpu_insn_exec_inline_t)(struct qemu_plugin_insn *insn,
                                                 enum qemu_plugin_op op,
                                                 void *ptr, uint64_t imm);
 
 /*
  * Helpers to query information about the instructions in a block
  */
-size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
+typedef size_t (*qemu_plugin_tb_n_insns_t)(const struct qemu_plugin_tb *tb);
 
-uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
+typedef uint64_t (*qemu_plugin_tb_vaddr_t)(const struct qemu_plugin_tb *tb);
 
-struct qemu_plugin_insn *
-qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
+typedef struct qemu_plugin_insn *
+(*qemu_plugin_tb_get_insn_t)(const struct qemu_plugin_tb *tb, size_t idx);
 
-const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
+typedef const void *(*qemu_plugin_insn_data_t)(const struct qemu_plugin_insn *insn);
 
-size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
+typedef size_t (*qemu_plugin_insn_size_t)(const struct qemu_plugin_insn *insn);
 
-uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
-void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
+typedef uint64_t (*qemu_plugin_insn_vaddr_t)(const struct qemu_plugin_insn *insn);
+typedef void *(*qemu_plugin_insn_haddr_t)(const struct qemu_plugin_insn *insn);
 
 /*
  * Memory Instrumentation
@@ -307,10 +320,10 @@ typedef uint32_t qemu_plugin_meminfo_t;
 struct qemu_plugin_hwaddr;
 
 /* meminfo queries */
-unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
-bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
-bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
-bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
+typedef unsigned int (*qemu_plugin_mem_size_shift_t)(qemu_plugin_meminfo_t info);
+typedef bool (*qemu_plugin_mem_is_sign_extended_t)(qemu_plugin_meminfo_t info);
+typedef bool (*qemu_plugin_mem_is_big_endian_t)(qemu_plugin_meminfo_t info);
+typedef bool (*qemu_plugin_mem_is_store_t)(qemu_plugin_meminfo_t info);
 
 /*
  * qemu_plugin_get_hwaddr():
@@ -324,7 +337,7 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
  * information about the handle should be recovered before the
  * callback returns.
  */
-struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
+typedef struct qemu_plugin_hwaddr *(*qemu_plugin_get_hwaddr_t)(qemu_plugin_meminfo_t info,
                                                   uint64_t vaddr);
 
 /*
@@ -332,21 +345,21 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
  * to return information about it. For non-IO accesses the device
  * offset will be into the appropriate block of RAM.
  */
-bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr);
-uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr);
+typedef bool (*qemu_plugin_hwaddr_is_io_t)(const struct qemu_plugin_hwaddr *haddr);
+typedef uint64_t (*qemu_plugin_hwaddr_device_offset_t)(const struct qemu_plugin_hwaddr *haddr);
 
 typedef void
 (*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
                              qemu_plugin_meminfo_t info, uint64_t vaddr,
                              void *userdata);
 
-void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
+typedef void (*qemu_plugin_register_vcpu_mem_cb_t)(struct qemu_plugin_insn *insn,
                                       qemu_plugin_vcpu_mem_cb_t cb,
                                       enum qemu_plugin_cb_flags flags,
                                       enum qemu_plugin_mem_rw rw,
                                       void *userdata);
 
-void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
+typedef void (*qemu_plugin_register_vcpu_mem_inline_t)(struct qemu_plugin_insn *insn,
                                           enum qemu_plugin_mem_rw rw,
                                           enum qemu_plugin_op op, void *ptr,
                                           uint64_t imm);
@@ -359,15 +372,15 @@ typedef void
                                  uint64_t a3, uint64_t a4, uint64_t a5,
                                  uint64_t a6, uint64_t a7, uint64_t a8);
 
-void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_vcpu_syscall_cb_t)(qemu_plugin_id_t id,
                                           qemu_plugin_vcpu_syscall_cb_t cb);
 
 typedef void
 (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
                                      int64_t num, int64_t ret);
 
-void
-qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
+typedef void
+(*qemu_plugin_register_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id,
                                          qemu_plugin_vcpu_syscall_ret_cb_t cb);
 
 
@@ -378,7 +391,7 @@ qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
  * Returns an allocated string containing the disassembly
  */
 
-char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
+typedef char *(*qemu_plugin_insn_disas_t)(const struct qemu_plugin_insn *insn);
 
 /**
  * qemu_plugin_vcpu_for_each() - iterate over the existing vCPU
@@ -389,25 +402,117 @@ char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
  *
  * See also: qemu_plugin_register_vcpu_init_cb()
  */
-void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_vcpu_for_each_t)(qemu_plugin_id_t id,
                                qemu_plugin_vcpu_simple_cb_t cb);
 
-void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_flush_cb_t)(qemu_plugin_id_t id,
                                    qemu_plugin_simple_cb_t cb);
 
-void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
+typedef void (*qemu_plugin_register_atexit_cb_t)(qemu_plugin_id_t id,
                                     qemu_plugin_udata_cb_t cb, void *userdata);
 
 /* returns -1 in user-mode */
-int qemu_plugin_n_vcpus(void);
+typedef int (*qemu_plugin_n_vcpus_t)(void);
 
 /* returns -1 in user-mode */
-int qemu_plugin_n_max_vcpus(void);
+typedef int (*qemu_plugin_n_max_vcpus_t)(void);
 
 /**
  * qemu_plugin_outs() - output string via QEMU's logging system
  * @string: a string
  */
-void qemu_plugin_outs(const char *string);
+typedef void (*qemu_plugin_outs_t)(const char *string);
+
+#if !defined(QEMU_PLUGIN_API_IMPLEMENTATION)
+#if defined(QEMU_PLUGIN_IMPLEMENTATION)
+#define QEMU_PLUGIN_EXTERN
+#else
+#define QEMU_PLUGIN_EXTERN extern
+#endif
+
+QEMU_PLUGIN_EXTERN qemu_plugin_uninstall_t qemu_plugin_uninstall;
+QEMU_PLUGIN_EXTERN qemu_plugin_reset_t qemu_plugin_reset;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_init_cb_t qemu_plugin_register_vcpu_init_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_exit_cb_t qemu_plugin_register_vcpu_exit_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_idle_cb_t qemu_plugin_register_vcpu_idle_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_resume_cb_t qemu_plugin_register_vcpu_resume_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_tb_trans_cb_t qemu_plugin_register_vcpu_tb_trans_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_tb_exec_cb_t qemu_plugin_register_vcpu_tb_exec_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_tb_exec_inline_t qemu_plugin_register_vcpu_tb_exec_inline;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_insn_exec_cb_t qemu_plugin_register_vcpu_insn_exec_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_insn_exec_inline_t qemu_plugin_register_vcpu_insn_exec_inline;
+QEMU_PLUGIN_EXTERN qemu_plugin_tb_n_insns_t qemu_plugin_tb_n_insns;
+QEMU_PLUGIN_EXTERN qemu_plugin_tb_vaddr_t qemu_plugin_tb_vaddr;
+QEMU_PLUGIN_EXTERN qemu_plugin_tb_get_insn_t qemu_plugin_tb_get_insn;
+QEMU_PLUGIN_EXTERN qemu_plugin_insn_data_t qemu_plugin_insn_data;
+QEMU_PLUGIN_EXTERN qemu_plugin_insn_size_t qemu_plugin_insn_size;
+QEMU_PLUGIN_EXTERN qemu_plugin_insn_vaddr_t qemu_plugin_insn_vaddr;
+QEMU_PLUGIN_EXTERN qemu_plugin_insn_haddr_t qemu_plugin_insn_haddr;
+QEMU_PLUGIN_EXTERN qemu_plugin_mem_size_shift_t qemu_plugin_mem_size_shift;
+QEMU_PLUGIN_EXTERN qemu_plugin_mem_is_sign_extended_t qemu_plugin_mem_is_sign_extended;
+QEMU_PLUGIN_EXTERN qemu_plugin_mem_is_big_endian_t qemu_plugin_mem_is_big_endian;
+QEMU_PLUGIN_EXTERN qemu_plugin_mem_is_store_t qemu_plugin_mem_is_store;
+QEMU_PLUGIN_EXTERN qemu_plugin_get_hwaddr_t qemu_plugin_get_hwaddr;
+QEMU_PLUGIN_EXTERN qemu_plugin_hwaddr_is_io_t qemu_plugin_hwaddr_is_io;
+QEMU_PLUGIN_EXTERN qemu_plugin_hwaddr_device_offset_t qemu_plugin_hwaddr_device_offset;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_mem_cb_t qemu_plugin_register_vcpu_mem_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_mem_inline_t qemu_plugin_register_vcpu_mem_inline;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_syscall_cb_t qemu_plugin_register_vcpu_syscall_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_vcpu_syscall_ret_cb_t qemu_plugin_register_vcpu_syscall_ret_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_insn_disas_t qemu_plugin_insn_disas;
+QEMU_PLUGIN_EXTERN qemu_plugin_vcpu_for_each_t qemu_plugin_vcpu_for_each;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_flush_cb_t qemu_plugin_register_flush_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_register_atexit_cb_t qemu_plugin_register_atexit_cb;
+QEMU_PLUGIN_EXTERN qemu_plugin_n_vcpus_t qemu_plugin_n_vcpus;
+QEMU_PLUGIN_EXTERN qemu_plugin_n_max_vcpus_t qemu_plugin_n_max_vcpus;
+QEMU_PLUGIN_EXTERN qemu_plugin_outs_t qemu_plugin_outs;
+
+#if defined(QEMU_PLUGIN_IMPLEMENTATION)
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_initialize(const qemu_info_t *info)
+{
+    qemu_plugin_uninstall = info->dlsym(info->context, "qemu_plugin_uninstall");
+    qemu_plugin_reset = info->dlsym(info->context, "qemu_plugin_reset");
+    qemu_plugin_register_vcpu_init_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_init_cb");
+    qemu_plugin_register_vcpu_exit_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_exit_cb");
+    qemu_plugin_register_vcpu_idle_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_idle_cb");
+    qemu_plugin_register_vcpu_resume_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_resume_cb");
+    qemu_plugin_register_vcpu_tb_trans_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_tb_trans_cb");
+    qemu_plugin_register_vcpu_tb_exec_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_tb_exec_cb");
+    qemu_plugin_register_vcpu_tb_exec_inline = info->dlsym(info->context, "qemu_plugin_register_vcpu_tb_exec_inline");
+    qemu_plugin_register_vcpu_insn_exec_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_insn_exec_cb");
+    qemu_plugin_register_vcpu_insn_exec_inline = info->dlsym(info->context, "qemu_plugin_register_vcpu_insn_exec_inline");
+    qemu_plugin_tb_n_insns = info->dlsym(info->context, "qemu_plugin_tb_n_insns");
+    qemu_plugin_tb_vaddr = info->dlsym(info->context, "qemu_plugin_tb_vaddr");
+    qemu_plugin_tb_get_insn = info->dlsym(info->context, "qemu_plugin_tb_get_insn");
+    qemu_plugin_insn_data = info->dlsym(info->context, "qemu_plugin_insn_data");
+    qemu_plugin_insn_size = info->dlsym(info->context, "qemu_plugin_insn_size");
+    qemu_plugin_insn_vaddr = info->dlsym(info->context, "qemu_plugin_insn_vaddr");
+    qemu_plugin_insn_haddr = info->dlsym(info->context, "qemu_plugin_insn_haddr");
+    qemu_plugin_mem_size_shift = info->dlsym(info->context, "qemu_plugin_mem_size_shift");
+    qemu_plugin_mem_is_sign_extended = info->dlsym(info->context, "qemu_plugin_mem_is_sign_extended");
+    qemu_plugin_mem_is_big_endian = info->dlsym(info->context, "qemu_plugin_mem_is_big_endian");
+    qemu_plugin_mem_is_store = info->dlsym(info->context, "qemu_plugin_mem_is_store");
+    qemu_plugin_get_hwaddr = info->dlsym(info->context, "qemu_plugin_get_hwaddr");
+    qemu_plugin_hwaddr_is_io = info->dlsym(info->context, "qemu_plugin_hwaddr_is_io");
+    qemu_plugin_hwaddr_device_offset = info->dlsym(info->context, "qemu_plugin_hwaddr_device_offset");
+    qemu_plugin_register_vcpu_mem_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_mem_cb");
+    qemu_plugin_register_vcpu_mem_inline = info->dlsym(info->context, "qemu_plugin_register_vcpu_mem_inline");
+    qemu_plugin_register_vcpu_syscall_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_syscall_cb");
+    qemu_plugin_register_vcpu_syscall_ret_cb = info->dlsym(info->context, "qemu_plugin_register_vcpu_syscall_ret_cb");
+    qemu_plugin_insn_disas = info->dlsym(info->context, "qemu_plugin_insn_disas");
+    qemu_plugin_vcpu_for_each = info->dlsym(info->context, "qemu_plugin_vcpu_for_each");
+    qemu_plugin_register_flush_cb = info->dlsym(info->context, "qemu_plugin_register_flush_cb");
+    qemu_plugin_register_atexit_cb = info->dlsym(info->context, "qemu_plugin_register_atexit_cb");
+    qemu_plugin_n_vcpus = info->dlsym(info->context, "qemu_plugin_n_vcpus");
+    qemu_plugin_n_max_vcpus = info->dlsym(info->context, "qemu_plugin_n_max_vcpus");
+    qemu_plugin_outs = info->dlsym(info->context, "qemu_plugin_outs");
+    return 0;
+}
+
+#endif
+
+#endif /* QEMU_PLUGIN_API_IMPLEMENTATION */
+
 
 #endif /* QEMU_PLUGIN_API_H */
diff --git a/meson.build b/meson.build
index 853064e983..3998d1f14a 100644
--- a/meson.build
+++ b/meson.build
@@ -243,7 +243,11 @@ endif
 rt = cc.find_library('rt', required: false)
 libdl = not_found
 if 'CONFIG_PLUGIN' in config_host
-  libdl = cc.find_library('dl', required: true)
+  if targetos == 'windows'
+    libdl = declare_dependency(compile_args: [], link_args: [])
+  else
+    libdl = cc.find_library('dl', required: true)
+  endif
 endif
 libiscsi = not_found
 if 'CONFIG_LIBISCSI' in config_host
diff --git a/plugins/api.c b/plugins/api.c
index d325084385..2acbbe5159 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -51,12 +51,12 @@
 
 /* Uninstall and Reset handlers */
 
-void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
+QEMU_PLUGIN_EXPORT void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
 {
     plugin_reset_uninstall(id, cb, false);
 }
 
-void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
+QEMU_PLUGIN_EXPORT void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
 {
     plugin_reset_uninstall(id, cb, true);
 }
@@ -68,19 +68,19 @@ void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
  * during the translation.
  */
 
-void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_INIT, cb);
 }
 
-void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_EXIT, cb);
 }
 
-void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
                                           qemu_plugin_vcpu_udata_cb_t cb,
                                           enum qemu_plugin_cb_flags flags,
                                           void *udata)
@@ -89,14 +89,14 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
                                   cb, flags, udata);
 }
 
-void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
                                               enum qemu_plugin_op op,
                                               void *ptr, uint64_t imm)
 {
     plugin_register_inline_op(&tb->cbs[PLUGIN_CB_INLINE], 0, op, ptr, imm);
 }
 
-void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
                                             qemu_plugin_vcpu_udata_cb_t cb,
                                             enum qemu_plugin_cb_flags flags,
                                             void *udata)
@@ -105,7 +105,7 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
         cb, flags, udata);
 }
 
-void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
                                                 enum qemu_plugin_op op,
                                                 void *ptr, uint64_t imm)
 {
@@ -115,7 +115,7 @@ void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
 
 
 
-void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
                                       qemu_plugin_vcpu_mem_cb_t cb,
                                       enum qemu_plugin_cb_flags flags,
                                       enum qemu_plugin_mem_rw rw,
@@ -125,7 +125,7 @@ void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
                                 cb, flags, rw, udata);
 }
 
-void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
                                           enum qemu_plugin_mem_rw rw,
                                           enum qemu_plugin_op op, void *ptr,
                                           uint64_t imm)
@@ -134,19 +134,19 @@ void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
         rw, op, ptr, imm);
 }
 
-void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
                                            qemu_plugin_vcpu_tb_trans_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_TB_TRANS, cb);
 }
 
-void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
                                           qemu_plugin_vcpu_syscall_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL, cb);
 }
 
-void
+QEMU_PLUGIN_EXPORT void
 qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
                                          qemu_plugin_vcpu_syscall_ret_cb_t cb)
 {
@@ -169,17 +169,17 @@ qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
  * each translated instruction.
  */
 
-size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb)
+QEMU_PLUGIN_EXPORT size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb)
 {
     return tb->n;
 }
 
-uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb)
+QEMU_PLUGIN_EXPORT uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb)
 {
     return tb->vaddr;
 }
 
-struct qemu_plugin_insn *
+QEMU_PLUGIN_EXPORT struct qemu_plugin_insn *
 qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx)
 {
     if (unlikely(idx >= tb->n)) {
@@ -195,27 +195,27 @@ qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx)
  * instruction being translated.
  */
 
-const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn)
+QEMU_PLUGIN_EXPORT const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn)
 {
     return insn->data->data;
 }
 
-size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn)
+QEMU_PLUGIN_EXPORT size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn)
 {
     return insn->data->len;
 }
 
-uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn)
+QEMU_PLUGIN_EXPORT uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn)
 {
     return insn->vaddr;
 }
 
-void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn)
+QEMU_PLUGIN_EXPORT void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn)
 {
     return insn->haddr;
 }
 
-char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn)
+QEMU_PLUGIN_EXPORT char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn)
 {
     CPUState *cpu = current_cpu;
     return plugin_disas(cpu, insn->vaddr, insn->data->len);
@@ -226,22 +226,22 @@ char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn)
  * memory access.
  */
 
-unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info)
+QEMU_PLUGIN_EXPORT unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info)
 {
     return info & TRACE_MEM_SZ_SHIFT_MASK;
 }
 
-bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info)
+QEMU_PLUGIN_EXPORT bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info)
 {
     return !!(info & TRACE_MEM_SE);
 }
 
-bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info)
+QEMU_PLUGIN_EXPORT bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info)
 {
     return !!(info & TRACE_MEM_BE);
 }
 
-bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
+QEMU_PLUGIN_EXPORT bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
 {
     return !!(info & TRACE_MEM_ST);
 }
@@ -254,7 +254,7 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
 static __thread struct qemu_plugin_hwaddr hwaddr_info;
 #endif
 
-struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
+QEMU_PLUGIN_EXPORT struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
                                                   uint64_t vaddr)
 {
 #ifdef CONFIG_SOFTMMU
@@ -274,7 +274,7 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
 #endif
 }
 
-bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
+QEMU_PLUGIN_EXPORT bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
 {
 #ifdef CONFIG_SOFTMMU
     return haddr->is_io;
@@ -283,7 +283,7 @@ bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
 #endif
 }
 
-uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr)
+QEMU_PLUGIN_EXPORT uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr)
 {
 #ifdef CONFIG_SOFTMMU
     if (haddr) {
@@ -314,7 +314,7 @@ static MachineState * get_ms(void)
 }
 #endif
 
-int qemu_plugin_n_vcpus(void)
+QEMU_PLUGIN_EXPORT int qemu_plugin_n_vcpus(void)
 {
 #ifdef CONFIG_USER_ONLY
     return -1;
@@ -323,7 +323,7 @@ int qemu_plugin_n_vcpus(void)
 #endif
 }
 
-int qemu_plugin_n_max_vcpus(void)
+QEMU_PLUGIN_EXPORT int qemu_plugin_n_max_vcpus(void)
 {
 #ifdef CONFIG_USER_ONLY
     return -1;
@@ -335,7 +335,7 @@ int qemu_plugin_n_max_vcpus(void)
 /*
  * Plugin output
  */
-void qemu_plugin_outs(const char *string)
+QEMU_PLUGIN_EXPORT void qemu_plugin_outs(const char *string)
 {
     qemu_log_mask(CPU_LOG_PLUGIN, "%s", string);
 }
diff --git a/plugins/core.c b/plugins/core.c
index 7a79ea4179..a59a0bd25b 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -234,7 +234,7 @@ static void plugin_vcpu_for_each(gpointer k, gpointer v, gpointer udata)
     args->cb(args->ctx->id, cpu_index);
 }
 
-void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
                                qemu_plugin_vcpu_simple_cb_t cb)
 {
     struct plugin_for_each_args args;
@@ -385,19 +385,19 @@ void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
     plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_RESUME);
 }
 
-void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
                                        qemu_plugin_vcpu_simple_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_IDLE, cb);
 }
 
-void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
                                          qemu_plugin_vcpu_simple_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_RESUME, cb);
 }
 
-void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
                                    qemu_plugin_simple_cb_t cb)
 {
     plugin_register_cb(id, QEMU_PLUGIN_EV_FLUSH, cb);
@@ -464,7 +464,7 @@ void qemu_plugin_atexit_cb(void)
     plugin_cb__udata(QEMU_PLUGIN_EV_ATEXIT);
 }
 
-void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
+QEMU_PLUGIN_EXPORT void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
                                     qemu_plugin_udata_cb_t cb,
                                     void *udata)
 {
diff --git a/plugins/loader.c b/plugins/loader.c
index 8ac5dbc20f..53fb1671ee 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -63,6 +63,7 @@ QemuOptsList qemu_plugin_opts = {
     },
 };
 
+typedef int (*qemu_plugin_initialize_func_t)(const qemu_info_t *);
 typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, const qemu_info_t *, int, char **);
 
 extern struct qemu_plugin_state plugin;
@@ -152,10 +153,12 @@ static uint64_t xorshift64star(uint64_t x)
 
 static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
 {
+    qemu_plugin_initialize_func_t initialize = NULL;
     qemu_plugin_install_func_t install;
     struct qemu_plugin_ctx *ctx;
     gpointer sym;
     int rc;
+    int version = -1;
 
     ctx = qemu_memalign(qemu_dcache_linesize, sizeof(*ctx));
     memset(ctx, 0, sizeof(*ctx));
@@ -184,7 +187,7 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
                      desc->path, g_module_error());
         goto err_symbol;
     } else {
-        int version = *(int *)sym;
+        version = *(int *)sym;
         if (version < QEMU_PLUGIN_MIN_VERSION) {
             error_report("TCG plugin %s requires API version %d, but "
                          "this QEMU supports only a minimum version of %d",
@@ -198,6 +201,21 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
         }
     }
 
+    if (version >= QEMU_PLUGIN_VERSION_1) {
+        /* This version should call to qemu_plugin_initialize first */
+        if (!g_module_symbol(ctx->handle, "qemu_plugin_initialize", &sym)) {
+            error_report("%s: %s", __func__, g_module_error());
+            goto err_symbol;
+        }
+        initialize = (qemu_plugin_initialize_func_t) sym;
+        /* symbol was found; it could be NULL though */
+        if (initialize == NULL) {
+            error_report("%s: %s: qemu_plugin_initialize is NULL",
+                        __func__, desc->path);
+            goto err_symbol;
+        }
+    }
+
     qemu_rec_mutex_lock(&plugin.lock);
 
     /* find an unused random id with &ctx as the seed */
@@ -216,6 +234,16 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
         }
     }
     QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry);
+    if (initialize != NULL) {
+        rc = initialize(info);
+        if (rc) {
+            error_report("%s: qemu_plugin_initialize returned error code %d",
+                        __func__, rc);
+            /* qemu_plugin_initialize only loading function symbols */
+            goto err_symbol;
+        }
+    }
+
     ctx->installing = true;
     rc = install(ctx->id, info, desc->argc, desc->argv);
     ctx->installing = false;
@@ -254,6 +282,17 @@ static void plugin_desc_free(struct qemu_plugin_desc *desc)
     g_free(desc);
 }
 
+static void *qemu_plugin_global_dlsym(void* context, const char *name)
+{
+    GModule *global_handle = context;
+    gpointer sym = NULL;
+    if (!g_module_symbol(global_handle, name, &sym)) {
+        error_report("%s: %s", __func__, g_module_error());
+        return NULL;
+    }
+    return sym;
+}
+
 /**
  * qemu_plugin_load_list - load a list of plugins
  * @head: head of the list of descriptors of the plugins to be loaded
@@ -267,6 +306,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
 {
     struct qemu_plugin_desc *desc, *next;
     g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
+    GModule *global_handle = NULL;
 
     info->target_name = TARGET_NAME;
     info->version.min = QEMU_PLUGIN_MIN_VERSION;
@@ -276,6 +316,12 @@ int qemu_plugin_load_list(QemuPluginList *head)
     info->system_emulation = true;
     info->system.smp_vcpus = ms->smp.cpus;
     info->system.max_vcpus = ms->smp.max_cpus;
+    global_handle = g_module_open(NULL, G_MODULE_BIND_LOCAL);
+    if (global_handle == NULL) {
+        goto err_dlopen;
+    }
+    info->dlsym = qemu_plugin_global_dlsym;
+    info->context = (void*)global_handle;
 #else
     info->system_emulation = false;
 #endif
@@ -289,6 +335,8 @@ int qemu_plugin_load_list(QemuPluginList *head)
         }
         QTAILQ_REMOVE(head, desc, entry);
     }
+
+err_dlopen:
     return 0;
 }
 
diff --git a/plugins/meson.build b/plugins/meson.build
index e77723010e..16af5d7ca3 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -1,13 +1,5 @@
-if 'CONFIG_HAS_LD_DYNAMIC_LIST' in config_host
-  plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.build_root() / 'qemu-plugins-ld.symbols')]
-elif 'CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST' in config_host
-  plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.build_root() / 'qemu-plugins-ld64.symbols')]
-else
-  plugin_ldflags = []
-endif
-
 specific_ss.add(when: 'CONFIG_PLUGIN', if_true: [files(
   'loader.c',
   'core.c',
   'api.c',
-), declare_dependency(link_args: plugin_ldflags)])
+), declare_dependency(link_args: [], compile_args: ['-Wno-missing-prototypes'])])
diff --git a/plugins/plugin.h b/plugins/plugin.h
index 1aa29dcadd..406f246a72 100644
--- a/plugins/plugin.h
+++ b/plugins/plugin.h
@@ -15,6 +15,7 @@
 #include <gmodule.h>
 
 #define QEMU_PLUGIN_MIN_VERSION 0
+#define QEMU_PLUGIN_VERSION_1 1
 
 /* global state */
 struct qemu_plugin_state {
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
deleted file mode 100644
index 4bdb381f48..0000000000
--- a/plugins/qemu-plugins.symbols
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  qemu_plugin_uninstall;
-  qemu_plugin_reset;
-  qemu_plugin_register_vcpu_init_cb;
-  qemu_plugin_register_vcpu_exit_cb;
-  qemu_plugin_register_vcpu_idle_cb;
-  qemu_plugin_register_vcpu_resume_cb;
-  qemu_plugin_register_vcpu_insn_exec_cb;
-  qemu_plugin_register_vcpu_insn_exec_inline;
-  qemu_plugin_register_vcpu_mem_cb;
-  qemu_plugin_register_vcpu_mem_haddr_cb;
-  qemu_plugin_register_vcpu_mem_inline;
-  qemu_plugin_ram_addr_from_host;
-  qemu_plugin_register_vcpu_tb_trans_cb;
-  qemu_plugin_register_vcpu_tb_exec_cb;
-  qemu_plugin_register_vcpu_tb_exec_inline;
-  qemu_plugin_register_flush_cb;
-  qemu_plugin_register_vcpu_syscall_cb;
-  qemu_plugin_register_vcpu_syscall_ret_cb;
-  qemu_plugin_register_atexit_cb;
-  qemu_plugin_tb_n_insns;
-  qemu_plugin_tb_get_insn;
-  qemu_plugin_tb_vaddr;
-  qemu_plugin_insn_data;
-  qemu_plugin_insn_size;
-  qemu_plugin_insn_vaddr;
-  qemu_plugin_insn_haddr;
-  qemu_plugin_insn_disas;
-  qemu_plugin_mem_size_shift;
-  qemu_plugin_mem_is_sign_extended;
-  qemu_plugin_mem_is_big_endian;
-  qemu_plugin_mem_is_store;
-  qemu_plugin_get_hwaddr;
-  qemu_plugin_hwaddr_is_io;
-  qemu_plugin_hwaddr_to_raddr;
-  qemu_plugin_vcpu_for_each;
-  qemu_plugin_n_vcpus;
-  qemu_plugin_n_max_vcpus;
-  qemu_plugin_outs;
-};
diff --git a/tests/plugin/bb.c b/tests/plugin/bb.c
index de09bdde4e..cda3fbdde9 100644
--- a/tests/plugin/bb.c
+++ b/tests/plugin/bb.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/tests/plugin/empty.c b/tests/plugin/empty.c
index 8fa6bacd93..0c3adf7aa0 100644
--- a/tests/plugin/empty.c
+++ b/tests/plugin/empty.c
@@ -11,6 +11,7 @@
 #include <unistd.h>
 #include <stdio.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/tests/plugin/insn.c b/tests/plugin/insn.c
index a9a6e41237..bf86fdafe6 100644
--- a/tests/plugin/insn.c
+++ b/tests/plugin/insn.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
diff --git a/tests/plugin/mem.c b/tests/plugin/mem.c
index 4725bd851d..f39be9c969 100644
--- a/tests/plugin/mem.c
+++ b/tests/plugin/mem.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <glib.h>
 
+#define QEMU_PLUGIN_IMPLEMENTATION
 #include <qemu-plugin.h>
 
 QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
-- 
2.28.0.windows.1



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed
  2020-10-01 16:34 ` [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed Yonggang Luo
@ 2020-10-05  9:59   ` Alex Bennée
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Bennée @ 2020-10-05  9:59 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: Paolo Bonzini, Richard Henderson, qemu-devel,
	Philippe Mathieu-Daudé


Yonggang Luo <luoyonggang@gmail.com> writes:

> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw
  2020-10-01 16:34 ` [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw Yonggang Luo
@ 2020-10-05 10:00   ` Alex Bennée
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Bennée @ 2020-10-05 10:00 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: Paolo Bonzini, Richard Henderson, qemu-devel,
	Philippe Mathieu-Daudé


Yonggang Luo <luoyonggang@gmail.com> writes:

> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows
  2020-10-01 16:34 ` [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows Yonggang Luo
@ 2020-10-05 10:17   ` Alex Bennée
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Bennée @ 2020-10-05 10:17 UTC (permalink / raw)
  To: Yonggang Luo; +Cc: Paolo Bonzini, Richard Henderson, qemu-devel


Yonggang Luo <luoyonggang@gmail.com> writes:

> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>

If the build doesn't work until your later fixes then this should be the
last patch in the series. 

> ---
>  .cirrus.yml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/.cirrus.yml b/.cirrus.yml
> index 86ea33926a..5363142373 100644
> --- a/.cirrus.yml
> +++ b/.cirrus.yml
> @@ -104,7 +104,8 @@ windows_msys2_task:
>      - C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build"
>      - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure
>        --python=python3 --ninja=ninja
> -      --target-list-exclude=i386-softmmu,arm-softmmu,ppc-softmmu,mips-softmmu"
> +      --target-list-exclude=i386-softmmu,arm-softmmu,ppc-softmmu,mips-softmmu
> +      --enable-plugins"
>      - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make -j$NUMBER_OF_PROCESSORS"
>    test_script:
>      - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check"


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first
  2020-10-01 16:34 ` [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first Yonggang Luo
@ 2020-10-05 10:44   ` Alex Bennée
  2020-10-05 15:58     ` 罗勇刚(Yonggang Luo)
  0 siblings, 1 reply; 20+ messages in thread
From: Alex Bennée @ 2020-10-05 10:44 UTC (permalink / raw)
  To: Yonggang Luo; +Cc: Paolo Bonzini, Richard Henderson, qemu-devel


Yonggang Luo <luoyonggang@gmail.com> writes:

> This is used to distinguish from the qemu and plugin in
> header qemu-plugin.h
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  plugins/api.c  | 1 +
>  plugins/core.c | 1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/plugins/api.c b/plugins/api.c
> index bbdc5a4eb4..f16922ca8b 100644
> --- a/plugins/api.c
> +++ b/plugins/api.c
> @@ -35,6 +35,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#define QEMU_PLUGIN_API_IMPLEMENTATION
>  #include "qemu/plugin.h"

This doesn't do anything in this patch. You should split the special
handling in the plugin header and combine it in this patch. Also I'm not
quite sure of the logic you are trying to achieve later on:

  #if !defined(QEMU_PLUGIN_API_IMPLEMENTATION)
  #if defined(QEMU_PLUGIN_IMPLEMENTATION)
  #define QEMU_PLUGIN_EXTERN
  #else
  #define QEMU_PLUGIN_EXTERN extern
  #endif

It seems to me you could get away with only one symbol - ideally just
defined in plugins/api.c so you don't need to churn the plugins with
changes, e.g.

  #ifdef QEMU_PLUGIN_API_IMPLEMENTATION
  #define QEMU_PLUGIN_EXTERN
  #else
  #define QEMU_PLUGIN_EXTERN extern
  #endif

But I'd still like to have a better answer as to why we need the extern?
Is this a limitation of the mingw compiler or some windows special?

>  #include "cpu.h"
>  #include "sysemu/sysemu.h"
> diff --git a/plugins/core.c b/plugins/core.c
> index 51bfc94787..7a79ea4179 100644
> --- a/plugins/core.c
> +++ b/plugins/core.c
> @@ -12,6 +12,7 @@
>   * SPDX-License-Identifier: GPL-2.0-or-later
>   */
>  #include "qemu/osdep.h"
> +#define QEMU_PLUGIN_API_IMPLEMENTATION
>  #include "qemu/error-report.h"
>  #include "qemu/config-file.h"
>  #include "qapi/error.h"

I don't think we include qemu/plugin.h from this file although it does
raise the question of what happens when other parts of QEMU include the
internal qemu/plugins.h header.

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype
  2020-10-01 16:34 ` [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype Yonggang Luo
@ 2020-10-05 10:48   ` Alex Bennée
  2020-10-05 15:34     ` 罗勇刚(Yonggang Luo)
  0 siblings, 1 reply; 20+ messages in thread
From: Alex Bennée @ 2020-10-05 10:48 UTC (permalink / raw)
  To: Yonggang Luo; +Cc: Paolo Bonzini, Richard Henderson, qemu-devel


Yonggang Luo <luoyonggang@gmail.com> writes:

> This is used for counting how much function are export to qemu plugin.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  plugins/api.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/plugins/api.c b/plugins/api.c
> index f16922ca8b..d325084385 100644
> --- a/plugins/api.c
> +++ b/plugins/api.c
> @@ -252,10 +252,12 @@ bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
>  
>  #ifdef CONFIG_SOFTMMU
>  static __thread struct qemu_plugin_hwaddr hwaddr_info;
> +#endif
>  
>  struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
>                                                    uint64_t vaddr)
>  {
> +#ifdef CONFIG_SOFTMMU
>      CPUState *cpu = current_cpu;
>      unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
>      hwaddr_info.is_store = info & TRACE_MEM_ST;
> @@ -267,14 +269,10 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
>      }
>  
>      return &hwaddr_info;
> -}
>  #else
> -struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
> -                                                  uint64_t vaddr)
> -{
>      return NULL;
> -}
>  #endif
> +}

Hmm I'm not sure about this, surely you want the plugin system to
complain early if your plugin is going to use a function that is
incorrect for the mode you are running in?

Although we do currently unconditionally export the syscall functions
and arguably they should be CONFIG_USER only as well.

>  
>  bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
>  {


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype
  2020-10-05 10:48   ` Alex Bennée
@ 2020-10-05 15:34     ` 罗勇刚(Yonggang Luo)
  2020-10-05 15:46       ` Alex Bennée
  0 siblings, 1 reply; 20+ messages in thread
From: 罗勇刚(Yonggang Luo) @ 2020-10-05 15:34 UTC (permalink / raw)
  To: Alex Bennée; +Cc: Paolo Bonzini, Richard Henderson, qemu-level

[-- Attachment #1: Type: text/plain, Size: 2151 bytes --]

On Mon, Oct 5, 2020 at 6:48 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
>
> Yonggang Luo <luoyonggang@gmail.com> writes:
>
> > This is used for counting how much function are export to qemu plugin.
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  plugins/api.c | 8 +++-----
> >  1 file changed, 3 insertions(+), 5 deletions(-)
> >
> > diff --git a/plugins/api.c b/plugins/api.c
> > index f16922ca8b..d325084385 100644
> > --- a/plugins/api.c
> > +++ b/plugins/api.c
> > @@ -252,10 +252,12 @@ bool
qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
> >
> >  #ifdef CONFIG_SOFTMMU
> >  static __thread struct qemu_plugin_hwaddr hwaddr_info;
> > +#endif
> >
> >  struct qemu_plugin_hwaddr
*qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
> >                                                    uint64_t vaddr)
> >  {
> > +#ifdef CONFIG_SOFTMMU
> >      CPUState *cpu = current_cpu;
> >      unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
> >      hwaddr_info.is_store = info & TRACE_MEM_ST;
> > @@ -267,14 +269,10 @@ struct qemu_plugin_hwaddr
*qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
> >      }
> >
> >      return &hwaddr_info;
> > -}
> >  #else
> > -struct qemu_plugin_hwaddr
*qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
> > -                                                  uint64_t vaddr)
> > -{
> >      return NULL;
> > -}
> >  #endif
> > +}
>
> Hmm I'm not sure about this, surely you want the plugin system to
> complain early if your plugin is going to use a function that is
> incorrect for the mode you are running in?
I merged these two function for couting how much function are exported, so
getting the code easier to review, otherwise
 function qemu_plugin_get_hwaddr   would be exported twice.
>
> Although we do currently unconditionally export the syscall functions
> and arguably they should be CONFIG_USER only as well.
>
> >
> >  bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
> >  {
>
>
> --
> Alex Bennée



--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 2872 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype
  2020-10-05 15:34     ` 罗勇刚(Yonggang Luo)
@ 2020-10-05 15:46       ` Alex Bennée
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Bennée @ 2020-10-05 15:46 UTC (permalink / raw)
  To: luoyonggang; +Cc: Paolo Bonzini, Richard Henderson, qemu-level


罗勇刚(Yonggang Luo) <luoyonggang@gmail.com> writes:

> On Mon, Oct 5, 2020 at 6:48 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>>
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > This is used for counting how much function are export to qemu plugin.
>> >
>> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>> > ---
>> >  plugins/api.c | 8 +++-----
>> >  1 file changed, 3 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/plugins/api.c b/plugins/api.c
>> > index f16922ca8b..d325084385 100644
>> > --- a/plugins/api.c
>> > +++ b/plugins/api.c
>> > @@ -252,10 +252,12 @@ bool
> qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
>> >
>> >  #ifdef CONFIG_SOFTMMU
>> >  static __thread struct qemu_plugin_hwaddr hwaddr_info;
>> > +#endif
>> >
>> >  struct qemu_plugin_hwaddr
> *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
>> >                                                    uint64_t vaddr)
>> >  {
>> > +#ifdef CONFIG_SOFTMMU
>> >      CPUState *cpu = current_cpu;
>> >      unsigned int mmu_idx = info >> TRACE_MEM_MMU_SHIFT;
>> >      hwaddr_info.is_store = info & TRACE_MEM_ST;
>> > @@ -267,14 +269,10 @@ struct qemu_plugin_hwaddr
> *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
>> >      }
>> >
>> >      return &hwaddr_info;
>> > -}
>> >  #else
>> > -struct qemu_plugin_hwaddr
> *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
>> > -                                                  uint64_t vaddr)
>> > -{
>> >      return NULL;
>> > -}
>> >  #endif
>> > +}
>>
>> Hmm I'm not sure about this, surely you want the plugin system to
>> complain early if your plugin is going to use a function that is
>> incorrect for the mode you are running in?
> I merged these two function for couting how much function are exported, so
> getting the code easier to review, otherwise
>  function qemu_plugin_get_hwaddr   would be exported twice.

Ahh I see now..

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first
  2020-10-05 10:44   ` Alex Bennée
@ 2020-10-05 15:58     ` 罗勇刚(Yonggang Luo)
  0 siblings, 0 replies; 20+ messages in thread
From: 罗勇刚(Yonggang Luo) @ 2020-10-05 15:58 UTC (permalink / raw)
  To: Alex Bennée; +Cc: Paolo Bonzini, Richard Henderson, qemu-level

[-- Attachment #1: Type: text/plain, Size: 2432 bytes --]

Hi, I split this out just for easier review, so the lines changed in api.c
and core.c
equales to the number of function exported, anyway

On Mon, Oct 5, 2020 at 6:44 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
>
> Yonggang Luo <luoyonggang@gmail.com> writes:
>
> > This is used to distinguish from the qemu and plugin in
> > header qemu-plugin.h
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  plugins/api.c  | 1 +
> >  plugins/core.c | 1 +
> >  2 files changed, 2 insertions(+)
> >
> > diff --git a/plugins/api.c b/plugins/api.c
> > index bbdc5a4eb4..f16922ca8b 100644
> > --- a/plugins/api.c
> > +++ b/plugins/api.c
> > @@ -35,6 +35,7 @@
> >   */
> >
> >  #include "qemu/osdep.h"
> > +#define QEMU_PLUGIN_API_IMPLEMENTATION
> >  #include "qemu/plugin.h"
>
> This doesn't do anything in this patch. You should split the special
> handling in the plugin header and combine it in this patch. Also I'm not
> quite sure of the logic you are trying to achieve later on:
>
>   #if !defined(QEMU_PLUGIN_API_IMPLEMENTATION)
>   #if defined(QEMU_PLUGIN_IMPLEMENTATION)
>   #define QEMU_PLUGIN_EXTERN
>   #else
>   #define QEMU_PLUGIN_EXTERN extern
>   #endif
>
> It seems to me you could get away with only one symbol - ideally just
> defined in plugins/api.c so you don't need to churn the plugins with
> changes, e.g.
>
>   #ifdef QEMU_PLUGIN_API_IMPLEMENTATION
>   #define QEMU_PLUGIN_EXTERN
>   #else
>   #define QEMU_PLUGIN_EXTERN extern
>   #endif
>
> But I'd still like to have a better answer as to why we need the extern?
> Is this a limitation of the mingw compiler or some windows special?
>
> >  #include "cpu.h"
> >  #include "sysemu/sysemu.h"
> > diff --git a/plugins/core.c b/plugins/core.c
> > index 51bfc94787..7a79ea4179 100644
> > --- a/plugins/core.c
> > +++ b/plugins/core.c
> > @@ -12,6 +12,7 @@
> >   * SPDX-License-Identifier: GPL-2.0-or-later
> >   */
> >  #include "qemu/osdep.h"
> > +#define QEMU_PLUGIN_API_IMPLEMENTATION
> >  #include "qemu/error-report.h"
> >  #include "qemu/config-file.h"
> >  #include "qapi/error.h"
>
> I don't think we include qemu/plugin.h from this file although it does
> raise the question of what happens when other parts of QEMU include the
> internal qemu/plugins.h header.
>
> --
> Alex Bennée



--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 3211 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32.
  2020-10-01 16:34 ` [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32 Yonggang Luo
@ 2020-10-06 11:29   ` Alex Bennée
  2020-10-06 12:08     ` 罗勇刚(Yonggang Luo)
  0 siblings, 1 reply; 20+ messages in thread
From: Alex Bennée @ 2020-10-06 11:29 UTC (permalink / raw)
  To: Yonggang Luo; +Cc: Paolo Bonzini, Richard Henderson, qemu-devel


Yonggang Luo <luoyonggang@gmail.com> writes:

> We removed the need of .symbols file, so is the
> configure script, if we one expose a function to qemu-plugin
> just need prefix the function with QEMU_PLUGIN_EXPORT
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  Makefile                     |   1 -
>  configure                    |  71 -------------
>  contrib/plugins/hotblocks.c  |   1 +
>  contrib/plugins/hotpages.c   |   1 +
>  contrib/plugins/howvec.c     |   1 +
>  contrib/plugins/lockstep.c   |   1 +
>  include/qemu/qemu-plugin.h   | 197 +++++++++++++++++++++++++++--------
>  meson.build                  |   6 +-
>  plugins/api.c                |  62 +++++------
>  plugins/core.c               |  10 +-
>  plugins/loader.c             |  50 ++++++++-
>  plugins/meson.build          |  10 +-
>  plugins/plugin.h             |   1 +
>  plugins/qemu-plugins.symbols |  40 -------
>  tests/plugin/bb.c            |   1 +
>  tests/plugin/empty.c         |   1 +
>  tests/plugin/insn.c          |   1 +
>  tests/plugin/mem.c           |   1 +
>  18 files changed, 251 insertions(+), 205 deletions(-)
>  delete mode 100644 plugins/qemu-plugins.symbols
>
> diff --git a/Makefile b/Makefile
> index 54fc1a9d10..9981dd5209 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -105,7 +105,6 @@ config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
>  
>  # Force configure to re-run if the API symbols are updated
>  ifeq ($(CONFIG_PLUGIN),y)
> -config-host.mak: $(SRC_PATH)/plugins/qemu-plugins.symbols
>  
>  .PHONY: plugins
>  plugins:
> diff --git a/configure b/configure
> index 1c21a73c3b..ea447919fc 100755
> --- a/configure
> +++ b/configure
> @@ -5435,61 +5435,6 @@ if compile_prog "" "" ; then
>    atomic64=yes
>  fi
>  
> -#########################################
> -# See if --dynamic-list is supported by the linker
> -ld_dynamic_list="no"
> -if test "$static" = "no" ; then
> -    cat > $TMPTXT <<EOF
> -{
> -  foo;
> -};
> -EOF
> -
> -    cat > $TMPC <<EOF
> -#include <stdio.h>
> -void foo(void);
> -
> -void foo(void)
> -{
> -  printf("foo\n");
> -}
> -
> -int main(void)
> -{
> -  foo();
> -  return 0;
> -}
> -EOF
> -
> -    if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
> -        ld_dynamic_list="yes"
> -    fi
> -fi
> -
> -#########################################
> -# See if -exported_symbols_list is supported by the linker
> -
> -ld_exported_symbols_list="no"
> -if test "$static" = "no" ; then
> -    cat > $TMPTXT <<EOF
> -  _foo
> -EOF
> -
> -    if compile_prog "" "-Wl,-exported_symbols_list,$TMPTXT" ; then
> -        ld_exported_symbols_list="yes"
> -    fi
> -fi
> -
> -if  test "$plugins" = "yes" &&
> -    test "$ld_dynamic_list" = "no" &&
> -    test "$ld_exported_symbols_list" = "no" ; then
> -  error_exit \
> -      "Plugin support requires dynamic linking and specifying a set of symbols " \
> -      "that are exported to plugins. Unfortunately your linker doesn't " \
> -      "support the flag (--dynamic-list or -exported_symbols_list) used " \
> -      "for this purpose. You can't build with --static."
> -fi
> -
>  ########################################
>  # See if __attribute__((alias)) is supported.
>  # This false for Xcode 9, but has been remedied for Xcode 10.
> @@ -7074,22 +7019,6 @@ fi
>  
>  if test "$plugins" = "yes" ; then
>      echo "CONFIG_PLUGIN=y" >> $config_host_mak
> -    # Copy the export object list to the build dir
> -    if test "$ld_dynamic_list" = "yes" ; then
> -	echo "CONFIG_HAS_LD_DYNAMIC_LIST=yes" >> $config_host_mak
> -	ld_symbols=qemu-plugins-ld.symbols
> -	cp "$source_path/plugins/qemu-plugins.symbols" $ld_symbols
> -    elif test "$ld_exported_symbols_list" = "yes" ; then
> -	echo "CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST=yes" >> $config_host_mak
> -	ld64_symbols=qemu-plugins-ld64.symbols
> -	echo "# Automatically generated by configure - do not modify" > $ld64_symbols
> -	grep 'qemu_' "$source_path/plugins/qemu-plugins.symbols" | sed 's/;//g' | \
> -	    sed -E 's/^[[:space:]]*(.*)/_\1/' >> $ld64_symbols
> -    else
> -	error_exit \
> -	    "If \$plugins=yes, either \$ld_dynamic_list or " \
> -	    "\$ld_exported_symbols_list should have been set to 'yes'."
> -    fi
>  fi
>  
>  if test -n "$gdb_bin" ; then
> diff --git a/contrib/plugins/hotblocks.c b/contrib/plugins/hotblocks.c
> index 37435a3fc7..39e77d2980 100644
> --- a/contrib/plugins/hotblocks.c
> +++ b/contrib/plugins/hotblocks.c
> @@ -13,6 +13,7 @@
>  #include <stdio.h>
>  #include <glib.h>
>  
> +#define QEMU_PLUGIN_IMPLEMENTATION
>  #include <qemu-plugin.h>

As mentioned in earlier patch we should be able to just have the tweak
in api.c and avoid touching all the plugins themselves.
>  
> -#define QEMU_PLUGIN_VERSION 0
> +#define QEMU_PLUGIN_VERSION 1
> +
> +typedef void *(*qemu_plugin_global_dlsym_t)(void* context, const char *name);
>  
>  typedef struct {
>      /* string describing architecture */
> @@ -73,8 +71,23 @@ typedef struct {
>              int max_vcpus;
>          } system;
>      };
> +    void *context;
> +    qemu_plugin_global_dlsym_t dlsym;
>  } qemu_info_t;
>  
> +/**
> + * qemu_plugin_initialize() - Initialize a plugin before install
> + * @info: a block describing some details about the guest
> + *
> + * All plugins must export this symbol, and in most case using qemu-plugin.h
> + * provided implementation directly.
> + * For plugin provide this function, the QEMU_PLUGIN_VERSION should >= 1
> + *
> + * Note: This function only used to loading qemu's exported functions, nothing
> + * else should doding in this function.
> + */
> +QEMU_PLUGIN_EXPORT int qemu_plugin_initialize(const qemu_info_t *info);
> +

So this is essentially working around the linker/dlopen stage and
manually linking in all the API functions? Does this affect the
efficiency of the API calls?
> -void qemu_plugin_outs(const char *string);
> +typedef void (*qemu_plugin_outs_t)(const char *string);
> +
> +#if !defined(QEMU_PLUGIN_API_IMPLEMENTATION)
> +#if defined(QEMU_PLUGIN_IMPLEMENTATION)
> +#define QEMU_PLUGIN_EXTERN
> +#else
> +#define QEMU_PLUGIN_EXTERN extern
> +#endif

As mentioned in the earlier patch I want to understand why the extern is
required. Could we avoid it with a parameter to the compiler when
building plugins?

<snip>
>  
>  static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>  {
> +    qemu_plugin_initialize_func_t initialize = NULL;
>      qemu_plugin_install_func_t install;
>      struct qemu_plugin_ctx *ctx;
>      gpointer sym;
>      int rc;
> +    int version = -1;
>  
>      ctx = qemu_memalign(qemu_dcache_linesize, sizeof(*ctx));
>      memset(ctx, 0, sizeof(*ctx));
> @@ -184,7 +187,7 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>                       desc->path, g_module_error());
>          goto err_symbol;
>      } else {
> -        int version = *(int *)sym;
> +        version = *(int *)sym;
>          if (version < QEMU_PLUGIN_MIN_VERSION) {
>              error_report("TCG plugin %s requires API version %d, but "
>                           "this QEMU supports only a minimum version of %d",
> @@ -198,6 +201,21 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>          }
>      }
>  
> +    if (version >= QEMU_PLUGIN_VERSION_1) {
> +        /* This version should call to qemu_plugin_initialize first */
> +        if (!g_module_symbol(ctx->handle, "qemu_plugin_initialize", &sym)) {
> +            error_report("%s: %s", __func__, g_module_error());
> +            goto err_symbol;
> +        }
> +        initialize = (qemu_plugin_initialize_func_t) sym;
> +        /* symbol was found; it could be NULL though */
> +        if (initialize == NULL) {
> +            error_report("%s: %s: qemu_plugin_initialize is NULL",
> +                        __func__, desc->path);
> +            goto err_symbol;
> +        }
> +    }
> +
>      qemu_rec_mutex_lock(&plugin.lock);
>  
>      /* find an unused random id with &ctx as the seed */
> @@ -216,6 +234,16 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>          }
>      }
>      QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry);
> +    if (initialize != NULL) {
> +        rc = initialize(info);
> +        if (rc) {
> +            error_report("%s: qemu_plugin_initialize returned error code %d",
> +                        __func__, rc);
> +            /* qemu_plugin_initialize only loading function symbols */
> +            goto err_symbol;
> +        }
> +    }
> +
>      ctx->installing = true;
>      rc = install(ctx->id, info, desc->argc, desc->argv);
>      ctx->installing = false;
> @@ -254,6 +282,17 @@ static void plugin_desc_free(struct qemu_plugin_desc *desc)
>      g_free(desc);
>  }
>  
> +static void *qemu_plugin_global_dlsym(void* context, const char *name)
> +{
> +    GModule *global_handle = context;
> +    gpointer sym = NULL;
> +    if (!g_module_symbol(global_handle, name, &sym)) {
> +        error_report("%s: %s", __func__, g_module_error());
> +        return NULL;
> +    }
> +    return sym;
> +}
> +
>  /**
>   * qemu_plugin_load_list - load a list of plugins
>   * @head: head of the list of descriptors of the plugins to be loaded
> @@ -267,6 +306,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
>  {
>      struct qemu_plugin_desc *desc, *next;
>      g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
> +    GModule *global_handle = NULL;
>  
>      info->target_name = TARGET_NAME;
>      info->version.min = QEMU_PLUGIN_MIN_VERSION;
> @@ -276,6 +316,12 @@ int qemu_plugin_load_list(QemuPluginList *head)
>      info->system_emulation = true;
>      info->system.smp_vcpus = ms->smp.cpus;
>      info->system.max_vcpus = ms->smp.max_cpus;
> +    global_handle = g_module_open(NULL, G_MODULE_BIND_LOCAL);
> +    if (global_handle == NULL) {
> +        goto err_dlopen;
> +    }
> +    info->dlsym = qemu_plugin_global_dlsym;
> +    info->context = (void*)global_handle;
>  #else
>      info->system_emulation = false;
>  #endif
> @@ -289,6 +335,8 @@ int qemu_plugin_load_list(QemuPluginList *head)
>          }
>          QTAILQ_REMOVE(head, desc, entry);
>      }
> +
> +err_dlopen:
>      return 0;

This doesn't compile cleanly for both linux-user and softmmu:

  Compiling C object libqemu-aarch64-linux-user.fa.p/tcg_tcg-common.c.o
  ../../plugins/loader.c: In function ‘qemu_plugin_load_list’:
  ../../plugins/loader.c:339:1: error: label ‘err_dlopen’ defined but not used [-Werror=unused-label]
   err_dlopen:
   ^~~~~~~~~~
  ../../plugins/loader.c:309:14: error: unused variable ‘global_handle’ [-Werror=unused-variable]
       GModule *global_handle = NULL;
                ^~~~~~~~~~~~~
  At top level:
  ../../plugins/loader.c:285:14: error: ‘qemu_plugin_global_dlsym’ defined but not used [-Werror=unused-function]
   static void *qemu_plugin_global_dlsym(void* context, const char *name)
                ^~~~~~~~~~~~~~~~~~~~~~~~
  cc1: all warnings being treated as errors
  make: *** [Makefile.ninja:6703: libqemu-aarch64-linux-user.fa.p/plugins_loader.c.o] Error 1
  make: *** Waiting for unfinished jobs....

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 0/6] Enable plugin support on msys2/mingw
  2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
                   ` (5 preceding siblings ...)
  2020-10-01 16:34 ` [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32 Yonggang Luo
@ 2020-10-06 11:35 ` Alex Bennée
  2021-01-27  3:52   ` 罗勇刚(Yonggang Luo)
  6 siblings, 1 reply; 20+ messages in thread
From: Alex Bennée @ 2020-10-06 11:35 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: Paolo Bonzini, Emilio G . Cota, Richard Henderson, qemu-devel


Yonggang Luo <luoyonggang@gmail.com> writes:

> V2-V3
> Split following patches out
>
> V1-V2
> 1. Fixes review comments
> 2. Increase QEMU_PLUGIN_VERSION to 1 for compat  QEMU_PLUGIN_VERSION 0
> 3. Revise the loader to support for version 0 and 1
> 4. By export function qemu_plugin_initialize in plugin, and call it in loader=
> , so
>   we have no need call it in every plugin. And also provide a standard implem=
> entation,
>   anyway, use can also override it.
>
> Add this feature on msys2/mingw by using glib provided cross-platform dlsym f=
> unctional.

I've grabbed the first two fixes into plugins/next for now. Aside from
fixing the review comments I'd like to have an indication that the
proposed change to the API linking doesn't adversely affect the
performance of the plugins.

It might be worth enabling a --enable-plugins build for mingw gitlab as Cirrus
seems a bit broken at the moment.

Thanks,


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32.
  2020-10-06 11:29   ` Alex Bennée
@ 2020-10-06 12:08     ` 罗勇刚(Yonggang Luo)
  0 siblings, 0 replies; 20+ messages in thread
From: 罗勇刚(Yonggang Luo) @ 2020-10-06 12:08 UTC (permalink / raw)
  To: Alex Bennée; +Cc: Paolo Bonzini, Richard Henderson, qemu-level

[-- Attachment #1: Type: text/plain, Size: 12721 bytes --]

On Tue, Oct 6, 2020 at 7:29 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
>
> Yonggang Luo <luoyonggang@gmail.com> writes:
>
> > We removed the need of .symbols file, so is the
> > configure script, if we one expose a function to qemu-plugin
> > just need prefix the function with QEMU_PLUGIN_EXPORT
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  Makefile                     |   1 -
> >  configure                    |  71 -------------
> >  contrib/plugins/hotblocks.c  |   1 +
> >  contrib/plugins/hotpages.c   |   1 +
> >  contrib/plugins/howvec.c     |   1 +
> >  contrib/plugins/lockstep.c   |   1 +
> >  include/qemu/qemu-plugin.h   | 197 +++++++++++++++++++++++++++--------
> >  meson.build                  |   6 +-
> >  plugins/api.c                |  62 +++++------
> >  plugins/core.c               |  10 +-
> >  plugins/loader.c             |  50 ++++++++-
> >  plugins/meson.build          |  10 +-
> >  plugins/plugin.h             |   1 +
> >  plugins/qemu-plugins.symbols |  40 -------
> >  tests/plugin/bb.c            |   1 +
> >  tests/plugin/empty.c         |   1 +
> >  tests/plugin/insn.c          |   1 +
> >  tests/plugin/mem.c           |   1 +
> >  18 files changed, 251 insertions(+), 205 deletions(-)
> >  delete mode 100644 plugins/qemu-plugins.symbols
> >
> > diff --git a/Makefile b/Makefile
> > index 54fc1a9d10..9981dd5209 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -105,7 +105,6 @@ config-host.mak: $(SRC_PATH)/configure
$(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
> >
> >  # Force configure to re-run if the API symbols are updated
> >  ifeq ($(CONFIG_PLUGIN),y)
> > -config-host.mak: $(SRC_PATH)/plugins/qemu-plugins.symbols
> >
> >  .PHONY: plugins
> >  plugins:
> > diff --git a/configure b/configure
> > index 1c21a73c3b..ea447919fc 100755
> > --- a/configure
> > +++ b/configure
> > @@ -5435,61 +5435,6 @@ if compile_prog "" "" ; then
> >    atomic64=yes
> >  fi
> >
> > -#########################################
> > -# See if --dynamic-list is supported by the linker
> > -ld_dynamic_list="no"
> > -if test "$static" = "no" ; then
> > -    cat > $TMPTXT <<EOF
> > -{
> > -  foo;
> > -};
> > -EOF
> > -
> > -    cat > $TMPC <<EOF
> > -#include <stdio.h>
> > -void foo(void);
> > -
> > -void foo(void)
> > -{
> > -  printf("foo\n");
> > -}
> > -
> > -int main(void)
> > -{
> > -  foo();
> > -  return 0;
> > -}
> > -EOF
> > -
> > -    if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
> > -        ld_dynamic_list="yes"
> > -    fi
> > -fi
> > -
> > -#########################################
> > -# See if -exported_symbols_list is supported by the linker
> > -
> > -ld_exported_symbols_list="no"
> > -if test "$static" = "no" ; then
> > -    cat > $TMPTXT <<EOF
> > -  _foo
> > -EOF
> > -
> > -    if compile_prog "" "-Wl,-exported_symbols_list,$TMPTXT" ; then
> > -        ld_exported_symbols_list="yes"
> > -    fi
> > -fi
> > -
> > -if  test "$plugins" = "yes" &&
> > -    test "$ld_dynamic_list" = "no" &&
> > -    test "$ld_exported_symbols_list" = "no" ; then
> > -  error_exit \
> > -      "Plugin support requires dynamic linking and specifying a set of
symbols " \
> > -      "that are exported to plugins. Unfortunately your linker doesn't
" \
> > -      "support the flag (--dynamic-list or -exported_symbols_list)
used " \
> > -      "for this purpose. You can't build with --static."
> > -fi
> > -
> >  ########################################
> >  # See if __attribute__((alias)) is supported.
> >  # This false for Xcode 9, but has been remedied for Xcode 10.
> > @@ -7074,22 +7019,6 @@ fi
> >
> >  if test "$plugins" = "yes" ; then
> >      echo "CONFIG_PLUGIN=y" >> $config_host_mak
> > -    # Copy the export object list to the build dir
> > -    if test "$ld_dynamic_list" = "yes" ; then
> > -     echo "CONFIG_HAS_LD_DYNAMIC_LIST=yes" >> $config_host_mak
> > -     ld_symbols=qemu-plugins-ld.symbols
> > -     cp "$source_path/plugins/qemu-plugins.symbols" $ld_symbols
> > -    elif test "$ld_exported_symbols_list" = "yes" ; then
> > -     echo "CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST=yes" >> $config_host_mak
> > -     ld64_symbols=qemu-plugins-ld64.symbols
> > -     echo "# Automatically generated by configure - do not modify" >
$ld64_symbols
> > -     grep 'qemu_' "$source_path/plugins/qemu-plugins.symbols" | sed
's/;//g' | \
> > -         sed -E 's/^[[:space:]]*(.*)/_\1/' >> $ld64_symbols
> > -    else
> > -     error_exit \
> > -         "If \$plugins=yes, either \$ld_dynamic_list or " \
> > -         "\$ld_exported_symbols_list should have been set to 'yes'."
> > -    fi
> >  fi
> >
> >  if test -n "$gdb_bin" ; then
> > diff --git a/contrib/plugins/hotblocks.c b/contrib/plugins/hotblocks.c
> > index 37435a3fc7..39e77d2980 100644
> > --- a/contrib/plugins/hotblocks.c
> > +++ b/contrib/plugins/hotblocks.c
> > @@ -13,6 +13,7 @@
> >  #include <stdio.h>
> >  #include <glib.h>
> >
> > +#define QEMU_PLUGIN_IMPLEMENTATION
> >  #include <qemu-plugin.h>
>
> As mentioned in earlier patch we should be able to just have the tweak
> in api.c and avoid touching all the plugins themselves.
> >
> > -#define QEMU_PLUGIN_VERSION 0
> > +#define QEMU_PLUGIN_VERSION 1
> > +
> > +typedef void *(*qemu_plugin_global_dlsym_t)(void* context, const char
*name);
> >
> >  typedef struct {
> >      /* string describing architecture */
> > @@ -73,8 +71,23 @@ typedef struct {
> >              int max_vcpus;
> >          } system;
> >      };
> > +    void *context;
> > +    qemu_plugin_global_dlsym_t dlsym;
> >  } qemu_info_t;
> >
> > +/**
> > + * qemu_plugin_initialize() - Initialize a plugin before install
> > + * @info: a block describing some details about the guest
> > + *
> > + * All plugins must export this symbol, and in most case using
qemu-plugin.h
> > + * provided implementation directly.
> > + * For plugin provide this function, the QEMU_PLUGIN_VERSION should >=
1
> > + *
> > + * Note: This function only used to loading qemu's exported functions,
nothing
> > + * else should doding in this function.
> > + */
> > +QEMU_PLUGIN_EXPORT int qemu_plugin_initialize(const qemu_info_t *info);
> > +
>
> So this is essentially working around the linker/dlopen stage and
> manually linking in all the API functions? Does this affect the
> efficiency of the API calls?
> > -void qemu_plugin_outs(const char *string);
> > +typedef void (*qemu_plugin_outs_t)(const char *string);
> > +
> > +#if !defined(QEMU_PLUGIN_API_IMPLEMENTATION)
> > +#if defined(QEMU_PLUGIN_IMPLEMENTATION)
> > +#define QEMU_PLUGIN_EXTERN
> > +#else
> > +#define QEMU_PLUGIN_EXTERN extern
> > +#endif
>
> As mentioned in the earlier patch I want to understand why the extern is
> required. Could we avoid it with a parameter to the compiler when
> building plugins?
Hi, I've publisehd with v5 of the patch and explain that,

If we only have a single .c file in a plugin, then define
QEMU_PLUGIN_EXTERN to empty is OK, but if we have multiple .c files
in a plugin, then we need distinguish the implementation and the
deceleration. only the main .c file should define the macro
QEMU_PLUGIN_IMPLEMENTATION
other sources are user and should use extern
>
> <snip>
> >
> >  static int plugin_load(struct qemu_plugin_desc *desc, const
qemu_info_t *info)
> >  {
> > +    qemu_plugin_initialize_func_t initialize = NULL;
> >      qemu_plugin_install_func_t install;
> >      struct qemu_plugin_ctx *ctx;
> >      gpointer sym;
> >      int rc;
> > +    int version = -1;
> >
> >      ctx = qemu_memalign(qemu_dcache_linesize, sizeof(*ctx));
> >      memset(ctx, 0, sizeof(*ctx));
> > @@ -184,7 +187,7 @@ static int plugin_load(struct qemu_plugin_desc
*desc, const qemu_info_t *info)
> >                       desc->path, g_module_error());
> >          goto err_symbol;
> >      } else {
> > -        int version = *(int *)sym;
> > +        version = *(int *)sym;
> >          if (version < QEMU_PLUGIN_MIN_VERSION) {
> >              error_report("TCG plugin %s requires API version %d, but "
> >                           "this QEMU supports only a minimum version of
%d",
> > @@ -198,6 +201,21 @@ static int plugin_load(struct qemu_plugin_desc
*desc, const qemu_info_t *info)
> >          }
> >      }
> >
> > +    if (version >= QEMU_PLUGIN_VERSION_1) {
> > +        /* This version should call to qemu_plugin_initialize first */
> > +        if (!g_module_symbol(ctx->handle, "qemu_plugin_initialize",
&sym)) {
> > +            error_report("%s: %s", __func__, g_module_error());
> > +            goto err_symbol;
> > +        }
> > +        initialize = (qemu_plugin_initialize_func_t) sym;
> > +        /* symbol was found; it could be NULL though */
> > +        if (initialize == NULL) {
> > +            error_report("%s: %s: qemu_plugin_initialize is NULL",
> > +                        __func__, desc->path);
> > +            goto err_symbol;
> > +        }
> > +    }
> > +
> >      qemu_rec_mutex_lock(&plugin.lock);
> >
> >      /* find an unused random id with &ctx as the seed */
> > @@ -216,6 +234,16 @@ static int plugin_load(struct qemu_plugin_desc
*desc, const qemu_info_t *info)
> >          }
> >      }
> >      QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry);
> > +    if (initialize != NULL) {
> > +        rc = initialize(info);
> > +        if (rc) {
> > +            error_report("%s: qemu_plugin_initialize returned error
code %d",
> > +                        __func__, rc);
> > +            /* qemu_plugin_initialize only loading function symbols */
> > +            goto err_symbol;
> > +        }
> > +    }
> > +
> >      ctx->installing = true;
> >      rc = install(ctx->id, info, desc->argc, desc->argv);
> >      ctx->installing = false;
> > @@ -254,6 +282,17 @@ static void plugin_desc_free(struct
qemu_plugin_desc *desc)
> >      g_free(desc);
> >  }
> >
> > +static void *qemu_plugin_global_dlsym(void* context, const char *name)
> > +{
> > +    GModule *global_handle = context;
> > +    gpointer sym = NULL;
> > +    if (!g_module_symbol(global_handle, name, &sym)) {
> > +        error_report("%s: %s", __func__, g_module_error());
> > +        return NULL;
> > +    }
> > +    return sym;
> > +}
> > +
> >  /**
> >   * qemu_plugin_load_list - load a list of plugins
> >   * @head: head of the list of descriptors of the plugins to be loaded
> > @@ -267,6 +306,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
> >  {
> >      struct qemu_plugin_desc *desc, *next;
> >      g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
> > +    GModule *global_handle = NULL;
> >
> >      info->target_name = TARGET_NAME;
> >      info->version.min = QEMU_PLUGIN_MIN_VERSION;
> > @@ -276,6 +316,12 @@ int qemu_plugin_load_list(QemuPluginList *head)
> >      info->system_emulation = true;
> >      info->system.smp_vcpus = ms->smp.cpus;
> >      info->system.max_vcpus = ms->smp.max_cpus;
> > +    global_handle = g_module_open(NULL, G_MODULE_BIND_LOCAL);
> > +    if (global_handle == NULL) {
> > +        goto err_dlopen;
> > +    }
> > +    info->dlsym = qemu_plugin_global_dlsym;
> > +    info->context = (void*)global_handle;
> >  #else
> >      info->system_emulation = false;
> >  #endif
> > @@ -289,6 +335,8 @@ int qemu_plugin_load_list(QemuPluginList *head)
> >          }
> >          QTAILQ_REMOVE(head, desc, entry);
> >      }
> > +
> > +err_dlopen:
> >      return 0;
>
> This doesn't compile cleanly for both linux-user and softmmu:
>
>   Compiling C object libqemu-aarch64-linux-user.fa.p/tcg_tcg-common.c.o
>   ../../plugins/loader.c: In function ‘qemu_plugin_load_list’:
>   ../../plugins/loader.c:339:1: error: label ‘err_dlopen’ defined but not
used [-Werror=unused-label]
>    err_dlopen:
>    ^~~~~~~~~~
>   ../../plugins/loader.c:309:14: error: unused variable ‘global_handle’
[-Werror=unused-variable]
>        GModule *global_handle = NULL;
>                 ^~~~~~~~~~~~~
>   At top level:
>   ../../plugins/loader.c:285:14: error: ‘qemu_plugin_global_dlsym’
defined but not used [-Werror=unused-function]
>    static void *qemu_plugin_global_dlsym(void* context, const char *name)
>                 ^~~~~~~~~~~~~~~~~~~~~~~~
>   cc1: all warnings being treated as errors
>   make: *** [Makefile.ninja:6703:
libqemu-aarch64-linux-user.fa.p/plugins_loader.c.o] Error 1
>   make: *** Waiting for unfinished jobs....
>
> --
> Alex Bennée



--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 16700 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 0/6] Enable plugin support on msys2/mingw
  2020-10-06 11:35 ` [PATCH v3 0/6] Enable plugin support on msys2/mingw Alex Bennée
@ 2021-01-27  3:52   ` 罗勇刚(Yonggang Luo)
  2021-02-10 15:10     ` Alex Bennée
  0 siblings, 1 reply; 20+ messages in thread
From: 罗勇刚(Yonggang Luo) @ 2021-01-27  3:52 UTC (permalink / raw)
  To: Alex Bennée
  Cc: Paolo Bonzini, Emilio G . Cota, Richard Henderson, qemu-level

[-- Attachment #1: Type: text/plain, Size: 1244 bytes --]

Hi alex, when does plugins/next getting PR

On Tue, Oct 6, 2020 at 7:35 PM Alex Bennée <alex.bennee@linaro.org> wrote:

>
> Yonggang Luo <luoyonggang@gmail.com> writes:
>
> > V2-V3
> > Split following patches out
> >
> > V1-V2
> > 1. Fixes review comments
> > 2. Increase QEMU_PLUGIN_VERSION to 1 for compat  QEMU_PLUGIN_VERSION 0
> > 3. Revise the loader to support for version 0 and 1
> > 4. By export function qemu_plugin_initialize in plugin, and call it in
> loader=
> > , so
> >   we have no need call it in every plugin. And also provide a standard
> implem=
> > entation,
> >   anyway, use can also override it.
> >
> > Add this feature on msys2/mingw by using glib provided cross-platform
> dlsym f=
> > unctional.
>
> I've grabbed the first two fixes into plugins/next for now. Aside from
> fixing the review comments I'd like to have an indication that the
> proposed change to the API linking doesn't adversely affect the
> performance of the plugins.
>
> It might be worth enabling a --enable-plugins build for mingw gitlab as
> Cirrus
> seems a bit broken at the moment.
>
> Thanks,
>
>
> --
> Alex Bennée
>


-- 
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 1799 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 0/6] Enable plugin support on msys2/mingw
  2021-01-27  3:52   ` 罗勇刚(Yonggang Luo)
@ 2021-02-10 15:10     ` Alex Bennée
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Bennée @ 2021-02-10 15:10 UTC (permalink / raw)
  To: luoyonggang; +Cc: Paolo Bonzini, Emilio G . Cota, Richard Henderson, qemu-level


罗勇刚(Yonggang Luo) <luoyonggang@gmail.com> writes:

> Hi alex, when does plugins/next getting PR

Sorry for the delay. I should be cooking up a pre-PR series this week
once the recent icount/io_recompile fix has been tested and reviewed.
You can see the current state of the tree here:

  https://github.com/stsquad/qemu/tree/plugins/next

I'm afraid I've dropped the ball on your plugin patches... I can't seem
to find the v5 series referenced.

>
> On Tue, Oct 6, 2020 at 7:35 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
>>
>> Yonggang Luo <luoyonggang@gmail.com> writes:
>>
>> > V2-V3
>> > Split following patches out
>> >
>> > V1-V2
>> > 1. Fixes review comments
>> > 2. Increase QEMU_PLUGIN_VERSION to 1 for compat  QEMU_PLUGIN_VERSION 0
>> > 3. Revise the loader to support for version 0 and 1
>> > 4. By export function qemu_plugin_initialize in plugin, and call it in
>> loader=
>> > , so
>> >   we have no need call it in every plugin. And also provide a standard
>> implem=
>> > entation,
>> >   anyway, use can also override it.
>> >
>> > Add this feature on msys2/mingw by using glib provided cross-platform
>> dlsym f=
>> > unctional.
>>
>> I've grabbed the first two fixes into plugins/next for now. Aside from
>> fixing the review comments I'd like to have an indication that the
>> proposed change to the API linking doesn't adversely affect the
>> performance of the plugins.
>>
>> It might be worth enabling a --enable-plugins build for mingw gitlab as
>> Cirrus
>> seems a bit broken at the moment.
>>
>> Thanks,
>>
>>
>> --
>> Alex Bennée
>>


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-02-10 15:28 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 16:34 [PATCH v3 0/6] Enable plugin support on msys2/mingw Yonggang Luo
2020-10-01 16:34 ` [PATCH v3 1/6] plugins: Fixes a issue when dlsym failed, the handle not closed Yonggang Luo
2020-10-05  9:59   ` Alex Bennée
2020-10-01 16:34 ` [PATCH v3 2/6] plugin: Fixes compiling errors on msys2/mingw Yonggang Luo
2020-10-05 10:00   ` Alex Bennée
2020-10-01 16:34 ` [PATCH v3 3/6] cirrus: Enable plugin in cirrus for windows Yonggang Luo
2020-10-05 10:17   ` Alex Bennée
2020-10-01 16:34 ` [PATCH v3 4/6] plugin: define QEMU_PLUGIN_API_IMPLEMENTATION first Yonggang Luo
2020-10-05 10:44   ` Alex Bennée
2020-10-05 15:58     ` 罗勇刚(Yonggang Luo)
2020-10-01 16:34 ` [PATCH v3 5/6] plugin: getting qemu_plugin_get_hwaddr only expose one function prototype Yonggang Luo
2020-10-05 10:48   ` Alex Bennée
2020-10-05 15:34     ` 罗勇刚(Yonggang Luo)
2020-10-05 15:46       ` Alex Bennée
2020-10-01 16:34 ` [PATCH v3 6/6] plugin: Getting qemu-plugin works under win32 Yonggang Luo
2020-10-06 11:29   ` Alex Bennée
2020-10-06 12:08     ` 罗勇刚(Yonggang Luo)
2020-10-06 11:35 ` [PATCH v3 0/6] Enable plugin support on msys2/mingw Alex Bennée
2021-01-27  3:52   ` 罗勇刚(Yonggang Luo)
2021-02-10 15:10     ` Alex Bennée

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.