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.c329
1 files changed, 190 insertions, 139 deletions
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;