summaryrefslogtreecommitdiff
path: root/src/arch/processor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/processor.c')
-rw-r--r--src/arch/processor.c177
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;