summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-05-12 21:15:45 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-05-12 21:17:31 (GMT)
commit90d1fa65a1d13128a66117095a44224e8c9de656 (patch)
tree024674c4d199018d93f0064a3ec1ddd8f3bd4321
parentd2861533cc53fbcc217048bafebf34b1f70ba3aa (diff)
Described the Python API for binary portions.
-rw-r--r--plugins/pychrysalide/format/symbol.c4
-rw-r--r--plugins/pychrysalide/glibext/binportion.c131
-rw-r--r--plugins/pychrysalide/glibext/constants.c97
-rw-r--r--plugins/pychrysalide/glibext/constants.h6
-rw-r--r--plugins/pychrysalide/glibext/module.c9
-rw-r--r--plugins/pychrysalide/gui/module.c2
6 files changed, 197 insertions, 52 deletions
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c
index 71832cb..c86b453 100644
--- a/plugins/pychrysalide/format/symbol.c
+++ b/plugins/pychrysalide/format/symbol.c
@@ -525,7 +525,9 @@ static PyObject *py_binary_symbol_get_range(PyObject *self, void *closure)
#define BINARY_SYMBOL_RANGE_ATTRIB PYTHON_GETSET_DEF_FULL \
( \
range, py_binary_symbol, \
- "Memory range covered by the symbol." \
+ "Memory range covered by the symbol.\n" \
+ "\n" \
+ "This property is a pychrysalide.arch.mrange instance." \
)
symbol = G_BIN_SYMBOL(pygobject_get(self));
diff --git a/plugins/pychrysalide/glibext/binportion.c b/plugins/pychrysalide/glibext/binportion.c
index 1119293..14df461 100644
--- a/plugins/pychrysalide/glibext/binportion.c
+++ b/plugins/pychrysalide/glibext/binportion.c
@@ -33,6 +33,7 @@
#include <plugins/dt.h>
+#include "constants.h"
#include "../access.h"
#include "../helpers.h"
#include "../arch/vmpa.h"
@@ -51,8 +52,6 @@ static PyObject *py_binary_portion_richcompare(PyObject *, PyObject *, int);
/* Assure qu'une portion ne dépasse pas une position donnée. */
static PyObject *py_binary_portion_limit_range(PyObject *, PyObject *);
-
-
/* Fournit la description attribuée à une partie de code. */
static PyObject *py_binary_portion_get_desc(PyObject *, void *);
@@ -165,6 +164,19 @@ static int py_bin_portion_init(PyObject *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = { "code", "addr", "size", NULL };
+#define BINARY_PORTION_DOC \
+ "The BinPortion object handles parts of binaries usually formally" \
+ " identified in binary formats, like program segments or sections for ELF" \
+ " files for example.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " BinPortion(code, addr, size)" \
+ "\n" \
+ "Where code is the CSS class style for the rendering color to use, addr is" \
+ " the starting point of the portion in memory, as a pychrysalide.arch.vmpa" \
+ " value, and size is the size of the portion." \
+
/* Récupération des paramètres */
ret = PyArg_ParseTupleAndKeywords(args, kwds, "sO&K", kwlist,
@@ -268,6 +280,19 @@ static PyObject *py_binary_portion_limit_range(PyObject *self, PyObject *args)
GBinPortion *portion; /* Version GLib du type */
bool status; /* Bilan de la modification */
+#define BINARY_SYMBOL_LIMIT_RANGE_METHOD PYTHON_METHOD_DEF \
+( \
+ limit_range, "$self, max, /", \
+ METH_VARARGS, py_binary_portion, \
+ "Ensure the portion range does not cross a boundary size.\n" \
+ "\n" \
+ "An integer value is expected as the maximum size of the" \
+ " portion.\n" \
+ "\n" \
+ "A boolean value indicating the success of the operation is" \
+ " returned." \
+)
+
ret = PyArg_ParseTuple(args, "K", &max);
if (!ret) return NULL;
@@ -302,6 +327,16 @@ static PyObject *py_binary_portion_include(PyObject *self, PyObject *args)
int ret; /* Bilan de lecture des args. */
GBinPortion *portion; /* Version GLib du type */
+#define BINARY_SYMBOL_INCLUDE_METHOD PYTHON_METHOD_DEF \
+( \
+ include, "$self, sub, /", \
+ METH_VARARGS, py_binary_portion, \
+ "Include another binary portion as a child item.\n" \
+ "\n" \
+ "The sub portion has to be a pychrysalide.glibext.BinPortion" \
+ " instance." \
+)
+
ret = PyArg_ParseTuple(args, "O&", convert_to_binary_portion, &sub);
if (!ret) return NULL;
@@ -334,6 +369,13 @@ static PyObject *py_binary_portion_get_desc(PyObject *self, void *closure)
GBinPortion *portion; /* Version GLib du type */
const char *desc; /* Description récupérée */
+#define BINARY_PORTION_DESC_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ desc, py_binary_portion, \
+ "Human description for the binary portion, as a" \
+ " simple string." \
+)
+
portion = G_BIN_PORTION(pygobject_get(self));
desc = g_binary_portion_get_desc(portion);
@@ -400,6 +442,14 @@ static PyObject *py_binary_portion_get_range(PyObject *self, void *closure)
GBinPortion *portion; /* Version GLib du type */
const mrange_t *range; /* Espace de couverture */
+#define BINARY_PORTION_RANGE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ range, py_binary_portion, \
+ "Area covered by the binary portion.\n" \
+ "\n" \
+ "This property is a pychrysalide.arch.mrange instance." \
+)
+
portion = G_BIN_PORTION(pygobject_get(self));
range = g_binary_portion_get_range(portion);
@@ -430,6 +480,16 @@ static PyObject *py_binary_portion_get_continuation(PyObject *self, void *closur
GBinPortion *portion; /* Version GLib du type */
bool status; /* Bilan d'une consultation */
+#define BINARY_PORTION_CONTINUATION_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ continuation, py_binary_portion, \
+ "Tell if the current portion is a continuation of another" \
+ " one.\n" \
+ "\n" \
+ "If a section belongs to several parents, it is cut into" \
+ " several parts when included in the portion tree." \
+)
+
portion = G_BIN_PORTION(pygobject_get(self));
status = g_binary_portion_is_continuation(portion);
@@ -497,11 +557,18 @@ static PyObject *py_binary_portion_get_rights(PyObject *self, void *closure)
GBinPortion *portion; /* Version GLib du type */
PortionAccessRights rights; /* Bilan d'une consultation */
+#define BINARY_PORTION_RIGHTS_ATTRIB PYTHON_GETSET_DEF_FULL \
+( \
+ rights, py_binary_portion, \
+ "Access rights declared for the binary portion, as a" \
+ " pychrysalide.glibext.BinPortion.PortionAccessRights value." \
+)
+
portion = G_BIN_PORTION(pygobject_get(self));
rights = g_binary_portion_get_rights(portion);
- result = PyLong_FromUnsignedLong(rights);
+ result = cast_with_constants_group_from_type(get_python_binary_portion_type(), "PortionAccessRights", rights);
return result;
@@ -525,21 +592,10 @@ static PyObject *py_binary_portion_get_rights(PyObject *self, void *closure)
static int py_binary_portion_set_rights(PyObject *self, PyObject *value, void *closure)
{
GBinPortion *portion; /* Version GLib du type */
- unsigned long rights; /* Valeur à manipuler */
+ PortionAccessRights rights; /* Valeur à manipuler */
- if (!PyLong_Check(value))
- {
- PyErr_SetString(PyExc_TypeError, _("The attribute value must be an integer value (PAC_*)."));
+ if (convert_to_portion_access_rights(value, &rights) != 1)
return -1;
- }
-
- rights = PyLong_AsUnsignedLong(value);
-
- if ((rights & ~PAC_ALL) != 0)
- {
- PyErr_SetString(PyExc_TypeError, _("Invalid attribute value."));
- return -1;
- }
portion = G_BIN_PORTION(pygobject_get(self));
@@ -574,12 +630,6 @@ static bool py_binary_portion_define_constants(PyTypeObject *obj_type)
if (result) result = PyDict_AddStringMacro(obj_type, BPC_DATA_RO);
if (result) result = PyDict_AddStringMacro(obj_type, BPC_DISASS_ERROR);
- if (result) result = PyDict_AddULongMacro(obj_type, PAC_NONE);
- if (result) result = PyDict_AddULongMacro(obj_type, PAC_READ);
- if (result) result = PyDict_AddULongMacro(obj_type, PAC_WRITE);
- if (result) result = PyDict_AddULongMacro(obj_type, PAC_EXEC);
- if (result) result = PyDict_AddULongMacro(obj_type, PAC_ALL);
-
return result;
}
@@ -600,36 +650,16 @@ static bool py_binary_portion_define_constants(PyTypeObject *obj_type)
PyTypeObject *get_python_binary_portion_type(void)
{
static PyMethodDef py_binary_portion_methods[] = {
- {
- "limit_range", py_binary_portion_limit_range,
- METH_VARARGS,
- "limit_range($self, maxsz, /)\n--\n\nEnsure the portion range does not cross a boundary size."
- },
- {
- "include", py_binary_portion_include,
- METH_VARARGS,
- "include($self, other, /)\n--\n\nInclude another binary portion as a child item."
- },
+ BINARY_SYMBOL_LIMIT_RANGE_METHOD,
+ BINARY_SYMBOL_INCLUDE_METHOD,
{ NULL }
};
static PyGetSetDef py_binary_portion_getseters[] = {
- {
- "desc", py_binary_portion_get_desc, py_binary_portion_set_desc,
- "Human description for the binary portion.", NULL
- },
- {
- "range", py_binary_portion_get_range, NULL,
- "Area registered for the binary portion.", NULL
- },
- {
- "continuation", py_binary_portion_get_continuation, py_binary_portion_set_continuation,
- "Tell if the current portion is a continuation of another one.", NULL
- },
- {
- "rights", py_binary_portion_get_rights, py_binary_portion_set_rights,
- "Access rights declared for the binary portion.", NULL
- },
+ BINARY_PORTION_DESC_ATTRIB,
+ BINARY_PORTION_RANGE_ATTRIB,
+ BINARY_PORTION_CONTINUATION_ATTRIB,
+ BINARY_PORTION_RIGHTS_ATTRIB,
{ NULL }
};
@@ -642,7 +672,7 @@ PyTypeObject *get_python_binary_portion_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide binary portion",
+ .tp_doc = BINARY_PORTION_DOC,
.tp_richcompare = py_binary_portion_richcompare,
@@ -691,6 +721,9 @@ bool ensure_python_binary_portion_is_registered(void)
if (!py_binary_portion_define_constants(type))
return false;
+ if (!define_binary_portion_constants(type))
+ return false;
+
}
return true;
diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c
index 823465a..680feaf 100644
--- a/plugins/pychrysalide/glibext/constants.c
+++ b/plugins/pychrysalide/glibext/constants.c
@@ -26,6 +26,7 @@
#include <glibext/linesegment.h>
+#include <glibext/gbinportion.h>
#include <glibext/gbufferline.h>
@@ -37,6 +38,102 @@
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
+* Description : Définit les constantes relatives aux portions de binaires. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_binary_portion_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", PAC_NONE);
+ if (result) result = add_const_to_group(values, "READ", PAC_READ);
+ if (result) result = add_const_to_group(values, "WRITE", PAC_WRITE);
+ if (result) result = add_const_to_group(values, "EXEC", PAC_EXEC);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, false, "PortionAccessRights", values,
+ "Access rights for binary portions.");
+
+ exit:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 constante PortionAccessRights. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_portion_access_rights(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur récupérée */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 PortionAccessRights");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if ((value & ~PAC_ALL) != 0)
+ {
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to PortionAccessRights");
+ result = 0;
+ }
+
+ else
+ *((PortionAccessRights *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
* Description : Définit les constantes relatives aux segments de ligne. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h
index a1c56af..b815586 100644
--- a/plugins/pychrysalide/glibext/constants.h
+++ b/plugins/pychrysalide/glibext/constants.h
@@ -31,6 +31,12 @@
+/* Définit les constantes relatives aux portions de binaires. */
+bool define_binary_portion_constants(PyTypeObject *);
+
+/* Tente de convertir en constante PortionAccessRights. */
+int convert_to_portion_access_rights(PyObject *, void *);
+
/* Définit les constantes relatives aux segments de ligne. */
bool define_line_segment_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index ff0a1bd..b45da4d 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -58,12 +58,19 @@ bool add_glibext_module(PyObject *super)
bool result; /* Bilan à retourner */
PyObject *module; /* Sous-module mis en place */
+#define PYCHRYSALIDE_GLIBEXT_DOC \
+ "This module contains the definition of some objects derived from" \
+ " the GObject structure.\n" \
+ "\n" \
+ "These common objects are used in several places inside Chrysalide" \
+ " and could be seen as extensions to the GLib API."
+
static PyModuleDef py_chrysalide_glibext_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "pychrysalide.glibext",
- .m_doc = "Python module for Chrysalide.glibext",
+ .m_doc = PYCHRYSALIDE_GLIBEXT_DOC,
.m_size = -1,
diff --git a/plugins/pychrysalide/gui/module.c b/plugins/pychrysalide/gui/module.c
index a2699b4..9c06940 100644
--- a/plugins/pychrysalide/gui/module.c
+++ b/plugins/pychrysalide/gui/module.c
@@ -62,7 +62,7 @@ bool add_gui_module(PyObject *super)
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "pychrysalide.gui",
- .m_doc = PYCHRYSALIDE_GUI_DOC,
+ .m_doc = PYCHRYSALIDE_GUI_DOC,
.m_size = -1,