diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-15 13:40:28 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-15 13:40:28 (GMT) | 
| commit | 124c8410dbfcad59d66b850c50c96ec73a607ab7 (patch) | |
| tree | b7127c66abfccd11b9126741e2809a893ee44143 /src/arch | |
| parent | db1a6171007a6641a4659392c9bcc05670396643 (diff) | |
Defined proper accesses to instructions loaded by a processor.
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/dalvik/link.c | 7 | ||||
| -rw-r--r-- | src/arch/instriter.c | 81 | ||||
| -rw-r--r-- | src/arch/instriter.h | 6 | ||||
| -rw-r--r-- | src/arch/link.c | 34 | ||||
| -rw-r--r-- | src/arch/processor.c | 329 | ||||
| -rw-r--r-- | src/arch/processor.h | 60 | 
6 files changed, 345 insertions, 172 deletions
diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c index 311f672..694ec65 100644 --- a/src/arch/dalvik/link.c +++ b/src/arch/dalvik/link.c @@ -151,6 +151,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *                  g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); +                g_object_unref(G_OBJECT(target)); +              }              /* Autres cas */ @@ -223,6 +225,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *                      g_arch_instruction_link_with(instr, target, ILT_CASE_JUMP); +                    g_object_unref(G_OBJECT(target)); +                  }              } @@ -298,6 +302,9 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *          } +        if (switch_ins != NULL) +            g_object_unref(G_OBJECT(switch_ins)); +      }  } diff --git a/src/arch/instriter.c b/src/arch/instriter.c index 0f33998..5a534d5 100644 --- a/src/arch/instriter.c +++ b/src/arch/instriter.c @@ -99,6 +99,83 @@ void delete_instruction_iterator(instr_iter_t *iter)  *                                                                             *  *  Paramètres  : iter = itérateur à manipuler.                                *  *                                                                             * +*  Description : Fournit l'instruction courante de l'itérateur.               * +*                                                                             * +*  Retour      : Instruction suivante trouvée, ou NULL.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *get_instruction_iterator_current(instr_iter_t *iter) +{ +    GArchInstruction *result;               /* Résultat à retourner        */ + +    g_arch_processor_lock(iter->proc); + +    if (iter->stamp != g_arch_processor_get_stamp(iter->proc)) +        result = NULL; + +    else +    { +        if (iter->index < g_arch_processor_count_instructions(iter->proc)) +            result = g_arch_processor_get_instruction(iter->proc, iter->index); +        else +            result = NULL; + +    } + +    g_arch_processor_unlock(iter->proc); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iter = itérateur à manipuler.                                * +*                                                                             * +*  Description : Fournit l'instruction qui en précède une autre.              * +*                                                                             * +*  Retour      : Instruction suivante trouvée, ou NULL.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *get_instruction_iterator_prev(instr_iter_t *iter) +{ +    GArchInstruction *result;               /* Résultat à retourner        */ + +    g_arch_processor_lock(iter->proc); + +    if (iter->stamp != g_arch_processor_get_stamp(iter->proc)) +        result = NULL; + +    else +    { +        if (iter->index > 0) +            result = g_arch_processor_get_instruction(iter->proc, iter->index); +        else +            result = NULL; + +        if (result != NULL) +            iter->index--; + +    } + +    g_arch_processor_unlock(iter->proc); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iter = itérateur à manipuler.                                * +*                                                                             *  *  Description : Fournit l'instruction qui en suit une autre.                 *  *                                                                             *  *  Retour      : Instruction suivante trouvée, ou NULL.                       * @@ -118,8 +195,8 @@ GArchInstruction *get_instruction_iterator_next(instr_iter_t *iter)      else      { -        if (iter->index < g_arch_processor_count_disassembled_instructions(iter->proc)) -            result = g_arch_processor_get_disassembled_instruction(iter->proc, iter->index); +        if (iter->index < g_arch_processor_count_instructions(iter->proc)) +            result = g_arch_processor_get_instruction(iter->proc, iter->index);          else              result = NULL; diff --git a/src/arch/instriter.h b/src/arch/instriter.h index b9c7621..74e853d 100644 --- a/src/arch/instriter.h +++ b/src/arch/instriter.h @@ -42,6 +42,12 @@ instr_iter_t *create_instruction_iterator(GArchProcessor *, size_t);  /* Détruit un itérateur mis en place. */  void delete_instruction_iterator(instr_iter_t *); +/* Fournit l'instruction courante de l'itérateur. */ +GArchInstruction *get_instruction_iterator_current(instr_iter_t *); + +/* Fournit l'instruction qui en précède une autre. */ +GArchInstruction *get_instruction_iterator_prev(instr_iter_t *); +  /* Fournit l'instruction qui en suit une autre. */  GArchInstruction *get_instruction_iterator_next(instr_iter_t *); diff --git a/src/arch/link.c b/src/arch/link.c index 4519bc5..e5406da 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -66,7 +66,10 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon          target = g_arch_processor_find_instr_by_address(proc, &addr);          if (target != NULL) +        {              g_arch_instruction_link_with(instr, target, ILT_JUMP); +            g_object_unref(G_OBJECT(target)); +        }      } @@ -94,8 +97,8 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC      GArchOperand *op;                       /* Opérande numérique en place */      virt_t virt;                            /* Adresse virtuelle           */      vmpa2t addr;                            /* Adresse de destination      */ +    instr_iter_t *iter;                     /* Parcours d'instructions     */      GArchInstruction *target;               /* Ligne visée par la référence*/ -    GArchInstruction *list;                 /* Ensemble des instructions   */      assert(g_arch_instruction_count_operands(instr) > index); @@ -114,24 +117,34 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC      if (virt != VMPA_NO_VIRTUAL)      { -        /* TODO : utiliser format pour contruire une adresse avec une position physique, -         * ce qui accélèrerait les recherches. -         */          init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); -        target = g_arch_processor_find_instr_by_address(proc, &addr); +        iter = g_arch_processor_get_iter_from_address(proc, &addr); -        if (target != NULL) +        if (iter != NULL)          { -            g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE); +            target = get_instruction_iterator_current(iter); + +            if (target != NULL) +            { +                g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE); -            list = g_arch_processor_get_disassembled_instructions(proc); +                g_object_unref(G_OBJECT(target)); -            target = g_arch_instruction_get_next_iter(list, instr, ~0); +            } + +            target = get_instruction_iterator_next(iter);              if (target != NULL) +            {                  g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE); +                g_object_unref(G_OBJECT(target)); + +            } + +            delete_instruction_iterator(iter); +          }      } @@ -174,7 +187,10 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon          target = g_arch_processor_find_instr_by_address(proc, &addr);          if (target != NULL) +        {              g_arch_instruction_link_with(instr, target, ILT_CALL); +            g_object_unref(G_OBJECT(target)); +        }      } diff --git a/src/arch/processor.c b/src/arch/processor.c index 26c7170..24e2db6 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -78,6 +78,8 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction  /* Termine la définition d'un nouveau groupe d'instructions. */  static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruction *, size_t); +/* Recherche rapidement un indice d'instruction via une adresse. */ +static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool, size_t *); @@ -375,89 +377,28 @@ void g_arch_processor_lock_unlock(GArchProcessor *proc, bool state)  unsigned int g_arch_processor_get_stamp(const GArchProcessor *proc)  { -    //assert(g_atomic_int_get(&proc->locked) == 1); -      return proc->stamp;  } - -/* ---------------------------------------------------------------------------------- */ -/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : proc  = architecture à comléter par la procédure.            * -*                first = première instruction d'un nouveau groupe.            * -*                start = indice de cette instruction dans l'ensemble global.  * -*                                                                             * -*  Description : Démarre la définition d'un nouveau groupe d'instructions.    * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start) -{ -    instr_coverage *coverage;               /* Couverture à définir        */ -    const mrange_t *irange;                 /* Couverture de l'instruction */ - -    /* Mise à disposition de d'avantage d'espace */ -    if (proc->cov_allocated == proc->cov_count) -    { -        proc->cov_allocated += INSTR_ALLOC_BLOCK; - -        proc->coverages = (instr_coverage *)realloc(proc->coverages, -                                                    proc->cov_allocated * sizeof(instr_coverage)); - -    } - -    coverage = &proc->coverages[proc->cov_count++]; - -    irange = g_arch_instruction_get_range(first); - -    init_mrange(&coverage->range, get_mrange_addr(irange), 0); - -    coverage->start = start; - -} - -  /******************************************************************************  *                                                                             * -*  Paramètres  : proc = architecture à comléter par la procédure.             * -*                last = dernière instruction d'un nouveau groupe.             * -*                end  = indice de cette instruction dans l'ensemble global.   * +*  Paramètres  : proc = architecture visée par la procédure.                  *  *                                                                             * -*  Description : Termine la définition d'un nouveau groupe d'instructions.    * +*  Description : Compte le nombre d'instructions représentées.                *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Nombre d'instructions présentes.                             *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end) +size_t g_arch_processor_count_instructions(const GArchProcessor *proc)  { -    instr_coverage *coverage;               /* Couverture à définir        */ -    const mrange_t *irange;                 /* Couverture de l'instruction */ -    phys_t diff;                            /* Ecart entre les extrémités  */ - -    coverage = &proc->coverages[proc->cov_count - 1]; - -    irange = g_arch_instruction_get_range(last); - -    diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange)); -    diff += get_mrange_length(irange); +    assert(g_atomic_int_get(&proc->locked) == 1); -    set_mrange_length(&coverage->range, diff); - -    coverage->count = end - coverage->start + 1; +    return proc->instr_count;  } @@ -523,70 +464,117 @@ void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchI  /******************************************************************************  *                                                                             *  *  Paramètres  : proc = architecture visée par la procédure.                  * +*                index = indice de l'instruction visée.                       *  *                                                                             * -*  Description : Fournit les instructions désassemblées pour une architecture.* +*  Description : Fournit une instruction désassemblée pour une architecture.  *  *                                                                             * -*  Retour      : Liste des instructions désassemblées ou NULL si aucune.      * +*  Retour      : Instructions désassemblée trouvée ou NULL si aucune.         *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc) +GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *proc, size_t index)  { -    return (proc->instr_count > 0 ? proc->instructions[0] : NULL); +    GArchInstruction *result;               /* Instruction à retourner     */ + +    assert(g_atomic_int_get(&proc->locked) == 1); + +    if (proc->instr_count == 0) +        result = NULL; + +    else +    { +        assert(index < proc->instr_count); + +        result = proc->instructions[index]; + +        if (result != NULL) +            g_object_ref(G_OBJECT(result)); + +    } + +    return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : proc = architecture visée par la procédure.                  * -*                index = indice de l'instruction visée.                       * +*  Paramètres  : proc  = architecture à comléter par la procédure.            * +*                first = première instruction d'un nouveau groupe.            * +*                start = indice de cette instruction dans l'ensemble global.  *  *                                                                             * -*  Description : Fournit une instruction désassemblée pour une architecture.  * +*  Description : Démarre la définition d'un nouveau groupe d'instructions.    *  *                                                                             * -*  Retour      : Instructions désassemblée trouvée ou NULL si aucune.         * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *proc, size_t index) +static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruction *first, size_t start)  { -    GArchInstruction *result;               /* Instruction à retourner     */ - -    if (proc->instr_count == 0) -        result = NULL; +    instr_coverage *coverage;               /* Couverture à définir        */ +    const mrange_t *irange;                 /* Couverture de l'instruction */ -    else +    /* Mise à disposition de d'avantage d'espace */ +    if (proc->cov_allocated == proc->cov_count)      { -        assert(index < proc->instr_count); +        proc->cov_allocated += INSTR_ALLOC_BLOCK; -        result = proc->instructions[index]; +        proc->coverages = (instr_coverage *)realloc(proc->coverages, +                                                    proc->cov_allocated * sizeof(instr_coverage));      } -    return result; +    coverage = &proc->coverages[proc->cov_count++]; + +    irange = g_arch_instruction_get_range(first); + +    init_mrange(&coverage->range, get_mrange_addr(irange), 0); + +    coverage->start = start;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : proc = architecture visée par la procédure.                  * +*  Paramètres  : proc = architecture à comléter par la procédure.             * +*                last = dernière instruction d'un nouveau groupe.             * +*                end  = indice de cette instruction dans l'ensemble global.   *  *                                                                             * -*  Description : Compte le nombre d'instructions représentées.                * +*  Description : Termine la définition d'un nouveau groupe d'instructions.    *  *                                                                             * -*  Retour      : Nombre d'instructions présentes.                             * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *proc) +static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end)  { -    return proc->instr_count; +    instr_coverage *coverage;               /* Couverture à définir        */ +    const mrange_t *irange;                 /* Couverture de l'instruction */ +    phys_t diff;                            /* Ecart entre les extrémités  */ + +    coverage = &proc->coverages[proc->cov_count - 1]; + +    irange = g_arch_instruction_get_range(last); + +    diff = compute_vmpa_diff(get_mrange_addr(&coverage->range), get_mrange_addr(irange)); +    diff += get_mrange_length(irange); + +    set_mrange_length(&coverage->range, diff); + +    coverage->count = end - coverage->start + 1;  } @@ -609,6 +597,8 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce      instr_coverage *result;                 /* Trouvaille à retourner      */      void *ptr;                              /* Résultat des recherches     */ +    // TODO : assert locked ! +      int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c)      {          int status;                         /* Bilan d'une comparaison     */ @@ -631,6 +621,72 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce  /******************************************************************************  *                                                                             * +*  Paramètres  : proc     = processeur recensant diverses instructions.       * +*                coverage = zone de couverture fine à fouiller.               * +*                addr     = position en mémoire ou physique à chercher.       * +*                nearby   = la recherche s'effectue-t-elle de façon stricte ? * +*                index    = indice de l'instruction trouvée. [OUT]            * +*                                                                             * +*  Description : Recherche rapidement un indice d'instruction via une adresse.* +*                                                                             * +*  Retour      : Validité de l'indice fourni.                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_find_covered_index_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby, size_t *index) +{ +    bool result;                            /* Bilan à faire remonter      */ +    void *ptr;                              /* Résultat des recherches     */ +    __compar_fn_t fn;                       /* Fonction auxiliaire adaptée */ + +    assert(g_atomic_int_get(&proc->locked) == 1); + +    int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b) +    { +        const mrange_t *range_b;            /* Emplacement pour l'instr. B */ + +        range_b = g_arch_instruction_get_range(*b); + +        return cmp_vmpa(a, get_mrange_addr(range_b)); + +    } + +    int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b) +    { +        const mrange_t *range_b;            /* Emplacement pour l'instr. B */ + +        range_b = g_arch_instruction_get_range(*b); + +        return cmp_mrange_with_vmpa(range_b, a); + +    } + +    if (nearby) +        fn = (__compar_fn_t)search_for_instr_by_nearby_addr; +    else +        fn = (__compar_fn_t)search_for_instr_by_addr; + +    ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count, +                  sizeof(GArchInstruction *), fn); + +    if (ptr == NULL) +        result = false; + +    else +    { +        result = true; +        *index = ((GArchInstruction **)ptr) - proc->instructions; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc   = processeur recensant diverses instructions.         *  *                addr   = position en mémoire ou physique à chercher.         *  *                nearby = la recherche s'effectue-t-elle de façon stricte ?   * @@ -643,11 +699,13 @@ const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProce  *                                                                             *  ******************************************************************************/ -GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr, bool nearby) +GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)  {      GArchInstruction *result;               /* Trouvaille à retourner      */      const instr_coverage *coverage;         /* Couverture fine à fouiller  */ +    g_arch_processor_lock(proc); +      coverage = g_arch_processor_find_coverage_by_address(proc, addr);      if (coverage != NULL) @@ -655,6 +713,8 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *      else          result = NULL; +    g_arch_processor_unlock(proc); +      return result;  } @@ -678,92 +738,83 @@ GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *  GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)  {      GArchInstruction *result;               /* Trouvaille à retourner      */ -    void *ptr;                              /* Résultat des recherches     */ -    __compar_fn_t fn;                       /* Fonction auxiliaire adaptée */ +    size_t index;                           /* Indice d'instruction visée  */ +    bool valid;                             /* Validité de l'indice        */ -    int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b) -    { -        const mrange_t *range_b;            /* Emplacement pour l'instr. B */ - -        range_b = g_arch_instruction_get_range(*b); - -        return cmp_vmpa(a, get_mrange_addr(range_b)); - -    } - -    int search_for_instr_by_nearby_addr(const vmpa2t *a, const GArchInstruction **b) -    { -        const mrange_t *range_b;            /* Emplacement pour l'instr. B */ - -        range_b = g_arch_instruction_get_range(*b); - -        return cmp_mrange_with_vmpa(range_b, a); +    valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index); -    } - -    if (nearby) -        fn = (__compar_fn_t)search_for_instr_by_nearby_addr; +    if (valid) +        result = g_arch_processor_get_instruction(proc, index);      else -        fn = (__compar_fn_t)search_for_instr_by_addr; - -    ptr = bsearch(addr, &proc->instructions[coverage->start], coverage->count, -                  sizeof(GArchInstruction *), fn); - -    result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); +        result = NULL;      return result;  } - +   /******************************************************************************  *                                                                             * -*  Paramètres  : proc  = processeur recensant diverses instructions.          * -*                instr = instruction de référence pour un parcours.           * +*  Paramètres  : proc   = processeur recensant diverses instructions.         * +*                addr   = position en mémoire ou physique à chercher.         * +*                nearby = la recherche s'effectue-t-elle de façon stricte ?   *  *                                                                             * -*  Description : Fournit l'instruction qui en précède une autre.              * +*  Description : Met en place un itérateur d'instruction selon une adresse.   *  *                                                                             * -*  Retour      : Instruction précédente trouvée, ou NULL.                     * +*  Retour      : Itérateur mis en place, ou NULL si l'opération est un échec. *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *proc, const GArchInstruction *instr) +instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *proc, const vmpa2t *addr, bool nearby)  { -    GArchInstruction *result;               /* Instruction à retourner     */ -    GArchInstruction *list;                 /* Ensemble des instructions   */ +    instr_iter_t *result;                   /* Itérateur à retourner       */ +    const instr_coverage *coverage;         /* Couverture fine à fouiller  */ + +    g_arch_processor_lock(proc); + +    coverage = g_arch_processor_find_coverage_by_address(proc, addr); -    list = g_arch_processor_get_disassembled_instructions(proc); +    if (coverage != NULL) +        result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, nearby); +    else +        result = NULL; -    result = g_arch_instruction_get_prev_iter(list, instr); +    g_arch_processor_unlock(proc);      return result;  } - +   /******************************************************************************  *                                                                             * -*  Paramètres  : proc  = processeur recensant diverses instructions.          * -*                instr = instruction de référence pour un parcours.           * +*  Paramètres  : proc     = processeur recensant diverses instructions.       * +*                coverage = zone de couverture fine à fouiller.               * +*                addr     = position en mémoire ou physique à chercher.       * +*                nearby   = la recherche s'effectue-t-elle de façon stricte ? *  *                                                                             * -*  Description : Fournit l'instruction qui en suit une autre.                 * +*  Description : Met en place un itérateur d'instruction selon une adresse.   *  *                                                                             * -*  Retour      : Instruction suivante trouvée, ou NULL.                       * +*  Retour      : Itérateur mis en place, ou NULL si l'opération est un échec. *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *proc, const GArchInstruction *instr) +instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *proc, const instr_coverage *coverage, const vmpa2t *addr, bool nearby)  { -    GArchInstruction *result;               /* Instruction à retourner     */ -    GArchInstruction *list;                 /* Ensemble des instructions   */ +    instr_iter_t *result;                   /* Itérateur à retourner       */ +    size_t index;                           /* Indice d'instruction visée  */ +    bool valid;                             /* Validité de l'indice        */ -    list = g_arch_processor_get_disassembled_instructions(proc); +    valid = g_arch_processor_find_covered_index_by_address(proc, coverage, addr, nearby, &index); -    result = g_arch_instruction_get_next_iter(list, instr, ~0); +    if (valid) +        result = create_instruction_iterator(proc, index); +    else +        result = NULL;      return result; diff --git a/src/arch/processor.h b/src/arch/processor.h index 02b3533..05ea77a 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -29,6 +29,7 @@  #include "context.h" +#include "instriter.h"  #include "instruction.h"  #include "../common/endianness.h"  #include "../format/executable.h" @@ -86,47 +87,62 @@ void g_arch_processor_lock_unlock(GArchProcessor *, bool);  /* Fournit la marque de dernière modification des instructions. */  unsigned int g_arch_processor_get_stamp(const GArchProcessor *); +/* Compte le nombre d'instructions représentées. */ +size_t g_arch_processor_count_instructions(const GArchProcessor *); +/* Note les instructions désassemblées avec une architecture. */ +void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *); -/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ - +/* Fournit une instruction désassemblée pour une architecture. */ +GArchInstruction *g_arch_processor_get_instruction(const GArchProcessor *, size_t); -/* Couverture d'un groupe d'instructions */ -typedef struct _instr_coverage  instr_coverage; -/* Note les instructions désassemblées avec une architecture. */ -void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *); +/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ -/* Fournit les instructions désassemblées pour une architecture. */ -GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *); -/* Fournit une instruction désassemblée pour une architecture. */ -GArchInstruction *g_arch_processor_get_disassembled_instruction(const GArchProcessor *, size_t); +/* Couverture d'un groupe d'instructions */ +typedef struct _instr_coverage  instr_coverage; -/* Compte le nombre d'instructions représentées. */ -size_t g_arch_processor_count_disassembled_instructions(const GArchProcessor *);  /* Recherche un groupe d'instruction d'après son adresse. */  const instr_coverage *g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *);  /* Recherche une instruction d'après son adresse. */ -GArchInstruction *_g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *, bool); +GArchInstruction *_g_arch_processor_find_instr_by_address(GArchProcessor *, const vmpa2t *, bool);  /* Recherche rapidement une instruction d'après son adresse. */  GArchInstruction *_g_arch_processor_find_covered_instr_by_address(const GArchProcessor *, const instr_coverage *, const vmpa2t *, bool); -#define g_arch_processor_find_instr_by_address(proc, addr)      \ +#define g_arch_processor_find_instr_by_address(proc, addr)                                          \      _g_arch_processor_find_instr_by_address(proc, addr, false) -#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr)    \ -    _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false) - -/* Fournit l'instruction qui en précède une autre. */ -GArchInstruction *g_arch_processor_get_prev_instr(const GArchProcessor *, const GArchInstruction *); - -/* Fournit l'instruction qui en suit une autre. */ -GArchInstruction *g_arch_processor_get_next_instr(const GArchProcessor *, const GArchInstruction *); +#define g_arch_processor_find_covered_instr_by_address(proc, coverage, addr)                        \ +    ({                                                                                              \ +        GArchInstruction *__result;                                                                 \ +        g_arch_processor_lock(proc);                                                                \ +        __result = _g_arch_processor_find_covered_instr_by_address(proc, coverage, addr, false);    \ +        g_arch_processor_unlock(proc);                                                              \ +        __result;                                                                                   \ +    }) + +/* Met en place un itérateur d'instruction selon une adresse. */ +instr_iter_t *_g_arch_processor_get_iter_from_address(GArchProcessor *, const vmpa2t *, bool); + +/* Met en place un itérateur d'instruction selon une adresse. */ +instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *, const instr_coverage *, const vmpa2t *, bool); + +#define g_arch_processor_get_iter_from_address(proc, addr) \ +    _g_arch_processor_get_iter_from_address(proc, addr, false) + +#define g_arch_processor_get_covered_iter_from_address(proc, coverage, addr)                        \ +    ({                                                                                              \ +        instr_iter_t *__result;                                                                     \ +        g_arch_processor_lock(proc);                                                                \ +        __result = _g_arch_processor_get_covered_iter_from_address(proc, coverage, addr, false);    \ +        g_arch_processor_unlock(proc);                                                              \ +        __result;                                                                                   \ +    })  | 
