summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/analysis/disass/area.c33
2 files changed, 34 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 1a4768d..b710ca2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+17-08-05 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/disass/area.c:
+ Handle any partial replaced instruction when replacing instructions.
+
17-07-28 Cyrille Bagard <nocbos@gmail.com>
* src/gtkext/easygtk.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 06893ff..9a5387c 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -372,6 +372,8 @@ static bool mark_range_in_mem_area_as_processed(mem_area *area, GArchInstruction
const vmpa2t *addr; /* Début de la zone à traiter */
phys_t len; /* Taille de l'aire visée */
phys_t offset; /* Décallage de départ */
+ phys_t coverage_start; /* Début de zone à vider */
+ phys_t coverage_len; /* Taille de cette même zone */
phys_t i; /* Boucle de parcours */
GArchInstruction *old; /* Instruction remplacée */
const mrange_t *old_range; /* Emplacement de l'instruction*/
@@ -445,19 +447,42 @@ 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; i < len; i++)
+ coverage_start = offset;
+ coverage_len = len;
+
+ /**
+ * Par ailleurs, il se peut que la nouvelle instruction ne couvre
+ * que partiellement une instruction existante.
+ *
+ * Il faut donc dans ce cas remonter la table des enregistrements
+ * pour retrouver l'instruction à l'origine de la couverture à remplacer.
+ */
+
+ while (area->instructions[coverage_start] == NULL)
+ {
+ if (coverage_start == 0)
+ break;
+
+ coverage_start--;
+ coverage_len++;
+
+ }
+
+ assert(area->instructions[coverage_start] != NULL);
+
+ for (i = 0; i < coverage_len; i++)
{
- old = area->instructions[offset + i];
+ old = area->instructions[coverage_start + 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);
+ reset_in_bit_field(area->processed, coverage_start + i, old_len);
g_object_unref(G_OBJECT(old));
- area->instructions[offset + i] = NULL;
+ area->instructions[coverage_start + i] = NULL;
g_atomic_pointer_add(&area->count, -1);