From 5de93a90f20b9ce35d4799d521029f2fde5c6441 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 10 Apr 2020 00:23:49 +0200 Subject: Created extra flags for binary symbols. --- plugins/pychrysalide/format/constants.c | 14 +++ plugins/pychrysalide/format/symbol.c | 198 ++++++++++++++++++++++++++++++++ src/format/symbol-int.h | 1 + src/format/symbol.c | 133 ++++++++++++++++++++- src/format/symbol.h | 23 +++- tests/format/symbol.py | 43 ++++++- 6 files changed, 402 insertions(+), 10 deletions(-) diff --git a/plugins/pychrysalide/format/constants.c b/plugins/pychrysalide/format/constants.c index 4ffdc5f..dfa4615 100644 --- a/plugins/pychrysalide/format/constants.c +++ b/plugins/pychrysalide/format/constants.c @@ -85,6 +85,20 @@ bool define_binary_symbol_constants(PyTypeObject *type) result = attach_constants_group_to_type(type, false, "SymbolStatus", values, "Status of a symbol visibility."); + values = PyDict_New(); + + result = add_const_to_group(values, "NONE", SFL_NONE); + if (result) result = add_const_to_group(values, "PREFIXED_NAME", SFL_PREFIXED_NAME); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, true, "SymbolFlag", values, + "Extra indications for symbols."); + exit: return result; diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c index c67d6e7..75eb8f4 100644 --- a/plugins/pychrysalide/format/symbol.c +++ b/plugins/pychrysalide/format/symbol.c @@ -72,6 +72,15 @@ static int py_binary_symbol_init(PyObject *, PyObject *, PyObject *); /* Effectue une comparaison avec un objet Python 'BinSymbol'. */ static PyObject *py_binary_symbol_richcompare(PyObject *, PyObject *, int); +/* Ajoute une information complémentaire à un symbole. */ +static PyObject *py_binary_symbol_set_flag(PyObject *, PyObject *); + +/* Retire une information complémentaire à un symbole. */ +static PyObject *py_binary_symbol_unset_flag(PyObject *, PyObject *); + +/* Détermine si un symbole possède un fanion particulier. */ +static PyObject *py_binary_symbol_has_flag(PyObject *, PyObject *); + /* Fournit l'emplacement où se situe un symbole. */ static PyObject *py_binary_symbol_get_range(PyObject *, void *); @@ -93,6 +102,9 @@ static PyObject *py_binary_symbol_get_status(PyObject *, void *); /* Définit la visibilité du symbole. */ static int py_binary_symbol_set_status(PyObject *, PyObject *, void *); +/* Fournit les particularités du symbole. */ +static PyObject *py_binary_symbol_get_flags(PyObject *, void *); + /* Définit un autre nom pour le symbole. */ static int py_binary_symbol_set_label(PyObject *, PyObject *, void *); @@ -343,6 +355,152 @@ static PyObject *py_binary_symbol_richcompare(PyObject *a, PyObject *b, int op) /****************************************************************************** * * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Ajoute une information complémentaire à un symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_symbol_set_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + unsigned int flag; /* Propriété à traiter */ + int ret; /* Bilan de lecture des args. */ + GBinSymbol *symbol; /* Elément à manipuler */ + bool status; /* Bilan de l'opération */ + +#define BINARY_SYMBOL_SET_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + set_flag, "$self, flag, /", \ + METH_VARARGS, py_binary_symbol, \ + "Add a property from a binary symbol.\n" \ + "\n" \ + "This property is one of the values listed in the" \ + " of pychrysalide.format.BinSymbol.SymbolFlag enumeration.\n" \ + "\n" \ + "If the flag was not set before the operation, True is" \ + " returned, else the result is False." \ +) + + ret = PyArg_ParseTuple(args, "I", &flag); + if (!ret) return NULL; + + symbol = G_BIN_SYMBOL(pygobject_get(self)); + + status = g_binary_symbol_set_flag(symbol, flag); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Retire une information complémentaire à un symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_symbol_unset_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + unsigned int flag; /* Propriété à traiter */ + int ret; /* Bilan de lecture des args. */ + GBinSymbol *symbol; /* Elément à manipuler */ + bool status; /* Bilan de l'opération */ + +#define BINARY_SYMBOL_UNSET_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + unset_flag, "$self, flag, /", \ + METH_VARARGS, py_binary_symbol, \ + "Remove a property from a binary symbol.\n" \ + "\n" \ + "This property is one of the values listed in the" \ + " of pychrysalide.format.BinSymbol.SymbolFlag enumeration.\n" \ + "\n" \ + "If the flag was not set before the operation, False is" \ + " returned, else the result is True." \ +) + + ret = PyArg_ParseTuple(args, "I", &flag); + if (!ret) return NULL; + + symbol = G_BIN_SYMBOL(pygobject_get(self)); + + status = g_binary_symbol_unset_flag(symbol, flag); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Détermine si un symbole possède un fanion particulier. * +* * +* Retour : Bilan de la détection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_symbol_has_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + unsigned int flag; /* Propriété à traiter */ + int ret; /* Bilan de lecture des args. */ + GBinSymbol *symbol; /* Elément à manipuler */ + bool status; /* Bilan de l'opération */ + +#define BINARY_SYMBOL_HAS_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + has_flag, "$self, flag, /", \ + METH_VARARGS, py_binary_symbol, \ + "Test if a binary symbol has a given property.\n" \ + "\n" \ + "This property is one of the values listed in the" \ + " of pychrysalide.format.BinSymbol.SymbolFlag enumeration.\n" \ + "\n" \ + "The result is a boolean value." \ +) + + ret = PyArg_ParseTuple(args, "I", &flag); + if (!ret) return NULL; + + symbol = G_BIN_SYMBOL(pygobject_get(self)); + + status = g_binary_symbol_has_flag(symbol, flag); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -553,6 +711,42 @@ static int py_binary_symbol_set_status(PyObject *self, PyObject *value, void *cl * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * +* Description : Fournit les particularités du symbole. * +* * +* Retour : Somme de tous les fanions associés au symbole. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_binary_symbol_get_flags(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBinSymbol *symbol; /* Elément à consulter */ + SymbolFlag flags; /* Indications complémentaires */ + +#define BINARY_SYMBOL_FLAGS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + flags, py_binary_symbol, \ + "Provide all the flags set for a symbol. The return value" \ + " is of type pychrysalide.format.BinSymbol.SymbolFlag." \ +) + + symbol = G_BIN_SYMBOL(pygobject_get(self)); + flags = g_binary_symbol_get_flags(symbol); + + result = cast_with_constants_group_from_type(get_python_binary_symbol_type(), "SymbolFlag", flags); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * * Description : Fournit un étiquette pour viser un symbole. * * * * Retour : Chaîne de caractères renvoyant au symbole. * @@ -647,6 +841,9 @@ static int py_binary_symbol_set_label(PyObject *self, PyObject *value, void *clo PyTypeObject *get_python_binary_symbol_type(void) { static PyMethodDef binary_symbol_methods[] = { + BINARY_SYMBOL_SET_FLAG_METHOD, + BINARY_SYMBOL_UNSET_FLAG_METHOD, + BINARY_SYMBOL_HAS_FLAG_METHOD, { NULL } }; @@ -654,6 +851,7 @@ PyTypeObject *get_python_binary_symbol_type(void) BINARY_SYMBOL_RANGE_ATTRIB, BINARY_SYMBOL_STYPE_ATTRIB, BINARY_SYMBOL_STATUS_ATTRIB, + BINARY_SYMBOL_FLAGS_ATTRIB, BINARY_SYMBOL_LABEL_ATTRIB, { NULL } }; diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h index e2c3292..77ffd39 100644 --- a/src/format/symbol-int.h +++ b/src/format/symbol-int.h @@ -41,6 +41,7 @@ typedef union _sym_obj_extra { SymbolType stype; /* Type du symbole */ SymbolStatus status; /* Visibilité du symbole */ + SymbolFlag flags; /* Informations complémentaires*/ }; diff --git a/src/format/symbol.c b/src/format/symbol.c index c10c46d..7d272ce 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -68,7 +68,7 @@ static void g_binary_symbol_compute_cursor(const GBinSymbol *, gint, size_t, siz static int g_binary_symbol_contains_cursor(const GBinSymbol *, size_t, size_t, const GLineCursor *); /* Renseigne sur les propriétés liées à un générateur. */ -static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *, size_t, size_t); +static BufferLineFlags g_binary_symbol_get_line_flags(const GBinSymbol *, size_t, size_t); /* Imprime dans une ligne de rendu le contenu représenté. */ static void g_binary_symbol_print(GBinSymbol *, GBufferLine *, size_t, size_t, const GBinContent *); @@ -149,7 +149,7 @@ static void g_binary_symbol_interface_init(GLineGeneratorInterface *iface) iface->count = (linegen_count_lines_fc)g_binary_symbol_count_lines; iface->compute = (linegen_compute_fc)g_binary_symbol_compute_cursor; iface->contains = (linegen_contains_fc)g_binary_symbol_contains_cursor; - iface->get_flags = (linegen_get_flags_fc)g_binary_symbol_get_flags; + iface->get_flags = (linegen_get_flags_fc)g_binary_symbol_get_line_flags; iface->print = (linegen_print_fc)g_binary_symbol_print; } @@ -433,6 +433,133 @@ SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol) /****************************************************************************** * * +* Paramètres : symbol = symbole à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Ajoute une information complémentaire à un symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_symbol_set_flag(GBinSymbol *symbol, SymbolFlag flag) +{ + bool result; /* Bilan à retourner */ + sym_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_BIN_SYMBOL_EXTRA(symbol); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = !(extra->flags & flag); + + extra->flags |= flag; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir modifier. * +* flag = drapeau d'information complémentaire à planter. * +* * +* Description : Retire une information complémentaire à un symbole. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_symbol_unset_flag(GBinSymbol *symbol, SymbolFlag flag) +{ + bool result; /* Bilan à retourner */ + sym_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_BIN_SYMBOL_EXTRA(symbol); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = (extra->flags & flag); + + extra->flags &= ~flag; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir consulter. * +* flag = drapeau d'information à rechercher. * +* * +* Description : Détermine si un symbole possède un fanion particulier. * +* * +* Retour : Bilan de la détection. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_binary_symbol_has_flag(const GBinSymbol *symbol, SymbolFlag flag) +{ + bool result; /* Bilan à retourner */ + sym_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_BIN_SYMBOL_EXTRA(symbol); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = (extra->flags & flag); + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : symbol = symbole à venir consulter. * +* * +* Description : Fournit les particularités du symbole. * +* * +* Retour : Somme de tous les fanions associés au symbole. * +* * +* Remarques : - * +* * +******************************************************************************/ + +SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *symbol) +{ + SymbolFlag result; /* Fanions à retourner */ + sym_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_BIN_SYMBOL_EXTRA(symbol); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = extra->flags; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : symbol = symbole à venir consulter. * * * * Description : Fournit une étiquette pour viser un symbole. * @@ -626,7 +753,7 @@ static int g_binary_symbol_contains_cursor(const GBinSymbol *symbol, size_t inde * * ******************************************************************************/ -static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *symbol, size_t index, size_t repeat) +static BufferLineFlags g_binary_symbol_get_line_flags(const GBinSymbol *symbol, size_t index, size_t repeat) { return BLF_IS_LABEL; diff --git a/src/format/symbol.h b/src/format/symbol.h index 48f740e..e304d69 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -50,7 +50,6 @@ typedef enum _SymbolType } SymbolType; - /* Visibilité du symbole */ typedef enum _SymbolStatus { @@ -63,6 +62,16 @@ typedef enum _SymbolStatus } SymbolStatus; +/* Indications supplémentaires liées aux symboles */ +typedef enum _SymbolFlag +{ + SFL_NONE = (0 << 0), /* Aucune propriété */ + SFL_PREFIXED_NAME = (1 << 0), /* Indication en amont du nom */ + + SFL_COUNT + +} SymbolFlag; + #define G_TYPE_BIN_SYMBOL g_binary_symbol_get_type() #define G_BIN_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BIN_SYMBOL, GBinSymbol)) @@ -109,6 +118,18 @@ void g_binary_symbol_set_status(GBinSymbol *, SymbolStatus); /* Fournit la visibilité du symbole. */ SymbolStatus g_binary_symbol_get_status(const GBinSymbol *); +/* Ajoute une information complémentaire à un symbole. */ +bool g_binary_symbol_set_flag(GBinSymbol *, SymbolFlag); + +/* Retire une information complémentaire à un symbole. */ +bool g_binary_symbol_unset_flag(GBinSymbol *, SymbolFlag); + +/* Détermine si un symbole possède un fanion particulier. */ +bool g_binary_symbol_has_flag(const GBinSymbol *, SymbolFlag); + +/* Fournit les particularités du symbole. */ +SymbolFlag g_binary_symbol_get_flags(const GBinSymbol *); + /* Fournit une étiquette pour viser un symbole. */ char *g_binary_symbol_get_label(const GBinSymbol *); diff --git a/tests/format/symbol.py b/tests/format/symbol.py index 6c4f573..fed4133 100644 --- a/tests/format/symbol.py +++ b/tests/format/symbol.py @@ -17,7 +17,7 @@ class TestBinarySymbols(ChrysalideTestCase): def testSymbolProperties(self): """Validate the basic properties of symbols.""" - saddr = vmpa(0x10, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x10, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x3) symbol = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) @@ -53,7 +53,7 @@ class TestBinarySymbols(ChrysalideTestCase): def testSymbolDefaultStatus(self): """Validate the default status for symbols.""" - saddr = vmpa(0x10, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x10, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x3) symbol = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) @@ -62,18 +62,49 @@ class TestBinarySymbols(ChrysalideTestCase): self.assertEqual(str(symbol.status), 'SymbolStatus.INTERNAL') + def testSymbolFlags(self): + """Play with symbol flags.""" + + saddr = vmpa(0x10, vmpa.VmpaSpecialValue.NO_VIRTUAL) + srange = mrange(saddr, 0x3) + symbol = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) + + self.assertEqual(symbol.flags, BinSymbol.SymbolFlag.NONE) + + ret = symbol.set_flag(BinSymbol.SymbolFlag.NONE) + self.assertTrue(ret) + + ret = symbol.has_flag(BinSymbol.SymbolFlag.NONE) + self.assertFalse(ret) + + ret = symbol.unset_flag(BinSymbol.SymbolFlag.NONE) + self.assertFalse(ret) + + ret = symbol.set_flag(BinSymbol.SymbolFlag.PREFIXED_NAME) + self.assertTrue(ret) + + ret = symbol.has_flag(BinSymbol.SymbolFlag.PREFIXED_NAME) + self.assertTrue(ret) + + ret = symbol.unset_flag(BinSymbol.SymbolFlag.PREFIXED_NAME) + self.assertTrue(ret) + + ret = symbol.has_flag(BinSymbol.SymbolFlag.PREFIXED_NAME) + self.assertFalse(ret) + + def testSymbolComparison(self): """Compare symbols and check the result.""" - saddr = vmpa(0x100, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x100, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x3) symbol0 = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) - saddr = vmpa(0x10, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x10, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x3) symbol1 = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) - saddr = vmpa(0x100, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x100, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x30) symbol2 = BinSymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) @@ -93,7 +124,7 @@ class TestBinarySymbols(ChrysalideTestCase): def _get_label(self): return 'AAA' - saddr = vmpa(0x100, vmpa.VMPA_NO_VIRTUAL) + saddr = vmpa(0x100, vmpa.VmpaSpecialValue.NO_VIRTUAL) srange = mrange(saddr, 0x3) symbol = MySymbol(srange, BinSymbol.SymbolType.ENTRY_POINT) -- cgit v0.11.2-87-g4458