diff options
Diffstat (limited to 'src/arch/processor.c')
| -rw-r--r-- | src/arch/processor.c | 177 | 
1 files changed, 173 insertions, 4 deletions
| diff --git a/src/arch/processor.c b/src/arch/processor.c index 7e2ecec..c70d586 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -63,13 +63,26 @@ static void g_arch_processor_init(GArchProcessor *); +/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */ + + +/* Démarre la définition d'un nouveau groupe d'instructions. */ +static void g_arch_processor_add_new_coverage(GArchProcessor *, GArchInstruction *, size_t); + +/* Termine la définition d'un nouveau groupe d'instructions. */ +static void g_arch_processor_finish_last_coverage(GArchProcessor *, GArchInstruction *, size_t); + +/* Recherche un groupe d'instruction d'après son adresse. */ +static bool g_arch_processor_find_coverage_by_address(const GArchProcessor *, const vmpa2t *, size_t *, size_t *); + + +  /* Indique le type défini pour un processeur d'architecture. */  G_DEFINE_TYPE(GArchProcessor, g_arch_processor, G_TYPE_OBJECT); -  /******************************************************************************  *                                                                             *  *  Paramètres  : klass = classe à initialiser.                                * @@ -102,6 +115,9 @@ static void g_arch_processor_class_init(GArchProcessorClass *klass)  static void g_arch_processor_init(GArchProcessor *proc)  { +    proc->coverages = NULL; +    proc->cov_allocated = 0; +    proc->cov_count = 0;  } @@ -307,6 +323,131 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc  /******************************************************************************  *                                                                             * +*  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.   * +*                                                                             * +*  Description : Termine la définition d'un nouveau groupe d'instructions.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_arch_processor_finish_last_coverage(GArchProcessor *proc, GArchInstruction *last, size_t end) +{ +    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; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : proc  = processeur recensant diverses instructions.          * +*                addr  = position en mémoire ou physique à chercher.          * +*                start = indice de départ du groupe concerné trouvé. [OUT]    * +*                end   = indice de fin du groupe d'instructions visées. [OUT] * +*                                                                             * +*  Description : Recherche un groupe d'instruction d'après son adresse.       * +*                                                                             * +*  Retour      : Bilan de la recherche menée.                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arch_processor_find_coverage_by_address(const GArchProcessor *proc, const vmpa2t *addr, size_t *start, size_t *count) +{ +    bool result;                            /* Bilan à retourner           */ +    void *ptr;                              /* Résultat des recherches     */ + +    int search_for_coverage_by_addr(const vmpa2t *a, const instr_coverage *c) +    { +        int status;                         /* Bilan d'une comparaison     */ + +        status = cmp_mrange_with_vmpa(&c->range, a); + +        return status; + +    } + +    ptr = bsearch(addr, proc->coverages, proc->cov_count, +                  sizeof(instr_coverage), (__compar_fn_t)search_for_coverage_by_addr); + +    if (ptr != NULL) +    { +        result = true; +        *start = ((instr_coverage *)ptr)->start; +        *count = ((instr_coverage *)ptr)->count; +    } +    else +        result = false; + +    return result; + +} + + + + + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : proc = architecture visée par la procédure.                  *  *                list = liste des instructions désassemblées.                 *  *                                                                             * @@ -320,11 +461,14 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc  void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list)  { +    GArchInstruction *last;                 /* Dernière instruction traitée*/      GArchInstruction *iter;                 /* Boucle de parcours          */      /* TODO : vider une éventuelle liste existante */      /* TODO : incrémenter les références (cf. code Python) */ +    last = NULL; +      ainstr_list_for_each(iter, list)      {          /* Mise à disposition de d'avantage d'espace */ @@ -337,10 +481,26 @@ void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchI          } +        /* Constitution des groupes */ +        if (last == NULL || g_arch_instruction_get_flags(iter) & AIF_ROUTINE_START) +        { +            if (last != NULL) +                g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1); + +            g_arch_processor_add_new_coverage(proc, iter, proc->instr_count); + +        } + +        /* Enregistrement */          proc->instructions[proc->instr_count++] = iter; +        last = iter; +      } +    if (last != NULL) +        g_arch_processor_finish_last_coverage(proc, last, proc->instr_count - 1); +  } @@ -383,6 +543,8 @@ GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProc  GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr)  {      GArchInstruction *result;               /* Trouvaille à retourner      */ +    size_t cov_start;                       /* Début d'un groupe ciblé     */ +    size_t cov_count;                       /* Nombre d'éléments à tester  */      void *ptr;                              /* Résultat des recherches     */      int search_for_instr_by_addr(const vmpa2t *a, const GArchInstruction **b) @@ -395,10 +557,17 @@ GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *p      } -    ptr = bsearch(addr, proc->instructions, proc->instr_count, -                  sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr); -    result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); +    if (g_arch_processor_find_coverage_by_address(proc, addr, &cov_start, &cov_count)) +    { +        ptr = bsearch(addr, &proc->instructions[cov_start], cov_count, +                      sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr); + +        result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL); + +    } +    else +        result = NULL;      return result; | 
