summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pychrysa/arch/vmpa.c283
1 files changed, 267 insertions, 16 deletions
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index b429699..f9a9db7 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -25,6 +25,9 @@
#include "vmpa.h"
+#include <string.h>
+
+
#include <src/arch/vmpa.h>
@@ -37,7 +40,7 @@ typedef struct _py_vmpa_t
{
PyObject_HEAD
- vmpa2_t addr;
+ vmpa2t addr;
} py_vmpa_t;
@@ -47,11 +50,20 @@ typedef struct _py_vmpa_t
/* Fournit une représentation d'une variable 'vmpa_t'. */
static PyObject *py_vmpa_to_str(PyObject *);
+/* Effectue une conversion d'un objet Python en type 'vmpa_t'. */
+static PyObject *py_vmpa_richcompare(PyObject *, PyObject *, int);
+/* Fournit une partie du contenu de la position représentée. */
+static PyObject *py_vmpa_get_value(PyObject *, void *);
+/* Définit une partie du contenu de la position représentée. */
+static int py_vmpa_set_value(PyObject *, PyObject *, void *);
+
+/* Crée un nouvel objet Python de type 'vmpa2t'. */
+static PyObject *py_vmpa_new(PyTypeObject *, PyObject *, PyObject *);
/* Effectue une conversion d'un objet Python en type 'vmpa_t'. */
-static bool convert_pyobj_to_vmpa(PyObject *, vmpa2_t *);
+static bool convert_pyobj_to_vmpa(PyObject *, vmpa2t *);
/* Effectue une opération de type 'add' avec le type 'vmpa'. */
static PyObject *py_vmpa_nb_add(PyObject *, PyObject *);
@@ -60,6 +72,8 @@ static PyObject *py_vmpa_nb_add(PyObject *, PyObject *);
+
+
/******************************************************************************
* *
* Paramètres : obj = objet Python à traiter. *
@@ -74,15 +88,234 @@ static PyObject *py_vmpa_nb_add(PyObject *, PyObject *);
static PyObject *py_vmpa_to_str(PyObject *obj)
{
- vmpa2_t *addr;
+ PyObject *result; /* Chaîne à retourner */
+ vmpa2t *addr; /* Véritable adresse manipulée */
+ off_t physical; /* Position physique */
+ uint64_t virtual; /* Adresse virtuelle */
addr = &((py_vmpa_t *)obj)->addr;
- return PyUnicode_FromFormat("<phy=%d, virt=0x%08x>", addr->physical, addr->virtual);
+ physical = get_phy_addr(addr);
+ virtual = get_virt_addr(addr);
+
+ if (physical == VMPA_NO_PHYSICAL && virtual == VMPA_NO_VIRTUAL)
+ result = PyUnicode_FromFormat("<phy=None, virt=None>");
+
+ else if (physical != VMPA_NO_PHYSICAL && virtual == VMPA_NO_VIRTUAL)
+ result = PyUnicode_FromFormat("<phy=%d, virt=None>", physical);
+
+ else if (physical == VMPA_NO_PHYSICAL && virtual != VMPA_NO_VIRTUAL)
+ result = PyUnicode_FromFormat("<phy=None, virt=0x%08x>", virtual);
+
+ else
+ result = PyUnicode_FromFormat("<phy=%d, virt=0x%08x>", physical, virtual);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : obj = objet Python à tenter de convertir. *
+* addr = structure équivalente pour Chrysalide. *
+* *
+* Description : Effectue une conversion d'un objet Python en type 'vmpa_t'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_vmpa_richcompare(PyObject *a, PyObject *b, int op)
+{
+ PyObject *result; /* Chaîne à retourner */
+ vmpa2t *addr_a; /* Première adresse à traiter */
+ vmpa2t addr_b; /* Seconde adresse à traiter */
+
+ addr_a = &((py_vmpa_t *)a)->addr;
+
+ if (!convert_pyobj_to_vmpa(b, &addr_b))
+ return NULL;
+
+ switch (op)
+ {
+ case Py_EQ:
+ result = are_equal(addr_a, &addr_b) ? Py_True : Py_False;
+ break;
+
+ case Py_NE:
+ result = are_equal(addr_a, &addr_b) ? Py_False : Py_True;
+ break;
+
+ default:
+ result = Py_NotImplemented;
+ break;
+
+ }
+
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = définition d'adresse visée par la procédure. *
+* closure = sélection de la valeur à traiter. *
+* *
+* Description : Fournit une partie du contenu de la position représentée. *
+* *
+* Retour : Nombre positif ou nul ou None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_vmpa_get_value(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ py_vmpa_t *vmpa; /* Véritable objet Python */
+ char *key; /* Contenu à cibler précisément*/
+
+ vmpa = (py_vmpa_t *)self;
+
+ key = (char *)closure;
+
+ if (strcmp(key, "phy") == 0)
+ {
+ if (get_phy_addr(&vmpa->addr) == VMPA_NO_PHYSICAL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else result = Py_BuildValue("K", get_phy_addr(&vmpa->addr));
+ }
+ else
+ {
+ if (get_virt_addr(&vmpa->addr) == VMPA_NO_VIRTUAL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else result = Py_BuildValue("K", get_virt_addr(&vmpa->addr));
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = définition d'adresse visée par la procédure. *
+* value = valeur fournie à intégrer ou prendre en compte. *
+* closure = sélection de la valeur à traiter. *
+* *
+* Description : Définit une partie du contenu de la position représentée. *
+* *
+* Retour : Bilan de l'opération pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_vmpa_set_value(PyObject *self, PyObject *value, void *closure)
+{
+ int result; /* Bilan à faire remonter */
+ py_vmpa_t *vmpa; /* Véritable objet Python */
+ char *key; /* Contenu à cibler précisément*/
+ PY_LONG_LONG val; /* Valeur traduite génériquemt */
+ int overflow; /* Détection d'une grosse val. */
+
+ result = 0;
+
+ vmpa = (py_vmpa_t *)self;
+
+ key = (char *)closure;
+
+ if (strcmp(key, "phy") == 0)
+ {
+ if (value == Py_None)
+ init_vmpa(&vmpa->addr, VMPA_NO_PHYSICAL, get_virt_addr(&vmpa->addr));
+
+ else
+ {
+ val = PyLong_AsLongLongAndOverflow(value, &overflow);
+
+ if (val == -1 && (overflow == 1 || PyErr_Occurred()))
+ {
+ result = -1;
+ PyErr_Clear();
+ }
+ else init_vmpa(&vmpa->addr, val, get_virt_addr(&vmpa->addr));
+
+ }
+
+ }
+ else
+ {
+ if (value == Py_None)
+ init_vmpa(&vmpa->addr, get_phy_addr(&vmpa->addr), VMPA_NO_VIRTUAL);
+
+ else
+ {
+ val = PyLong_AsLongLongAndOverflow(value, &overflow);
+
+ if (val == -1 && (overflow == 1 || PyErr_Occurred()))
+ {
+ result = -1;
+ PyErr_Clear();
+ }
+ else init_vmpa(&vmpa->addr, get_phy_addr(&vmpa->addr), val);
+
+ }
+
+ }
+
+ 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 'vmpa2t'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_vmpa_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ py_vmpa_t *result; /* Instance à retourner */
+ unsigned long long phy; /* Position physique */
+ unsigned long long virt; /* Adresse en mémoire virtuelle*/
+ int ret; /* Bilan de lecture des args. */
+
+ phy = VMPA_NO_PHYSICAL;
+ virt = VMPA_NO_VIRTUAL;
+
+ ret = PyArg_ParseTuple(args, "|KK", &phy, &virt);
+ if (!ret) Py_RETURN_NONE;
+
+ result = (py_vmpa_t *)type->tp_alloc(type, 0);
+
+ init_vmpa(&result->addr, phy, virt);
+
+ return (PyObject *)result;
+
+}
+
@@ -101,7 +334,7 @@ static PyObject *py_vmpa_to_str(PyObject *obj)
* *
******************************************************************************/
-static bool convert_pyobj_to_vmpa(PyObject *obj, vmpa2_t *addr)
+static bool convert_pyobj_to_vmpa(PyObject *obj, vmpa2t *addr)
{
bool result; /* Résulats à retourner */
PyTypeObject *py_vmpa_type; /* Type Python pour 'vmpa' */
@@ -161,8 +394,8 @@ static bool convert_pyobj_to_vmpa(PyObject *obj, vmpa2_t *addr)
static PyObject *py_vmpa_nb_add(PyObject *o1, PyObject *o2)
{
PyObject *result; /* Résultat à retourner */
- vmpa2_t addr1; /* Première adresse à traiter */
- vmpa2_t addr2; /* Seconde adresse à traiter */
+ vmpa2t addr1; /* Première adresse à traiter */
+ vmpa2t addr2; /* Seconde adresse à traiter */
PyTypeObject *py_vmpa_type; /* Type Python pour 'vmpa' */
if (!convert_pyobj_to_vmpa(o1, &addr1))
@@ -262,27 +495,47 @@ PyTypeObject *get_python_vmpa_type(void)
binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide;
-
+
unaryfunc nb_index;
*/
};
+ static PyGetSetDef py_vmpa_getseters[] = {
+
+ {
+ "phy", py_vmpa_get_value, py_vmpa_set_value,
+ "Give access to the physical offset of the location", "phy"
+ },
+
+ {
+ "virt", py_vmpa_get_value, py_vmpa_set_value,
+ "Give access to the virtual address of the location", "virt"
+ },
+ { NULL }
+
+ };
+
static PyTypeObject py_vmpa_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.arch.vmpa",
- .tp_basicsize = sizeof(py_vmpa_t),
+ .tp_name = "pychrysalide.arch.vmpa",
+ .tp_basicsize = sizeof(py_vmpa_t),
+
+ .tp_as_number = &py_vmpa_nb_proto,
- .tp_as_number = &py_vmpa_nb_proto,
+ .tp_str = py_vmpa_to_str,
- .tp_str = py_vmpa_to_str,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "Python object for vmpa_t",
- .tp_doc = "Python object for vmpa_t"
+ .tp_richcompare = py_vmpa_richcompare,
+
+ .tp_getset = py_vmpa_getseters,
+ .tp_new = (newfunc)py_vmpa_new
};
@@ -312,8 +565,6 @@ bool register_python_vmpa(PyObject *module)
py_vmpa_type = get_python_vmpa_type();
- py_vmpa_type->tp_new = PyType_GenericNew;
-
if (PyType_Ready(py_vmpa_type) != 0)
return false;