diff options
Diffstat (limited to 'plugins/pychrysalide/constval.c')
-rw-r--r-- | plugins/pychrysalide/constval.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/plugins/pychrysalide/constval.c b/plugins/pychrysalide/constval.c new file mode 100644 index 0000000..b6d20aa --- /dev/null +++ b/plugins/pychrysalide/constval.c @@ -0,0 +1,300 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constval.c - conversion de constantes C en équivalent Python + * + * Copyright (C) 2018 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 "constval.h" + + +#include <longintrepr.h> + + +#include <i18n.h> + + +#include "access.h" +#include "helpers.h" + + + +/* Objet à vocation interne */ +typedef struct _PyConstvalObject +{ + PyLongObject base; /* A laisser en premier */ + + /** + * Le champ suivant est rajouté à la fin de l'allocation + * de l'objet PyLongObject, dont la taille est dynamique. + */ + + /*const char *name;*/ /* Désignation de la valeur */ + +} PyConstvalObject; + + + +/* Interdit la création d'une instance depuis Python. */ +static PyObject *py_constval_new(PyTypeObject *, PyObject *, PyObject *); + +/* Calcule l'emplacement reservé pour une désignation de valeur. */ +static const char **py_constval_compute_name_ptr(PyConstvalObject *); + +/* Construit une représentation textuelle de l'objet. */ +static PyObject *py_constval_str(PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : type = type du nouvel objet à mettre en place. * +* args = éventuelle liste d'arguments. * +* kwds = éventuel dictionnaire de valeurs mises à disposition. * +* * +* Description : Interdit la création d'une instance depuis Python. * +* * +* Retour : NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_constval_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyErr_Format(PyExc_RuntimeError, _("%s is meant to be only used from C code"), type->tp_name); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : self = valeur constante C convertie en Python. * +* * +* Description : Calcule l'emplacement reservé pour une désignation de valeur.* +* * +* Retour : Pointeur vers l'adresse de désignation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char **py_constval_compute_name_ptr(PyConstvalObject *self) +{ + digit *result; /* Adresse mémoire à retourner */ + Py_ssize_t size; /* Taille supplémentaire */ + + size = Py_SIZE(&self->base); + + if (size < 0) + size = -size; + + result = &self->base.ob_digit[size]; + + return (const char **)result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = valeur constante C convertie en Python. * +* * +* Description : Construit une représentation textuelle de l'objet. * +* * +* Retour : Chaîne de caractère Unicode. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_constval_str(PyObject *self) +{ + PyObject *result; /* Elément à retourner */ + PyConstvalObject *constval; /* Autre version de l'objet */ + const char **ptr; /* Désignation à convertir */ + + constval = (PyConstvalObject *)self; + + ptr = py_constval_compute_name_ptr(constval); + + result = PyUnicode_FromString(*ptr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_py_constval_type(void) +{ + static PyMethodDef py_constval_methods[] = { + { NULL } + }; + + static PyGetSetDef py_constval_getseters[] = { + { NULL } + }; + + static PyTypeObject py_constval_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.PyConstvalObject", + .tp_basicsize = offsetof(PyLongObject, ob_digit), + .tp_itemsize = sizeof(digit), + + .tp_str = py_constval_str, + + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + + .tp_doc = "PyChrysalide object for C constant values", + + .tp_methods = py_constval_methods, + .tp_getset = py_constval_getseters, + .tp_base = &PyLong_Type, + + .tp_new = py_constval_new, + + }; + + return &py_constval_type; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Prend en charge l'objet 'pychrysalide.PyConstvalObject'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool ensure_python_py_constval_is_registered(void) +{ + PyTypeObject *type; /* Type Python 'PyConstval...' */ + PyObject *module; /* Module à recompléter */ + + type = get_python_py_constval_type(); + + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide"); + + if (PyType_Ready(type) != 0) + return false; + + if (!register_python_module_object(module, type)) + return false; + + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation de la constante à représenter. * +* value = valeur de la constante à représenter. * +* * +* Description : Construit un objet pour valeur constante en C. * +* * +* Retour : Object Python résultant de la construction opérée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *build_constval_from_c_code(const char *name, unsigned long value) +{ + PyObject *result; /* Instance à retourner */ + PyLongObject *tmp; /* Construction temporaire */ + Py_ssize_t size; /* Taille supplémentaire */ + PyTypeObject *type; /* Type Python 'PyConstval...' */ + PyConstvalObject *constval; /* Autre version de l'objet */ + const char **ptr; /* Désignation à convertir */ + + /* Création d'une base de travail */ + + tmp = (PyLongObject *)PyLong_FromUnsignedLong(value); + + size = Py_SIZE(tmp); + + if (size < 0) + size = -size; + + /** + * En allouant 2 éléments "digit" supplémentaires, on est assuré + * de disposer de l'espace nécessaire pour la conservation + * d'un pointeur. + */ + + result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + (size + 2) * sizeof(digit)); + + if (!result) + { + PyErr_NoMemory(); + return NULL; + } + + type = get_python_py_constval_type(); + + result = PyObject_INIT_VAR(result, type, size); + + /* Copie de la valeur */ + + Py_SIZE(result) = Py_SIZE(tmp); + + constval = (PyConstvalObject *)result; + + while (--size >= 0) + constval->base.ob_digit[size] = tmp->ob_digit[size]; + + Py_DECREF(tmp); + + /* Copie de la désignation */ + + ptr = py_constval_compute_name_ptr(constval); + + *ptr = name; + + return result; + +} |