diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-01-03 23:36:47 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-01-03 23:36:47 (GMT) |
commit | 55ccf25e0c6666436f0ecd222e60208ebf6ab30e (patch) | |
tree | 21c1ecc9e6d6ae50d0cfb0ffa4eaf61bf78a45a2 /src/plugins/plugin.c | |
parent | 28bfc34862513acb8fe9fcd02afca493c2411c02 (diff) |
Defined a dynamic type for each plugin.
Diffstat (limited to 'src/plugins/plugin.c')
-rw-r--r-- | src/plugins/plugin.c | 396 |
1 files changed, 328 insertions, 68 deletions
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index a9bd9da..ff3db31 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -35,6 +35,7 @@ #include <string.h> +#include "dt.h" #include "pglist.h" #include "plugin-int.h" @@ -52,6 +53,10 @@ static void g_plugin_module_dispose(GPluginModule *); /* Procède à la libération totale de la mémoire. */ static void g_plugin_module_finalize(GPluginModule *); +/* Initialise la classe des greffons d'extension. */ +static void g_plugin_module_init_gclass(GPluginModuleClass *, GModule *); + + /* Indique le type défini pour un greffon. */ G_DEFINE_TYPE(GPluginModule, g_plugin_module, G_TYPE_OBJECT); @@ -117,6 +122,7 @@ static void g_plugin_module_dispose(GPluginModule *plugin) const plugin_interface *pg_iface; /* Définition du greffon */ size_t i; /* Boucle de parcours */ GPluginModule *dependency; /* Module nécessaire */ + GPluginModuleClass *class; /* Classe de l'instance active */ pg_iface = g_plugin_module_get_interface(plugin); @@ -145,11 +151,16 @@ static void g_plugin_module_dispose(GPluginModule *plugin) } - if (plugin->exit != NULL) - plugin->exit(plugin); + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + if (class->exit != NULL) + class->exit(plugin); if (plugin->module != NULL) + { g_module_close(plugin->module); + plugin->module = NULL; + } G_OBJECT_CLASS(g_plugin_module_parent_class)->dispose(G_OBJECT(plugin)); @@ -195,25 +206,26 @@ static void g_plugin_module_finalize(GPluginModule *plugin) GPluginModule *g_plugin_module_new(const gchar *filename) { GPluginModule *result; /* Structure à retourner */ + GModule *module; /* Abstration de manipulation */ + const plugin_interface *interface; /* Déclaration d'interfaçage */ plugin_abi_version_t current; /* Version de l'ABI actuelle */ + bool valid; /* Statut de validité */ size_t i; /* Boucle de parcours */ uint32_t action; /* Identifiant d'une action */ uint32_t category; /* Catégorie principale */ uint32_t sub; /* Sous-catégorie visée */ + GType gtype; /* Nouveau type de greffon */ - result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL); - - result->filename = strdup(filename); - - result->module = g_module_open(filename, G_MODULE_BIND_LAZY); - if (result->module == NULL) + module = g_module_open(filename, G_MODULE_BIND_LAZY); + if (module == NULL) { log_variadic_message(LMT_ERROR, _("Error while loading the plugin candidate '%s' : %s"), filename, g_module_error()); - goto bad_plugin; + goto bad_module; } + #define load_plugin_symbol(mod, sym, dest) \ ({ \ bool __result; \ @@ -221,7 +233,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename) { \ log_variadic_message(LMT_ERROR, \ _("No '%s' entry in plugin candidate '%s'"), \ - sym, result->filename); \ + sym, filename); \ __result = false; \ } \ else __result = true; \ @@ -231,12 +243,12 @@ GPluginModule *g_plugin_module_new(const gchar *filename) /* Récupération de la version d'ABI */ - if (!load_plugin_symbol(result->module, "_chrysalide_plugin", &result->interface)) + if (!load_plugin_symbol(module, "_chrysalide_plugin", &interface)) goto bad_plugin; current = CURRENT_ABI_VERSION; - if (current != result->interface->abi_version) + if (current != interface->abi_version) { log_variadic_message(LMT_ERROR, _("ABI mismatch detected! Plugin '%s' rejected"), @@ -247,9 +259,20 @@ GPluginModule *g_plugin_module_new(const gchar *filename) /* Localisation des différents points d'entrée déclarés */ - for (i = 0; i < result->interface->actions_count; i++) + +#define check_plugin_symbol(mod, sym) \ + ({ \ + bool __result; \ + __result = g_module_symbol(mod, sym, (gpointer []) { 0 }); \ + __result; \ + }) + + + valid = true; + + for (i = 0; i < interface->actions_count && valid; i++) { - action = result->interface->actions[i]; + action = interface->actions[i]; category = MASK_PLUGIN_CATEGORY(action); sub = MASK_PLUGIN_SUB_CATEGORY(action); @@ -267,21 +290,17 @@ GPluginModule *g_plugin_module_new(const gchar *filename) switch (action) { case PGA_PLUGIN_INIT: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_init", &result->init)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_init"); break; case PGA_PLUGIN_EXIT: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_exit", &result->exit)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_exit"); break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + interface->actions[i], filename); break; } @@ -293,16 +312,13 @@ GPluginModule *g_plugin_module_new(const gchar *filename) switch (action) { case PGA_NATIVE_LOADED: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_on_native_loaded", - &result->native_loaded)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_on_native_loaded"); break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + interface->actions[i], filename); break; } @@ -327,15 +343,13 @@ GPluginModule *g_plugin_module_new(const gchar *filename) switch (action) { case PGA_GUI_THEME: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_include_theme", &result->include_theme)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_include_theme"); break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + interface->actions[i], filename); break; } @@ -361,23 +375,17 @@ GPluginModule *g_plugin_module_new(const gchar *filename) { case PGA_CONTENT_EXPLORER: case PGA_CONTENT_RESOLVER: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_handle_binary_content", - &result->handle_content)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_handle_binary_content"); break; case PGA_CONTENT_ANALYZED: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_handle_loaded_content", - &result->handle_loaded)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_handle_loaded_content"); break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + interface->actions[i], filename); break; } @@ -392,28 +400,21 @@ GPluginModule *g_plugin_module_new(const gchar *filename) case PGA_FORMAT_ANALYSIS_ENDED: case PGA_FORMAT_POST_ANALYSIS_STARTED: case PGA_FORMAT_POST_ANALYSIS_ENDED: - if (!load_plugin_symbol(result->module, - "handle_binary_format_analysis", - &result->handle_fmt_analysis)) - goto bad_plugin; + valid = check_plugin_symbol(module, "handle_binary_format_analysis"); break; case PGA_FORMAT_PRELOAD: - if (!load_plugin_symbol(result->module, - "preload_binary_format", &result->preload_format)) - goto bad_plugin; + valid = check_plugin_symbol(module, "preload_binary_format"); break; case PGA_FORMAT_ATTACH_DEBUG: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_attach_debug", &result->attach_debug)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_attach_debug"); break; default: log_variadic_message(LMT_WARNING, _("Unknown action '0x%02x' in plugin '%s'..."), - result->interface->actions[i], filename); + interface->actions[i], filename); break; } @@ -421,15 +422,11 @@ GPluginModule *g_plugin_module_new(const gchar *filename) break; case DPS_DISASSEMBLY: - if (!load_plugin_symbol(result->module, - "process_binary_disassembly", &result->process_disass)) - goto bad_plugin; + valid = check_plugin_symbol(module, "process_binary_disassembly"); break; case DPS_DETECTION: - if (!load_plugin_symbol(result->module, - "chrysalide_plugin_detect_external_tools", &result->detect)) - goto bad_plugin; + valid = check_plugin_symbol(module, "chrysalide_plugin_detect_external_tools"); break; default: @@ -450,11 +447,29 @@ GPluginModule *g_plugin_module_new(const gchar *filename) } + if (!valid) + goto bad_plugin; + + gtype = built_dynamic_type(G_TYPE_PLUGIN_MODULE, interface->gtp_name, + (GClassInitFunc)g_plugin_module_init_gclass, module); + + if (gtype == G_TYPE_INVALID) + goto bad_plugin; + + result = g_object_new(gtype, NULL); + + result->filename = strdup(filename); + result->module = module; + + result->interface = interface; + return result; bad_plugin: - g_object_unref(G_OBJECT(result)); + g_module_close(module); + + bad_module: return NULL; @@ -463,6 +478,212 @@ GPluginModule *g_plugin_module_new(const gchar *filename) /****************************************************************************** * * +* Paramètres : class = classe à initialiser. * +* module = module représentant le greffon chargé en mémoire. * +* * +* Description : Initialise la classe des greffons d'extension. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_plugin_module_init_gclass(GPluginModuleClass *class, GModule *module) +{ + const plugin_interface *interface; /* Déclaration d'interfaçage */ + size_t i; /* Boucle de parcours */ + uint32_t action; /* Identifiant d'une action */ + uint32_t category; /* Catégorie principale */ + uint32_t sub; /* Sous-catégorie visée */ + + +#undef load_plugin_symbol + +#define load_plugin_symbol(mod, sym, dest) \ + ({ \ + bool __result; \ + __result = g_module_symbol(mod, sym, (gpointer *)dest); \ + assert(__result); \ + __result; \ + }) + + + load_plugin_symbol(module, "_chrysalide_plugin", &interface); + + for (i = 0; i < interface->actions_count; i++) + { + action = interface->actions[i]; + category = MASK_PLUGIN_CATEGORY(action); + sub = MASK_PLUGIN_SUB_CATEGORY(action); + + switch (category) + { + case DPC_BASIC: + + switch (sub) + { + case DPS_NONE: + break; + + case DPS_PG_MANAGEMENT: + + switch (action) + { + case PGA_PLUGIN_INIT: + load_plugin_symbol(module, "chrysalide_plugin_init", &class->init); + break; + + case PGA_PLUGIN_EXIT: + load_plugin_symbol(module, "chrysalide_plugin_exit", &class->exit); + break; + + default: + assert(false); + break; + + } + + break; + + case DPS_CORE_MANAGEMENT: + + switch (action) + { + case PGA_NATIVE_LOADED: + load_plugin_symbol(module, "chrysalide_plugin_on_native_loaded", + &class->native_loaded); + break; + + default: + assert(false); + break; + + } + + break; + + default: + assert(false); + break; + + } + + break; + + case DPC_GUI: + + switch (sub) + { + case DPS_SETUP: + + switch (action) + { + case PGA_GUI_THEME: + load_plugin_symbol(module, "chrysalide_plugin_include_theme", + &class->include_theme); + break; + + default: + assert(false); + break; + + } + + break; + + default: + assert(false); + break; + + } + + break; + + case DPC_BINARY_PROCESSING: + + switch (sub) + { + case DPS_CONTENT: + + switch (action) + { + case PGA_CONTENT_EXPLORER: + case PGA_CONTENT_RESOLVER: + load_plugin_symbol(module, "chrysalide_plugin_handle_binary_content", + &class->handle_content); + break; + + case PGA_CONTENT_ANALYZED: + load_plugin_symbol(module, "chrysalide_plugin_handle_loaded_content", + &class->handle_loaded); + break; + + default: + assert(false); + break; + + } + + break; + + case DPS_FORMAT: + + switch (action) + { + case PGA_FORMAT_ANALYSIS_STARTED: + case PGA_FORMAT_ANALYSIS_ENDED: + case PGA_FORMAT_POST_ANALYSIS_STARTED: + case PGA_FORMAT_POST_ANALYSIS_ENDED: + load_plugin_symbol(module, "handle_binary_format_analysis", + &class->handle_fmt_analysis); + break; + + case PGA_FORMAT_PRELOAD: + load_plugin_symbol(module, "preload_binary_format", &class->preload_format); + break; + + case PGA_FORMAT_ATTACH_DEBUG: + load_plugin_symbol(module, "chrysalide_plugin_attach_debug", &class->attach_debug); + break; + + default: + assert(false); + break; + + } + + break; + + case DPS_DISASSEMBLY: + load_plugin_symbol(module, "process_binary_disassembly", &class->process_disass); + break; + + case DPS_DETECTION: + load_plugin_symbol(module, "chrysalide_plugin_detect_external_tools", &class->detect); + break; + + default: + assert(false); + break; + + } + + break; + + default: + assert(false); + break; + + } + + } + +} + + +/****************************************************************************** +* * * Paramètres : plugin = greffon à consulter. * * * * Description : Indique le fichier contenant le greffon manipulé. * @@ -654,6 +875,7 @@ bool g_plugin_module_load(GPluginModule *plugin, GPluginModule **list, size_t co const plugin_interface *pg_iface; /* Définition du greffon */ size_t i; /* Boucle de parcours */ GPluginModule *dependency; /* Module nécessaire */ + GPluginModuleClass *class; /* Classe de l'instance active */ char *dir; /* Répertoire modifiable */ /* Si un essai précédent a déjà échoué ou réussi... */ @@ -689,9 +911,11 @@ bool g_plugin_module_load(GPluginModule *plugin, GPluginModule **list, size_t co if (result) { - if (plugin->init != NULL) + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + if (class->init != NULL) { - result = plugin->init(plugin); + result = class->init(plugin); if (!result) { @@ -810,7 +1034,11 @@ void g_plugin_module_log_variadic_message(const GPluginModule *plugin, LogMessag void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction action, void *unused) { - plugin->native_loaded(plugin, action); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->native_loaded(plugin, action); } @@ -832,7 +1060,11 @@ void g_plugin_module_notify_native_loaded(GPluginModule *plugin, PluginAction ac void g_plugin_module_include_theme(const GPluginModule *plugin, PluginAction action, char ***resources, size_t *count) { - plugin->include_theme(plugin, action, resources, count); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->include_theme(plugin, action, resources, count); } @@ -855,7 +1087,11 @@ void g_plugin_module_include_theme(const GPluginModule *plugin, PluginAction act void g_plugin_module_handle_binary_content(const GPluginModule *plugin, PluginAction action, GBinContent *content, wgroup_id_t wid, GtkStatusStack *status) { - return plugin->handle_content(plugin, action, content, wid, status); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->handle_content(plugin, action, content, wid, status); } @@ -878,7 +1114,11 @@ void g_plugin_module_handle_binary_content(const GPluginModule *plugin, PluginAc void g_plugin_module_handle_loaded_content(const GPluginModule *plugin, PluginAction action, GLoadedContent *content, wgroup_id_t wid, GtkStatusStack *status) { - return plugin->handle_loaded(plugin, action, content, wid, status); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + return class->handle_loaded(plugin, action, content, wid, status); } @@ -901,7 +1141,11 @@ void g_plugin_module_handle_loaded_content(const GPluginModule *plugin, PluginAc bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *plugin, PluginAction action, GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) { - return plugin->handle_fmt_analysis(plugin, action, format, gid, status); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + return class->handle_fmt_analysis(plugin, action, format, gid, status); } @@ -924,7 +1168,11 @@ bool g_plugin_module_handle_binary_format_analysis(const GPluginModule *plugin, bool g_plugin_module_preload_binary_format(const GPluginModule *plugin, PluginAction action, GBinFormat *format, GPreloadInfo *info, GtkStatusStack *status) { - return plugin->preload_format(plugin, action, format, info, status); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + return class->preload_format(plugin, action, format, info, status); } @@ -945,7 +1193,11 @@ bool g_plugin_module_preload_binary_format(const GPluginModule *plugin, PluginAc void g_plugin_module_attach_debug_format(const GPluginModule *plugin, PluginAction action, GExeFormat *format) { - plugin->attach_debug(plugin, action, format); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->attach_debug(plugin, action, format); } @@ -968,7 +1220,11 @@ void g_plugin_module_attach_debug_format(const GPluginModule *plugin, PluginActi void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, PluginAction action, GLoadedBinary *binary, GtkStatusStack *status, GProcContext *context) { - plugin->process_disass(plugin, action, binary, status, context); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->process_disass(plugin, action, binary, status, context); } @@ -992,6 +1248,10 @@ void g_plugin_module_process_disassembly_event(const GPluginModule *plugin, Plug void g_plugin_module_detect_external_tools(const GPluginModule *plugin, PluginAction action, const GLoadedContent *content, bool version, char ***names, size_t *count) { - plugin->detect(plugin, action, content, version, names, count); + GPluginModuleClass *class; /* Classe de l'instance active */ + + class = G_PLUGIN_MODULE_GET_CLASS(plugin); + + class->detect(plugin, action, content, version, names, count); } |