diff options
| -rw-r--r-- | ChangeLog | 13 | ||||
| -rw-r--r-- | src/analysis/disass/area.c | 54 | ||||
| -rw-r--r-- | src/analysis/disass/loop.c | 2 | ||||
| -rw-r--r-- | src/common/bits.c | 234 | ||||
| -rw-r--r-- | src/common/bits.h | 42 | ||||
| -rw-r--r-- | src/gtkext/graph/cluster.c | 2 | 
6 files changed, 138 insertions, 209 deletions
| @@ -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 */ | 
