[PATCH 7/8] include/qemu: added macro for QPP import function

Andrew Fasano posted 8 patches 1 year, 10 months ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, Alexandre Iooss <erdnaxe@crans.org>, Mahmoud Mandour <ma.mandourr@gmail.com>, Thomas Huth <thuth@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Peter Maydell <peter.maydell@linaro.org>
[PATCH 7/8] include/qemu: added macro for QPP import function
Posted by Andrew Fasano 1 year, 10 months ago
From: Elysia Witham <elysia.witham@ll.mit.edu>

Plugins can use this macro in a header file which can be included
by both the exporting and importing plugins. The macro will
either use qemu_plugin_import_function to import the function
or just define it if the plugin is the same one that exports it.
If importing a function, "_qpp" will be appended to the end of the
function name.

Signed-off-by: Elysia Witham <elysia.witham@ll.mit.edu>
Signed-off-by: Andrew Fasano <fasano@mit.edu>
---
 include/qemu/plugin-qpp.h | 54 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 include/qemu/plugin-qpp.h

diff --git a/include/qemu/plugin-qpp.h b/include/qemu/plugin-qpp.h
new file mode 100644
index 0000000000..7aea98a14d
--- /dev/null
+++ b/include/qemu/plugin-qpp.h
@@ -0,0 +1,54 @@
+#ifndef PLUGIN_QPP_H
+#define PLUGIN_QPP_H
+
+/*
+ * Facilities for "Plugin to plugin" (QPP) interactions between tcg plugins.
+ * These allows for direct function calls between loaded plugins. For more
+ * details see docs/devel/plugin.rst.
+ */
+
+
+/*
+ * Internal macros
+ */
+#define _PLUGIN_STR(s) #s
+#define PLUGIN_STR(s) _PLUGIN_STR(s)
+#define _PLUGIN_CONCAT(x, y) x##y
+#define PLUGIN_CONCAT(x, y) _PLUGIN_CONCAT(x, y)
+#define _QPP_SETUP_NAME(fn) PLUGIN_CONCAT(_qpp_setup_, fn)
+
+/*
+ * A header file that defines an exported function should use
+ * the QPP_FUN_PROTOTYPE macro to create the necessary types.
+ *
+ * The generated function named after the output of QPP_SETUP_NAME should
+ * dynamically resolve a target function in another plugin or raise a fatal
+ * error on failure. This function has the constructor attribute so it will
+ * run immediately when the plugin shared object object is loaded.
+ *
+ * Note that the variable qemu_plugin_name must be set before this macro is
+ * used. In other words the plugin that includes a header file with these
+ * macros should set qemu_plugin_name before including such headers. When the
+ * generated function is run it compares the current plugin name to the name
+ * of the plugin that provides the target function.
+ *
+ * If the target plugin is not the current plugin it will resolve the function
+ * pointer from qemu_plugin_import_function, correctly cast it, and assign the
+ * function pointer "[function_name]_qpp" which can then be used by the plugin
+ * that imported it.
+ */
+
+#define QPP_FUN_PROTOTYPE(plugin_name, fn_ret, fn, args)                      \
+  fn_ret fn(args);                                                            \
+  typedef fn_ret(*PLUGIN_CONCAT(fn, _t))(args);                               \
+  fn##_t fn##_qpp;                                                            \
+  void _QPP_SETUP_NAME(fn) (void);                                            \
+                                                                              \
+  void __attribute__ ((constructor)) _QPP_SETUP_NAME(fn) (void) {             \
+    if (strcmp(qemu_plugin_name, #plugin_name) != 0) {                        \
+        fn##_qpp = (fn##_t)qemu_plugin_import_function(                       \
+                                                      PLUGIN_STR(plugin_name),\
+                                                      PLUGIN_STR(fn));        \
+    }                                                                         \
+  }
+#endif /* PLUGIN_QPP_H */
-- 
2.34.1