diff options
Diffstat (limited to 'src/arch/processor.c')
-rw-r--r-- | src/arch/processor.c | 329 |
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; |