From 1e30e2c3822f55848e2306e59a2e66d7285f6b78 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 24 Jun 2024 23:55:03 +0200 Subject: Create functions suitable for [un]setting only one bit. --- plugins/pychrysalide/Makefile.am | 3 +- plugins/pychrysalide/common/Makefile.am | 20 ++++---- plugins/pychrysalide/common/bits.c | 32 +++++++++---- plugins/pychrysalide/common/module.c | 18 ++++---- plugins/pychrysalide/core.c | 6 +-- src/common/Makefile.am | 1 - src/common/bits.c | 82 +++++++++++++++++++++++++++++++-- src/common/bits.h | 10 +++- src/plugins/plugin.c | 2 +- tests/common/bitfield.py | 22 ++++----- 10 files changed, 147 insertions(+), 49 deletions(-) diff --git a/plugins/pychrysalide/Makefile.am b/plugins/pychrysalide/Makefile.am index a6abf7f..8408c96 100644 --- a/plugins/pychrysalide/Makefile.am +++ b/plugins/pychrysalide/Makefile.am @@ -57,6 +57,7 @@ AM_CFLAGS = $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) $(TOOLKIT_CFL pychrysalide_la_LIBADD = \ analysis/libpychrysaanalysis4.la \ arch/libpychrysaarch4.la \ + common/libpychrysacommon.la \ core/libpychrysacore.la \ glibext/libpychrysaglibext.la \ plugins/libpychrysaplugins.la @@ -76,4 +77,4 @@ dev_HEADERS = $(pychrysalide_la_SOURCES:%c=) #SUBDIRS = analysis arch common core debug format glibext $(GTKEXT_SUBDIR) $(GUI_SUBDIR) mangling plugins -SUBDIRS = analysis arch core glibext plugins +SUBDIRS = analysis arch common core glibext plugins diff --git a/plugins/pychrysalide/common/Makefile.am b/plugins/pychrysalide/common/Makefile.am index b5249b9..199ef43 100644 --- a/plugins/pychrysalide/common/Makefile.am +++ b/plugins/pychrysalide/common/Makefile.am @@ -1,16 +1,20 @@ noinst_LTLIBRARIES = libpychrysacommon.la +# libpychrysacommon_la_SOURCES = \ +# bits.h bits.c \ +# fnv1a.h fnv1a.c \ +# hex.h hex.c \ +# itoa.h itoa.c \ +# leb128.h leb128.c \ +# module.h module.c \ +# packed.h packed.c \ +# pathname.h pathname.c \ +# pearson.h pearson.c + libpychrysacommon_la_SOURCES = \ bits.h bits.c \ - fnv1a.h fnv1a.c \ - hex.h hex.c \ - itoa.h itoa.c \ - leb128.h leb128.c \ - module.h module.c \ - packed.h packed.c \ - pathname.h pathname.c \ - pearson.h pearson.c + module.h module.c libpychrysacommon_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c index a127251..35d6ea4 100644 --- a/plugins/pychrysalide/common/bits.c +++ b/plugins/pychrysalide/common/bits.c @@ -534,27 +534,33 @@ static PyObject *py_bitfield_set_all(PyObject *self, PyObject *args) static PyObject *py_bitfield_reset(PyObject *self, PyObject *args) { - unsigned long first; /* Indice du premier bit testé */ unsigned long count; /* Nombre de bits à analyser */ + unsigned long first; /* Indice du premier bit testé */ int ret; /* Bilan de lecture des args. */ py_bitfield_t *bf; /* Instance à manipuler */ #define BITFIELD_RESET_METHOD PYTHON_METHOD_DEF \ ( \ - reset, "$self, first, count, /", \ + reset, "$self, first, /, count=1", \ METH_VARARGS, py_bitfield, \ "Switch to 0 a part of bits in a bitfield.\n" \ "\n" \ "The area to process starts at bit *first* and has a" \ - " size of *count* bits." \ + " size of *count* bits (only one bit is processed if" \ + " no *size* is provided)." \ ) - ret = PyArg_ParseTuple(args, "kk", &first, &count); + count = 1; + + ret = PyArg_ParseTuple(args, "k|k", &first, &count); if (!ret) return NULL; bf = (py_bitfield_t *)self; - reset_in_bit_field(bf->native, first, count); + if (count == 1) + reset_in_bit_field(bf->native, first); + else + reset_multi_in_bit_field(bf->native, first, count); Py_RETURN_NONE; @@ -576,27 +582,33 @@ static PyObject *py_bitfield_reset(PyObject *self, PyObject *args) static PyObject *py_bitfield_set(PyObject *self, PyObject *args) { - unsigned long first; /* Indice du premier bit testé */ unsigned long count; /* Nombre de bits à analyser */ + unsigned long first; /* Indice du premier bit testé */ int ret; /* Bilan de lecture des args. */ py_bitfield_t *bf; /* Instance à manipuler */ #define BITFIELD_SET_METHOD PYTHON_METHOD_DEF \ ( \ - set, "$self, first, count, /", \ + set, "$self, first, /, count=1", \ METH_VARARGS, py_bitfield, \ "Switch to 1 a part of bits in a bitfield.\n" \ "\n" \ "The area to process starts at bit *first* and has a" \ - " size of *count* bits." \ + " size of *count* bits (only one bit is processed if" \ + " no *size* is provided)." \ ) - ret = PyArg_ParseTuple(args, "kk", &first, &count); + count = 1; + + ret = PyArg_ParseTuple(args, "k|k", &first, &count); if (!ret) return NULL; bf = (py_bitfield_t *)self; - set_in_bit_field(bf->native, first, count); + if (count == 1) + set_in_bit_field(bf->native, first); + else + set_multi_in_bit_field(bf->native, first, count); Py_RETURN_NONE; diff --git a/plugins/pychrysalide/common/module.c b/plugins/pychrysalide/common/module.c index a0042ee..5fc1135 100644 --- a/plugins/pychrysalide/common/module.c +++ b/plugins/pychrysalide/common/module.c @@ -26,13 +26,13 @@ #include "bits.h" -#include "fnv1a.h" -#include "hex.h" -#include "itoa.h" -#include "leb128.h" -#include "packed.h" -#include "pathname.h" -#include "pearson.h" +//#include "fnv1a.h" +//#include "hex.h" +//#include "itoa.h" +//#include "leb128.h" +//#include "packed.h" +//#include "pathname.h" +//#include "pearson.h" #include "../helpers.h" @@ -98,15 +98,17 @@ bool populate_common_module(void) result = true; + /* if (result) result = populate_common_module_with_fnv1a(); if (result) result = populate_common_module_with_hex(); if (result) result = populate_common_module_with_itoa(); if (result) result = populate_common_module_with_leb128(); if (result) result = populate_common_module_with_pathname(); if (result) result = populate_common_module_with_pearson(); + */ if (result) result = ensure_python_bitfield_is_registered(); - if (result) result = ensure_python_packed_buffer_is_registered(); + //if (result) result = ensure_python_packed_buffer_is_registered(); assert(result); diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index 4d744c7..8510d78 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -60,8 +60,8 @@ #include "struct.h" #include "analysis/module.h" #include "arch/module.h" +#include "common/module.h" #include "glibext/module.h" -/* #include "common/module.h" */ /* #include "core/module.h" */ /* #include "debug/module.h" */ /* #include "format/module.h" */ @@ -645,9 +645,9 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) if (status) status = add_analysis_module(result); if (status) status = add_arch_module(result); + if (status) status = add_common_module(result); if (status) status = add_glibext_module(result); /* - if (status) status = add_common_module(result); if (status) status = add_core_module(result); if (status) status = add_debug_module(result); if (status) status = add_format_module(result); @@ -669,8 +669,8 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) if (status) status = populate_analysis_module(); if (status) status = populate_arch_module(); if (status) status = populate_glibext_module(); - /* if (status) status = populate_common_module(); + /* if (status) status = populate_core_module(); if (status) status = populate_debug_module(); if (status) status = populate_format_module(); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 27ead1d..0a7475f 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -6,7 +6,6 @@ libcommon_la_SOURCES = \ array.h array.c \ asm.h asm.c \ bconst.h \ - bits.h bits.c \ compression.h compression.c \ cpp.h \ cpu.h cpu.c \ diff --git a/src/common/bits.c b/src/common/bits.c index 37e3141..91872e1 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -442,6 +442,34 @@ void set_all_in_bit_field(bitfield_t *field) * * * Paramètres : field = champ de bits à modifier. * * first = indice du premier bit à traiter. * +* * +* Description : Bascule à 0 une partie d'un champ de bits. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void reset_in_bit_field(bitfield_t *field, size_t first) +{ + size_t index; /* Cellule de tableau visée */ + size_t remaining; /* Nombre de bits restants */ + + assert(first < field->length); + + index = first / (sizeof(unsigned long) * 8); + remaining = first % (sizeof(unsigned long) * 8); + + field->bits[index] &= ~(1ul << remaining); + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à modifier. * +* first = indice du premier bit à traiter. * * count = nombre de bits à marquer. * * * * Description : Bascule à 0 une partie d'un champ de bits. * @@ -452,7 +480,7 @@ void set_all_in_bit_field(bitfield_t *field) * * ******************************************************************************/ -void reset_in_bit_field(bitfield_t *field, size_t first, size_t count) +void reset_multi_in_bit_field(bitfield_t *field, size_t first, size_t count) { size_t last; /* Point d'arrêt de la boucle */ size_t i; /* Boucle de parcours */ @@ -479,6 +507,34 @@ void reset_in_bit_field(bitfield_t *field, size_t first, size_t count) * * * Paramètres : field = champ de bits à modifier. * * first = indice du premier bit à traiter. * +* * +* Description : Bascule à 1 une partie d'un champ de bits. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_in_bit_field(bitfield_t *field, size_t first) +{ + size_t index; /* Cellule de tableau visée */ + size_t remaining; /* Nombre de bits restants */ + + assert(first < field->length); + + index = first / (sizeof(unsigned long) * 8); + remaining = first % (sizeof(unsigned long) * 8); + + field->bits[index] |= (1ul << remaining); + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à modifier. * +* first = indice du premier bit à traiter. * * count = nombre de bits à marquer. * * * * Description : Bascule à 1 une partie d'un champ de bits. * @@ -489,7 +545,7 @@ void reset_in_bit_field(bitfield_t *field, size_t first, size_t count) * * ******************************************************************************/ -void set_in_bit_field(bitfield_t *field, size_t first, size_t count) +void set_multi_in_bit_field(bitfield_t *field, size_t first, size_t count) { size_t last; /* Point d'arrêt de la boucle */ size_t i; /* Boucle de parcours */ @@ -805,9 +861,25 @@ static bool test_state_within_bit_field(const bitfield_t *field, size_t first, c unsigned long bitmask; /* Masque à appliquer */ unsigned long test; /* Valeur résultante du test */ - result = true; + /** + * Si un masque est à appliquer avec débordement, les bits débordés sont considérés + * comme initialisés à la valeur par défaut. + */ + + if ((first + mask->length) > field->length) + { + assert(mask->length > 0); + + result = (state == field->default_state); + if (!result) goto done; - assert((first + mask->length) <= field->length); + if (first >= field->length) + goto done; + + } + + else + result = true; start = first / (sizeof(unsigned long) * 8); offset = first % (sizeof(unsigned long) * 8); @@ -849,6 +921,8 @@ static bool test_state_within_bit_field(const bitfield_t *field, size_t first, c } + done: + return result; } diff --git a/src/common/bits.h b/src/common/bits.h index a66c6f0..3898c73 100644 --- a/src/common/bits.h +++ b/src/common/bits.h @@ -65,10 +65,16 @@ void reset_all_in_bit_field(bitfield_t *); void set_all_in_bit_field(bitfield_t *); /* Bascule à 0 une partie d'un champ de bits. */ -void reset_in_bit_field(bitfield_t *, size_t, size_t); +void reset_in_bit_field(bitfield_t *, size_t); + +/* Bascule à 0 une partie d'un champ de bits. */ +void reset_multi_in_bit_field(bitfield_t *, size_t, size_t); + +/* Bascule à 1 une partie d'un champ de bits. */ +void set_in_bit_field(bitfield_t *, size_t); /* Bascule à 1 une partie d'un champ de bits. */ -void set_in_bit_field(bitfield_t *, size_t, size_t); +void set_multi_in_bit_field(bitfield_t *, size_t, size_t); /* Réalise une opération ET logique entre deux champs de bits. */ void and_bit_field(bitfield_t *, const bitfield_t *); diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index 5b3e475..1dc20e8 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -1015,7 +1015,7 @@ bool g_plugin_module_resolve_dependencies(GPluginModule *plugin, GPluginModule * if (dependency->dependencies == NULL) dependency->dependencies = create_bit_field(count, false); - set_in_bit_field(new, index, 1); + set_in_bit_field(new, index); or_bit_field(new, dependency->dependencies); /** diff --git a/tests/common/bitfield.py b/tests/common/bitfield.py index 75dfb6e..5d535fd 100644 --- a/tests/common/bitfield.py +++ b/tests/common/bitfield.py @@ -93,7 +93,7 @@ class TestBitFields(ChrysalideTestCase): bf_a = BitField(75, 0) bf_b = BitField(4, 1) - bf_b.reset(2, 1) + bf_b.reset(2) bf_a.or_at(bf_b, 63) @@ -130,14 +130,14 @@ class TestBitFields(ChrysalideTestCase): bf_t = BitField(75, 0) for i in range(75): - bf_t.set(i, 1) + bf_t.set(i) self.assertEqual(bf_t, bf_1) self.assertEqual(bf_t.popcount, bf_1.popcount) for i in range(75): - bf_t.reset(i, 1) + bf_t.reset(i) self.assertEqual(bf_t, bf_0) @@ -223,8 +223,8 @@ class TestBitFields(ChrysalideTestCase): """Check bitfield comparison.""" bf_a = BitField(9, 0) - bf_a.set(0, 1) - bf_a.set(5, 1) + bf_a.set(0) + bf_a.set(5) bf_b = BitField(9, 1) @@ -240,7 +240,7 @@ class TestBitFields(ChrysalideTestCase): bits = [ 0, 1, 50, 63, 64, 65, 111 ] for b in bits: - bf.set(b, 1) + bf.set(b) prev = None found = [] @@ -261,17 +261,17 @@ class TestBitFields(ChrysalideTestCase): def testRealCase00(self): - """Test bits in bitfields against other bitfields in a real case (#02).""" + """Test bits in bitfields against other bitfields in a real case (#00).""" bf = BitField(128, 0) for b in [ 0, 50, 54, 58, 66, 70, 98 ]: - bf.set(b, 1) + bf.set(b) mask = BitField(128, 0) for b in [ 0, 51 ]: - mask.set(b, 1) + mask.set(b) self.assertFalse(bf.test_zeros_with(0, mask)) @@ -284,7 +284,7 @@ class TestBitFields(ChrysalideTestCase): self.assertTrue(bf.test_zeros_with(0, mask)) for b in [ 0, 8, 9, 10 ]: - mask.set(b, 1) + mask.set(b) self.assertTrue(bf.test_zeros_with(0, mask)) @@ -305,7 +305,7 @@ class TestBitFields(ChrysalideTestCase): bits = [ 0, 50, 54, 58, 66, 70, 98 ] for b in bits: - mask.set(b, 1) + mask.set(b) bf.or_at(mask, 0) -- cgit v0.11.2-87-g4458