From cc3e31eecd90766ae4f0bb391428c5c59567ef4c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 9 Jan 2015 22:30:16 +0000
Subject: Chosen the right encoding to use when disassembling ARM binary.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@452 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   |  29 +++++
 src/arch/arm/Makefile.am    |   1 +
 src/arch/arm/context-int.h  |  74 ++++++++++++
 src/arch/arm/context.c      | 216 +++++++++++++++++++++++++++++------
 src/arch/arm/processor.c    |  28 -----
 src/arch/arm/v7/Makefile.am |   1 +
 src/arch/arm/v7/context.c   | 267 ++++++++++++++++++++++++++++++++++++++++++++
 src/arch/arm/v7/context.h   |  82 ++++++++++++++
 src/arch/arm/v7/link.c      |  27 ++++-
 src/arch/arm/v7/link.h      |   5 +-
 src/arch/arm/v7/processor.c | 117 ++++++++++++++-----
 11 files changed, 749 insertions(+), 98 deletions(-)
 create mode 100644 src/arch/arm/context-int.h
 create mode 100644 src/arch/arm/v7/context.c
 create mode 100644 src/arch/arm/v7/context.h

diff --git a/ChangeLog b/ChangeLog
index 6420043..4c93b08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+15-01-09  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/arm/context.c:
+	Update code. Deal with generic markers for code disassembling.
+
+	* src/arch/arm/context-int.h:
+	New entry: allow to subclass an ARM context.
+
+	* src/arch/arm/Makefile.am:
+	Add the 'context-int.h' file to libarcharm_la_SOURCES.
+
+	* src/arch/arm/processor.c:
+	Do not provide a generic context for ARM anymore.
+
+	* src/arch/arm/v7/context.c:
+	* src/arch/arm/v7/context.h:
+	New entries: create a context for ARM v7 disassembling.
+
+	* src/arch/arm/v7/link.c:
+	* src/arch/arm/v7/link.h:
+	Update code.
+
+	* src/arch/arm/v7/Makefile.am:
+	Add the 'context.[ch]' files to libarcharmv7_la_SOURCES.
+
+	* src/arch/arm/v7/processor.c:
+	Provide a specific context for ARM v7 disassembling. Update code and
+	choose the right encoding to use when disassembling ARM binary.
+
 15-01-08  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/dialogs/goto.c:
diff --git a/src/arch/arm/Makefile.am b/src/arch/arm/Makefile.am
index 1c9ace8..0fde813 100644
--- a/src/arch/arm/Makefile.am
+++ b/src/arch/arm/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libarcharm.la
 
 libarcharm_la_SOURCES =					\
 	cond.h								\
+	context-int.h						\
 	context.h context.c					\
 	instruction-int.h					\
 	instruction.h instruction.c			\
diff --git a/src/arch/arm/context-int.h b/src/arch/arm/context-int.h
new file mode 100644
index 0000000..51ed6d0
--- /dev/null
+++ b/src/arch/arm/context-int.h
@@ -0,0 +1,74 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context-int.h - prototypes internes pour le contexte lié à l'exécution d'un processeur
+ *
+ * Copyright (C) 2011-2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_ARM_CONTEXT_INT_H
+#define _ARCH_ARM_CONTEXT_INT_H
+
+
+#include "context.h"
+
+
+#include "../context-int.h"
+
+
+
+/* Découpage de la zone de désassemblage */
+typedef struct _disass_arm_area
+{
+    virt_t start;                           /* Début de la zone            */
+    virt_t end;                             /* Fin de la zone              */
+
+    unsigned int marker;                    /* Type de décodage associé    */
+
+} disass_arm_area;
+
+
+/* Définition d'un contexte pour processeur ARM (instance) */
+struct _GArmContext
+{
+    GProcContext parent;                    /* A laisser en premier        */
+
+    disass_arm_area *areas;                 /* Désassemblage découpé       */
+    size_t acount;                          /* Nombre de zones définies    */
+
+};
+
+
+/* Définition d'un contexte pour processeur ARM (classe) */
+struct _GArmContextClass
+{
+    GProcContextClass parent;               /* A laisser en premier        */
+
+};
+
+
+
+/* Enregistre l'encodage (générique) utilisé à une adresse. */
+void _g_arm_context_define_encoding(GArmContext *, virt_t, unsigned int);
+
+/* Indique l'encodage (générique) utilisé à une adresse donnée. */
+unsigned int _g_arm_context_find_encoding(GArmContext *, virt_t);
+
+
+
+#endif  /* _ARCH_ARM_CONTEXT_INT_H */
diff --git a/src/arch/arm/context.c b/src/arch/arm/context.c
index 7f41b92..24546c0 100644
--- a/src/arch/arm/context.c
+++ b/src/arch/arm/context.c
@@ -24,28 +24,17 @@
 #include "context.h"
 
 
-#include "../context-int.h"
-#include "../../decomp/context-int.h"
-
-
-
-/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
-
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
 
-/* Définition d'un contexte pour processeur ARM (instance) */
-struct _GArmContext
-{
-    GProcContext parent;                    /* A laisser en premier        */
 
-};
+#include "context-int.h"
+#include "../../decomp/context-int.h"
 
 
-/* Définition d'un contexte pour processeur ARM (classe) */
-struct _GArmContextClass
-{
-    GProcContextClass parent;               /* A laisser en premier        */
 
-};
+/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
 
 
 /* Initialise la classe des contextes de processeur ARM. */
@@ -60,8 +49,8 @@ static void g_arm_context_dispose(GArmContext *);
 /* Procède à la libération totale de la mémoire. */
 static void g_arm_context_finalize(GArmContext *);
 
-/* Ajoute une adresse virtuelle comme point de départ de code. */
-static void g_arm_context_push_drop_point(GArmContext *, virt_t );
+/* Indique l'encodage (générique) utilisé à une adresse donnée. */
+static size_t find_disass_arm_area(disass_arm_area *, virt_t, size_t, size_t);
 
 
 
@@ -127,17 +116,12 @@ G_DEFINE_TYPE(GArmContext, g_arm_context, G_TYPE_PROC_CONTEXT);
 static void g_arm_context_class_init(GArmContextClass *klass)
 {
     GObjectClass *object;                   /* Autre version de la classe  */
-    GProcContextClass *proc;                /* Version parente de la classe*/
 
     object = G_OBJECT_CLASS(klass);
 
     object->dispose = (GObjectFinalizeFunc/* ! */)g_arm_context_dispose;
     object->finalize = (GObjectFinalizeFunc)g_arm_context_finalize;
 
-	proc = G_PROC_CONTEXT_CLASS(klass);
-
-	proc->push_point = (push_drop_point_fc)g_arm_context_push_drop_point;
-
 }
 
 
@@ -222,10 +206,61 @@ GArmContext *g_arm_context_new(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
-*                addr = adresse d'un nouveau point de départ à traiter.       *
+*  Paramètres  : areas = ensemble des découpages du désassemblage.            *
+*                addr = adresse d'un nouveau point de départ à retrouver.     *
+*                first = indice de la première zone à considérer.             *
+*                last  = indice de la dernière zone à considérer.             *
+*                                                                             *
+*  Description : Indique l'encodage (générique) utilisé à une adresse donnée. *
 *                                                                             *
-*  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
+*  Retour      : Marqueur à priori toujours valide.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static size_t find_disass_arm_area(disass_arm_area *areas, virt_t addr, size_t first, size_t last)
+{
+    size_t index;                           /* Indice de cellule idéale    */
+    size_t mid;                             /* Division de l'espace        */
+
+    printf(" < 0x%08x > %zu / %zu...\n", addr, first, last);
+
+    if (first == last)
+        index = first;
+
+    else
+    {
+        mid = first + (last - first + 1) / 2;
+
+        printf(" --looking-- %zu / %zu -> %zu\n", first, last, mid);
+
+        if (areas[mid].start <= addr)
+            index = find_disass_arm_area(areas, addr, mid, last);
+        else
+            index = find_disass_arm_area(areas, addr, first, mid - 1);
+
+    }
+
+    printf(" !! FOUND !! (for 0x%08x) --  [%zu] [%zu/%zu] 0x%08x <-> 0x%08x\n",
+           (unsigned int)addr, index, first, last,
+           (unsigned int)areas[index].start,
+           (unsigned int)areas[index].end);
+
+    assert(areas[index].start <= addr && addr < areas[index].end);
+
+    return index;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx    = contexte de désassemblage à compléter.              *
+*                addr   = adresse d'un nouveau point de départ à créer.       *
+*                marker = forme générique d'un encodage à mémoriser.          *
+*                                                                             *
+*  Description : Enregistre l'encodage (générique) utilisé à une adresse.     *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -233,29 +268,138 @@ GArmContext *g_arm_context_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static void g_arm_context_push_drop_point(GArmContext *ctx, virt_t addr)
+void _g_arm_context_define_encoding(GArmContext *ctx, virt_t addr, unsigned int marker)
 {
+    size_t selected;                        /* Zone associée à une adresse */
+
+    /* TODO : pose de verroux ? */
+
+    selected = find_disass_arm_area(ctx->areas, addr, 0, ctx->acount - 1);
+
+    /* S'agit-il d'une redéfinition ? */
+    if (ctx->areas[selected].start == addr)
+        ctx->areas[selected].marker = marker;
+
+    /* Sinon on redivise... */
+    else
+    {
+
+
+
+
+
+    do
+    {
+        unsigned int i;
+
+        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr);
 
+        for (i = 0; i < ctx->acount; i++)
+            printf(" --def before-- [%u] 0x%08x <-> 0x%08x\n",
+                   i,
+                   (unsigned int)ctx->areas[i].start,
+                   (unsigned int)ctx->areas[i].end);
 
-	printf("PUSH !!\n");
+    }
+    while (0);
 
 
 
-	if (addr & 0x1)
-	{
-		addr -= 0x1;
 
 
-	}
-	else ;
 
-	// ARM / Thumb
 
-	G_PROC_CONTEXT_CLASS(g_arm_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr);
+        ctx->areas = (disass_arm_area *)realloc(ctx->areas, ++ctx->acount * sizeof(disass_arm_area));
+
+        memmove(&ctx->areas[selected + 1], &ctx->areas[selected],
+                (ctx->acount - selected - 1) * sizeof(disass_arm_area));
+
+        ctx->areas[selected].start = ctx->areas[selected + 1].start;
+        ctx->areas[selected].end = addr - 1;
+        ctx->areas[selected].marker = ctx->areas[selected + 1].marker;
+
+        ctx->areas[selected + 1].start = addr;
+        ctx->areas[selected + 1].marker = marker;
+
+
+
+    do
+    {
+        unsigned int i;
+
+        for (i = 0; i < ctx->acount; i++)
+            printf(" --def after-- [%u] 0x%08x <-> 0x%08x\n",
+                   i,
+                   (unsigned int)ctx->areas[i].start,
+                   (unsigned int)ctx->areas[i].end);
+
+    }
+    while (0);
+
+
+
+
+
+
+    }
+
+
+
+
+    /*
+    do
+    {
+        unsigned int i;
+
+        printf(" --sel-- %u for 0x%08x\n", (unsigned int)selected, (unsigned int)addr);
+
+        for (i = 0; i < ctx->acount; i++)
+            printf(" --def-- [%u] 0x%08x <-> 0x%08x\n",
+                   i,
+                   (unsigned int)ctx->areas[i].start,
+                   (unsigned int)ctx->areas[i].end);
+
+    }
+    while (0);
+    */
+
+
+
+
 
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à consulter.                *
+*                addr = adresse d'un nouveau point de départ à retrouver.     *
+*                                                                             *
+*  Description : Indique l'encodage (générique) utilisé à une adresse donnée. *
+*                                                                             *
+*  Retour      : Marqueur à priori toujours valide.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int _g_arm_context_find_encoding(GArmContext *ctx, virt_t addr)
+{
+    size_t selected;                        /* Zone associée à une adresse */
+
+    /* TODO : pose de verroux ? */
+
+    selected = find_disass_arm_area(ctx->areas, addr, 0, ctx->acount - 1);
+
+    return ctx->areas[selected].marker;
+
+}
+
+
+
+
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                           CONTEXTE POUR LA DECOMPILATION                           */
diff --git a/src/arch/arm/processor.c b/src/arch/arm/processor.c
index cf993c0..2c676be 100644
--- a/src/arch/arm/processor.c
+++ b/src/arch/arm/processor.c
@@ -24,7 +24,6 @@
 #include "processor.h"
 
 
-#include "context.h"
 #include "processor-int.h"
 
 
@@ -41,9 +40,6 @@ static void g_arm_processor_dispose(GArmProcessor *);
 /* Procède à la libération totale de la mémoire. */
 static void g_arm_processor_finalize(GArmProcessor *);
 
-/* Fournit un contexte pour l'exécution du processeur ARM. */
-static GArmContext *g_arm_processor_get_context(const GArmProcessor *);
-
 
 
 /* Indique le type défini par la GLib pour le processeur ARM. */
@@ -88,11 +84,6 @@ static void g_arm_processor_class_init(GArmProcessorClass *klass)
 
 static void g_arm_processor_init(GArmProcessor *proc)
 {
-    GArchProcessor *parent;                 /* Instance parente            */
-
-    parent = G_ARCH_PROCESSOR(proc);
-
-    parent->get_ctx = (get_processor_context_fc)g_arm_processor_get_context;
 
 }
 
@@ -133,22 +124,3 @@ static void g_arm_processor_finalize(GArmProcessor *proc)
     G_OBJECT_CLASS(g_arm_processor_parent_class)->finalize(G_OBJECT(proc));
 
 }
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : proc = architecture, spectatrice ici.                        *
-*                                                                             *
-*  Description : Fournit un contexte pour l'exécution du processeur Arm.      *
-*                                                                             *
-*  Retour      : Contexte mis en place.                                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static GArmContext *g_arm_processor_get_context(const GArmProcessor *proc)
-{
-    return g_arm_context_new();
-
-}
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 28a899e..22e93d4 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libarcharmv7.la
 
 libarcharmv7_la_SOURCES =				\
 	arm.h arm.c							\
+	context.h context.c					\
 	helpers.h helpers.c					\
 	instruction.h instruction.c			\
 	link.h link.c						\
diff --git a/src/arch/arm/v7/context.c b/src/arch/arm/v7/context.c
new file mode 100644
index 0000000..41ffd29
--- /dev/null
+++ b/src/arch/arm/v7/context.c
@@ -0,0 +1,267 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.c - contexte lié à l'exécution d'un processeur
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "context.h"
+
+
+#include "../context-int.h"
+
+
+
+/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
+
+
+/* Définition d'un contexte pour processeur ARM (instance) */
+struct _GArmV7Context
+{
+    GArmContext parent;                     /* A laisser en premier        */
+
+};
+
+
+/* Définition d'un contexte pour processeur ARM (classe) */
+struct _GArmV7ContextClass
+{
+    GArmContextClass parent;                /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des contextes de processeur ARM. */
+static void g_armv7_context_class_init(GArmV7ContextClass *);
+
+/* Initialise une instance de contexte de processeur ARM. */
+static void g_armv7_context_init(GArmV7Context *);
+
+/* Supprime toutes les références externes. */
+static void g_armv7_context_dispose(GArmV7Context *);
+
+/* Procède à la libération totale de la mémoire. */
+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 );
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          MANIPULATION GLOBALE DU CONTEXTE                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type définit par la GLib pour le contexte de processeur ARM. */
+G_DEFINE_TYPE(GArmV7Context, g_armv7_context, G_TYPE_ARM_CONTEXT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des contextes de processeur ARM.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_context_class_init(GArmV7ContextClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GProcContextClass *proc;                /* Version parente de la classe*/
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_context_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_armv7_context_finalize;
+
+	proc = G_PROC_CONTEXT_CLASS(klass);
+
+	proc->push_point = (push_drop_point_fc)g_armv7_context_push_drop_point;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx = instance à initialiser.                                *
+*                                                                             *
+*  Description : Initialise une instance de contexte de processeur ARM.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_context_init(GArmV7Context *ctx)
+{
+    GArmContext *base;                      /* Autre version du contexte   */
+
+    base = G_ARM_CONTEXT(ctx);
+
+    base->areas = (disass_arm_area *)calloc(1, sizeof(disass_arm_area));
+    base->acount = 1;
+
+    base->areas[0].start = 0;
+    base->areas[0].end = (virt_t)-1;
+    base->areas[0].marker = AV7IS_ARM;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx = instance d'objet GLib à traiter.                       *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_context_dispose(GArmV7Context *ctx)
+{
+    G_OBJECT_CLASS(g_armv7_context_parent_class)->dispose(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx = instance d'objet GLib à traiter.                       *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_context_finalize(GArmV7Context *ctx)
+{
+    G_OBJECT_CLASS(g_armv7_context_parent_class)->finalize(G_OBJECT(ctx));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée un contexte pour l'exécution du processeur ARM.         *
+*                                                                             *
+*  Retour      : Contexte mis en place.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArmV7Context *g_armv7_context_new(void)
+{
+    GArmV7Context *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_ARMV7_CONTEXT, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à compléter.                *
+*                addr = adresse d'un nouveau point de départ à traiter.       *
+*                                                                             *
+*  Description : Ajoute une adresse virtuelle comme point de départ de code.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr)
+{
+
+
+	printf("PUSH v7 !!\n");
+
+
+
+	if (addr & 0x1)
+	{
+		addr -= 0x1;
+        g_armv7_context_define_encoding(ctx, addr, AV7IS_THUMB);
+	}
+    else
+        g_armv7_context_define_encoding(ctx, addr, AV7IS_ARM);
+
+	G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr);
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx    = contexte de désassemblage à compléter.              *
+*                addr   = adresse d'un nouveau point de départ à créer.       *
+*                marker = forme générique d'un encodage à mémoriser.          *
+*                                                                             *
+*  Description : Enregistre l'encodage (générique) utilisé à une adresse.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_armv7_context_define_encoding(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker)
+{
+    _g_arm_context_define_encoding(G_ARM_CONTEXT(ctx), addr, marker);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ctx  = contexte de désassemblage à consulter.                *
+*                addr = adresse d'un nouveau point de départ à retrouver.     *
+*                                                                             *
+*  Description : Indique l'encodage (générique) utilisé à une adresse donnée. *
+*                                                                             *
+*  Retour      : Marqueur à priori toujours valide.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+ArmV7InstrSet g_armv7_context_find_encoding(GArmV7Context *ctx, virt_t addr)
+{
+    return (ArmV7InstrSet)_g_arm_context_find_encoding(G_ARM_CONTEXT(ctx), addr);
+
+}
diff --git a/src/arch/arm/v7/context.h b/src/arch/arm/v7/context.h
new file mode 100644
index 0000000..65b5302
--- /dev/null
+++ b/src/arch/arm/v7/context.h
@@ -0,0 +1,82 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * context.h - prototypes pour le contexte lié à l'exécution d'un processeur
+ *
+ * Copyright (C) 2014 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_ARM_V7_CONTEXT_H
+#define _ARCH_ARM_V7_CONTEXT_H
+
+
+#include <glib-object.h>
+
+
+#include "../../vmpa.h"
+
+
+
+/* ------------------------ MANIPULATION GLOBALE DU CONTEXTE ------------------------ */
+
+
+#define G_TYPE_ARMV7_CONTEXT              g_armv7_context_get_type()
+#define G_ARMV7_CONTEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_context_get_type(), GArmV7Context))
+#define G_IS_ARMV7_CONTEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_context_get_type()))
+#define G_ARMV7_CONTEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_CONTEXT, GGArmV7ContextClass))
+#define G_IS_ARMV7_CONTEXT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_CONTEXT))
+#define G_ARMV7_CONTEXT_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_CONTEXT, GGArmV7ContextClass))
+
+
+/* Définition d'un contexte pour processeur ARM (instance) */
+typedef struct _GArmV7Context GArmV7Context;
+
+/* Définition d'un contexte pour processeur ARM (classe) */
+typedef struct _GArmV7ContextClass GArmV7ContextClass;
+
+
+/* Indique le type définit par la GLib pour le contexte de processeur ARM. */
+GType g_armv7_context_get_type(void);
+
+/* Crée un contexte pour l'exécution du processeur ARM. */
+GArmV7Context *g_armv7_context_new(void);
+
+
+
+/* Jeux d'instructions possibles avec ARM v7 */
+typedef enum _ArmV7InstrSet
+{
+    AV7IS_ARM,                              /* Encodage classique          */
+    AV7IS_THUMB,                            /* Encodage compressé          */
+    AV7IS_JAZELLE,                          /* Encodage JVM                */
+    AV7IS_THUMBEE,                          /* Encodage dense + JIT/AOT    */
+
+    AV7IS_COUNT
+
+} ArmV7InstrSet;
+
+
+/* Enregistre l'encodage (générique) utilisé à une adresse. */
+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);
+
+
+
+#endif  /* _ARCH_ARM_V7_CONTEXT_H */
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
index 65ae09e..69b43bc 100644
--- a/src/arch/arm/v7/link.c
+++ b/src/arch/arm/v7/link.c
@@ -27,6 +27,9 @@
 #include <assert.h>
 
 
+#include "context.h"
+
+
 
 /******************************************************************************
 *                                                                             *
@@ -42,12 +45,14 @@
 *                                                                             *
 ******************************************************************************/
 
-void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
     GArchOperand *op;                       /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
+    virt_t target;                          /* Adresse virtuelle visée     */
+    ArmV7InstrSet iset;                     /* Type de jeu courant         */
 
     range = g_arch_instruction_get_range(instr);
 
@@ -70,6 +75,11 @@ void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GProcContex
 
     //printf("[@ 0x%08x] Add 0x%08x to %p\n", (uint32_t)get_virt_addr(get_mrange_addr(range)), (uint32_t)(pc + offset), context);
 
+    target = pc + offset;
+    iset = g_armv7_context_find_encoding(context, get_virt_addr(get_mrange_addr(range)));
+
+    g_armv7_context_define_encoding(context, target, iset);
+
 }
 
 
@@ -87,12 +97,14 @@ void handle_links_with_thumb_instruction_bl(GArchInstruction *instr, GProcContex
 *                                                                             *
 ******************************************************************************/
 
-void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
 {
     const mrange_t *range;                  /* Emplacementt d'instruction  */
     virt_t pc;                              /* Position dans l'exécution   */
     GArchOperand *op;                       /* Opérande numérique en place */
     int32_t offset;                         /* Décallage encodé en dur     */
+    virt_t target;                          /* Adresse virtuelle visée     */
+    ArmV7InstrSet iset;                     /* Type de jeu courant         */
 
     range = g_arch_instruction_get_range(instr);
 
@@ -116,5 +128,16 @@ void handle_links_with_thumb_instruction_blx(GArchInstruction *instr, GProcConte
 
     //printf("[@ 0x%08x] Add 0x%08x to %p\n", (uint32_t)get_virt_addr(get_mrange_addr(range)), (uint32_t)(pc + offset), context);
 
+    target = pc + offset;
+    iset = g_armv7_context_find_encoding(context, get_virt_addr(get_mrange_addr(range)));
+
+    printf(" --link-- @ 0x%08x iset = %u\n", (unsigned int)target, (unsigned int)iset);
+
+    if (iset == AV7IS_ARM)
+        g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
+    else
+        g_armv7_context_define_encoding(context, target, AV7IS_ARM);
+
+
 
 }
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
index 79da9f3..fa38f74 100644
--- a/src/arch/arm/v7/link.h
+++ b/src/arch/arm/v7/link.h
@@ -25,16 +25,17 @@
 #define _ARCH_ARM_V7_LINK_H
 
 
+#include "context.h"
 #include "../../instruction.h"
 #include "../../../format/format.h"
 
 
 
 /* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_thumb_instruction_bl(GArchInstruction *, GProcContext *, GBinFormat *);
+void handle_links_with_thumb_instruction_bl(GArchInstruction *, GArmV7Context *, GBinFormat *);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_thumb_instruction_blx(GArchInstruction *, GProcContext *, GBinFormat *);
+void handle_links_with_thumb_instruction_blx(GArchInstruction *, GArmV7Context *, GBinFormat *);
 
 
 
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c
index 4ae933b..45b53ae 100644
--- a/src/arch/arm/v7/processor.c
+++ b/src/arch/arm/v7/processor.c
@@ -24,10 +24,13 @@
 #include "processor.h"
 
 
+#include <assert.h>
+
+
 #include "arm.h"
+#include "context.h"
 #include "thumb_16.h"
 #include "thumb_32.h"
-#include "../context.h"
 #include "../processor-int.h"
 #include "../../raw.h"
 
@@ -61,8 +64,11 @@ static void g_armv7_processor_dispose(GArmV7Processor *);
 /* Procède à la libération totale de la mémoire. */
 static void g_armv7_processor_finalize(GArmV7Processor *);
 
+/* Fournit un contexte pour l'exécution du processeur ARM. */
+static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *);
+
 /* Décode une instruction dans un flux de données. */
-static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *, GArmContext *, const bin_t *, vmpa2t *, phys_t);
+static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *, GArmV7Context *, const bin_t *, vmpa2t *, phys_t);
 
 
 
@@ -121,6 +127,12 @@ static void g_armv7_processor_init(GArmV7Processor *proc)
     parent->memsize = MDS_32_BITS;
     parent->inssize = MDS_32_BITS;
 
+
+
+
+    parent->get_ctx = (get_processor_context_fc)g_armv7_processor_get_context;
+
+
 }
 
 
@@ -187,6 +199,25 @@ GArmV7Processor *g_armv7_processor_new(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : proc = architecture, spectatrice ici.                        *
+*                                                                             *
+*  Description : Fournit un contexte pour l'exécution du processeur Arm.      *
+*                                                                             *
+*  Retour      : Contexte mis en place.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *proc)
+{
+    return g_armv7_context_new();
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : proc = architecture visée par la procédure.                  *
 *                ctx  = contexte lié à l'exécution du processeur.             *
 *                data = flux de données à analyser.                           *
@@ -202,7 +233,7 @@ GArmV7Processor *g_armv7_processor_new(void)
 ******************************************************************************/
 #include "link.h"
 #include "post.h"
-static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmContext *ctx, const bin_t *data, vmpa2t *pos, phys_t end)
+static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmV7Context *ctx, const bin_t *data, vmpa2t *pos, phys_t end)
 {
     GArchInstruction *result;               /* Instruction à renvoyer      */
     phys_t start;                           /* Point de départ de lecture  */
@@ -213,45 +244,71 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
 
 
 
+
+
+
+    ArmV7InstrSet iset;
+
+
+
+    iset = g_armv7_context_find_encoding(ctx, get_virt_addr(pos));
+
+
+
+    printf(" --decoding-- 0x%08x -> %u\n",
+           (unsigned int)get_virt_addr(pos),
+           (unsigned int)iset);
+
+
     start = get_phy_addr(pos);
 
     diff = 4;
 
-    if (1/*Thumb*/)
+
+    switch (iset)
     {
-        if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
-            return NULL;
+        case AV7IS_ARM:
 
-        switch (raw16 >> 11)
-        {
-            case 0b11101:
-            case 0b11110:
-            case 0b11111:
+            if (!read_u32(&raw32, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
+                return NULL;
 
-                raw32 = raw16 << 16;
+            result = process_armv7_arm_instruction_set_encoding(raw32);
 
-                if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
-                    return NULL;
+            break;
 
-                raw32 |= raw16;
+        case AV7IS_THUMB:
 
-                result = process_armv7_thumb_32_instruction_set_encoding(raw32);
-                break;
+            if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
+                return NULL;
 
-            default:
-                diff = 2;
-                result = process_armv7_thumb_16_instruction_set_encoding(raw16);
-                break;
+            switch (raw16 >> 11)
+            {
+                case 0b11101:
+                case 0b11110:
+                case 0b11111:
 
-        }
+                    raw32 = raw16 << 16;
 
-    }
-    else
-    {
-        if (!read_u32(&raw32, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
-            return NULL;
+                    if (!read_u16(&raw16, data, &start, end, G_ARCH_PROCESSOR(proc)->endianness))
+                        return NULL;
+
+                    raw32 |= raw16;
+
+                    result = process_armv7_thumb_32_instruction_set_encoding(raw32);
+                    break;
+
+                default:
+                    diff = 2;
+                    result = process_armv7_thumb_16_instruction_set_encoding(raw16);
+                    break;
+
+            }
+
+            break;
 
-        result = process_armv7_arm_instruction_set_encoding(raw32);
+        default:
+            assert(0);
+            break;
 
     }
 
@@ -270,7 +327,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
     {
 
 
-        g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_bl);
+        g_arch_instruction_set_hook(result, IPH_LINK, (instr_hook_fc)handle_links_with_thumb_instruction_bl);
         g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
 
 
@@ -280,7 +337,7 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
     if (strcmp(g_arch_instruction_get_keyword(result, 0), "blx") == 0/* && pc == 0x000085b2*/)
     {
 
-        g_arch_instruction_set_hook(result, IPH_LINK, handle_links_with_thumb_instruction_blx);
+        g_arch_instruction_set_hook(result, IPH_LINK, (instr_hook_fc)handle_links_with_thumb_instruction_blx);
         g_arch_instruction_set_hook(result, IPH_POST, post_process_branch_instructions);
 
 
-- 
cgit v0.11.2-87-g4458