diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/pychrysa/arch/vmpa.c | 283 |
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; |