summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r--plugins/pychrysalide/analysis/constants.c23
-rw-r--r--plugins/pychrysalide/arch/Makefile.am2
-rw-r--r--plugins/pychrysalide/arch/constants.h1
-rw-r--r--plugins/pychrysalide/arch/module.c4
-rw-r--r--plugins/pychrysalide/arch/operands/Makefile.am5
-rw-r--r--plugins/pychrysalide/arch/operands/constants.c75
-rw-r--r--plugins/pychrysalide/arch/operands/constants.h39
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.c (renamed from plugins/pychrysalide/arch/immediate.c)315
-rw-r--r--plugins/pychrysalide/arch/operands/immediate.h (renamed from plugins/pychrysalide/arch/immediate.h)8
-rw-r--r--plugins/pychrysalide/arch/operands/module.c12
-rw-r--r--plugins/pychrysalide/arch/operands/register.c25
-rw-r--r--plugins/pychrysalide/arch/operands/targetable.c (renamed from plugins/pychrysalide/arch/targetableop.c)77
-rw-r--r--plugins/pychrysalide/arch/operands/targetable.h (renamed from plugins/pychrysalide/arch/targetableop.h)8
-rw-r--r--plugins/pychrysalide/format/format.c45
-rw-r--r--plugins/pychrysalide/format/format.h3
15 files changed, 412 insertions, 230 deletions
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
index efb88e2..36a46fe 100644
--- a/plugins/pychrysalide/analysis/constants.c
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -65,6 +65,29 @@ bool define_analysis_content_constants(PyTypeObject *type)
result = attach_constants_group_to_type(type, false, "SourceEndian", values,
"Endianness of handled data.");
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "UNDEFINED", MDS_UNDEFINED);
+ if (result) result = add_const_to_group(values, "4_BITS_UNSIGNED", MDS_4_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "8_BITS_UNSIGNED", MDS_8_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "16_BITS_UNSIGNED", MDS_16_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "32_BITS_UNSIGNED", MDS_32_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "64_BITS_UNSIGNED", MDS_64_BITS_UNSIGNED);
+ if (result) result = add_const_to_group(values, "4_BITS_SIGNED", MDS_4_BITS_SIGNED);
+ if (result) result = add_const_to_group(values, "8_BITS_SIGNED", MDS_8_BITS_SIGNED);
+ if (result) result = add_const_to_group(values, "16_BITS_SIGNED", MDS_16_BITS_SIGNED);
+ if (result) result = add_const_to_group(values, "32_BITS_SIGNED", MDS_32_BITS_SIGNED);
+ if (result) result = add_const_to_group(values, "64_BITS_SIGNED", MDS_64_BITS_SIGNED);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "MemoryDataSize", values,
+ "Size of processed data.");
+
exit:
return result;
diff --git a/plugins/pychrysalide/arch/Makefile.am b/plugins/pychrysalide/arch/Makefile.am
index 8b0e992..e167459 100644
--- a/plugins/pychrysalide/arch/Makefile.am
+++ b/plugins/pychrysalide/arch/Makefile.am
@@ -5,7 +5,6 @@ libpychrysaarch_la_SOURCES = \
constants.h constants.c \
context.h context.c \
feeder.h feeder.c \
- immediate.h immediate.c \
instriter.h instriter.c \
instruction.h instruction.c \
module.h module.c \
@@ -13,7 +12,6 @@ libpychrysaarch_la_SOURCES = \
processor.h processor.c \
raw.h raw.c \
register.h register.c \
- targetableop.h targetableop.c \
undefined.h undefined.c \
vmpa.h vmpa.c
diff --git a/plugins/pychrysalide/arch/constants.h b/plugins/pychrysalide/arch/constants.h
index d1fc2d4..5273bbd 100644
--- a/plugins/pychrysalide/arch/constants.h
+++ b/plugins/pychrysalide/arch/constants.h
@@ -30,6 +30,7 @@
#include <stdbool.h>
+
/* Définit les constantes relatives aux emplacements. */
bool define_arch_vmpa_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/arch/module.c b/plugins/pychrysalide/arch/module.c
index cacc167..3266194 100644
--- a/plugins/pychrysalide/arch/module.c
+++ b/plugins/pychrysalide/arch/module.c
@@ -34,14 +34,12 @@
#include "context.h"
#include "feeder.h"
-#include "immediate.h"
#include "instriter.h"
#include "instruction.h"
#include "operand.h"
#include "processor.h"
#include "raw.h"
#include "register.h"
-#include "targetableop.h"
#include "undefined.h"
#include "vmpa.h"
#include "operands/module.h"
@@ -171,14 +169,12 @@ bool populate_arch_module(void)
if (result) result = ensure_python_proc_context_is_registered();
if (result) result = ensure_python_proxy_feeder_is_registered();
- if (result) result = ensure_python_imm_operand_is_registered();
if (result) result = ensure_python_instr_iterator_is_registered();
if (result) result = ensure_python_arch_instruction_is_registered();
if (result) result = ensure_python_arch_operand_is_registered();
if (result) result = ensure_python_arch_processor_is_registered();
if (result) result = ensure_python_raw_instruction_is_registered();
if (result) result = ensure_python_arch_register_is_registered();
- if (result) result = ensure_python_targetable_operand_is_registered();
if (result) result = ensure_python_undefined_instruction_is_registered();
if (result) result = ensure_python_vmpa_is_registered();
if (result) result = ensure_python_mrange_is_registered();
diff --git a/plugins/pychrysalide/arch/operands/Makefile.am b/plugins/pychrysalide/arch/operands/Makefile.am
index 94da1d1..7974c42 100644
--- a/plugins/pychrysalide/arch/operands/Makefile.am
+++ b/plugins/pychrysalide/arch/operands/Makefile.am
@@ -2,8 +2,11 @@
noinst_LTLIBRARIES = libpychrysaarchoperands.la
libpychrysaarchoperands_la_SOURCES = \
+ constants.h constants.c \
+ immediate.h immediate.c \
module.h module.c \
- register.h register.c
+ register.h register.c \
+ targetable.h targetable.c
libpychrysaarchoperands_la_LIBADD =
diff --git a/plugins/pychrysalide/arch/operands/constants.c b/plugins/pychrysalide/arch/operands/constants.c
new file mode 100644
index 0000000..daec562
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/constants.c
@@ -0,0 +1,75 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes de base pour les opérandes
+ *
+ * Copyright (C) 2019 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "constants.h"
+
+
+#include <arch/operands/immediate.h>
+
+
+#include "../../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux opérandes d'immédiats. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_imm_operand_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "BIN", IOD_BIN);
+ if (result) result = add_const_to_group(values, "OCT", IOD_OCT);
+ if (result) result = add_const_to_group(values, "DEC", IOD_DEC);
+ if (result) result = add_const_to_group(values, "HEX", IOD_HEX);
+ if (result) result = add_const_to_group(values, "CHAR", IOD_CHAR);
+ if (result) result = add_const_to_group(values, "COUNT", IOD_COUNT);
+ if (result) result = add_const_to_group(values, "LAST_VALID", IOD_LAST_VALID);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "ImmOperandDisplay", values,
+ "Kind of display format for immediate operands.");
+
+ exit:
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/arch/operands/constants.h b/plugins/pychrysalide/arch/operands/constants.h
new file mode 100644
index 0000000..cea74f5
--- /dev/null
+++ b/plugins/pychrysalide/arch/operands/constants.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes de base pour les opérandes
+ *
+ * Copyright (C) 2019 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives aux opérandes d'immédiats. */
+bool define_imm_operand_constants(PyTypeObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/arch/immediate.c b/plugins/pychrysalide/arch/operands/immediate.c
index 4c538e4..ab9e16c 100644
--- a/plugins/pychrysalide/arch/immediate.c
+++ b/plugins/pychrysalide/arch/operands/immediate.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * immediate.c - équivalent Python du fichier "arch/immediate.h"
+ * immediate.c - équivalent Python du fichier "arch/operands/immediate.h"
*
* Copyright (C) 2012-2017 Cyrille Bagard
*
@@ -32,24 +32,32 @@
#include <i18n.h>
-#include <arch/immediate.h>
+#include <arch/operands/immediate.h>
-#include "operand.h"
-#include "targetableop.h"
-#include "../access.h"
-#include "../helpers.h"
+#include "constants.h"
+#include "targetable.h"
+#include "../operand.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../analysis/content.h"
+/* Crée un nouvel objet Python de type 'ImmOperand'. */
+static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Renseigne la taille de la valeur indiquée à la construction. */
+static PyObject *py_imm_operand_get_size(PyObject *, void *);
+
/* Fournit la valeur portée par une opérande numérique. */
static PyObject *py_imm_operand_get_value(PyObject *, void *);
/* Indique si l'affichage est complété avec des zéros. */
-static PyObject *py_imm_operand_get_padding_by_default(PyObject *self, void *);
+static PyObject *py_imm_operand_get_default_padding(PyObject *self, void *);
/* Précise si des zéro doivent compléter l'affichage ou non. */
-static int py_imm_operand_set_padding_by_default(PyObject *, PyObject *, void *);
+static int py_imm_operand_set_default_padding(PyObject *, PyObject *, void *);
/* Indique si l'affichage est complété avec des zéros. */
static PyObject *py_imm_operand_get_padding(PyObject *self, void *);
@@ -69,15 +77,59 @@ static PyObject *py_imm_operand_get_display(PyObject *, void *);
/* Définit la grande ligne du format textuel de la valeur. */
static int py_imm_operand_set_display(PyObject *, PyObject *, void *);
-/* Construit la chaîne de caractères correspondant à l'opérande. */
-static PyObject *py_imm_operand_to_string(PyObject *, PyObject *);
-/* Crée un nouvel objet Python de type 'ImmOperand'. */
-static PyObject *py_imm_operand_new(PyTypeObject *, PyObject *, PyObject *);
-/* Définit les constantes pour les opérandes d'immédiats. */
-static bool py_imm_operand_define_constants(PyTypeObject *);
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'ImmOperand'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Instance à retourner */
+ unsigned int raw_size; /* Taille obtenue de Python */
+ unsigned long long value; /* Valeur brute à représenter */
+ int ret; /* Bilan de lecture des args. */
+ MemoryDataSize size; /* Taille des données finale */
+ GArchOperand *operand; /* Création GLib à transmettre */
+
+#define IMM_OPERAND_DOC \
+ "The ImmOperand deals with immediate value as operand." \
+ "\n" \
+ "There are several ways to display these values in a disassembly," \
+ " the operand handles that."
+
+ ret = PyArg_ParseTuple(args, "IK", &raw_size, &value);
+ if (!ret) return NULL;
+
+ size = raw_size;
+
+ if (size != MDS_UNDEFINED
+ && !(MDS_4_BITS_UNSIGNED <= size && size <= MDS_64_BITS_UNSIGNED)
+ && !(MDS_4_BITS_SIGNED <= size && size <= MDS_64_BITS_SIGNED))
+ {
+ PyErr_SetString(PyExc_ValueError, _("Invalid size to build an immediate operand"));
+ return NULL;
+ }
+
+ operand = g_imm_operand_new_from_value(size, value);
+ result = pygobject_new(G_OBJECT(operand));
+
+ g_object_unref(operand);
+
+ return (PyObject *)result;
+
+}
/******************************************************************************
@@ -99,12 +151,19 @@ static PyObject *py_imm_operand_get_size(PyObject *self, void *closure)
GImmOperand *operand; /* Version GLib de l'opérande */
MemoryDataSize size; /* Type de donnée représentée */
- operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
+#define IMM_OPERAND_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ size, py_imm_operand, \
+ "Get or set the size of the value contained in the operand." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.analysis.BinContent.MemoryDataSize." \
+)
+ operand = G_IMM_OPERAND(pygobject_get(self));
size = g_imm_operand_get_size(operand);
- result = Py_BuildValue("I", size);
+ result = cast_with_constants_group_from_type(get_python_binary_content_type(), "MemoryDataSize", size);
return result;
@@ -138,8 +197,13 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
int32_t sval32; /* Valeur sur 32 bits */
int64_t sval64; /* Valeur sur 64 bits */
+#define IMM_OPERAND_VALUE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ value, py_imm_operand, \
+ "Value of the immediate operand, as an integer." \
+)
+
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
size = g_imm_operand_get_size(operand);
@@ -212,18 +276,27 @@ static PyObject *py_imm_operand_get_value(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_imm_operand_get_padding_by_default(PyObject *self, void *closure)
+static PyObject *py_imm_operand_get_default_padding(PyObject *self, void *closure)
{
PyObject *result; /* Instance Python à retourner */
GImmOperand *operand; /* Version GLib de l'opérande */
bool padding; /* Bourrage en préfixe ? */
+#define IMM_OPERAND_DEFAULT_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ default_padding, py_imm_operand, \
+ "Get or set the status of default padding with zeros in front of the" \
+ " textual representation." \
+ "\n" \
+ "The status is a boolean value." \
+)
+
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
- padding = g_imm_operand_does_padding_by_default(operand);
+ padding = g_imm_operand_get_default_padding(operand);
- result = Py_BuildValue("p", padding);
+ result = padding ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
@@ -244,7 +317,7 @@ static PyObject *py_imm_operand_get_padding_by_default(PyObject *self, void *clo
* *
******************************************************************************/
-static int py_imm_operand_set_padding_by_default(PyObject *self, PyObject *value, void *closure)
+static int py_imm_operand_set_default_padding(PyObject *self, PyObject *value, void *closure)
{
bool padding; /* Bourrage en préfixe ? */
GImmOperand *operand; /* Version GLib de l'opérande */
@@ -258,9 +331,8 @@ static int py_imm_operand_set_padding_by_default(PyObject *self, PyObject *value
padding = (value == Py_True);
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
- g_imm_operand_pad_by_default(operand, padding);
+ g_imm_operand_set_default_padding(operand, padding);
return 0;
@@ -286,12 +358,21 @@ static PyObject *py_imm_operand_get_padding(PyObject *self, void *closure)
GImmOperand *operand; /* Version GLib de l'opérande */
bool padding; /* Bourrage en préfixe ? */
+#define IMM_OPERAND_PADDING_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ padding, py_imm_operand, \
+ "Get or set the status of padding with zeros in front of the" \
+ " textual representation." \
+ "\n" \
+ "The status is a boolean value." \
+)
+
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
padding = g_imm_operand_does_padding(operand);
- result = Py_BuildValue("p", padding);
+ result = padding ? Py_True : Py_False;
+ Py_INCREF(result);
return result;
@@ -326,7 +407,6 @@ static int py_imm_operand_set_padding(PyObject *self, PyObject *value, void *clo
padding = (value == Py_True);
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
g_imm_operand_pad(operand, padding);
@@ -354,12 +434,19 @@ static PyObject *py_imm_operand_get_default_display(PyObject *self, void *closur
GImmOperand *operand; /* Version GLib de l'opérande */
ImmOperandDisplay display; /* Type d'affichage courant */
- operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
+#define IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ default_display, py_imm_operand, \
+ "Define of the immediate operand default textual representation." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
+)
+ operand = G_IMM_OPERAND(pygobject_get(self));
display = g_imm_operand_get_default_display(operand);
- result = Py_BuildValue("I", display);
+ result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", display);
return result;
@@ -400,7 +487,6 @@ static int py_imm_operand_set_default_display(PyObject *self, PyObject *value, v
}
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
g_imm_operand_set_default_display(operand, display);
@@ -428,12 +514,19 @@ static PyObject *py_imm_operand_get_display(PyObject *self, void *closure)
GImmOperand *operand; /* Version GLib de l'opérande */
ImmOperandDisplay display; /* Type d'affichage courant */
- operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
+#define IMM_OPERAND_DISPLAY_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ display, py_imm_operand, \
+ "Define of the immediate operand current textual representation." \
+ "\n" \
+ "The property is a value of type" \
+ " pychrysalide.arch.operands.ImmOperand.ImmOperandDisplay." \
+)
+ operand = G_IMM_OPERAND(pygobject_get(self));
display = g_imm_operand_get_display(operand);
- result = Py_BuildValue("I", display);
+ result = cast_with_constants_group_from_type(get_python_imm_operand_type(), "ImmOperandDisplay", display);
return result;
@@ -474,7 +567,6 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo
}
operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
g_imm_operand_set_display(operand, display);
@@ -485,114 +577,6 @@ static int py_imm_operand_set_display(PyObject *self, PyObject *value, void *clo
/******************************************************************************
* *
-* Paramètres : self = operande à manipuler. *
-* args = arguments accompagnant l'appel. *
-* *
-* Description : Construit la chaîne de caractères correspondant à l'opérande.*
-* *
-* Retour : Chaîne de caractères mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_imm_operand_to_string(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Instance à retourner */
- GImmOperand *operand; /* Version GLib de l'opérande */
- char value[IMM_MAX_SIZE]; /* Valeur humainement lisible */
-
- operand = G_IMM_OPERAND(pygobject_get(self));
- assert(operand != NULL);
-
- g_imm_operand_to_string(operand, value);
-
- result = PyUnicode_FromString(value);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : type = type de l'objet à instancier. *
-* args = arguments fournis à l'appel. *
-* kwds = arguments de type key=val fournis. *
-* *
-* Description : Crée un nouvel objet Python de type 'ImmOperand'. *
-* *
-* Retour : Instance Python mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_imm_operand_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject *result; /* Instance à retourner */
- unsigned int raw_size; /* Taille obtenue de Python */
- unsigned long long value; /* Valeur brute à représenter */
- int ret; /* Bilan de lecture des args. */
- MemoryDataSize size; /* Taille des données finale */
- GArchOperand *operand; /* Création GLib à transmettre */
-
- ret = PyArg_ParseTuple(args, "IK", &raw_size, &value);
- if (!ret) return NULL;
-
- size = raw_size;
-
- if (size != MDS_UNDEFINED
- && !(MDS_4_BITS_UNSIGNED <= size && size <= MDS_64_BITS_UNSIGNED)
- && !(MDS_4_BITS_SIGNED <= size && size <= MDS_64_BITS_SIGNED))
- {
- PyErr_SetString(PyExc_ValueError, _("Invalid size to build an immediate operand"));
- return NULL;
- }
-
- operand = g_imm_operand_new_from_value(size, value);
-
- result = pygobject_new(G_OBJECT(operand));
-
- g_object_unref(operand);
-
- return (PyObject *)result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : obj_type = type dont le dictionnaire est à compléter. *
-* *
-* Description : Définit les constantes pour les opérandes d'immédiats. *
-* *
-* Retour : true en cas de succès de l'opération, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool py_imm_operand_define_constants(PyTypeObject *obj_type)
-{
- bool result; /* Bilan à retourner */
-
- result = true;
-
- result &= PyDict_AddULongMacro(obj_type, IOD_BIN);
- result &= PyDict_AddULongMacro(obj_type, IOD_OCT);
- result &= PyDict_AddULongMacro(obj_type, IOD_DEC);
- result &= PyDict_AddULongMacro(obj_type, IOD_HEX);
- result &= PyDict_AddULongMacro(obj_type, IOD_CHAR);
- result &= PyDict_AddULongMacro(obj_type, IOD_COUNT);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : - *
* *
* Description : Fournit un accès à une définition de type à diffuser. *
@@ -606,39 +590,16 @@ static bool py_imm_operand_define_constants(PyTypeObject *obj_type)
PyTypeObject *get_python_imm_operand_type(void)
{
static PyMethodDef py_imm_operand_methods[] = {
- {
- "to_string", py_imm_operand_to_string,
- METH_NOARGS,
- "to_string($self, syntax, /)\n--\n\nConvert the immediate operand to a string."
- },
{ NULL }
};
static PyGetSetDef py_imm_operand_getseters[] = {
- {
- "size", py_imm_operand_get_size, NULL,
- "Size of the value contained in the operand.", NULL
- },
- {
- "value", py_imm_operand_get_value, NULL,
- "Value of the immediate operand.", NULL
- },
- {
- "padding", py_imm_operand_get_padding, py_imm_operand_set_padding,
- "Status of padding with zeros in front of the textual representation.", NULL
- },
- {
- "default_padding", py_imm_operand_get_padding_by_default, py_imm_operand_set_padding_by_default,
- "Status of default padding with zeros in front of the textual representation.", NULL
- },
- {
- "default_display", py_imm_operand_get_default_display, py_imm_operand_set_default_display,
- "Definition of the immediate operand default textual representation.", NULL
- },
- {
- "display", py_imm_operand_get_display, py_imm_operand_set_display,
- "Definition of the immediate operand current textual representation.", NULL
- },
+ IMM_OPERAND_SIZE_ATTRIB,
+ IMM_OPERAND_VALUE_ATTRIB,
+ IMM_OPERAND_DEFAULT_PADDING_ATTRIB,
+ IMM_OPERAND_PADDING_ATTRIB,
+ IMM_OPERAND_DEFAULT_DISPLAY_ATTRIB,
+ IMM_OPERAND_DISPLAY_ATTRIB,
{ NULL }
};
@@ -646,12 +607,12 @@ PyTypeObject *get_python_imm_operand_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.ImmOperand",
+ .tp_name = "pychrysalide.arch.operands.ImmOperand",
.tp_basicsize = sizeof(PyGObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide immediate operand.",
+ .tp_doc = IMM_OPERAND_DOC,
.tp_methods = py_imm_operand_methods,
.tp_getset = py_imm_operand_getseters,
@@ -686,7 +647,7 @@ bool ensure_python_imm_operand_is_registered(void)
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
- module = get_access_to_python_module("pychrysalide.arch");
+ module = get_access_to_python_module("pychrysalide.arch.operands");
dict = PyModule_GetDict(module);
@@ -699,7 +660,7 @@ bool ensure_python_imm_operand_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_IMM_OPERAND, type, get_python_arch_operand_type()))
return false;
- if (!py_imm_operand_define_constants(type))
+ if (!define_imm_operand_constants(type))
return false;
}
diff --git a/plugins/pychrysalide/arch/immediate.h b/plugins/pychrysalide/arch/operands/immediate.h
index fd456e4..9f32758 100644
--- a/plugins/pychrysalide/arch/immediate.h
+++ b/plugins/pychrysalide/arch/operands/immediate.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * immediate.h - prototypes pour l'équivalent Python du fichier "arch/immediate.h"
+ * immediate.h - prototypes pour l'équivalent Python du fichier "arch/operands/immediate.h"
*
* Copyright (C) 2017 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_IMMEDIATE_H
-#define _PLUGINS_PYCHRYSALIDE_ARCH_IMMEDIATE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H
#include <Python.h>
@@ -39,4 +39,4 @@ bool ensure_python_imm_operand_is_registered(void);
-#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_IMMEDIATE_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_IMMEDIATE_H */
diff --git a/plugins/pychrysalide/arch/operands/module.c b/plugins/pychrysalide/arch/operands/module.c
index 47a806a..f800e38 100644
--- a/plugins/pychrysalide/arch/operands/module.c
+++ b/plugins/pychrysalide/arch/operands/module.c
@@ -28,7 +28,9 @@
#include <assert.h>
+#include "immediate.h"
#include "register.h"
+#include "targetable.h"
#include "../../helpers.h"
@@ -50,12 +52,18 @@ bool add_arch_operands_module(PyObject *super)
bool result; /* Bilan à retourner */
PyObject *module; /* Sous-module mis en place */
+#define PYCHRYSALIDE_ARCH_OPERANDS_DOC \
+ "This module contains implementations for most common operand usages." \
+ "\n" \
+ "These operands are usually added to objects such as" \
+ " pychrysalide.arch.ArchInstruction when disassembling a binary."
+
static PyModuleDef py_chrysalide_arch_operands_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "pychrysalide.arch.operands",
- .m_doc = "Python module for Chrysalide.arch.operands",
+ .m_doc = PYCHRYSALIDE_ARCH_OPERANDS_DOC,
.m_size = -1,
@@ -88,7 +96,9 @@ bool populate_arch_operands_module(void)
result = true;
+ if (result) result = ensure_python_imm_operand_is_registered();
if (result) result = ensure_python_register_operand_is_registered();
+ if (result) result = ensure_python_targetable_operand_is_registered();
assert(result);
diff --git a/plugins/pychrysalide/arch/operands/register.c b/plugins/pychrysalide/arch/operands/register.c
index 3e77c9b..28d79f1 100644
--- a/plugins/pychrysalide/arch/operands/register.c
+++ b/plugins/pychrysalide/arch/operands/register.c
@@ -169,6 +169,17 @@ static int py_register_operand_init(PyObject *self, PyObject *args, PyObject *kw
PyObject *new_kwds; /* Nouveau dictionnaire épuré */
GRegisterOperand *operand; /* Opérande à manipuler */
+#define REGISTER_OPERAND_DOC \
+ "The RegisterOperand object handles an operand carrying an" \
+ " architecture register.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " RegisterOperand(reg)" \
+ "\n" \
+ "Where reg is an architecture register defined from a subclass of" \
+ " pychrysalide.arch.ArchRegister."
+
/* Récupération des paramètres */
ret = PyArg_ParseTuple(args, "O&", convert_to_arch_register, &reg);
@@ -223,6 +234,13 @@ static PyObject *py_register_operand_get_register(PyObject *self, void *closure)
GRegisterOperand *operand; /* Version GLib de l'opérande */
GArchRegister *reg; /* Registre lié à l'opérande */
+#define REGISTER_OPERAND_REGISTER_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ register, py_register_operand, \
+ "Provide the register used by the operand, as an" \
+ " instance of type pychrysalide.arch.ArchRegister." \
+)
+
operand = G_REGISTER_OPERAND(pygobject_get(self));
reg = g_register_operand_get_register(operand);
@@ -263,10 +281,7 @@ PyTypeObject *get_python_register_operand_type(void)
};
static PyGetSetDef py_register_operand_getseters[] = {
- {
- "register", py_register_operand_get_register, NULL,
- "Provide the register used by the operand.", NULL
- },
+ REGISTER_OPERAND_REGISTER_ATTRIB,
{ NULL }
};
@@ -279,7 +294,7 @@ PyTypeObject *get_python_register_operand_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide instruction register operand.",
+ .tp_doc = REGISTER_OPERAND_DOC,
.tp_methods = py_register_operand_methods,
.tp_getset = py_register_operand_getseters,
diff --git a/plugins/pychrysalide/arch/targetableop.c b/plugins/pychrysalide/arch/operands/targetable.c
index bc9e3af..a633b82 100644
--- a/plugins/pychrysalide/arch/targetableop.c
+++ b/plugins/pychrysalide/arch/operands/targetable.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * targetableop.c - prototypes pour l'équivalent Python du fichier "arch/targetableop.c"
+ * targetable.c - prototypes pour l'équivalent Python du fichier "arch/operands/targetable.c"
*
* Copyright (C) 2018 Cyrille Bagard
*
@@ -22,24 +22,32 @@
*/
-#include "targetableop.h"
+#include "targetable.h"
-#include <assert.h>
#include <pygobject.h>
#include <i18n.h>
-#include <arch/targetableop.h>
+#include <arch/operands/targetable.h>
-#include "processor.h"
-#include "vmpa.h"
-#include "../access.h"
-#include "../helpers.h"
-#include "../format/format.h"
+#include "../processor.h"
+#include "../vmpa.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../format/format.h"
+
+
+
+#define TARGETABLE_OPERAND_DOC \
+ "The TargetableOperand interface depicts operands which can drive to" \
+ " another location.\n" \
+ "\n" \
+ "By instance, an immediate value can target a given address into" \
+ " some function code."
@@ -64,31 +72,38 @@ static PyObject *py_targetable_operand_get_addr(PyObject *, PyObject *);
static PyObject *py_targetable_operand_get_addr(PyObject *self, PyObject *args)
{
PyObject *result; /* Instance à retourner */
- PyObject *src_obj; /* Objet pour une position */
- PyObject *format_obj; /* Objet pour un format */
- PyObject *proc_obj; /* Objet pour une architecture */
- int ret; /* Bilan de lecture des args. */
vmpa2t *src; /* Version native d'adresse */
GBinFormat *format; /* Instance GLib du format */
GArchProcessor *proc; /* Instance GLib de l'archi. */
+ int ret; /* Bilan de lecture des args. */
GTargetableOperand *operand; /* Instance à manipuler */
vmpa2t addr; /* Localisation à cibler */
bool defined; /* Cible définie ? */
- ret = PyArg_ParseTuple(args, "O!O!O!",
- get_python_vmpa_type(), &src_obj,
- get_python_binary_format_type(), &format_obj,
- get_python_arch_processor_type(), &proc_obj);
+#define TARGETABLE_OPERAND_GET_ADDR_METHOD PYTHON_METHOD_DEF \
+( \
+ get_addr, "$self, src, format, proc", \
+ METH_VARARGS, py_targetable_operand, \
+ "Compute a target address from an operand." \
+ "\n" \
+ "The following arguments are required:\n" \
+ "* src is the location of the instruction owning the operand, as a" \
+ " pychrysalide.arch.vmpa instance.\n" \
+ "* format is a pychrysalide.format.BinFormat instance, providing" \
+ " all needed information.\n" \
+ "* proc is a pychrysalide.arch.ArchProcessor instance, providing" \
+ " all needed information too.\n" \
+ "\n" \
+ "The result is a pychrysalide.arch.vmpa address or None." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&O&O&",
+ convert_any_to_vmpa, &src,
+ convert_to_binary_format, &format,
+ convert_to_arch_processor, &proc);
if (!ret) return NULL;
- src = get_internal_vmpa(src_obj);
- assert(src != NULL);
-
- format = G_BIN_FORMAT(pygobject_get(format_obj));
- proc = G_ARCH_PROCESSOR(pygobject_get(proc_obj));
-
operand = G_TARGETABLE_OPERAND(pygobject_get(self));
- assert(operand != NULL);
defined = g_targetable_operand_get_addr(operand, src, format, proc, &addr);
@@ -100,6 +115,8 @@ static PyObject *py_targetable_operand_get_addr(PyObject *self, PyObject *args)
Py_INCREF(result);
}
+ clean_vmpa_arg(src);
+
return result;
}
@@ -120,11 +137,7 @@ static PyObject *py_targetable_operand_get_addr(PyObject *self, PyObject *args)
PyTypeObject *get_python_targetable_operand_type(void)
{
static PyMethodDef py_targetable_operand_methods[] = {
- {
- "get_addr", py_targetable_operand_get_addr,
- METH_VARARGS,
- "get_addr($self, src, format, proc, /)\n--\n\nGet a target address from an operand."
- },
+ TARGETABLE_OPERAND_GET_ADDR_METHOD,
{ NULL }
};
@@ -136,12 +149,12 @@ PyTypeObject *get_python_targetable_operand_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.TargetableOperand",
+ .tp_name = "pychrysalide.arch.operands.TargetableOperand",
.tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide targetable operand",
+ .tp_doc = TARGETABLE_OPERAND_DOC,
.tp_methods = py_targetable_operand_methods,
.tp_getset = py_targetable_operand_getseters
@@ -175,7 +188,7 @@ bool ensure_python_targetable_operand_is_registered(void)
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
- module = get_access_to_python_module("pychrysalide.arch");
+ module = get_access_to_python_module("pychrysalide.arch.operands");
dict = PyModule_GetDict(module);
diff --git a/plugins/pychrysalide/arch/targetableop.h b/plugins/pychrysalide/arch/operands/targetable.h
index 4c41a4d..8a751fc 100644
--- a/plugins/pychrysalide/arch/targetableop.h
+++ b/plugins/pychrysalide/arch/operands/targetable.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * targetableop.h - prototypes pour l'équivalent Python du fichier "arch/targetableop.h"
+ * targetable.h - prototypes pour l'équivalent Python du fichier "arch/operands/targetable.h"
*
* Copyright (C) 2018 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_TARGETABLEOP_H
-#define _PLUGINS_PYCHRYSALIDE_ARCH_TARGETABLEOP_H
+#ifndef _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGETABLE_H
+#define _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGETABLE_H
#include <Python.h>
@@ -39,4 +39,4 @@ bool ensure_python_targetable_operand_is_registered(void);
-#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_TARGETABLEOP_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_ARCH_OPERANDS_TARGETABLE_H */
diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c
index 8afbca9..409e085 100644
--- a/plugins/pychrysalide/format/format.c
+++ b/plugins/pychrysalide/format/format.c
@@ -796,3 +796,48 @@ bool ensure_python_binary_format_is_registered(void)
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en format de binaire. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_binary_format(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_binary_format_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to binary format");
+ break;
+
+ case 1:
+ *((GBinFormat **)dst) = G_BIN_FORMAT(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/format/format.h b/plugins/pychrysalide/format/format.h
index 6423821..c7d5ee6 100644
--- a/plugins/pychrysalide/format/format.h
+++ b/plugins/pychrysalide/format/format.h
@@ -51,6 +51,9 @@ PyTypeObject *get_python_binary_format_type(void);
/* Prend en charge l'objet 'pychrysalide.format.BinFormat'. */
bool ensure_python_binary_format_is_registered(void);
+/* Tente de convertir en format de binaire. */
+int convert_to_binary_format(PyObject *, void *);
+
#endif /* _PLUGINS_PYCHRYSALIDE_FORMAT_FORMAT_H */