diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-05-10 20:21:56 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-05-10 20:21:56 (GMT) |
commit | 8e76324b01e5b4979f346f0bc8c84372477a3d38 (patch) | |
tree | 3db4057e113aa9f664f5b217dd349bb1e9288009 /src/analysis | |
parent | b0c6ffacf5c6c45c047172e348c737cb85fb5b36 (diff) |
Rewritten the whole bitfield management.
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/disass/area.c | 57 | ||||
-rw-r--r-- | src/analysis/disass/dragon.c | 2 |
2 files changed, 44 insertions, 15 deletions
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index f01b89c..ed53b28 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -60,6 +60,7 @@ typedef struct _mem_area bitfield_t *processed; /* Octets traités dans la zone */ GArchInstruction **instructions; /* Instructions en place */ size_t count; /* Quantité d'instructions */ + GMutex mutex; /* Garantie d'atomicité */ bool is_exec; /* Zone exécutable ? */ @@ -249,6 +250,7 @@ static void init_mem_area_from_addr(mem_area *area, const vmpa2t *addr, phys_t l area->processed = create_bit_field(len, false); area->instructions = (GArchInstruction **)calloc(len, sizeof(GArchInstruction *)); area->count = 0; + g_mutex_init(&area->mutex); } @@ -284,6 +286,8 @@ static void fini_mem_area(mem_area *area) free(area->instructions); + g_mutex_clear(&area->mutex); + } @@ -365,6 +369,10 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction phys_t offset; /* Décallage de départ */ phys_t i; /* Boucle de parcours */ GArchInstruction *old; /* Instruction remplacée */ + const mrange_t *old_range; /* Emplacement de l'instruction*/ + phys_t old_len; /* Taille de cette instruction */ + + /* Détermination de la couverture */ start = get_mrange_addr(&area->range); @@ -374,21 +382,23 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction offset = compute_vmpa_diff(start, addr); - result = set_atomic_in_bit_field(area->processed, offset, len); + /* Début des choses sérieuses */ + + g_mutex_lock(&area->mutex); - /* Si l'instruction était bien la première à s'inscrire... */ + /* Vérification de couverture */ - result |= force; + result = test_none_in_bit_field(area->processed, offset, len); - if (result) + if (!result) { - assert(area->instructions[offset] == NULL || force); + if (!force) goto mrimaap_exit; /** * Un cas de remplacement forcé intervient en ARM, lorsque qu'une * instruction utilise une valeur immédiate placée dans le code. * - * Cette valeur est référencée en tant que symbole. + * Cette valeur doit être référencée en tant que donnée. * * Mais cette même valeur a pu être désassemblée en tant que code * exécutable si le flot d'exécution s'est poursuivi jusqu'à elle. @@ -400,33 +410,52 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction * On réinitialise donc la zone couverte par la nouvelle instruction. */ - for (i = 0; force && i < len; i++) + for (i = 0; i < len; i++) { old = area->instructions[offset + i]; if (old != NULL) { + old_range = g_arch_instruction_get_range(old); + old_len = get_mrange_length(old_range); + + reset_in_bit_field(area->processed, offset + i, old_len); + g_object_unref(G_OBJECT(old)); area->instructions[offset + i] = NULL; + g_atomic_pointer_add(&area->count, -1); + } } + result = true; + + } + + /* Inscription de l'instruction dans les comptes */ + #ifndef NDEBUG - for (i = 0; i < len; i++) - assert(area->instructions[offset + i] == NULL); + for (i = 0; i < len; i++) + assert(area->instructions[offset + i] == NULL); #endif - area->instructions[offset] = instr; - g_atomic_pointer_add(&area->count, 1); + set_in_bit_field(area->processed, offset, len); - /* Au passage, association du contenu */ - g_arch_instruction_set_global_content(instr, area->content); + area->instructions[offset] = instr; + g_atomic_pointer_add(&area->count, 1); - } + /* Au passage, association du contenu */ + g_arch_instruction_set_global_content(instr, area->content); + + mrimaap_exit: + + /* Fin des choses sérieuses */ + + g_mutex_unlock(&area->mutex); return result; diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c index 75ccc40..9064af8 100644 --- a/src/analysis/disass/dragon.c +++ b/src/analysis/disass/dragon.c @@ -591,7 +591,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count) set_in_bit_field(inter, k, 1); - if (!is_bit_field_equal_to(node->bits, inter)) + if (compare_bit_fields(node->bits, inter) != 0) { copy_bit_field(node->bits, inter); changed = true; |