From 8ff010a34762737016624a68f593d0e6736d4349 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 17 Dec 2015 00:46:51 +0100
Subject: Tracked the ARM/Thumb areas in a clever way with levels.

---
 ChangeLog                 | 21 +++++++++++++
 src/arch/arm/context.c    |  2 +-
 src/arch/arm/v7/context.c | 76 ++++++++++++++++++++++-------------------------
 src/arch/arm/v7/context.h |  3 --
 src/arch/arm/v7/fetch.c   | 19 ++++++------
 src/arch/context-int.h    |  5 +++-
 src/arch/context.c        | 26 +++++++++++-----
 src/arch/context.h        |  2 +-
 src/format/format.c       |  4 +--
 9 files changed, 92 insertions(+), 66 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4ba3351..31dca7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+15-12-17  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/arm/context.c:
+	Fix a bug: the last byte is included in the decoding area.
+
+	* src/arch/arm/v7/context.c:
+	* src/arch/arm/v7/context.h:
+	Clean the code. Track the ARM/Thumb areas in a clever way with levels.
+	Fix a bug about overwritten encodings.
+
+	* src/arch/arm/v7/fetch.c:
+	Update calls. Remove some useless hard-coded limits.
+
+	* src/arch/context-int.h:
+	* src/arch/context.c:
+	* src/arch/context.h:
+	Allow to provide extra arguments when pushing new points to disassemble.
+
+	* src/format/format.c:
+	Update calls.
+
 15-12-16  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/vmpa.c:
diff --git a/src/arch/arm/context.c b/src/arch/arm/context.c
index d805e8c..e2a8842 100644
--- a/src/arch/arm/context.c
+++ b/src/arch/arm/context.c
@@ -241,7 +241,7 @@ static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t f
 
     }
 
-    assert(areas[index].start <= addr && addr < areas[index].end);
+    assert(areas[index].start <= addr && addr <= areas[index].end);
 
     return index;
 
diff --git a/src/arch/arm/v7/context.c b/src/arch/arm/v7/context.c
index 030457e..446a972 100644
--- a/src/arch/arm/v7/context.c
+++ b/src/arch/arm/v7/context.c
@@ -63,7 +63,7 @@ static void g_armv7_context_dispose(GArmV7Context *);
 static void g_armv7_context_finalize(GArmV7Context *);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-static void g_armv7_context_push_drop_point(GArmV7Context *, virt_t );
+static void g_armv7_context_push_drop_point(GArmV7Context *, unsigned int, virt_t, va_list);
 
 
 
@@ -196,8 +196,10 @@ GArmV7Context *g_armv7_context_new(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
-*                addr = adresse d'un nouveau point de départ à traiter.       *
+*  Paramètres  : ctx   = contexte de désassemblage à compléter.               *
+*                level = indication de priorité et d'origine de l'adresse.    *
+*                addr  = adresse d'un nouveau point de départ à traiter.      *
+*                ap    = forme générique d'un encodage à mémoriser.           *
 *                                                                             *
 *  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
 *                                                                             *
@@ -207,53 +209,45 @@ GArmV7Context *g_armv7_context_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr)
+static void g_armv7_context_push_drop_point(GArmV7Context *ctx, unsigned int level, virt_t addr, va_list ap)
 {
-	if (addr & 0x1)
-	{
-		addr -= 0x1;
-        g_armv7_context_define_encoding(ctx, addr, AV7IS_THUMB);
-	}
-    else
-        g_armv7_context_define_encoding(ctx, addr, AV7IS_ARM);
+    ArmV7InstrSet marker;                   /* Type de jeu d'instructions  */
 
-	G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr);
+    switch (level)
+    {
+        case 0:
 
-}
+            if (addr & 0x1)
+            {
+                addr -= 0x1;
+                marker = AV7IS_THUMB;
+            }
+            else
+                marker = AV7IS_ARM;
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : ctx    = contexte de désassemblage à compléter.              *
-*                addr   = adresse d'un nouveau point de départ à traiter.     *
-*                marker = forme générique d'un encodage à mémoriser.          *
-*                                                                             *
-*  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+            break;
+
+        default:
+
+            marker = va_arg(ap, ArmV7InstrSet);
+
+            /**
+             * Attention : toute adresse impaire est destinée à du mode Thumb.
+             *
+             * Mais la réciproque n'est pas vraie : le mode Thumb peut aussi
+             * manipuler des adresses paires.
+             */
+            assert(((addr & 0x1) && marker == AV7IS_THUMB) || (addr & 0x1) == 0);
+
+            addr &= ~0x1;
+
+            break;
 
-void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker)
-{
-	if (addr & 0x1)
-	{
-		addr -= 0x1;
-        assert(marker == AV7IS_THUMB);
     }
 
     g_armv7_context_define_encoding(ctx, addr, marker);
 
-    /**
-     * Il faut impérativement passer pour l'interface publique afin :
-     *  - de poser le verrou associé.
-     *  - de déclencher l'émission du signal lié.
-     *
-     * Pas d'appel via G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point() donc.
-     */
-
-    g_proc_context_push_drop_point(G_PROC_CONTEXT(ctx), addr);
+    G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), level, addr, ap);
 
 }
 
diff --git a/src/arch/arm/v7/context.h b/src/arch/arm/v7/context.h
index 48cafce..b7edfd5 100644
--- a/src/arch/arm/v7/context.h
+++ b/src/arch/arm/v7/context.h
@@ -76,9 +76,6 @@ void g_armv7_context_define_encoding(GArmV7Context *, virt_t, ArmV7InstrSet);
 /* Indique l'encodage (générique) utilisé à une adresse donnée. */
 ArmV7InstrSet g_armv7_context_find_encoding(GArmV7Context *, virt_t);
 
-/* Ajoute une adresse virtuelle comme point de départ de code. */
-void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker);
-
 
 
 #endif  /* _ARCH_ARM_V7_CONTEXT_H */
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index da83d15..33a9e92 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -99,7 +99,7 @@ void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchPr
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
 
 }
 
@@ -168,7 +168,7 @@ void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchP
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
 
 }
 
@@ -227,7 +227,7 @@ void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArch
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, iset);
 
 }
 
@@ -280,12 +280,12 @@ void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchP
         case AV7IS_ARM:
             pc += 8;
             //g_armv7_context_define_encoding(context, 
-            g_armv7_context_push_drop_point_ext(context, pc, AV7IS_THUMB);
+            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, pc, AV7IS_THUMB);
             break;
         case AV7IS_THUMB:
             pc += 4;
             //g_armv7_context_define_encoding(context, 
-            g_armv7_context_push_drop_point_ext(context, pc, AV7IS_ARM);
+            g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, pc, AV7IS_ARM);
             break;
         default:
             assert(0);
@@ -342,7 +342,7 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 3, target, AV7IS_THUMB);
 
 }
 
@@ -506,9 +506,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
 
     /// FIXME ?!
-    if (target < 0x8000) return;
+    //if (target < 0x8000) return;
 
-    if (target > 0x6966c) return;
+    //if (target > 0x6966c) return;
 
 
     new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
@@ -523,8 +523,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
     //target = pc + offset;
 
+
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
+    g_proc_context_push_drop_point(G_PROC_CONTEXT(context), 0/*FIXME*/, target);
 
 
     //exit(0);
diff --git a/src/arch/context-int.h b/src/arch/context-int.h
index b7f7a20..885c2f6 100644
--- a/src/arch/context-int.h
+++ b/src/arch/context-int.h
@@ -28,13 +28,16 @@
 #include "context.h"
 
 
+#include <stdarg.h>
+
+
 
 /* Granularité des allocations */
 #define DP_ALLOC_BLOCK 10
 
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-typedef void (* push_drop_point_fc) (GProcContext *, virt_t);
+typedef void (* push_drop_point_fc) (GProcContext *, unsigned int, virt_t, va_list);
 
 
 /* Définition d'un contexte pour processeur (instance) */
diff --git a/src/arch/context.c b/src/arch/context.c
index fe2e220..bb1d80a 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -40,7 +40,7 @@ static void g_proc_context_class_init(GProcContextClass *);
 static void g_proc_context_init(GProcContext *);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-static void _g_proc_context_push_drop_point(GProcContext *, virt_t);
+static void _g_proc_context_push_drop_point(GProcContext *, unsigned int, virt_t, va_list);
 
 
 
@@ -104,8 +104,10 @@ static void g_proc_context_init(GProcContext *ctx)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
-*                addr = adresse d'un nouveau point de départ à traiter.       *
+*  Paramètres  : ctx   = contexte de désassemblage à compléter.               *
+*                level = indication de priorité et d'origine de l'adresse.    *
+*                addr  = adresse d'un nouveau point de départ à traiter.      *
+*                ap    = éventuelles informations complémentaires.            *
 *                                                                             *
 *  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
 *                                                                             *
@@ -115,7 +117,7 @@ static void g_proc_context_init(GProcContext *ctx)
 *                                                                             *
 ******************************************************************************/
 
-static void _g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
+static void _g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_t addr, va_list ap)
 {
     if (ctx->dp_count >= ctx->dp_allocated)
     {
@@ -132,8 +134,10 @@ static void _g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
-*                addr = adresse d'un nouveau point de départ à traiter.       *
+*  Paramètres  : ctx   = contexte de désassemblage à compléter.               *
+*                level = indication de priorité et d'origine de l'adresse.    *
+*                addr  = adresse d'un nouveau point de départ à traiter.      *
+*                ...   = éventuelles informations complémentaires.            *
 *                                                                             *
 *  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
 *                                                                             *
@@ -143,16 +147,22 @@ static void _g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
 *                                                                             *
 ******************************************************************************/
 
-void g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr)
+void g_proc_context_push_drop_point(GProcContext *ctx, unsigned int level, virt_t addr, ...)
 {
+    va_list ap;                             /* Arguments complémentaires ? */
+
+    va_start(ap, addr);
+
     g_mutex_lock(&ctx->dp_access);
 
-    G_PROC_CONTEXT_GET_CLASS(ctx)->push_point(ctx, addr);
+    G_PROC_CONTEXT_GET_CLASS(ctx)->push_point(ctx, level, addr, ap);
 
     g_mutex_unlock(&ctx->dp_access);
 
     g_signal_emit_by_name(ctx, "drop-point-pushed");
 
+    va_end(ap);
+
 }
 
 
diff --git a/src/arch/context.h b/src/arch/context.h
index 36eb3e6..5dffd6a 100644
--- a/src/arch/context.h
+++ b/src/arch/context.h
@@ -52,7 +52,7 @@ typedef struct _GProcContextClass GProcContextClass;
 GType g_proc_context_get_type(void);
 
 /* Ajoute une adresse virtuelle comme point de départ de code. */
-void g_proc_context_push_drop_point(GProcContext *, virt_t);
+void g_proc_context_push_drop_point(GProcContext *, unsigned int, virt_t, ...);
 
 /* Précise si une adresse donnée figure comme point de départ. */
 bool g_proc_context_has_addr_as_drop_points(GProcContext *, virt_t);
diff --git a/src/format/format.c b/src/format/format.c
index 82d9e42..323e006 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -208,10 +208,10 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *format, GProc
     size_t i;                               /* Boucle de parcours          */
 
     for (i = 0; i < format->ep_count; i++)
-        g_proc_context_push_drop_point(ctx, format->entry_points[i]);
+        g_proc_context_push_drop_point(ctx, 0, format->entry_points[i]);
 
     for (i = 0; i < format->xp_count; i++)
-        g_proc_context_push_drop_point(ctx, format->extra_points[i]);
+        g_proc_context_push_drop_point(ctx, 0, format->extra_points[i]);
 
 }
 
-- 
cgit v0.11.2-87-g4458