From 9aee9648f671ac46dfa4fe3cc71887d1d633b7e4 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 5 Aug 2017 23:17:36 +0200
Subject: Handled any partial replaced instruction when replacing instructions.

---
 ChangeLog                  |  5 +++++
 src/analysis/disass/area.c | 33 +++++++++++++++++++++++++++++----
 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);
 
-- 
cgit v0.11.2-87-g4458