summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-03-31 21:12:35 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-03-31 21:12:35 (GMT)
commit7cbdd17b441b35d48624956aa438bde69f18bc37 (patch)
tree438af8d0a994d6e203cf66ea91cf336bb071ee44 /src
parentd5e55f2ad015781bd7bee0e3216e47d6218e0841 (diff)
Implemented first steps to a Python plugins support.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@146 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/analysis/exporter-int.h2
-rw-r--r--src/analysis/line-int.h3
-rw-r--r--src/analysis/line.c75
-rw-r--r--src/analysis/line.h9
-rw-r--r--src/analysis/line_code.c37
-rwxr-xr-xsrc/common/Makefile.am1
-rw-r--r--src/common/dllist.h7
-rw-r--r--src/common/environment.c94
-rw-r--r--src/common/environment.h40
-rw-r--r--src/plugins/Makefile.am1
-rw-r--r--src/plugins/pglist.c24
-rw-r--r--src/plugins/plugin-def.h3
-rw-r--r--src/plugins/plugin-int.h74
-rw-r--r--src/plugins/plugin.c36
14 files changed, 365 insertions, 41 deletions
diff --git a/src/analysis/exporter-int.h b/src/analysis/exporter-int.h
index 4219be2..3218bcf 100644
--- a/src/analysis/exporter-int.h
+++ b/src/analysis/exporter-int.h
@@ -1,6 +1,6 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * line-int.h - prototypes pour la traduction humaine des lignes de rendus
+ * exporter-int.h - prototypes pour la traduction humaine des lignes de rendus
*
* Copyright (C) 2009 Cyrille Bagard
*
diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h
index 9c8e52a..e240815 100644
--- a/src/analysis/line-int.h
+++ b/src/analysis/line-int.h
@@ -43,6 +43,8 @@ struct _GRenderingLine
vmpa_t offset; /* Position en mémoire/physique*/
off_t length; /* Nombre d'adresses associées */
+ char *comment; /* Texte à afficher */
+
RenderingLineType type; /* Type de représentation */
RenderingLineFlag flags; /* Extension d'informations */
@@ -57,6 +59,7 @@ struct _GRenderingLine
#define lines_list_last(head) dl_list_last(head, GRenderingLine, link)
#define lines_list_next_iter(iter, head) dl_list_next_iter(iter, head, GRenderingLine, link)
+#define lines_list_prev_iter(iter, head) dl_list_prev_iter(iter, head, GRenderingLine, link)
#define lines_list_add_before(new, head, pos) dl_list_add_before(new, head, pos, link)
#define lines_list_add_tail(new, head) dl_list_add_tail(new, head, GRenderingLine, link)
#define lines_list_for_each(pos, head) dl_list_for_each(pos, head, GRenderingLine, link)
diff --git a/src/analysis/line.c b/src/analysis/line.c
index 24a107b..a3ba7a5 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -150,6 +150,49 @@ off_t get_rendering_line_length(const GRenderingLine *line)
* *
* Paramètres : line = ligne dont les informations sont à consulter. *
* *
+* Description : Fournit le commentaire associé à la ligne s'il existe. *
+* *
+* Retour : Chaîne de caractères ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *get_rendering_line_comment(const GRenderingLine *line)
+{
+ return line->comment;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* comment = nouveau commentaire à insérer ou NULL. *
+* *
+* Description : Définit ou supprime un commentaire pour la ligne indiquée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_rendering_line_comment(GRenderingLine *line, const char *comment)
+{
+ if (line->comment != NULL)
+ free(line->comment);
+
+ if (comment == NULL) line->comment = NULL;
+ else line->comment = strdup(comment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont les informations sont à consulter. *
+* *
* Description : Fournit le type d'une ligne. *
* *
* Retour : Type de la ligne fournie. *
@@ -463,6 +506,38 @@ GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *lines, const GRen
/******************************************************************************
* *
* Paramètres : lines = liste de lignes de représentation à actualiser. *
+* : iter = position actuelle dans la liste. *
+* last = dernière élément imposé du parcours ou NULL. *
+* *
+* Description : Fournit l'élement précédant un autre pour un parcours. *
+* *
+* Retour : Elément suivant ou NULL si aucun. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GRenderingLine *g_rendering_line_get_prev_iter(GRenderingLine *lines, const GRenderingLine *iter, const GRenderingLine *last)
+{
+ GRenderingLine *result; /* Elément suivant à renvoyer */
+
+ if (iter == NULL)
+ {
+ if (last != NULL) iter = last;
+ else iter = lines_list_last(lines);
+ }
+
+ if (iter == lines) result = NULL;
+ else result = lines_list_prev_iter(iter, lines);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : lines = liste de lignes de représentation à actualiser. *
* last = dernière élément imposé du parcours ou NULL. *
* *
* Description : Fournit le dernier élément d'une liste de lignes. *
diff --git a/src/analysis/line.h b/src/analysis/line.h
index 20d6234..5061dcd 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -78,6 +78,12 @@ vmpa_t get_rendering_line_address(const GRenderingLine *);
/* Fournit la longueur du code représenté par une ligne. */
off_t get_rendering_line_length(const GRenderingLine *);
+/* Fournit le commentaire associé à la ligne s'il existe. */
+const char *get_rendering_line_comment(const GRenderingLine *);
+
+/* Définit ou supprime un commentaire pour la ligne indiquée. */
+void set_rendering_line_comment(GRenderingLine *, const char *);
+
/* Fournit le type d'une ligne. */
RenderingLineType get_rendering_line_type(const GRenderingLine *);
@@ -119,6 +125,9 @@ void g_rendering_line_insert_into_lines(GRenderingLine **, GRenderingLine *, boo
/* Fournit l'élement suivant un autre pour un parcours. */
GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *, const GRenderingLine *, const GRenderingLine *);
+/* Fournit l'élement précédant un autre pour un parcours. */
+GRenderingLine *g_rendering_line_get_prev_iter(GRenderingLine *, const GRenderingLine *, const GRenderingLine *);
+
/* Fournit le dernier élément d'une liste de lignes. */
GRenderingLine *g_rendering_line_get_last_iter(GRenderingLine *, GRenderingLine *);
diff --git a/src/analysis/line_code.c b/src/analysis/line_code.c
index 24f3ec9..7c80074 100644
--- a/src/analysis/line_code.c
+++ b/src/analysis/line_code.c
@@ -136,7 +136,8 @@ static void g_code_line_init(GCodeLine *line)
static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, MainRendering rendering, FILE *stream)
{
- GContentExporter *exporter; /* Autre vision de la ligne */
+ GContentExporter *exporter; /* Autre vision de la ligne #1 */
+ GRenderingLine *basic; /* Autre vision de la ligne #2 */
bool show_address; /* Affichage de l'adresse ? */
bool show_code; /* Affichage du code brut ? */
MemoryDataSize msize; /* Taille du bus d'adresses */
@@ -149,6 +150,7 @@ static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, Ma
off_t i; /* Boucle de parcours */
exporter = G_CONTENT_EXPORTER(line);
+ basic = G_RENDERING_LINE(line);
show_address = g_rendering_options_has_to_show_address(options, rendering);
show_code = g_rendering_options_has_to_show_code(options, rendering);
@@ -195,6 +197,16 @@ static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, Ma
g_content_exporter_add_text(G_CONTENT_EXPORTER(line->instr), options, rendering, stream);
+ /* Commentaire ? */
+
+ if (basic->comment != NULL)
+ {
+ g_content_exporter_insert_text(exporter, stream, "\t", 1, RTT_NONE);
+ g_content_exporter_insert_text(exporter, stream, "; ", 2, RTT_COMMENT);
+ g_content_exporter_insert_text(exporter, stream, basic->comment,
+ strlen(basic->comment), RTT_COMMENT);
+ }
+
}
@@ -216,6 +228,8 @@ static void g_code_line_add_text(GCodeLine *line, GRenderingOptions *options, Ma
static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering rendering, GtkTextBuffer *buffer, GtkTextIter *iter, size_t lengths[SAR_COUNT])
{
+ GContentExporter *exporter; /* Autre vision de la ligne #1 */
+ GRenderingLine *basic; /* Autre vision de la ligne #2 */
bool show_address; /* Affichage de l'adresse ? */
bool show_code; /* Affichage du code brut ? */
MemoryDataSize msize; /* Taille du bus d'adresses */
@@ -227,6 +241,9 @@ static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering renderi
char *bin_code; /* Tampon du code binaire */
off_t i; /* Boucle de parcours */
+ exporter = G_CONTENT_EXPORTER(line);
+ basic = G_RENDERING_LINE(line);
+
show_address = g_rendering_options_has_to_show_address(line->options, rendering);
show_code = g_rendering_options_has_to_show_code(line->options, rendering);
@@ -239,10 +256,10 @@ static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering renderi
len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address);
lengths[SAR_ADDRESS] = len;
- g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter,
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter,
address, len, RTT_NONE);
- g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter,
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter,
"\t", 1, RTT_NONE);
}
@@ -266,12 +283,12 @@ static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering renderi
snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[bin_offset + i]);
}
- g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter,
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter,
bin_code, bin_len * 3 - 1, RTT_RAW_CODE);
free(bin_code);
- g_content_exporter_insert_with_gtk_tag(G_CONTENT_EXPORTER(line), buffer, iter,
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter,
"\t", 1, RTT_NONE);
}
@@ -284,6 +301,16 @@ static void g_code_line_add_to_gtk_buffer(GCodeLine *line, MainRendering renderi
lengths[SAR_INSTRUCTION] = MAX(lengths[SAR_INSTRUCTION], 4 /* FIXME */);
+ /* Commentaire ? */
+
+ if (basic->comment != NULL)
+ {
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter, "\t", 1, RTT_NONE);
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter, "; ", 2, RTT_COMMENT);
+ g_content_exporter_insert_with_gtk_tag(exporter, buffer, iter, basic->comment,
+ strlen(basic->comment), RTT_COMMENT);
+ }
+
}
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index c4937dd..7aa255e 100755
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -4,6 +4,7 @@ lib_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
dllist.h dllist.c \
endianness.h endianness.c \
+ environment.h environment.c \
extstr.h extstr.c \
macros.h \
xml.h xml.c
diff --git a/src/common/dllist.h b/src/common/dllist.h
index 499151e..504291e 100644
--- a/src/common/dllist.h
+++ b/src/common/dllist.h
@@ -121,6 +121,10 @@ void __dl_list_del(dl_list_item *, dl_list_head *);
(iter->member.next == &head->member ? \
NULL : container_of(iter->member.next, type, member))
+#define dl_list_prev_iter(iter, head, type, member) \
+ (&iter->member == &head->member ? \
+ NULL : container_of(iter->member.prev, type, member))
+
#define dl_list_for_each(pos, head, type, member) \
for (pos = head; \
pos != NULL; \
@@ -140,8 +144,7 @@ void __dl_list_del(dl_list_item *, dl_list_head *);
#define dl_list_for_each_rev(pos, head, type, member) \
for (pos = dl_list_last(head, type, member); \
pos != NULL; \
- pos = (pos == head ? \
- NULL : container_of(pos->member.prev, type, member)))
+ pos = dl_list_prev_iter(pos, (head), type, member))
diff --git a/src/common/environment.c b/src/common/environment.c
new file mode 100644
index 0000000..a0fa568
--- /dev/null
+++ b/src/common/environment.c
@@ -0,0 +1,94 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * environment.c - manipulations des variables d'environnement.
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "environment.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "extstr.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : name = désignation de la variable à traiter. *
+* *
+* Description : Fournit le contenu d'une variable d'environnement. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *get_env_var(const char *name)
+{
+ char *result; /* Chaîne à retourner */
+
+ result = getenv(name);
+
+ if (result == NULL) result = strdup("");
+ else result = strdup(name);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : name = désignation de la variable à traiter. *
+* value = valeur à ajouter à la variable. *
+* sep = séparateur entre champs. *
+* *
+* Description : Complète le contenu d'une variable d'environnement. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_to_env_var(const char *name, const char *value, const char *sep)
+{
+ char *content; /* Contenu final à définir */
+ int ret; /* Bilan d'un appel système */
+
+ content = get_env_var(name);
+
+ if (strlen(content) > 0) content = stradd(content, sep);
+
+ content = stradd(content, value);
+
+ ret = setenv(name, content, 1);
+ if (ret != 0) perror(setenv);
+
+ free(content);
+
+ return (ret == 0);
+
+}
diff --git a/src/common/environment.h b/src/common/environment.h
new file mode 100644
index 0000000..a96c6eb
--- /dev/null
+++ b/src/common/environment.h
@@ -0,0 +1,40 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * environment.h - prototypes pour la manipulations des variables d'environnement.
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _COMMON_ENVIRONMENT_H
+#define _COMMON_ENVIRONMENT_H
+
+
+#include <stdbool.h>
+
+
+
+/* Fournit le contenu d'une variable d'environnement. */
+char *get_env_var(const char *);
+
+/* Complète le contenu d'une variable d'environnement. */
+bool add_to_env_var(const char *, const char *, const char *);
+
+
+
+#endif /* _COMMON_ENVIRONMENT_H */
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 36fc9b4..9a76f74 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -4,6 +4,7 @@ lib_LTLIBRARIES = libplugins.la
libplugins_la_SOURCES = \
pglist.h pglist.c \
plugin-def.h \
+ plugin-int.h \
plugin.h plugin.c
libplugins_la_CFLAGS = $(AM_CFLAGS)
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 6d47f57..f242cba 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -233,3 +233,27 @@ GPluginModule **get_all_plugins_for_action(PluginAction action, size_t *count)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à ajouter aux autres disponibles. *
+* *
+* Description : Ajoute un greffon à la liste principale de greffons. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void add_plugin_to_main_list(GPluginModule *plugin)
+{
+ plugins_list *list; /* Liste à modifier */
+
+ list = &_list;
+
+ list->plugins = (GPluginModule **)realloc(list->plugins, ++list->plugins_count * sizeof(GPluginModule *));
+ list->plugins[list->plugins_count - 1] = plugin;
+
+}
diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h
index f8f8fe3..1b47bd6 100644
--- a/src/plugins/plugin-def.h
+++ b/src/plugins/plugin-def.h
@@ -41,13 +41,14 @@ typedef enum _PluginAction
+struct _GPluginModule;
/* Fournit une indication sur le type d'opération(s) menée(s). */
typedef PluginAction (* get_plugin_action_fc) (void);
/* Exécute une action définie sur un binaire chargé. */
-typedef bool (* execute_action_on_binary_fc) (GOpenidaBinary *, PluginAction);
+typedef bool (* execute_action_on_binary_fc) (struct _GPluginModule *, GOpenidaBinary *, PluginAction);
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
new file mode 100644
index 0000000..7e2703b
--- /dev/null
+++ b/src/plugins/plugin-int.h
@@ -0,0 +1,74 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * elf-int.h - prototypes pour les structures internes du format ELF
+ *
+ * Copyright (C) 2008 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _FORMAT_PLUGINS_PLUGIN_INT_H
+#define _FORMAT_PLUGINS_PLUGIN_INT_H
+
+
+#include <glib-object.h>
+
+
+#include "plugin-def.h"
+
+
+
+
+/* Procède à l'initialisation du greffon */
+typedef bool (* init_plugin_fc) (GObject *);
+
+
+
+/* Greffon pour OpenIDA (instance) */
+struct _GPluginModule
+{
+ GObject parent; /* A laisser en premier */
+
+ GModule *module; /* Abstration de manipulation */
+
+ PluginAction action; /* Opération(s) menée(s) */
+
+ init_plugin_fc init; /* Procédure d'initialisation */
+
+ execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire */
+
+};
+
+
+/* Greffon pour OpenIDA (classe) */
+struct _GPluginModuleClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+
+
+
+/* Ajoute un greffon à la liste principale de greffons. */
+void add_plugin_to_main_list(GPluginModule *);
+
+
+
+
+#endif /* _FORMAT_PLUGINS_PLUGIN_INT_H */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index e6e4a1a..ed4c39d 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -1,6 +1,6 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * plugin.h - interactions avec un greffon donné
+ * plugin.c - interactions avec un greffon donné
*
* Copyright (C) 2009 Cyrille Bagard
*
@@ -29,38 +29,10 @@
#include <stdbool.h>
+#include "plugin-int.h"
-/* Procède à l'initialisation du greffon */
-typedef bool (* init_plugin_fc) (GObject *);
-
-
-
-/* Greffon pour OpenIDA (instance) */
-struct _GPluginModule
-{
- GObject parent; /* A laisser en premier */
-
- GModule *module; /* Abstration de manipulation */
-
- PluginAction action; /* Opération(s) menée(s) */
-
- init_plugin_fc init; /* Procédure d'initialisation */
-
- execute_action_on_binary_fc exec_on_bin;/* Action sur un binaire */
-
-};
-
-
-/* Greffon pour OpenIDA (classe) */
-struct _GPluginModuleClass
-{
- GObjectClass parent; /* A laisser en premier */
-
-};
-
-
/* Initialise la classe des greffons. */
static void g_plugin_module_class_init(GPluginModuleClass *);
@@ -135,7 +107,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref)
result->module = g_module_open(filename, G_MODULE_BIND_LAZY);
-#if 1
+#if 0
if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&__get_action))
{
printf("Err plugin get_action sym\n");
@@ -213,6 +185,6 @@ PluginAction g_plugin_module_get_action(const GPluginModule *plugin)
bool g_plugin_module_execute_action_on_binary(const GPluginModule *plugin, GOpenidaBinary *binary, PluginAction action)
{
- return plugin->exec_on_bin(binary, action);
+ return plugin->exec_on_bin(plugin, binary, action);
}