/* OpenIDA - Outil d'analyse de fichiers binaires * py_line.c - intermédiaire des lignes de représentation pour Python * * Copyright (C) 2009 Cyrille Bagard * * This file is part of OpenIDA. * * OpenIDA 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. * * OpenIDA 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 "py_line.h" #include #include "../../../src/analysis/line_code.h" #include "py_line-int.h" #include "py_line_code.h" #define _(str) str /* Prépare un parcours de lignes. */ static PyObject *pyline_get_iter(PyLine *); /* ---------------------- ITERATEUR POUR LE PARCOURS DE LIGNES ---------------------- */ /* Itérateur pour lignes de rendu */ typedef struct _PyLineIter { PyObject_HEAD /* A laisser en premier */ GRenderingLine *head; /* Liste à parcourir */ GRenderingLine *cur; /* Point de parcours courant */ } PyLineIter; /* Fournit la description de l'itérateur 'PyLine' pour Python. */ static PyTypeObject *pylineiter_get_type(void); /* Prépare l'itérateur pour un parcours de lignes de rendu. */ static PyObject *pylineiter_new(GRenderingLine *); /* Libère la mémoire occupée par un itérateur de 'PyLine'. */ static void pylineiter_dealloc(PyLineIter *); /* Fournit l'élément suivant dans un parcours de lignes. */ static PyObject *pylineiter_get_next(PyLineIter *); /* ---------------------- EQUIVALENT PYTHON DES LIGNES DE CODE ---------------------- */ /* Représentation Python d'une ligne de code */ typedef struct _PyCodeLine { PyLine base; /* A laisser en premier */ } PyCodeLine; static void pyline_dealloc(PyLine *self) { #if 0 Py_XDECREF(self->first); Py_XDECREF(self->last); #endif //printf("dealloc\n"); g_object_set_data(G_OBJECT(self->line), "pyline", NULL); self->ob_type->tp_free((PyObject*)self); //Py_TYPE(self)->tp_free((PyObject*)self); //printf("dealloc::end\n"); } static PyObject * pyline_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyLine *self; printf("creating a new line\n"); self = (PyLine *)type->tp_alloc(type, 0); if (self != NULL) { #if 0 self->first = PyString_FromString("");//PyUnicode_FromString(""); if (self->first == NULL) { Py_DECREF(self); return NULL; } self->last = PyString_FromString("");//PyUnicode_FromString(""); if (self->last == NULL) { Py_DECREF(self); return NULL; } self->number = 0; #endif } return (PyObject *)self; } /****************************************************************************** * * * Paramètres : head = ???? * * line = modèle à représenter en Python. * * * * Description : Initialise le greffon permettant l'usage de Python. * * * * Retour : Nouvelle instance d'objet Python ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ PyObject *pyline_new_from_existing(GRenderingLine *head, GRenderingLine *line) { PyLine *result; /* Nouvelle instance à renvoyer*/ PyTypeObject *type; /* Type d'objet à créer */ result = (PyLine *)g_object_get_data(G_OBJECT(line), "pyline"); if (result == NULL) { if (G_IS_CODE_LINE(line)) result = pycodeline_new_from_existing(head, line); else { type = pyline_get_type(); result = (PyLine *)type->tp_alloc(type, 0); if (result != NULL) { result->head = head; result->line = line; g_object_set_data(G_OBJECT(line), "pyline", result); } } } return (PyObject *)result; } static int pyline_init(PyLine *self, PyObject *args, PyObject *kwds) { #if 0 PyObject *first=NULL, *last=NULL, *tmp; static char *kwlist[] = {"first", "last", "number", NULL}; printf("pyline_init\n"); if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, &first, &last, &self->number)) return -1; if (first) { tmp = self->first; Py_INCREF(first); self->first = first; Py_DECREF(tmp); } if (last) { tmp = self->last; Py_INCREF(last); self->last = last; Py_DECREF(tmp); } #endif return 0; } /****************************************************************************** * * * Paramètres : self = instance à initialiser. * * head = ???? * * line = modèle à représenter en Python. * * * * Description : Initialise le greffon permettant l'usage de Python. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void pyline_init_from_existing(PyLine *self, GRenderingLine *head, GRenderingLine *line) { self->head = head; self->line = line; self->address = get_rendering_line_address(self->line); } /****************************************************************************** * * * Paramètres : self = instance manipulée à traiter. * * * * Description : Prépare un parcours de lignes. * * * * Retour : Point de départ d'un parcours. * * * * Remarques : - * * * ******************************************************************************/ static PyObject *pyline_get_iter(PyLine *self) { return (PyObject *)pylineiter_new(self->head); } #if 0 static PyObject * pyline_name(pyline* self) { static PyObject *format = NULL; PyObject *args, *result; if (format == NULL) { format = PyString_FromString("%s %s");//PyUnicode_FromString("%s %s"); if (format == NULL) return NULL; } args = Py_BuildValue("OO", self->first, self->last); if (args == NULL) return NULL; result = PyUnicode_Format(format, args); Py_DECREF(args); return result; } #endif /****************************************************************************** * * * Paramètres : - * * * * Description : Fournit la description du type 'PyLine' pour Python. * * * * Retour : Adresse de la description du type 'line'. * * * * Remarques : - * * * ******************************************************************************/ PyTypeObject *pyline_get_type(void) { static PyMethodDef pyline_methods[] = { #if 0 {"name", (PyCFunction)pyline_name, METH_NOARGS, "Return the name, combining the first and last name" }, #endif { NULL } }; static PyMemberDef pyline_members[] = { { "address", T_ULONGLONG, offsetof(PyLine, address), READONLY, "physical or virtual address relative to the line." }, { NULL } }; static PyTypeObject result = { PyObject_HEAD_INIT(NULL) #if PY_VERSION_HEX < 0x03000000 0, /*ob_size*/ #endif "noddy.pyline", /* tp_name */ sizeof(PyLine), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pyline_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved / tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ "PyLine objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ (getiterfunc)pyline_get_iter, /* tp_iter */ 0, /* tp_iternext */ pyline_methods, /* tp_methods */ pyline_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)pyline_init, /* tp_init */ 0, /* tp_alloc */ pyline_new, /* tp_new */ }; return &result; } /****************************************************************************** * * * Paramètres : module = module dont la définition est à compléter. * * * * Description : Ajoute l'objet 'line' au module Python. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ bool add_line_to_python_module(PyObject *module) { int ret; /* Bilan d'un appel */ if (PyType_Ready(pyline_get_type()) < 0) return false; if (PyType_Ready(pylineiter_get_type()) < 0) return false; printf("Adding line type\n"); Py_INCREF(pyline_get_type()); PyModule_AddObject(module, "line", (PyObject *)pyline_get_type()); Py_INCREF(pylineiter_get_type()); PyModule_AddObject(module, "lineiter", (PyObject *)pylineiter_get_type()); return true; /* FIXME */ } /* ---------------------------------------------------------------------------------- */ /* ITERATEUR POUR LE PARCOURS DE LIGNES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : - * * * * Description : Fournit la description de l'itérateur 'PyLine' pour Python. * * * * Retour : Adresse de la description du type 'PyLineIter'. * * * * Remarques : - * * * ******************************************************************************/ static PyTypeObject *pylineiter_get_type(void) { static PyTypeObject result = { PyObject_HEAD_INIT(NULL) #if PY_VERSION_HEX < 0x03000000 0, /* ob_size */ #endif "pyoida.analysis.PyLineIter", /* tp_name */ sizeof(PyLineIter), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pylineiter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved / tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "PyLineIter objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)pylineiter_get_next, /* tp_iternext */ 0, /* tp_methods */ }; return &result; } /****************************************************************************** * * * Paramètres : head = liste à parcourir. * * * * Description : Prépare l'itérateur pour un parcours de lignes de rendu. * * * * Retour : Instance d'itérateur prête à emploi. * * * * Remarques : - * * * ******************************************************************************/ static PyObject *pylineiter_new(GRenderingLine *head) { PyLineIter *result; /* Nouvelle instance à renvoyer*/ PyTypeObject *type; /* Type d'objet à créer */ type = pylineiter_get_type(); result = (PyLineIter *)type->tp_alloc(type, 0); if (result != NULL) { result->head = head; result->cur = NULL; } return (PyObject *)result; } /****************************************************************************** * * * Paramètres : self = instance d'objet à supprimer. * * * * Description : Libère la mémoire occupée par un itérateur de 'PyLine'. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void pylineiter_dealloc(PyLineIter *self) { #if PY_VERSION_HEX < 0x03000000 self->ob_type->tp_free((PyObject *)self); #else Py_TYPE(self)->tp_free((PyObject *)self); #endif } /****************************************************************************** * * * Paramètres : self = instance manipulée à traiter. * * * * Description : Fournit l'élément suivant dans un parcours de lignes. * * * * Retour : Point suivant du parcours ou NULL. * * * * Remarques : - * * * ******************************************************************************/ static PyObject *pylineiter_get_next(PyLineIter *self) { PyObject *result; /* Elément à retourner */ GRenderingLine *next; /* Elément réel suivant */ if (self->cur == NULL) next = self->head; else next = g_rendering_line_get_next_iter(self->head, self->cur, NULL); if (next != NULL) { self->cur = next; result = pyline_new_from_existing(self->head, next); } else result = NULL; return (PyObject *)result; }