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