summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-08-05 21:17:36 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-08-05 21:17:36 (GMT)
commit9aee9648f671ac46dfa4fe3cc71887d1d633b7e4 (patch)
treee4cc0cc21dc9deb292f0e39b431aa5ff4f4c72aa /src
parent16ce1225f1faf51d7cb8eba4f7fb8b5ec2fac2a2 (diff)
Handled any partial replaced instruction when replacing instructions.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/disass/area.c33
1 files changed, 29 insertions, 4 deletions
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);