summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-30 17:20:58 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-30 17:20:58 (GMT)
commitdda68634391bea512a7861468fcf45f8292300bb (patch)
treec56c9b1c0bb4500973247eef12ccadaf4ebe346d
parentb8d5a539b1e6837f7395598a3fa25ef69650e885 (diff)
Discriminated between tests for set and unset ranges of bits.
-rw-r--r--ChangeLog13
-rw-r--r--src/analysis/disass/area.c54
-rw-r--r--src/analysis/disass/loop.c2
-rw-r--r--src/common/bits.c234
-rw-r--r--src/common/bits.h42
-rw-r--r--src/gtkext/graph/cluster.c2
6 files changed, 138 insertions, 209 deletions
diff --git a/ChangeLog b/ChangeLog
index 4f92fe8..c1fd565 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+17-03-30 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/area.c:
+ * src/analysis/disass/loop.c:
+ Update code.
+
+ * src/common/bits.c:
+ * src/common/bits.h:
+ Discriminate between tests for set and unset ranges of bits.
+
+ * src/gtkext/graph/cluster.c:
+ Update code.
+
17-03-29 Cyrille Bagard <nocbos@gmail.com>
* plugins/readelf/section.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 5478fe3..5dab3ab 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -72,8 +72,11 @@ static void init_mem_area_from_addr(mem_area *, const vmpa2t *, phys_t, const GL
/* Libère d'une aire de données les ressources allouées. */
static void fini_mem_area(mem_area *);
-/* Indique si une zone donnée est intégralement vierge ou non. */
-static bool is_range_blank_in_mem_area(mem_area *, phys_t, phys_t);
+/* Indique si une zone donnée est intégralement vierge. */
+static bool is_range_empty_in_mem_area(mem_area *, phys_t, phys_t);
+
+/* Indique si une zone donnée est intégralement occupée. */
+static bool is_range_busy_in_mem_area(mem_area *, phys_t, phys_t);
/* Marque une série d'octets comme ayant été traités. */
static bool mark_range_in_mem_area_as_processed(mem_area *, GArchInstruction *, bool);
@@ -271,6 +274,33 @@ static void fini_mem_area(mem_area *area)
* start = début de la zone à manipuler. *
* len = taille de cette même aire de données. *
* *
+* Description : Indique si une zone donnée est intégralement vierge. *
+* *
+* Retour : true si l'aire visée n'a jamais été traitée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool is_range_empty_in_mem_area(mem_area *area, phys_t start, phys_t len)
+{
+ bool result; /* Résultat à renvoyer */
+
+ assert((start + len) <= get_mrange_length(&area->range));
+
+ result = test_none_in_bit_field(area->processed, start, len);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : area = aire représentant à contenu à parcourir. *
+* start = début de la zone à manipuler. *
+* len = taille de cette même aire de données. *
+* *
* Description : Indique si une zone donnée est intégralement vierge ou non. *
* *
* Retour : true si l'aire visée n'a jamais été traitée, false sinon. *
@@ -279,13 +309,13 @@ static void fini_mem_area(mem_area *area)
* *
******************************************************************************/
-static bool is_range_blank_in_mem_area(mem_area *area, phys_t start, phys_t len)
+static bool is_range_busy_in_mem_area(mem_area *area, phys_t start, phys_t len)
{
bool result; /* Résultat à renvoyer */
assert((start + len) <= get_mrange_length(&area->range));
- result = !test_in_bit_field(area->processed, start, len);
+ result = test_all_in_bit_field(area->processed, start, len);
return result;
@@ -425,7 +455,7 @@ static GArchInstruction *load_raw_instruction_from_mem_area(mem_area *area, phys
if (get_virt_addr(pos) % sz == 0
&& (offset + sz) <= get_mrange_length(&area->range)
- && is_range_blank_in_mem_area(area, offset, sz))
+ && is_range_empty_in_mem_area(area, offset, sz))
{
*size = sz;
@@ -593,7 +623,7 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
* inutile.
*/
- if (!is_range_blank_in_mem_area(area, i, 1))
+ if (is_range_busy_in_mem_area(area, i, 1))
break;
/* Décodage d'une nouvelle instruction */
@@ -636,7 +666,7 @@ void load_code_from_mem_area(mem_area *area, mem_area *list, size_t count, GProc
gtk_status_stack_update_activity_value(status, id, diff);
- assert(!is_range_blank_in_mem_area(area, i, diff));
+ assert(is_range_busy_in_mem_area(area, i, diff));
/* Enregistrement d'un éventuel début de routine */
@@ -712,7 +742,7 @@ static void load_data_from_mem_area(mem_area *area, GProcContext *ctx, const vmp
{
/* On cherche à obtenir l'assurance que le traitement n'a jamais été fait */
- if (!is_range_blank_in_mem_area(area, i, 1))
+ if (is_range_busy_in_mem_area(area, i, 1))
break;
/* Décodage d'une nouvelle instruction, sur mesure puis minimale */
@@ -745,7 +775,7 @@ static void load_data_from_mem_area(mem_area *area, GProcContext *ctx, const vmp
gtk_status_stack_update_activity_value(status, id, diff);
- assert(!is_range_blank_in_mem_area(area, i, diff));
+ assert(is_range_busy_in_mem_area(area, i, diff));
/* On laisse une chance au code pour se reprendre... */
@@ -786,7 +816,7 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon
for (i = 0; i < len; i++)
{
- if (is_range_blank_in_mem_area(area, i, 1))
+ if (is_range_empty_in_mem_area(area, i, 1))
{
copy_vmpa(&start, addr);
advance_vmpa(&start, i);
@@ -794,12 +824,12 @@ static void fill_mem_area(mem_area *area, mem_area *list, size_t count, GProcCon
if (area->is_exec && get_virt_addr(&start) % area->packing_size == 0)
load_code_from_mem_area(area, list, count, ctx, &start, false, status, id);
- if (is_range_blank_in_mem_area(area, i, 1))
+ if (is_range_empty_in_mem_area(area, i, 1))
load_data_from_mem_area(area, ctx, &start, status, id);
}
- assert(!is_range_blank_in_mem_area(area, i, 1));
+ assert(is_range_busy_in_mem_area(area, i, 1));
}
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index a0dba66..d8ca355 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -80,7 +80,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count)
id = get_dragon_node_index(nodes, target);
- if (test_in_bit_field(dominators, id, 1))
+ if (test_in_bit_field(dominators, id))
{
/*
diff --git a/src/common/bits.c b/src/common/bits.c
index d941e54..d4d5074 100644
--- a/src/common/bits.c
+++ b/src/common/bits.c
@@ -31,9 +31,6 @@
-/* ----------------------------- CHAMPS DE BITS SIMPLES ----------------------------- */
-
-
/* Champ de bits simple */
struct _bitfield_t
{
@@ -57,12 +54,10 @@ static bitfield_t *_create_bit_field_from(const bitfield_t *, bool, size_t);
/* Crée une copie d'un champ de bits classique. */
static bitfield_t *_dup_bit_field(const bitfield_t *, size_t);
+/* Détermine si un ensemble de bits est homogène dans un champ. */
+static bool test_state_in_bit_field(const bitfield_t *, size_t, size_t, bool);
-/* ---------------------------------------------------------------------------------- */
-/* CHAMPS DE BITS SIMPLES */
-/* ---------------------------------------------------------------------------------- */
-
/******************************************************************************
* *
@@ -397,14 +392,14 @@ bool set_atomic_in_bit_field(bitfield_t *field, size_t first, size_t count)
result = ((oldval & mask) == 0);
- assert(test_in_bit_field(field, first, count));
+ assert(test_all_in_bit_field(field, first, count));
}
else
{
g_mutex_lock(&field->mutex);
- result = !test_in_bit_field(field, first, count);
+ result = test_none_in_bit_field(field, first, count);
if (result)
set_in_bit_field(field, first, count);
@@ -471,8 +466,7 @@ void or_bit_field(bitfield_t *dest, const bitfield_t *src)
/******************************************************************************
* *
* Paramètres : field = champ de bits à modifier. *
-* first = indice du premier bit à traiter. *
-* count = nombre de bits à marquer. *
+* n = indice du bit à traiter. *
* *
* Description : Détermine si un bit est à 1 dans un champ de bits. *
* *
@@ -482,28 +476,18 @@ void or_bit_field(bitfield_t *dest, const bitfield_t *src)
* *
******************************************************************************/
-bool test_in_bit_field(const bitfield_t *field, size_t first, size_t count)
+bool test_in_bit_field(const bitfield_t *field, size_t n)
{
bool result; /* Valeur retrouvée à renvoyer */
- size_t last; /* Point d'arrêt de la boucle */
- size_t i; /* Boucle de parcours */
size_t index; /* Cellule de tableau visée */
size_t remaining; /* Nombre de bits restants */
- last = first + count;
-
- assert(last <= field->length);
-
- result = true;
-
- for (i = first; i < last && result; i++)
- {
- index = i / (sizeof(unsigned long) * 8);
- remaining = i % (sizeof(unsigned long) * 8);
+ assert(n < field->length);
- result = field->bits[index] & (1ul << remaining);
+ index = n / (sizeof(unsigned long) * 8);
+ remaining = n % (sizeof(unsigned long) * 8);
- }
+ result = field->bits[index] & (1ul << remaining);
return result;
@@ -512,220 +496,150 @@ bool test_in_bit_field(const bitfield_t *field, size_t first, size_t count)
/******************************************************************************
* *
-* Paramètres : a = premier champ de bits à comparer. *
-* b = second champ de bits à comparer. *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* count = nombre de bits à marquer. *
+* state = état global à retrouver idéalement. *
* *
-* Description : Indique si deux champs de bits sont identiques ou non. *
+* Description : Détermine si un ensemble de bits est homogène dans un champ. *
* *
-* Retour : true si les champs de bits sont égaux ou false sinon. *
+* Retour : true si le bit correspondant est à l'état haut. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool is_bit_field_equal_to(const bitfield_t *a, const bitfield_t *b)
+static bool test_state_in_bit_field(const bitfield_t *field, size_t first, size_t count, bool state)
{
- bool result; /* Résultat à retourner */
+ size_t last; /* Point d'arrêt de la boucle */
size_t i; /* Boucle de parcours */
+ size_t index; /* Cellule de tableau visée */
size_t remaining; /* Nombre de bits restants */
+ bool current; /* Etat d'un bit donné */
- if (a->length != b->length)
- return false;
-
- result = true;
+ assert(count > 0);
- for (i = 0; i < (a->requested - 1) && result; i++)
- result = (a->bits[i] == b->bits[i]);
+ last = first + count;
- if (result)
+ for (i = first; i < last; i++)
{
- remaining = a->length % sizeof(unsigned long);
-
- if (remaining == 0)
- result = (a->bits[i] == b->bits[i]);
-
- else
- {
- remaining = (1 << (remaining + 1)) - 1;
+ index = i / (sizeof(unsigned long) * 8);
+ remaining = i % (sizeof(unsigned long) * 8);
- result = ((a->bits[i] & remaining) == (b->bits[i] & remaining));
+ current = field->bits[index] & (1ul << remaining);
- }
+ if (current != state) break;
}
- return result;
-
-}
-
-
-
-
-unsigned long gfw(const bitfield_t *field)
-{
- return field->bits[0];
+ return (i == last);
}
-#if 0
-
-/* ---------------------------------------------------------------------------------- */
-/* CHAMPS LIES À UNE ZONE MEMOIRE */
-/* ---------------------------------------------------------------------------------- */
-
/******************************************************************************
* *
-* Paramètres : range = espace mémoire à couvrir. *
-* state = état initial de chaque des bits. *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* count = nombre de bits à marquer. *
* *
-* Description : Crée un champ de bits couvrant une zone mémoire. *
+* Description : Détermine si un ensemble de bits est à 0 dans un champ. *
* *
-* Retour : Champ de bits mis en place. *
+* Retour : true si le bit correspondant est à l'état haut. *
* *
* Remarques : - *
* *
******************************************************************************/
-memfield_t *create_mem_field(const mrange_t *range, bool state)
+bool test_none_in_bit_field(const bitfield_t *field, size_t first, size_t count)
{
- bitfield_t *result; /* Création à retourner */
-
- result = _create_bit_field(get_mrange_length(range), state, sizeof(vmpa2t));
+ bool result; /* Valeur retrouvée à renvoyer */
- copy_vmpa((vmpa2t *)result->tail, get_mrange_addr(range));
+ result = test_state_in_bit_field(field, first, count, false);
- return (memfield_t *)result;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : range = espace mémoire à couvrir. *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* count = nombre de bits à marquer. *
* *
-* Description : Crée une copie de champ de bits couvrant une zone mémoire. *
+* Description : Détermine si un ensemble de bits est à 1 dans un champ. *
* *
-* Retour : Champ de bits mis en place. *
+* Retour : true si le bit correspondant est à l'état haut. *
* *
* Remarques : - *
* *
******************************************************************************/
-memfield_t *create_mem_field_from(const memfield_t *field)
+bool test_all_in_bit_field(const bitfield_t *field, size_t first, size_t count)
{
- bitfield_t *result; /* Création à retourner */
-
- result = _create_bit_field_from((bitfield_t *)field, false, sizeof(vmpa2t));
-
- copy_vmpa((vmpa2t *)result->tail, (vmpa2t *)field->tail);
-
- return (memfield_t *)result;
-
-}
-
+ bool result; /* Valeur retrouvée à renvoyer */
-/******************************************************************************
-* *
-* Paramètres : field = champ de bits à effacer. *
-* *
-* Description : Supprime de la mémoire un champ de bits donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result = test_state_in_bit_field(field, first, count, true);
-void delete_mem_field(memfield_t *field)
-{
- delete_bit_field((bitfield_t *)field);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : field = champ de bits à dupliquer. *
+* Paramètres : a = premier champ de bits à comparer. *
+* b = second champ de bits à comparer. *
* *
-* Description : Crée une copie d'un champ de bits couvrant une zone mémoire. *
+* Description : Indique si deux champs de bits sont identiques ou non. *
* *
-* Retour : Champ de bits mis en place. *
+* Retour : true si les champs de bits sont égaux ou false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-memfield_t *dup_mem_field(const memfield_t *field)
+bool is_bit_field_equal_to(const bitfield_t *a, const bitfield_t *b)
{
- bitfield_t *result; /* Création à retourner */
-
- result = _dup_bit_field((bitfield_t *)field, sizeof(vmpa2t));
+ bool result; /* Résultat à retourner */
+ size_t i; /* Boucle de parcours */
+ size_t remaining; /* Nombre de bits restants */
- copy_vmpa((vmpa2t *)result->tail, (vmpa2t *)field->tail);
+ if (a->length != b->length)
+ return false;
- return (memfield_t *)result;
+ result = true;
-}
+ for (i = 0; i < (a->requested - 1) && result; i++)
+ result = (a->bits[i] == b->bits[i]);
+ if (result)
+ {
+ remaining = a->length % sizeof(unsigned long);
-/******************************************************************************
-* *
-* Paramètres : field = champ de bits à modifier. *
-* addr = emplacement en mémoire à traiter. *
-* *
-* Description : Bascule à 1 un bit d'un champ de bits. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ if (remaining == 0)
+ result = (a->bits[i] == b->bits[i]);
-void set_in_mem_field(memfield_t *field, const vmpa2t *addr)
-{
- vmpa2t *start; /* Adresse de début */
- phys_t offset; /* Décallage de départ */
+ else
+ {
+ remaining = (1 << (remaining + 1)) - 1;
- start = (vmpa2t *)field->tail;
+ result = ((a->bits[i] & remaining) == (b->bits[i] & remaining));
- assert(cmp_vmpa(start, addr) <= 0);
+ }
- offset = compute_vmpa_diff(start, addr);
+ }
- set_in_bit_field((bitfield_t *)field, offset, 1);
+ return result;
}
-/******************************************************************************
-* *
-* Paramètres : field = champ de bits à modifier. *
-* addr = emplacement en mémoire à tester. *
-* *
-* Description : Détermine si un bit est à 1 dans un champ de bits. *
-* *
-* Retour : true si le bit correspondant est à l'état haut. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool test_in_mem_field(memfield_t *field, const vmpa2t *addr)
-{
- bool result; /* Valeur retrouvée à renvoyer */
- vmpa2t *start; /* Adresse de début */
- phys_t offset; /* Décallage de départ */
-
- start = (vmpa2t *)field->tail;
-
- assert(cmp_vmpa(start, addr) <= 0);
- offset = compute_vmpa_diff(start, addr);
- result = test_in_bit_field((bitfield_t *)field, offset, 1);
-
- return result;
+unsigned long gfw(const bitfield_t *field)
+{
+ return field->bits[0];
}
-#endif
diff --git a/src/common/bits.h b/src/common/bits.h
index 1396789..4a2937f 100644
--- a/src/common/bits.h
+++ b/src/common/bits.h
@@ -29,9 +29,6 @@
-/* ----------------------------- CHAMPS DE BITS SIMPLES ----------------------------- */
-
-
/* Champ de bits simple */
typedef struct _bitfield_t bitfield_t;
@@ -70,7 +67,13 @@ void and_bit_field(bitfield_t *, const bitfield_t *);
void or_bit_field(bitfield_t *, const bitfield_t *);
/* Détermine si un bit est à 1 dans un champ de bits. */
-bool test_in_bit_field(const bitfield_t *, size_t, size_t);
+bool test_in_bit_field(const bitfield_t *, size_t);
+
+/* Détermine si un ensemble de bits est à 0 dans un champ. */
+bool test_none_in_bit_field(const bitfield_t *, size_t, size_t);
+
+/* Détermine si un ensemble de bits est à 1 dans un champ. */
+bool test_all_in_bit_field(const bitfield_t *, size_t, size_t);
/* Indique si deux champs de bits sont identiques ou non. */
bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *);
@@ -80,37 +83,6 @@ bool is_bit_field_equal_to(const bitfield_t *, const bitfield_t *);
unsigned long gfw(const bitfield_t *);
-#if 0
-/* ------------------------- CHAMPS LIES À UNE ZONE MEMOIRE ------------------------- */
-
-
-/* Champ de bits couvrant une mémoire */
-typedef struct _bitfield_t memfield_t;
-
-
-/* Crée un champ de bits couvrant une zone mémoire. */
-memfield_t *create_mem_field(const mrange_t *, bool);
-
-/* Crée une copie de champ de bits couvrant une zone mémoire. */
-memfield_t *create_mem_field_from(const memfield_t *);
-
-/* Supprime de la mémoire un champ de bits donné. */
-void delete_mem_field(memfield_t *);
-
-/* Crée une copie d'un champ de bits couvrant une zone mémoire. */
-memfield_t *dup_mem_field(const memfield_t *);
-
-/* Bascule à 1 un bit d'un champ de bits. */
-void set_in_mem_field(memfield_t *, const vmpa2t *);
-
-/* Détermine si un bit est à 1 dans un champ de bits. */
-bool test_in_mem_field(memfield_t *, const vmpa2t *);
-
-
-
-#define set_atomic_in_mem_field(f, range) false
-
-#endif
#endif /* _COMMON_BITS_H */
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index c1ed8ce..9aee82c 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -1631,7 +1631,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
block = pending->list[i];
dominators = g_basic_block_get_domination(block);
- if (test_in_bit_field(dominators, index, 1))
+ if (test_in_bit_field(dominators, index))
{
/* Dépilement */