summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-03 23:36:47 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-03 23:36:47 (GMT)
commit55ccf25e0c6666436f0ecd222e60208ebf6ab30e (patch)
tree21c1ecc9e6d6ae50d0cfb0ffa4eaf61bf78a45a2 /src/plugins
parent28bfc34862513acb8fe9fcd02afca493c2411c02 (diff)
Defined a dynamic type for each plugin.
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Makefile.am1
-rw-r--r--src/plugins/dt.c474
-rw-r--r--src/plugins/dt.h47
-rw-r--r--src/plugins/plugin-def.h13
-rw-r--r--src/plugins/plugin-int.h16
-rw-r--r--src/plugins/plugin.c396
-rw-r--r--src/plugins/plugin.h12
7 files changed, 872 insertions, 87 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 996c418..4059e0b 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libplugins.la
libplugins_la_SOURCES = \
context-int.h \
context.h context.c \
+ dt.h dt.c \
pglist.h pglist.c \
plugin-def.h \
plugin-int.h \
diff --git a/src/plugins/dt.c b/src/plugins/dt.c
new file mode 100644
index 0000000..afdba21
--- /dev/null
+++ b/src/plugins/dt.c
@@ -0,0 +1,474 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * dt.c - possibilité de créer de nouveaux types de façon dynamique
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "dt.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+
+/* ------------------------- MODULE DE GESTION DES NOUVEAUX ------------------------- */
+
+
+#define G_TYPE_DYNAMIC_TYPES g_dynamic_types_get_type()
+#define G_DYNAMIC_TYPES(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DYNAMIC_TYPES, GDynamicTypes))
+#define G_IS_DYNAMIC_TYPES(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DYNAMIC_TYPES))
+#define G_DYNAMIC_TYPES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DYNAMIC_TYPES, GDynamicTypesClass))
+#define G_IS_DYNAMIC_TYPES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DYNAMIC_TYPES))
+#define G_DYNAMIC_TYPES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DYNAMIC_TYPES, GDynamicTypesClass))
+
+
+/* Mémorisation des caractéristiques de type */
+typedef struct _type_dyn_info_t
+{
+ GType type; /* Identifiant unique obtenu */
+ GClassInitFunc init; /* Définition des méthodes */
+ gconstpointer data; /* Eventuelles données utiles */
+
+} type_dyn_info_t;
+
+/* Description de fichier binaire (instance) */
+typedef struct _GDynamicTypes
+{
+ GObject parent; /* A laisser en premier */
+
+ type_dyn_info_t **info; /* Liste d'informations utiles */
+ size_t count; /* Taille de cette liste */
+
+} GDynamicTypes;
+
+/* Description de fichier binaire (classe) */
+typedef struct _GDynamicTypesClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+} GDynamicTypesClass;
+
+
+/* Indique le type défini pour une gestion de types dynamique. */
+static GType g_dynamic_types_get_type(void);
+
+/* Initialise la classe de gestion de types dynamique. */
+static void g_dynamic_types_class_init(GDynamicTypesClass *);
+
+/* Initialise une gestion de types dynamique. */
+static void g_dynamic_types_init(GDynamicTypes *);
+
+/* Procède à l'initialisation de l'interface de typage nouveau. */
+static void g_dynamic_types_interface_init(GTypePluginClass *);
+
+/* Supprime toutes les références externes. */
+static void g_dynamic_types_dispose(GDynamicTypes *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dynamic_types_finalize(GDynamicTypes *);
+
+/* Crée un nouveau gestionnaire de nouveaux types. */
+static GDynamicTypes *g_dynamic_types_new(void);
+
+/* Marque une augmentation des utilisations. */
+static void g_dynamic_types_use(GDynamicTypes *);
+
+/* Marque une diminution des utilisations. */
+static void g_dynamic_types_unuse(GDynamicTypes *);
+
+/* Complète la définition d'un type dynamiquement. */
+static void g_dynamic_types_complete_type(GDynamicTypes *, GType, GTypeInfo *, GTypeValueTable *);
+
+/* Retrouve les informations concernant un type dynamique. */
+static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *, GType);
+
+/* Fournit un identifiant GLib pour un nouveau type. */
+static GType g_dynamic_types_register_type(GDynamicTypes *, GType, const char *, GClassInitFunc, gconstpointer);
+
+
+
+/* ----------------------- ACCOMPAGNEMENTS DES NOUVEAUX TYPES ----------------------- */
+
+
+/* Encadrement des nouveaux types dérivés */
+static GDynamicTypes *_chrysalide_dtypes = NULL;
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MODULE DE GESTION DES NOUVEAUX */
+/* ---------------------------------------------------------------------------------- */
+
+/* Indique le type défini pour une gestion de types dynamique. */
+G_DEFINE_TYPE_WITH_CODE(GDynamicTypes, g_dynamic_types, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_TYPE_PLUGIN, g_dynamic_types_interface_init));
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe de gestion de types dynamique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_class_init(GDynamicTypesClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dynamic_types_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dynamic_types_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : types = instance à initialiser. *
+* *
+* Description : Initialise une gestion de types dynamique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_init(GDynamicTypes *types)
+{
+
+}
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de typage nouveau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_interface_init(GTypePluginClass *iface)
+{
+ iface->use_plugin = (GTypePluginUse)g_dynamic_types_use;
+ iface->unuse_plugin = (GTypePluginUnuse)g_dynamic_types_unuse;
+ iface->complete_type_info = (GTypePluginCompleteTypeInfo)g_dynamic_types_complete_type;
+
+}
+
+/******************************************************************************
+* *
+* Paramètres : types = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_dispose(GDynamicTypes *types)
+{
+ G_OBJECT_CLASS(g_dynamic_types_parent_class)->dispose(G_OBJECT(types));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : types = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_finalize(GDynamicTypes *types)
+{
+ G_OBJECT_CLASS(g_dynamic_types_parent_class)->finalize(G_OBJECT(types));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée un nouveau gestionnaire de nouveaux types. *
+* *
+* Retour : Instance mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GDynamicTypes *g_dynamic_types_new(void)
+{
+ GDynamicTypes *result; /* Adresse à retourner */
+
+ result = g_object_new(G_TYPE_DYNAMIC_TYPES, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : types = gestionnaire de types courant. *
+* *
+* Description : Marque une augmentation des utilisations. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_use(GDynamicTypes *types)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : types = gestionnaire de types courant. *
+* *
+* Description : Marque une diminution des utilisations. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_unuse(GDynamicTypes *types)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : types = gestionnaire de types courant. *
+* type = nouveau type GLib à traiter. *
+* info = information concernant ce type à constituer. [OUT] *
+* table = table de valeur à éventuellement initialiser. [OUT] *
+* *
+* Description : Complète la définition d'un type dynamiquement. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dynamic_types_complete_type(GDynamicTypes *types, GType type, GTypeInfo *info, GTypeValueTable *table)
+{
+ const type_dyn_info_t *nfo; /* Source d'inspiration */
+ GType parent; /* Type parent du type */
+ GTypeQuery query; /* Informations complémentaires*/
+
+ /* Consultation */
+
+ nfo = g_dynamic_types_find(types, type);
+ assert(nfo != NULL);
+
+ parent = g_type_parent(type);
+ g_type_query(parent, &query);
+
+ /* Définition */
+
+ info->class_size = query.class_size;
+ info->class_init = nfo->init;
+ info->class_data = nfo->data;
+
+ info->instance_size = query.instance_size;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : parent = type GLib parent. *
+* type = identifiant du type GLib à considérer. *
+* *
+* Description : Retrouve les informations concernant un type dynamique. *
+* *
+* Retour : Structure contenant les informations associées au type. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const type_dyn_info_t *g_dynamic_types_find(const GDynamicTypes *types, GType target)
+{
+ type_dyn_info_t *result; /* Informations à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = NULL;
+
+ for (i = 0; i < types->count && result == NULL; i++)
+ if (types->info[i]->type == target)
+ result = types->info[i];
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : parent = type GLib parent. *
+* name = désignation du nouveau type. *
+* init = procédure d'initialisation de la classe associée. *
+* data = éventuelles données à associer à la future classe. *
+* *
+* Description : Fournit un identifiant GLib pour un nouveau type. *
+* *
+* Retour : identifiant d'un nouveau type valide, ou 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GType g_dynamic_types_register_type(GDynamicTypes *types, GType parent, const char *name, GClassInitFunc init, gconstpointer data)
+{
+ GType result; /* Identifiant à retourner */
+ type_dyn_info_t *new; /* Mémorisation de paramètres */
+
+ /* Création d'un nouveau type adapté */
+
+ result = g_type_register_dynamic(parent, name, G_TYPE_PLUGIN(types), 0);
+
+ if (result == 0)
+ goto exit;
+
+ new = malloc(sizeof(type_dyn_info_t));
+
+ new->type = result;
+ new->init = init;
+ new->data = data;
+
+ /* Inscription définitive */
+
+ types->info = realloc(types->info, ++types->count * sizeof(type_dyn_info_t *));
+
+ types->info[types->count - 1] = new;
+
+ exit:
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ACCOMPAGNEMENTS DES NOUVEAUX TYPES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Lance le support de dérivations de types dans Chrysalide. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool init_chrysalide_dynamic_types(void)
+{
+ bool result; /* Bilan à retourner */
+
+ _chrysalide_dtypes = g_dynamic_types_new();
+
+ result = (_chrysalide_dtypes != NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Arrête le support de dérivations de types dans Chrysalide. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void exit_chrysalide_dynamic_types(void)
+{
+ g_object_unref(G_OBJECT(_chrysalide_dtypes));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : parent = type GLib parent. *
+* name = désignation du nouveau type. *
+* init = procédure d'initialisation de la classe associée. *
+* data = éventuelles données à associer à la future classe. *
+* *
+* Description : Fournit un identifiant GLib pour un nouveau type. *
+* *
+* Retour : Identifiant d'un nouveau type valide, ou 0. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GType built_dynamic_type(GType parent, const char *name, GClassInitFunc init, gconstpointer data)
+{
+ GType result; /* Identifiant à retourner */
+
+ result = g_type_from_name(name);
+
+ if (result == 0)
+ result = g_dynamic_types_register_type(_chrysalide_dtypes, parent, name, init, data);
+
+ return result;
+
+}
diff --git a/src/plugins/dt.h b/src/plugins/dt.h
new file mode 100644
index 0000000..b9d4656
--- /dev/null
+++ b/src/plugins/dt.h
@@ -0,0 +1,47 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * dt.h - prototypes pour la possibilité de créer de nouveaux types de façon dynamique
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _PLUGINS_DT_H
+#define _PLUGINS_DT_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+
+/* ----------------------- ACCOMPAGNEMENTS DES NOUVEAUX TYPES ----------------------- */
+
+
+/* Lance le support de dérivations de types dans Chrysalide. */
+bool init_chrysalide_dynamic_types(void);
+
+/* Arrête le support de dérivations de types dans Chrysalide. */
+void exit_chrysalide_dynamic_types(void);
+
+/* Fournit un identifiant GLib pour un nouveau type. */
+GType built_dynamic_type(GType, const char *, GClassInitFunc, gconstpointer);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_DT_H */
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index 4c59606..b8cdca8 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -45,7 +45,7 @@ typedef uint32_t plugin_abi_version_t;
#define GET_ABI_MIN_VERSION(vs) ((vs >> 16) & 0xff)
#define GET_ABI_REV_VERSION(vs) (vs & 0xffff)
-#define CURRENT_ABI_VERSION DEFINE_PLUGIN_ABI_VERSION(0, 1, 0)
+#define CURRENT_ABI_VERSION DEFINE_PLUGIN_ABI_VERSION(0, 2, 0)
//#define HARD_CODE_CURRENT_ABI_VERSION const plugin_abi_version_t abi_version = CURRENT_ABI_VERSION
@@ -223,6 +223,7 @@ typedef struct _plugin_interface
uint64_t magic; /* Vérification a minima */
plugin_abi_version_t abi_version; /* Version du protocole utilisé*/
+ const char *gtp_name; /* Désignation du GType associé*/
const char *name; /* Désignation humaine courte */
const char *desc; /* Description plus loquace */
const char *version; /* Version du greffon */
@@ -253,12 +254,13 @@ typedef struct _plugin_interface
#define RL(...) BUILD_PG_LIST(.required, ((const char *[]){ __VA_ARGS__ }))
-#define DEFINE_CHRYSALIDE_PLUGIN(n, d, v, r, a) \
+#define DEFINE_CHRYSALIDE_PLUGIN(t, n, d, v, r, a) \
G_MODULE_EXPORT const plugin_interface _chrysalide_plugin = { \
\
.magic = CHRYSALIDE_PLUGIN_MAGIC, \
.abi_version = CURRENT_ABI_VERSION, \
\
+ .gtp_name = t, \
.name = n, \
.desc = d, \
.version = v, \
@@ -271,12 +273,13 @@ G_MODULE_EXPORT const plugin_interface _chrysalide_plugin = { \
\
}
-#define DEFINE_CHRYSALIDE_CONTAINER_PLUGIN(n, d, v, r, a) \
+#define DEFINE_CHRYSALIDE_CONTAINER_PLUGIN(t, n, d, v, r, a) \
G_MODULE_EXPORT const plugin_interface _chrysalide_plugin = { \
\
.magic = CHRYSALIDE_PLUGIN_MAGIC, \
.abi_version = CURRENT_ABI_VERSION, \
\
+ .gtp_name = t, \
.name = n, \
.desc = d, \
.version = v, \
@@ -291,8 +294,8 @@ G_MODULE_EXPORT const plugin_interface _chrysalide_plugin = { \
/* Interfaçage primaire avec Chrysalide */
-#define DEFINE_CHRYSALIDE_ACTIVE_PLUGIN(n, d, v, ...) \
- DEFINE_CHRYSALIDE_PLUGIN(n, d, v, EMPTY_PG_LIST(.required), AL( __VA_ARGS__ ))
+#define DEFINE_CHRYSALIDE_ACTIVE_PLUGIN(t, n, d, v, ...) \
+ DEFINE_CHRYSALIDE_PLUGIN(t, n, d, v, EMPTY_PG_LIST(.required), AL( __VA_ARGS__ ))
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 2d98217..4746867 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -83,6 +83,14 @@ struct _GPluginModule
bitfield_t *dependencies; /* Cartographie des dépendances*/
+};
+
+
+/* Greffon pour Chrysalide (classe) */
+struct _GPluginModuleClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
pg_management_fc init; /* Procédure d'initialisation */
pg_management_fc exit; /* Procédure d'extinction */
@@ -104,14 +112,6 @@ struct _GPluginModule
};
-/* Greffon pour Chrysalide (classe) */
-struct _GPluginModuleClass
-{
- GObjectClass parent; /* A laisser en premier */
-
-};
-
-
/* Présente dans le journal un message simple. */
void g_plugin_module_log_simple_message(const GPluginModule *, LogMessageType, const char *);
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);
}
diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h
index 4b3b306..cccd39b 100644
--- a/src/plugins/plugin.h
+++ b/src/plugins/plugin.h
@@ -59,12 +59,12 @@ typedef enum _PluginStatusFlags
#define BROKEN_PLUGIN_STATUS (PSF_UNKNOW_DEP | PSF_DEP_LOOP | PSF_FAILURE)
-#define G_TYPE_PLUGIN_MODULE (g_plugin_module_get_type())
-#define G_PLUGIN_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PLUGIN_MODULE, GPluginModule))
-#define G_IS_PLUGIN_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PLUGIN_MODULE))
-#define G_PLUGIN_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PLUGIN_MODULE, GPluginModuleClass))
-#define G_IS_PLUGIN_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PLUGIN_MODULE))
-#define G_PLUGIN_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PLUGIN_MODULE, GPluginModuleClass))
+#define G_TYPE_PLUGIN_MODULE (g_plugin_module_get_type())
+#define G_PLUGIN_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PLUGIN_MODULE, GPluginModule))
+#define G_IS_PLUGIN_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PLUGIN_MODULE))
+#define G_PLUGIN_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PLUGIN_MODULE, GPluginModuleClass))
+#define G_IS_PLUGIN_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PLUGIN_MODULE))
+#define G_PLUGIN_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PLUGIN_MODULE, GPluginModuleClass))
/* Indique le type défini pour un greffon. */