From 5cc7bd39ae41af40a0c939acf98f90bf1375effd Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 31 Mar 2015 23:20:33 +0000
Subject: Saved some progress in the definition of basic blocks.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@497 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                           |  63 +++++
 src/analysis/disass/area.c          |   2 +-
 src/analysis/disass/disassembler.c  |  37 ++-
 src/analysis/disass/links.c         |  87 +++++-
 src/analysis/disass/macro.c         | 105 +++++++-
 src/arch/Makefile.am                |   1 +
 src/arch/arm/v7/Makefile.am         |   2 +-
 src/arch/arm/v7/fetch.c             | 521 ++++++++++++++++++++++++++++++++++++
 src/arch/arm/v7/fetch.h             | 113 ++++++++
 src/arch/arm/v7/link.c              | 515 -----------------------------------
 src/arch/arm/v7/link.h              | 113 --------
 src/arch/arm/v7/opdefs/Makefile.am  |   2 +-
 src/arch/arm/v7/opdefs/b_A8818.d    |  25 +-
 src/arch/arm/v7/opdefs/bl_A8825.d   |   8 +-
 src/arch/arm/v7/opdefs/bx_A8827.d   |   4 +-
 src/arch/arm/v7/opdefs/cbnz_A8829.d |   4 +-
 src/arch/arm/v7/opdefs/ldr_A8864.d  |   6 +-
 src/arch/arm/v7/opdefs/pop_A88131.d |   3 +
 src/arch/arm/v7/opdefs/pop_A88132.d |   2 +
 src/arch/arm/v7/post.c              |  12 +-
 src/arch/arm/v7/post.h              |   8 +-
 src/arch/instruction.c              |   8 +-
 src/arch/instruction.h              |  16 +-
 src/arch/link.c                     | 190 +++++++++++++
 src/arch/link.h                     |  45 ++++
 src/arch/processor-int.h            |   7 +
 src/arch/processor.c                | 147 ++++++++++
 src/arch/processor.h                |  16 ++
 28 files changed, 1385 insertions(+), 677 deletions(-)
 create mode 100644 src/arch/arm/v7/fetch.c
 create mode 100644 src/arch/arm/v7/fetch.h
 delete mode 100644 src/arch/arm/v7/link.c
 delete mode 100644 src/arch/arm/v7/link.h
 create mode 100644 src/arch/link.c
 create mode 100644 src/arch/link.h

diff --git a/ChangeLog b/ChangeLog
index ffec386..0d4288c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+15-04-01  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/area.c:
+	Update code by changing IPH_LINK to IPH_FETCH.
+
+	* src/analysis/disass/disassembler.c:
+	Register all disassembled instructions and run the new IPH_LINK methods.
+
+	* src/analysis/disass/links.c:
+	Establish natural links in the execution flow.
+
+	* src/analysis/disass/macro.c:
+	Save some progress in the definition of basic blocks.
+
+	* src/arch/arm/v7/fetch.c:
+	* src/arch/arm/v7/fetch.h:
+	New entries: redefine the old IPH_LINK methods into IPH_FETCH new ones.
+
+	* src/arch/arm/v7/link.c:
+	* src/arch/arm/v7/link.h:
+	Moved entries: see the 'fetch.[ch]' files.
+
+	* src/arch/arm/v7/Makefile.am:
+	Replace the 'link.[ch]' files by the 'fetch.[ch]' ones
+	in libarcharmv7_la_SOURCES.
+
+	* src/arch/arm/v7/opdefs/b_A8818.d:
+	* src/arch/arm/v7/opdefs/bl_A8825.d:
+	* src/arch/arm/v7/opdefs/bx_A8827.d:
+	* src/arch/arm/v7/opdefs/cbnz_A8829.d:
+	* src/arch/arm/v7/opdefs/ldr_A8864.d:
+	Update definitions.
+
+	* src/arch/arm/v7/opdefs/Makefile.am:
+	Update included headers list.
+
+	* src/arch/arm/v7/opdefs/pop_A88131.d:
+	* src/arch/arm/v7/opdefs/pop_A88132.d:
+	Update definitions.
+
+	* src/arch/arm/v7/post.c:
+	* src/arch/arm/v7/post.h:
+	Update prototypes.
+
+	* src/arch/instruction.c:
+	Update code.
+
+	* src/arch/instruction.h:
+	Update code. Redefine prototypes for hooks. Register a link type dedicated
+	to cross refrences.
+
+	* src/arch/link.c:
+	* src/arch/link.h:
+	New entries: provide generic methods for some kinks of links.
+
+	* src/arch/Makefile.am:
+	Add the 'link.[ch]' files to libarch_la_SOURCES.
+
+	* src/arch/processor.c:
+	* src/arch/processor.h:
+	* src/arch/processor-int.h:
+	Begin to store all disassembled instructions in the processor structure.
+
 15-03-29  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/readelf/header.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index 90738be..3a23993 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -565,7 +565,7 @@ bool load_code_from_mem_area(mem_area **list, size_t *count, size_t *index, cons
 
         /* Eventuel renvoi vers d'autres adresses */
 
-        g_arch_instruction_call_hook(instr, IPH_LINK, ctx, format);
+        g_arch_instruction_call_hook(instr, IPH_FETCH, proc, ctx, format);
 
         /* Progression dans les traitements */
 
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 95d95d0..fcc41cb 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -186,6 +186,8 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GAr
 
 static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
 {
+    //GBinFormat *format;                     /* Format du fichier binaire   */
+    GArchProcessor *proc;                   /* Architecture du binaire     */
 
 
     unsigned int valid;                     /* Instructions traduites      */
@@ -199,9 +201,12 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
     bstatus_id_t id;                        /* Identifiant de statut       */
 
 
-    GArchProcessor *proc;                   /* Architecture du binaire     */
+    //GArchProcessor *proc;                   /* Architecture du binaire     */
 
 
+    //format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
+    proc = g_loaded_binary_get_processor(disass->binary);
+
 
     routines = g_binary_format_get_routines(G_BIN_FORMAT(disass->format), &routines_count);
 
@@ -219,6 +224,8 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
     *disass->instrs = disassemble_binary_content(disass->binary, statusbar);
 
 
+    g_arch_processor_set_disassembled_instructions(proc, *disass->instrs);
+
 
     /*
     *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count,
@@ -229,6 +236,32 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
 
 
 
+    do
+    {
+        GBinFormat *format;                     /* Format du fichier binaire   */
+        GArchInstruction *iter;                 /* Boucle de parcours          */
+
+
+
+        format = G_BIN_FORMAT(g_loaded_binary_get_format(disass->binary));
+
+        for (iter = *disass->instrs;
+             iter != NULL;
+             iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
+        {
+
+            g_arch_instruction_call_hook(iter, IPH_LINK, proc, /*ctx*/NULL, format);
+
+
+
+        }
+
+
+
+    } while (0);
+
+
+
 
     //gtk_extended_status_bar_remove(statusbar, id);
 
@@ -250,7 +283,7 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
              iter = g_arch_instruction_get_next_iter(*disass->instrs, iter, 0))
         {
 
-            g_arch_instruction_call_hook(iter, IPH_POST, /*ctx*/NULL, format);
+            g_arch_instruction_call_hook(iter, IPH_POST, proc, /*ctx*/NULL, format);
 
 
 
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 022ace3..06b6b03 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -33,10 +33,8 @@
 /* Complète un désassemblage accompli pour une instruction. */
 static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat *);
 
-
-
-
-
+/* Rétablit un lien naturel coupé par un autre lien. */
+static void establish_natural_link(GArchInstruction *, GArchInstruction *);
 
 
 
@@ -118,10 +116,83 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
         target = g_arch_instruction_find_by_address(list, &addr, true);
 
         if (target != NULL)
-            g_arch_instruction_link_with(instr, target, ILT_JUMP /* FIXME */);
+            g_arch_instruction_link_with(instr, target, ILT_REF);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instruction désassemblée à traiter.                  *
+*                prev  = instruction précédente.                              *
+*                                                                             *
+*  Description : Rétablit un lien naturel coupé par un autre lien.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
+{
+    GArchInstruction **others;              /* Instructions diverses liées */
+    InstructionLinkType *types;             /* Types de lien existants     */
+    size_t count;                           /* Nbre de sources affichées   */
+    size_t i;                               /* Boucle de parcours          */
+
+    /**
+     * Si rien ne vient séparer les deux instructions,
+     * on ne peut pas créer de lien plus naturel que l'existant.
+     */
+
+    if (!g_arch_instruction_has_sources(instr))
+        return;
+
+    /**
+     * Si on se trouve à une extrémité, on ne se lie pas
+     * avec le voisin.
+     */
+
+    if (g_arch_instruction_is_return(prev))
+        return;
+
+    if (g_arch_instruction_get_flags(instr) & AIF_ROUTINE_START)
+        return;
+
+    /**
+     * On s'assure que le lien naturel est valide.
+     */
+
+    count = g_arch_instruction_get_destinations(prev, &others, &types, NULL);
+
+    for (i = 0; i < count; i++)
+    {
+        if (types[i] == ILT_EXEC_FLOW) break;
+        if (types[i] == ILT_JUMP) break;
+        if (types[i] == ILT_CASE_JUMP) break;
+        if (types[i] == ILT_LOOP) break;
+    }
+
+    if (i < count) return;
+
+    /**
+     * On vérifie que le lien n'existe pas déjà avant d'en créer un...
+     */
 
+    count = g_arch_instruction_get_sources(instr, &others, &types);
+
+    for (i = 0; i < count; i++)
+    {
+        if (others[i] == prev && types[i] == ILT_JUMP_IF_TRUE) break;
+        if (others[i] == prev && types[i] == ILT_JUMP_IF_FALSE) break;
     }
 
+    if (i == count)
+        g_arch_instruction_link_with(prev, instr, ILT_EXEC_FLOW);
+
 }
 
 
@@ -142,13 +213,19 @@ static void establish_links_for_instruction(GArchInstruction *instr, GArchInstru
 
 void establish_links_between_instructions(GArchInstruction *list, GBinFormat *format, GtkExtStatusBar *statusbar, bstatus_id_t id)
 {
+    GArchInstruction *prev;                 /* Itération précédente        */
     GArchInstruction *iter;                 /* Boucle de parcours          */
 
+    prev = NULL;
+
     for (iter = list;
          iter != NULL;
          iter = g_arch_instruction_get_next_iter(list, iter, ~0/* FIXME */))
     {
+        if (prev != NULL)
+            establish_natural_link(iter, prev);
 
+        prev = iter;
 
         establish_links_for_instruction(iter, list, format);
 
diff --git a/src/analysis/disass/macro.c b/src/analysis/disass/macro.c
index 218371b..087f1ae 100644
--- a/src/analysis/disass/macro.c
+++ b/src/analysis/disass/macro.c
@@ -297,6 +297,9 @@ static bool code_coverage_stop_here(const code_coverage *coverage, const vmpa2t
 {
     void *ptr;                              /* Résultat des recherches     */
 
+    if (!mrange_contains_addr(&coverage->range, addr))
+        return true;
+
     ptr = bsearch(addr, coverage->ends, coverage->ends_count,
                   sizeof(vmpa2t), (__compar_fn_t)cmp_vmpa);
 
@@ -532,10 +535,21 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
     InstructionLinkType *types;             /* Type de lien entre lignes   */
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours #2       */
+    size_t not_handled;                     /* Nombre d'éléments écartés   */
+
+    printf(" ---- FN [ %p ] ---------------------------\n", info);
+
+
+    printf("CONTAINS ? %d\n", mrange_contains_addr(&coverage->range, start));
 
     /* Si la position est déjà présente, on évite de boucler... */
     if (!add_hop_into_branch(info, start))
+    {
+        printf("  ++ !add 0x%08x\n", (unsigned int)start->virtual);
         return;
+    }
+    else
+        printf("  ++ add 0x%08x\n", (unsigned int)start->virtual);
 
     /* On suit le flot jusqu'à la prochaine bifurcation */
     for (iter = g_arch_instruction_find_by_address(instrs, start, true);
@@ -544,20 +558,43 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
     {
         range = g_arch_instruction_get_range(iter);
 
+
+        if (code_coverage_stop_here(coverage, get_mrange_addr(range)))
+            printf("  ++ stop here 0x%08x\n", (unsigned int)range->addr.virtual);
+
         if (code_coverage_stop_here(coverage, get_mrange_addr(range)))
             break;
 
+
+        if (g_arch_instruction_has_sources(iter))
+            add_hop_into_branch(info, get_mrange_addr(range));
+
+
+
+        if (g_arch_instruction_is_return(iter))
+            printf("  ++ return 0x%08x\n", (unsigned int)range->addr.virtual);
+
         if (g_arch_instruction_is_return(iter))
         {
             iter = NULL;
             break;
         }
 
+        /*
+        if (!g_arch_instruction_has_destinations(iter))
+            printf("  ++ no dest 0x%08x\n", (unsigned int)range->addr.virtual);
+        */
+
         if (!g_arch_instruction_has_destinations(iter))
             continue;
 
+
+        printf("  ++ dcount 0x%08x\n", (unsigned int)range->addr.virtual);
+
         dcount = g_arch_instruction_get_destinations(iter, &dests, &types, NULL);
 
+        not_handled = 0;
+
         for (i = 0; i < dcount; i++)
         {
             range = g_arch_instruction_get_range(dests[i]);
@@ -577,19 +614,23 @@ static void find_next_hops(GArchInstruction *instrs, const vmpa2t *start, const
                     break;
 
                 default:
+                    not_handled++;
                     break;
 
             }
 
         }
 
-        break;
+        if (not_handled < dcount)
+            break;
 
     }
 
     /* Si on termine... */
     if (iter != NULL) add_hop_into_branch(info, get_mrange_addr(range));
 
+    printf(" ------- [ %p ] ---\n", info);
+
 }
 
 
@@ -614,6 +655,20 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b
 
     result = false;
 
+
+    printf("....................\n");
+
+    printf(" A :: ");
+    for (i = 0; i < a->count; i++)
+        printf("0x%08x ", a->hops[i].virtual);
+    printf("\n");
+
+    printf(" B :: ");
+    for (i = 0; i < b->count; i++)
+        printf("0x%08x ", b->hops[i].virtual);
+    printf("\n");
+
+
     for (i = 0; i < a->count && !result; i++)
         if (is_addr_in_branch(b, &a->hops[i]))
         {
@@ -621,6 +676,13 @@ static bool compute_first_common_addr(const branch_info *a, const branch_info *b
             copy_vmpa(c, &a->hops[i]);
         }
 
+    if (result)
+        printf(" N :: 0x%08x\n", (unsigned int)c->virtual);
+    else
+        printf(" N :: ----\n");
+
+    printf("....................\n");
+
     return result;
 
 }
@@ -862,6 +924,7 @@ static GInstrBlock *build_instruction_blocks_ite(GArchInstruction *instrs, code_
     GInstrBlock *block;                     /* Nouveau bloc mis en place   */
 
     has_common = compute_first_common_addr(true_branch, false_branch, next);
+    if (!has_common) printf("   === nothing in common\n");
     if (!has_common) return NULL;
 
     result = g_virtual_block_new();
@@ -980,7 +1043,7 @@ static void add_instruction_blocks_except(GInstrBlock **result, GInstrBlock **ca
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-
+#include "../../arch/instruction-int.h"
 static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_coverage *coverage)
 {
     GInstrBlock *result;                    /* Regroupement à retourner    */
@@ -1059,11 +1122,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
                 case ILT_EXEC_FLOW:
                 case ILT_JUMP:
 
+
+                    //break;
+                {
+                    GArchInstruction *_saved0;
+
+                    _saved0 = first;
+
                     block = build_instruction_block_simple(instrs, coverage, &first, iter);
+                    printf(" -- simple block JMP -- @ 0x%08x <-> 0x%08x\n",
+                           (unsigned int)(_saved0 ? _saved0->range.addr.virtual : ~0),
+                           (unsigned int)iter->range.addr.virtual);
+                    fflush(NULL);
+                }
                     DELAYED_BLOCK_ADDING(result, result_cached, block);
 
                     range = g_arch_instruction_get_range(iter);
-                    copy_vmpa(&next_addr, get_mrange_addr(range));
+                    compute_mrange_end_addr(range, &next_addr);
+
+                    first = NULL;
 
                     break;
 
@@ -1072,10 +1149,12 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
                     break;
 
                 case ILT_JUMP_IF_TRUE:
+                    printf("FIND TRUE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);
                     branch = &true_branch;
                     break;
 
                 case ILT_JUMP_IF_FALSE:
+                    printf("FIND FALSE BRANCH @ 0x%08x\n", (unsigned int)iter->range.addr.virtual);
                     branch = &false_branch;
                     break;
 
@@ -1097,10 +1176,13 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
             /* Si on a une branche à compléter... */
             if (branch != NULL)
             {
-                range = g_arch_instruction_get_range(iter);
+                range = g_arch_instruction_get_range(dests[i]);
                 addr = get_mrange_addr(range);
 
+                printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+                printf("BUILD @ 0x%08x\n", (unsigned int)addr->virtual);
                 find_next_hops(instrs, addr, coverage, branch);
+                printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
 
             }
 
@@ -1126,10 +1208,25 @@ static GInstrBlock *build_instruction_blocks(GArchInstruction *instrs, code_cove
         else if (true_branch.count > 0 || false_branch.count > 0)
         {
             block = build_instruction_block_simple(instrs, coverage, &first, iter);
+
+            GArchInstruction *_saved1;
+
+            _saved1 = first;
+
+
+
+            printf(" -- branches -- %d vs %d\n", (int)true_branch.count, (int)false_branch.count);
+
+            printf(" -- simple block ITE -- @ 0x%08x <-> 0x%08x\n",
+                   (unsigned int)(_saved1 ? _saved1->range.addr.virtual : ~0),
+                   (unsigned int)iter->range.addr.virtual);
+            fflush(NULL);
             DELAYED_BLOCK_ADDING(result, result_cached, block);
 
             group = build_instruction_blocks_ite(instrs, coverage, &true_branch, &false_branch, &next_addr);
 
+            printf(" --> group = %p  -  next = 0x%08x\n", group, next_addr.virtual);
+
             if (group != NULL)
             {
                 DELAYED_BLOCK_ADDING(result, result_cached, group);
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 33747fb..aab7ec8 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -9,6 +9,7 @@ libarch_la_SOURCES =					\
 	immediate.h immediate.c				\
 	instruction-int.h					\
 	instruction.h instruction.c			\
+	link.h link.c						\
 	operand-int.h						\
 	operand.h operand.c					\
 	processor-int.h						\
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 22e93d4..f9b35b6 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -4,9 +4,9 @@ noinst_LTLIBRARIES = libarcharmv7.la
 libarcharmv7_la_SOURCES =				\
 	arm.h arm.c							\
 	context.h context.c					\
+	fetch.h fetch.c						\
 	helpers.h helpers.c					\
 	instruction.h instruction.c			\
-	link.h link.c						\
 	post.h post.c						\
 	processor.h processor.c				\
 	pseudo.h pseudo.c					\
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
new file mode 100644
index 0000000..18d61f0
--- /dev/null
+++ b/src/arch/arm/v7/fetch.c
@@ -0,0 +1,521 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * fetch.c - traitements complémentaires à la phase de désassemblage
+ *
+ * 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 "fetch.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include <i18n.h>
+
+
+#include "operands/offset.h"
+#include "../register.h"
+#include "../../raw.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à faire suivre. *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+    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     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+
+
+
+    switch (iset)
+    {
+        case AV7IS_ARM:
+            pc += 8;
+            break;
+        case AV7IS_THUMB:
+            pc += 4;
+            break;
+        default:
+            assert(0);
+            break;
+    }
+
+
+
+    //pc += get_mrange_length(range);
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+    else assert(0);
+
+    printf("1... 0x%x (0x%x) + 0x%x\n",
+           (unsigned int)get_virt_addr(get_mrange_addr(range)),
+           (unsigned int)pc, (unsigned int)offset);
+
+    target = pc + offset;
+
+    //g_armv7_context_define_encoding(context, target, iset);
+    g_armv7_context_push_drop_point_ext(context, target, iset);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à faire suivre. *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+    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     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+    /**
+     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+     * ne peut qu'être encodée sur 4 octets.
+     */
+
+    assert(get_mrange_length(range) == 4);
+
+    pc += 4;
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+    else assert(0);
+
+    printf("2... 0x%x (0x%x) + 0x%x\n",
+           (unsigned int)get_virt_addr(get_mrange_addr(range)),
+           (unsigned int)pc, (unsigned int)offset);
+
+
+
+    target = pc + offset;
+
+    //g_armv7_context_define_encoding(context, target, iset);
+    g_armv7_context_push_drop_point_ext(context, target, iset);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à inverser.     *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+    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     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+    /**
+     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
+     * ne peut qu'être encodée sur 4 octets.
+     */
+
+    assert(get_mrange_length(range) == 4);
+
+    pc += 4;
+    pc -= pc % 4;
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+    else assert(0);
+
+    printf("3... 0x%x (0x%x) + 0x%x\n",
+           (unsigned int)get_virt_addr(get_mrange_addr(range)),
+           (unsigned int)pc, (unsigned int)offset);
+
+
+
+    target = pc + offset;
+
+    //g_armv7_context_define_encoding(context, target, iset);
+    g_armv7_context_push_drop_point_ext(context, target, iset);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à faire suivre. *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+    GArchOperand *op;                       /* Opérande numérique en place */
+    GArmRegister *reg;                      /* Registre matériel manipulé  */
+    const mrange_t *range;                  /* Emplacementt d'instruction  */
+    virt_t pc;                              /* Position dans l'exécution   */
+
+    op = g_arch_instruction_get_operand(instr, 0);
+    assert(G_IS_REGISTER_OPERAND(op));
+
+    reg = G_ARM_REGISTER(g_register_operand_get_register(G_REGISTER_OPERAND(op)));
+
+    /**
+     * On ne sait agir qu'avec le seul contenu facilement prédictible : pc !
+     */
+
+    if (g_arm_register_get_index(reg) != 15 /* pc */)
+        return;
+
+    /**
+     * On bascule alors le mode de décodage à cette adresse...
+     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+    switch (iset)
+    {
+        case AV7IS_ARM:
+            pc += 8;
+            //g_armv7_context_define_encoding(context, 
+            g_armv7_context_push_drop_point_ext(context, 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);
+            break;
+        default:
+            assert(0);
+            break;
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcessor *proc, 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 */
+    uint32_t offset;                        /* Décallage encodé en dur     */
+    virt_t target;                          /* Adresse virtuelle visée     */
+
+    range = g_arch_instruction_get_range(instr);
+
+    pc = get_virt_addr(get_mrange_addr(range));
+
+
+    printf("PC :: 0x%08x\n", (unsigned int)pc);
+
+
+    /**
+     * En mode Thumb, pc a pour valeur l'adresse courante plus 4.
+     */
+
+    pc += 4;
+
+    op = g_arch_instruction_get_operand(instr, 1);
+
+    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset))
+        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+    else assert(0);
+
+    target = pc + offset;
+
+    //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
+    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                iset    = type de jeu d'instructions courant à inverser.     *
+*                                                                             *
+*  Description : Complète un désassemblage accompli pour une instruction.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+    const mrange_t *range;                  /* Emplacementt d'instruction  */
+    phys_t phys_pc;                         /* Position dans l'exécution   */
+    GArchOperand *op;                       /* Opérande de surcouche       */
+    GArchOperand *sub_op;                   /* Opérande numérique en place */
+    uint32_t offset;                        /* Décallage encodé en dur     */
+    bool ret;                               /* Bilan d'une récupération    */
+    off_t val_offset;                       /* Position de valeur à lire   */
+    vmpa2t sym_addr;                        /* Adresse de nouveau symbole  */
+    off_t length;                           /* Taille des données à lire   */
+    const bin_t *data;                      /* Données binaires à lire     */
+    uint32_t target;                        /* Adresse virtuelle visée     */
+    mrange_t sym_range;                     /* Espace du nouveau symbole   */
+    VMPA_BUFFER(loc);                       /* Adresse au format texte     */
+    size_t name_len;                        /* Taille de nomination finale */
+    char *name;                             /* Désignation humaine         */
+    GArchInstruction *sym_instr;            /* Instruction de symbole      */
+    GBinSymbol *symbol;                     /* Nouveau symbole construit   */
+    GDbComment *comment;                    /* Définition de commentaire   */
+    GArchOperand *new;                      /* Instruction de ciblage      */
+
+    /* Récupération de l'adresse visée par le chargement */
+
+    range = g_arch_instruction_get_range(instr);
+
+    phys_pc = get_phy_addr(get_mrange_addr(range));
+
+    phys_pc &= ~3;
+    //phys_pc = (phys_pc + 3) & ~3;
+
+    printf(">>>>>>> @pc @ 0x%08x\n", (unsigned int)phys_pc);
+
+
+    switch (iset)
+    {
+        case AV7IS_ARM:
+            phys_pc += 8;
+            break;
+        case AV7IS_THUMB:
+            phys_pc += 4;
+            break;
+        default:
+            assert(0);
+            break;
+    }
+
+    op = g_arch_instruction_get_operand(instr, 1);
+    assert(G_IS_ARMV7_OFFSET_OPERAND(op));
+
+    sub_op = g_armv7_offset_operand_get_value(G_ARMV7_OFFSET_OPERAND(op));
+
+    ret = g_imm_operand_get_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, &offset);
+    if (!ret)
+    {
+        assert(0);
+        return;
+    }
+
+    /* Transformations et conservation d'une position de symbole */
+
+    if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op)))
+        val_offset = phys_pc + offset;
+    else
+        val_offset = phys_pc - offset;
+
+    init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL);
+    init_mrange(&sym_range, &sym_addr, 4);
+
+
+
+
+
+
+
+
+    /* Lecture de la valeur vers laquelle renvoyer */
+
+    data = g_binary_format_get_content(format, &length);
+
+
+    printf(">>>>>>> @reading @ 0x%08x (0x%x)\n", (unsigned int)val_offset, offset);
+
+
+    ret = read_u32(&target, data, &val_offset, length, SRE_LITTLE /* FIXME */);
+    if (!ret) return;
+
+
+    printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target);
+
+
+
+
+
+    /* Réalise l'intégration du symbole associé */
+
+    sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target);
+
+    name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1;
+
+    name = (char *)calloc(name_len, sizeof(char));
+
+    vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL);
+    snprintf(name, name_len, _("Value used @ %s"), loc);
+
+    ADD_RAW_AS_SYM(format, symbol, &sym_addr, sym_instr, comment, name);
+
+    free(name);
+
+
+
+    g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr);
+    printf("repush :: from 0x%x :: %x / %x\n",
+           (unsigned int)get_phy_addr(get_mrange_addr(range)),
+           (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual);
+
+
+    printf("add sym %p\n", symbol);
+
+
+
+    //g_proc_context_push_new_symbol_at(context, &sym_addr);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target);
+
+
+
+    if (target < 0x8000) return;
+
+
+
+    new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
+    g_arch_instruction_replace_operand(instr, new, op);
+
+
+
+
+    //exit(0);
+
+
+
+    //target = pc + offset;
+
+    //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
+    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+
+
+    //exit(0);
+
+}
diff --git a/src/arch/arm/v7/fetch.h b/src/arch/arm/v7/fetch.h
new file mode 100644
index 0000000..af42f2e
--- /dev/null
+++ b/src/arch/arm/v7/fetch.h
@@ -0,0 +1,113 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * fetch.h - prototypes pour l'édition des liens durant la phase de désassemblage
+ *
+ * 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_FETCH_H
+#define _ARCH_ARM_V7_FETCH_H
+
+
+#include "context.h"
+#include "../../instruction.h"
+#include "../../../format/format.h"
+
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_b_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_b_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_b_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_b_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_bl_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_bl_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_bl_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_bl_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_blx_with_dest(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_blx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+static inline void help_fetching_with_instruction_blx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_blx_with_dest(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_bx_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_bx_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_bx_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_bx_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_cb_n_z(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArchProcessor *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void help_fetching_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void help_fetching_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArchProcessor *proc, GArmV7Context *ctx, GBinFormat *fmt)
+{
+    help_fetching_with_instruction_ldr_literal_with_orig(ins, proc, ctx, fmt, AV7IS_THUMB);
+}
+
+
+
+#endif  /* _ARCH_ARM_V7_FETCH_H */
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
deleted file mode 100644
index 308d4e5..0000000
--- a/src/arch/arm/v7/link.c
+++ /dev/null
@@ -1,515 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * post.c - traitements complémentaires à la phase de désassemblage
- *
- * 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 "link.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-
-
-#include <i18n.h>
-
-
-#include "operands/offset.h"
-#include "../register.h"
-#include "../../raw.h"
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à faire suivre. *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
-{
-    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     */
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range));
-
-
-
-
-    switch (iset)
-    {
-        case AV7IS_ARM:
-            pc += 8;
-            break;
-        case AV7IS_THUMB:
-            pc += 4;
-            break;
-        default:
-            assert(0);
-            break;
-    }
-
-
-
-    //pc += get_mrange_length(range);
-
-    op = g_arch_instruction_get_operand(instr, 0);
-
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
-        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
-
-    else assert(0);
-
-    printf("1... 0x%x (0x%x) + 0x%x\n",
-           (unsigned int)get_virt_addr(get_mrange_addr(range)),
-           (unsigned int)pc, (unsigned int)offset);
-
-    target = pc + offset;
-
-    //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à faire suivre. *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
-{
-    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     */
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range));
-
-    /**
-     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
-     * ne peut qu'être encodée sur 4 octets.
-     */
-
-    assert(get_mrange_length(range) == 4);
-
-    pc += 4;
-
-    op = g_arch_instruction_get_operand(instr, 0);
-
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
-        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
-
-    else assert(0);
-
-    printf("2... 0x%x (0x%x) + 0x%x\n",
-           (unsigned int)get_virt_addr(get_mrange_addr(range)),
-           (unsigned int)pc, (unsigned int)offset);
-
-
-
-    target = pc + offset;
-
-    //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à inverser.     *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
-{
-    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     */
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range));
-
-    /**
-     * Qu'on se trouve en mode Thumb ou ARM, l'instruction
-     * ne peut qu'être encodée sur 4 octets.
-     */
-
-    assert(get_mrange_length(range) == 4);
-
-    pc += 4;
-    pc -= pc % 4;
-
-    op = g_arch_instruction_get_operand(instr, 0);
-
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
-        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
-
-    else assert(0);
-
-    printf("3... 0x%x (0x%x) + 0x%x\n",
-           (unsigned int)get_virt_addr(get_mrange_addr(range)),
-           (unsigned int)pc, (unsigned int)offset);
-
-
-
-    target = pc + offset;
-
-    //g_armv7_context_define_encoding(context, target, iset);
-    g_armv7_context_push_drop_point_ext(context, target, iset);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à faire suivre. *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_bx_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
-{
-    GArchOperand *op;                       /* Opérande numérique en place */
-    GArmRegister *reg;                      /* Registre matériel manipulé  */
-    const mrange_t *range;                  /* Emplacementt d'instruction  */
-    virt_t pc;                              /* Position dans l'exécution   */
-
-    op = g_arch_instruction_get_operand(instr, 0);
-    assert(G_IS_REGISTER_OPERAND(op));
-
-    reg = G_ARM_REGISTER(g_register_operand_get_register(G_REGISTER_OPERAND(op)));
-
-    /**
-     * On ne sait agir qu'avec le seul contenu facilement prédictible : pc !
-     */
-
-    if (g_arm_register_get_index(reg) != 15 /* pc */)
-        return;
-
-    /**
-     * On bascule alors le mode de décodage à cette adresse...
-     */
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range));
-
-    switch (iset)
-    {
-        case AV7IS_ARM:
-            pc += 8;
-            //g_armv7_context_define_encoding(context, 
-            g_armv7_context_push_drop_point_ext(context, 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);
-            break;
-        default:
-            assert(0);
-            break;
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_cb_n_z(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 */
-    uint32_t offset;                        /* Décallage encodé en dur     */
-    virt_t target;                          /* Adresse virtuelle visée     */
-
-    range = g_arch_instruction_get_range(instr);
-
-    pc = get_virt_addr(get_mrange_addr(range));
-
-
-    printf("PC :: 0x%08x\n", (unsigned int)pc);
-
-
-    /**
-     * En mode Thumb, pc a pour valeur l'adresse courante plus 4.
-     */
-
-    pc += 4;
-
-    op = g_arch_instruction_get_operand(instr, 1);
-
-    if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset))
-        g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
-
-    else assert(0);
-
-    target = pc + offset;
-
-    //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
-*                context = contexte associé à la phase de désassemblage.      *
-*                format  = acès aux données du binaire d'origine.             *
-*                iset    = type de jeu d'instructions courant à inverser.     *
-*                                                                             *
-*  Description : Complète un désassemblage accompli pour une instruction.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
-{
-    const mrange_t *range;                  /* Emplacementt d'instruction  */
-    phys_t phys_pc;                         /* Position dans l'exécution   */
-    GArchOperand *op;                       /* Opérande de surcouche       */
-    GArchOperand *sub_op;                   /* Opérande numérique en place */
-    uint32_t offset;                        /* Décallage encodé en dur     */
-    bool ret;                               /* Bilan d'une récupération    */
-    off_t val_offset;                       /* Position de valeur à lire   */
-    vmpa2t sym_addr;                        /* Adresse de nouveau symbole  */
-    off_t length;                           /* Taille des données à lire   */
-    const bin_t *data;                      /* Données binaires à lire     */
-    uint32_t target;                        /* Adresse virtuelle visée     */
-    mrange_t sym_range;                     /* Espace du nouveau symbole   */
-    VMPA_BUFFER(loc);                       /* Adresse au format texte     */
-    size_t name_len;                        /* Taille de nomination finale */
-    char *name;                             /* Désignation humaine         */
-    GArchInstruction *sym_instr;            /* Instruction de symbole      */
-    GBinSymbol *symbol;                     /* Nouveau symbole construit   */
-    GDbComment *comment;                    /* Définition de commentaire   */
-    GArchOperand *new;                      /* Instruction de ciblage      */
-
-    /* Récupération de l'adresse visée par le chargement */
-
-    range = g_arch_instruction_get_range(instr);
-
-    phys_pc = get_phy_addr(get_mrange_addr(range));
-
-    phys_pc &= ~3;
-    //phys_pc = (phys_pc + 3) & ~3;
-
-    printf(">>>>>>> @pc @ 0x%08x\n", (unsigned int)phys_pc);
-
-
-    switch (iset)
-    {
-        case AV7IS_ARM:
-            phys_pc += 8;
-            break;
-        case AV7IS_THUMB:
-            phys_pc += 4;
-            break;
-        default:
-            assert(0);
-            break;
-    }
-
-    op = g_arch_instruction_get_operand(instr, 1);
-    assert(G_IS_ARMV7_OFFSET_OPERAND(op));
-
-    sub_op = g_armv7_offset_operand_get_value(G_ARMV7_OFFSET_OPERAND(op));
-
-    ret = g_imm_operand_get_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, &offset);
-    if (!ret)
-    {
-        assert(0);
-        return;
-    }
-
-    /* Transformations et conservation d'une position de symbole */
-
-    if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op)))
-        val_offset = phys_pc + offset;
-    else
-        val_offset = phys_pc - offset;
-
-    init_vmpa(&sym_addr, val_offset, VMPA_NO_VIRTUAL);
-    init_mrange(&sym_range, &sym_addr, 4);
-
-
-
-
-
-
-
-
-    /* Lecture de la valeur vers laquelle renvoyer */
-
-    data = g_binary_format_get_content(format, &length);
-
-
-    printf(">>>>>>> @reading @ 0x%08x (0x%x)\n", (unsigned int)val_offset, offset);
-
-
-    ret = read_u32(&target, data, &val_offset, length, SRE_LITTLE /* FIXME */);
-    if (!ret) return;
-
-
-    printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target);
-
-
-
-
-
-    /* Réalise l'intégration du symbole associé */
-
-    sym_instr = g_raw_instruction_new_from_value(&sym_addr, MDS_32_BITS_UNSIGNED, target);
-
-    name_len = strlen(_("Value used @ %s")) + VMPA_MAX_LEN + 1;
-
-    name = (char *)calloc(name_len, sizeof(char));
-
-    vmpa2_virt_to_string(get_mrange_addr(range), MDS_32_BITS, loc, NULL);
-    snprintf(name, name_len, _("Value used @ %s"), loc);
-
-    ADD_RAW_AS_SYM(format, symbol, &sym_addr, sym_instr, comment, name);
-
-    free(name);
-
-
-
-    g_proc_context_push_new_symbol_at(G_PROC_CONTEXT(context), &sym_addr);
-    printf("repush :: from 0x%x :: %x / %x\n",
-           (unsigned int)get_phy_addr(get_mrange_addr(range)),
-           (unsigned int)sym_addr.physical, (unsigned int)sym_addr.virtual);
-
-
-    printf("add sym %p\n", symbol);
-
-
-
-    //g_proc_context_push_new_symbol_at(context, &sym_addr);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target);
-
-
-
-    if (target < 0x8000) return;
-
-
-
-    new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
-    g_arch_instruction_replace_operand(instr, new, op);
-
-
-
-
-    //exit(0);
-
-
-
-    //target = pc + offset;
-
-    //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
-    g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
-
-
-    //exit(0);
-
-}
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
deleted file mode 100644
index 9e52fe6..0000000
--- a/src/arch/arm/v7/link.h
+++ /dev/null
@@ -1,113 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * link.h - prototypes pour l'édition des liens durant la phase de désassemblage
- *
- * 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_LINK_H
-#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_instruction_b_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_b_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_b_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_bl_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_bl_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_bl_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_blx_with_dest(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_blx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_blx_with_dest(ins, ctx, fmt, AV7IS_ARM);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_bx_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_bx_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_bx_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_bx_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_cb_n_z(GArchInstruction *, GArmV7Context *, GBinFormat *);
-
-/* Complète un désassemblage accompli pour une instruction. */
-void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
-
-
-static inline void handle_links_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_ARM);
-}
-
-static inline void handle_links_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
-{
-    handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_THUMB);
-}
-
-
-
-#endif  /* _ARCH_ARM_V7_LINK_H */
diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am
index 318e20b..b95b588 100644
--- a/src/arch/arm/v7/opdefs/Makefile.am
+++ b/src/arch/arm/v7/opdefs/Makefile.am
@@ -106,7 +106,7 @@ fmk.done: $(ARMV7_DEFS)
 fix_includes_in_c_templates:
 	@for f in `find .gen/ -name '*tmpl.c'`; do			\
 		if grep -q '##INCLUDES##' $$f; then				\
-			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/link.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\
+			$(fix_verbose)sed -i 's/##INCLUDES##/\n#include "..\/helpers.h"\n#include "..\/instruction.h"\n#include "..\/fetch.h"\n#include "..\/post.h"\n#include "..\/..\/instruction.h"\n#include "..\/..\/..\/link.h"\n#include "..\/..\/..\/..\/common\/bconst.h"\n\n/' $$f;	\
 		fi;												\
 	done
 
diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d
index 50bdda9..a275177 100644
--- a/src/arch/arm/v7/opdefs/b_A8818.d
+++ b/src/arch/arm/v7/opdefs/b_A8818.d
@@ -38,7 +38,8 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_b_from_thumb
+        fetch = help_fetching_with_instruction_b_from_thumb
+        link = handle_branch_if_true_as_link
         post = post_process_branch_instructions
 
     }
@@ -47,7 +48,7 @@
 
         //if cond == '1110' then UNDEFINED;
         //if cond == '1111' then SEE SVC;
-        chk_call DefineAsReturn(1)
+        //chk_call DefineAsReturn(1)
 
     }
 
@@ -67,7 +68,8 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_b_from_thumb
+        fetch = help_fetching_with_instruction_b_from_thumb
+        link = handle_branch_if_true_as_link
         post = post_process_branch_instructions
 
     }
@@ -75,7 +77,7 @@
     @rules {
 
         //if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
-        chk_call DefineAsReturn(1)
+        //chk_call DefineAsReturn(1)
 
     }
 
@@ -96,7 +98,8 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_b_from_thumb
+        fetch = help_fetching_with_instruction_b_from_thumb
+        link = handle_branch_if_true_as_link
         post = post_process_branch_instructions
 
     }
@@ -105,7 +108,7 @@
 
         //if cond<3:1> == '111' then SEE "Related encodings";
         //if InITBlock() then UNPREDICTABLE;
-        chk_call DefineAsReturn(1)
+        //chk_call DefineAsReturn(1)
 
     }
 
@@ -127,7 +130,8 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_b_from_thumb
+        fetch = help_fetching_with_instruction_b_from_thumb
+        link = handle_branch_if_true_as_link
         post = post_process_branch_instructions
 
     }
@@ -135,7 +139,7 @@
     @rules {
 
         //if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
-        chk_call DefineAsReturn(1)
+        //chk_call DefineAsReturn(1)
 
     }
 
@@ -156,14 +160,15 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_b_from_arm
+        fetch = help_fetching_with_instruction_b_from_arm
+        link = handle_branch_if_true_as_link
         post = post_process_branch_instructions
 
     }
 
     @rules {
 
-        chk_call DefineAsReturn(1)
+        //chk_call DefineAsReturn(1)
 
     }
 
diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d
index 63922dd..62ac8f9 100644
--- a/src/arch/arm/v7/opdefs/bl_A8825.d
+++ b/src/arch/arm/v7/opdefs/bl_A8825.d
@@ -39,7 +39,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_bl_from_thumb
+        fetch = help_fetching_with_instruction_bl_from_thumb
         post = post_process_branch_and_link_instructions
 
     }
@@ -68,7 +68,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_blx_from_thumb
+        fetch = help_fetching_with_instruction_blx_from_thumb
         post = post_process_branch_and_link_instructions
 
     }
@@ -95,7 +95,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_bl_from_arm
+        fetch = help_fetching_with_instruction_bl_from_arm
         post = post_process_branch_and_link_instructions
 
     }
@@ -122,7 +122,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_blx_from_arm
+        fetch = help_fetching_with_instruction_blx_from_arm
         post = post_process_branch_and_link_instructions
 
     }
diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d
index 4856885..f8027a4 100644
--- a/src/arch/arm/v7/opdefs/bx_A8827.d
+++ b/src/arch/arm/v7/opdefs/bx_A8827.d
@@ -38,7 +38,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_bx_from_thumb
+        fetch = help_fetching_with_instruction_bx_from_thumb
 
     }
 
@@ -65,7 +65,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_bx_from_thumb
+        fetch = help_fetching_with_instruction_bx_from_thumb
 
     }
 
diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d
index 93a8d1f..d9815c1 100644
--- a/src/arch/arm/v7/opdefs/cbnz_A8829.d
+++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d
@@ -38,7 +38,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_cb_n_z
+        fetch = help_fetching_with_instruction_cb_n_z
         post = post_process_comp_and_branch_instructions
 
     }
@@ -60,7 +60,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_cb_n_z
+        fetch = help_fetching_with_instruction_cb_n_z
         post = post_process_comp_and_branch_instructions
 
     }
diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d
index c5b0dd0..4cf0048 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8864.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8864.d
@@ -39,7 +39,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_ldr_literal_from_thumb
+        fetch = help_fetching_with_instruction_ldr_literal_from_thumb
         post = post_process_ldr_instructions
 
     }
@@ -62,7 +62,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_ldr_literal_from_thumb
+        fetch = help_fetching_with_instruction_ldr_literal_from_thumb
         post = post_process_ldr_instructions
 
     }
@@ -93,7 +93,7 @@
 
     @hooks {
 
-        link = handle_links_with_instruction_ldr_literal_from_arm
+        fetch = help_fetching_with_instruction_ldr_literal_from_arm
         post = post_process_ldr_instructions
 
     }
diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d
index 2663e1b..ef5ab25 100644
--- a/src/arch/arm/v7/opdefs/pop_A88131.d
+++ b/src/arch/arm/v7/opdefs/pop_A88131.d
@@ -39,6 +39,7 @@
 
         //if BitCount(registers) < 1 then UNPREDICTABLE;
         //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+        chk_call DefineAsReturn(1)
 
     }
 
@@ -60,6 +61,7 @@
 
         //if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
         //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+        chk_call DefineAsReturn(1)
 
     }
 
@@ -81,6 +83,7 @@
     @rules {
 
         //if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
+        chk_call DefineAsReturn(1)
 
     }
 
diff --git a/src/arch/arm/v7/opdefs/pop_A88132.d b/src/arch/arm/v7/opdefs/pop_A88132.d
index 0c6c1b0..89c51c9 100644
--- a/src/arch/arm/v7/opdefs/pop_A88132.d
+++ b/src/arch/arm/v7/opdefs/pop_A88132.d
@@ -40,6 +40,7 @@
 
         //if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
         //if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
+        chk_call DefineAsReturn(1)
 
     }
 
@@ -62,6 +63,7 @@
     @rules {
 
         //if t == 13 then UNPREDICTABLE;
+        chk_call DefineAsReturn(1)
 
     }
 
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index e6a6c2e..23d0198 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -34,6 +34,7 @@
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
@@ -45,7 +46,7 @@
 *                                                                             *
 ******************************************************************************/
 
-void post_process_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
 {
     GArchOperand *op;                       /* Opérande numérique en place */
     uint32_t addr;                          /* Adresse visée par le saut   */
@@ -97,6 +98,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
@@ -108,7 +110,7 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con
 *                                                                             *
 ******************************************************************************/
 
-void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_branch_and_link_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
 {
     GArchOperand *op;                       /* Opérande numérique en place */
     uint32_t addr;                          /* Adresse visée par le saut   */
@@ -160,6 +162,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
@@ -171,7 +174,7 @@ void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcCon
 *                                                                             *
 ******************************************************************************/
 
-void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_comp_and_branch_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
 {
     GArchOperand *op;                       /* Opérande numérique en place */
     uint32_t addr;                          /* Adresse visée par le saut   */
@@ -223,6 +226,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
@@ -234,7 +238,7 @@ void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcCon
 *                                                                             *
 ******************************************************************************/
 
-void post_process_ldr_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
 {
     GArchOperand *op;                       /* Opérande numérique en place */
     uint32_t addr;                          /* Adresse visée par le saut   */
diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h
index 79dcaa8..6165597 100644
--- a/src/arch/arm/v7/post.h
+++ b/src/arch/arm/v7/post.h
@@ -31,16 +31,16 @@
 
 
 /* Complète un désassemblage accompli pour une instruction. */
-void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void post_process_branch_and_link_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_branch_and_link_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void post_process_comp_and_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_comp_and_branch_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void post_process_ldr_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+void post_process_ldr_instructions(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
 
 
 
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 0bcc739..08256d1 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -234,6 +234,7 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,
 *                                                                             *
 *  Paramètres  : instr   = instruction quelconque à traiter.                  *
 *                type    = type de procédure à utiliser.                      *
+*                proc    = représentation de l'architecture utilisée.         *
 *                context = contexte associé à la phase de désassemblage.      *
 *                format  = accès aux données du binaire d'origine.            *
 *                                                                             *
@@ -245,12 +246,15 @@ void g_arch_instruction_set_hook(GArchInstruction *instr, InstrProcessHook type,
 *                                                                             *
 ******************************************************************************/
 
-void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GProcContext *context, GBinFormat *format)
+void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
 {
+    if (instr->range.addr.virtual == 0x83c2)
+        printf(" [%u] HAS BRANCH ? %p\n", (unsigned int)type, instr->hooks[type]);
+
     assert(type < IPH_COUNT);
 
     if (instr->hooks[type] != NULL)
-        instr->hooks[type](instr, context, format);
+        instr->hooks[type](instr, proc, context, format);
 
 }
 
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 9251a34..0198bb5 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -76,22 +76,29 @@ void g_arch_instruction_set_flag(GArchInstruction *, ArchInstrFlag);
 /* Fournit les informations complémentaires d'une instruction. */
 ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
 
+
 /**
  * La définition de "GBinFormat", utile aux traitements complémentaires, ne peut
  * se faire en incluant le fichier d'en-tête "../format/format.h", pour cause
  * de références circulaires.
  *
  * On procède donc à une seconde déclaration, en attendant éventuellement mieux.
+ *
+ * Pareil pour "GArchProcessor", définie dans le fichier "processor.h", lequel
+ * inclut directement ce fichier.
  */
 
-
 /* Format binaire générique (instance) */
 typedef struct _GBinFormat GBinFormat;
 
+/* Ligne de représentation générique (instance) */
+typedef struct _GArchProcessor GArchProcessor;
+
 
 /* Types de crochet de traitement */
 typedef enum _InstrProcessHook
 {
+    IPH_FETCH,                              /* Itinéraire de désassemblage */
     IPH_LINK,                               /* Edition des liens           */
     IPH_POST,                               /* Résolution des symboles     */
 
@@ -100,13 +107,13 @@ typedef enum _InstrProcessHook
 } InstrProcessHook;
 
 /* Complète un désassemblage accompli pour une instruction. */
-typedef void (* instr_hook_fc) (GArchInstruction *, GProcContext *, GBinFormat *);
+typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
 
 /* Définit un traitement complémentare au désassemblage. */
 void g_arch_instruction_set_hook(GArchInstruction *, InstrProcessHook, instr_hook_fc);
 
 /* Complète un désassemblage accompli pour une instruction. */
-void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GProcContext *, GBinFormat *);
+void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GBinFormat *);
 
 /* Définit la localisation d'une instruction. */
 void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *);
@@ -155,7 +162,8 @@ typedef enum _InstructionLinkType
     ILT_JUMP_IF_FALSE,                      /* Saut conditionnel (si faux) */
     ILT_LOOP,                               /* Retour en arrière (boucle)  */
     ILT_CALL,                               /* Appel d'une fonction        */
-    ILT_CATCH_EXCEPTION                     /* Gestion d'une exception     */
+    ILT_CATCH_EXCEPTION,                    /* Gestion d'une exception     */
+    ILT_REF                                 /* Simple référence croisée    */
 
 } InstructionLinkType;
 
diff --git a/src/arch/link.c b/src/arch/link.c
new file mode 100644
index 0000000..bc80e39
--- /dev/null
+++ b/src/arch/link.c
@@ -0,0 +1,190 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.c - édition des liens après la phase de désassemblage
+ *
+ * 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 "link.h"
+
+
+#include <assert.h>
+
+
+#include "target.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Etablit un lien de saut selon une instruction donnée.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+    GArchOperand *op;                       /* Opérande numérique en place */
+    virt_t virt;                            /* Adresse virtuelle           */
+    vmpa2t addr;                            /* Adresse de destination      */
+    GArchInstruction *target;               /* Ligne visée par la référence*/
+
+    assert(g_arch_instruction_count_operands(instr) > 0);
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (!G_IS_IMM_OPERAND(op)) return;
+
+    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+    {
+        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+        target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+        if (target != NULL)
+            g_arch_instruction_link_with(instr, target, ILT_JUMP);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Etablit un lien d'appel selon une instruction donnée.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#include "instruction-int.h"
+void handle_branch_if_true_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+    GArchOperand *op;                       /* Opérande numérique en place */
+    virt_t virt;                            /* Adresse virtuelle           */
+    vmpa2t addr;                            /* Adresse de destination      */
+    GArchInstruction *target;               /* Ligne visée par la référence*/
+    GArchInstruction *list;                 /* Ensemble des instructions   */
+
+    assert(g_arch_instruction_count_operands(instr) > 0);
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    virt = VMPA_NO_VIRTUAL;
+
+    if (G_IS_TARGET_OPERAND(op))
+        virt = g_target_operand_get_addr(G_TARGET_OPERAND(op));
+
+    else if (G_IS_IMM_OPERAND(op))
+    {
+        if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+            virt = VMPA_NO_VIRTUAL;
+    }
+
+    if (virt != VMPA_NO_VIRTUAL)
+    {
+        /* TODO : utiliser format pour contruire une adresse avec une position physique,
+         * ce qui accélèrerait les recherches.
+         */
+        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+        target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+        printf(" @ 0x%08x BRANCH to 0x%08x -->> %p\n",
+               (unsigned int)instr->range.addr.virtual, (unsigned int)virt, target);
+
+        if (target != NULL)
+        {
+            g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_TRUE);
+
+            list = g_arch_processor_get_disassembled_instructions(proc);
+
+            target = g_arch_instruction_get_next_iter(list, instr, ~0);
+
+            if (target != NULL)
+                g_arch_instruction_link_with(instr, target, ILT_JUMP_IF_FALSE);
+
+        }
+
+    }
+
+
+    else printf(" @ 0x%08x FAILED TO BRANCH\n",
+                (unsigned int)instr->range.addr.virtual);
+
+
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr   = instruction ARMv7 à traiter.                       *
+*                proc    = représentation de l'architecture utilisée.         *
+*                context = contexte associé à la phase de désassemblage.      *
+*                format  = acès aux données du binaire d'origine.             *
+*                                                                             *
+*  Description : Etablit un lien d'appel selon une instruction donnée.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcContext *context, GBinFormat *format)
+{
+    GArchOperand *op;                       /* Opérande numérique en place */
+    virt_t virt;                            /* Adresse virtuelle           */
+    vmpa2t addr;                            /* Adresse de destination      */
+    GArchInstruction *target;               /* Ligne visée par la référence*/
+
+    assert(g_arch_instruction_count_operands(instr) > 0);
+
+    op = g_arch_instruction_get_operand(instr, 0);
+
+    if (!G_IS_IMM_OPERAND(op)) return;
+
+    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+    {
+        init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
+
+        target = g_arch_processor_find_instr_by_address(proc, &addr);
+
+        if (target != NULL)
+            g_arch_instruction_link_with(instr, target, ILT_CALL);
+
+    }
+
+}
diff --git a/src/arch/link.h b/src/arch/link.h
new file mode 100644
index 0000000..1923e0b
--- /dev/null
+++ b/src/arch/link.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * link.h - prototypes pour l'édition des liens après la phase de désassemblage
+ *
+ * Copyright (C) 2015 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_LINK_H
+#define _ARCH_LINK_H
+
+
+#include "instruction.h"
+#include "processor.h"
+#include "../format/format.h"
+
+
+
+/* Etablit un lien de saut selon une instruction donnée. */
+void handle_jump_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+/* Etablit un lien d'appel selon une instruction donnée. */
+void handle_branch_if_true_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+/* Etablit un lien d'appel selon une instruction donnée. */
+void handle_call_as_link(GArchInstruction *, GArchProcessor *, GProcContext *, GBinFormat *);
+
+
+
+#endif  /* _ARCH_LINK_H */
diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h
index 2b91b36..d387bde 100644
--- a/src/arch/processor-int.h
+++ b/src/arch/processor-int.h
@@ -43,6 +43,9 @@
 
 
 
+/* Taille des pré-allocations pour les instructions */
+#define INSTR_ALLOC_BLOCK 100
+
 
 
 /* Fournit un contexte propre au processeur d'une architecture. */
@@ -70,6 +73,10 @@ struct _GArchProcessor
     get_processor_context_fc get_ctx;       /* Obtention d'un contexte #1  */
     get_decomp_context_fc get_dec_ctx;      /* Obtention d'un contexte #2  */
 
+    GArchInstruction **instructions;        /* Instructions désassemblées  */
+    size_t instr_allocated;                 /* Taille de la liste allouée  */
+    size_t instr_count;                     /* Taille de la liste aplatie  */
+
 };
 
 
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 0b33552..c2d190b 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -24,12 +24,16 @@
 #include "processor.h"
 
 
+#include <malloc.h>
+#include <stdlib.h>
+
 
 
 
 
 #include "instruction-int.h"
 #include "processor-int.h"
+#include "raw.h"
 
 
 
@@ -294,3 +298,146 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *proc, GProc
     return result;
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                    MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES                    */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : proc = architecture visée par la procédure.                  *
+*                list = liste des instructions désassemblées.                 *
+*                                                                             *
+*  Description : Note les instructions désassemblées avec une architecture.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *proc, GArchInstruction *list)
+{
+    GArchInstruction *iter;                 /* Boucle de parcours          */
+
+    ainstr_list_for_each(iter, list)
+    {
+        /* Mise à disposition de d'avantage d'espace */
+        if (proc->instr_allocated == proc->instr_count)
+        {
+            proc->instr_allocated += INSTR_ALLOC_BLOCK;
+
+            proc->instructions = (GArchInstruction **)realloc(proc->instructions,
+                                                              proc->instr_allocated * sizeof(GArchInstruction  *));
+
+        }
+
+        proc->instructions[proc->instr_count++] = iter;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : proc = architecture visée par la procédure.                  *
+*                                                                             *
+*  Description : Fournit les instructions désassemblées pour une architecture.*
+*                                                                             *
+*  Retour      : Liste des instructions désassemblées ou NULL si aucune.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *proc)
+{
+    return (proc->instr_count > 0 ? proc->instructions[0] : NULL);
+
+}
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : proc = processeur recensant diverses instructions.           *
+*                addr = position en mémoire ou physique à chercher.           *
+*                                                                             *
+*  Description : Recherche une instruction d'après son adresse.               *
+*                                                                             *
+*  Retour      : Instruction trouvée à l'adresse donnée, NULL si aucune.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *proc, const vmpa2t *addr)
+{
+    GArchInstruction *result;               /* Trouvaille à retourner      */
+    GArchInstruction *fake;                 /* Coquille vide à comparer    */
+    void *ptr;                              /* Résultat des recherches     */
+    size_t i;                               /* Boucle de parcours          */
+    const mrange_t *range;                  /* Emplacement d'instruction   */
+
+    if (has_phys_addr(addr))
+    {
+        fake = g_raw_instruction_new_from_value(addr, MDS_8_BITS_UNSIGNED, 0);
+
+        int search_for_instr_by_addr(const GArchInstruction **a, const GArchInstruction **b)
+        {
+            const mrange_t *range_a;        /* Emplacement pour l'instr. A */
+            const mrange_t *range_b;        /* Emplacement pour l'instr. B */
+
+            range_a = g_arch_instruction_get_range(*a);
+            range_b = g_arch_instruction_get_range(*b);
+
+            /*
+            printf("  -- cmp -- 0x%08x vs 0x%08x => %d\n",
+                   (unsigned int)range_a->addr.virtual,
+                   (unsigned int)range_b->addr.virtual,
+                   cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b)));
+            */
+
+            return cmp_vmpa(get_mrange_addr(range_a), get_mrange_addr(range_b));
+
+        }
+
+        ptr = bsearch(&fake, proc->instructions, proc->instr_count,
+                      sizeof(GArchInstruction *), (__compar_fn_t)search_for_instr_by_addr);
+
+        g_object_unref(G_OBJECT(fake));
+
+        result = (ptr != NULL ? *((GArchInstruction **)ptr) : NULL);
+
+    }
+
+    else
+    {
+        result = NULL;
+
+        for (i = 0; i < proc->instr_count && result == NULL; i++)
+        {
+            range = g_arch_instruction_get_range(proc->instructions[i]);
+
+            if (cmp_vmpa(addr, get_mrange_addr(range)) == 0)
+                result = proc->instructions[i];
+
+        }
+
+        /*
+        for (i = 0; i < proc->instr_count; i++)
+            printf("  # %04zu  0x%08x\n", i, proc->instructions[i]->range.addr.virtual);
+        */
+
+    }
+
+    return result;
+
+}
diff --git a/src/arch/processor.h b/src/arch/processor.h
index 725307f..3eeefd5 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -78,4 +78,20 @@ GArchInstruction *g_arch_processor_disassemble(const GArchProcessor *, GProcCont
 
 
 
+/* ------------------ MANIPULATIONS DES INSTRUCTIONS DESASSEMBLEES ------------------ */
+
+
+/* Note les instructions désassemblées avec une architecture. */
+void g_arch_processor_set_disassembled_instructions(GArchProcessor *, GArchInstruction *);
+
+/* Fournit les instructions désassemblées pour une architecture. */
+GArchInstruction *g_arch_processor_get_disassembled_instructions(const GArchProcessor *);
+
+
+
+/* Recherche une instruction d'après son adresse. */
+GArchInstruction *g_arch_processor_find_instr_by_address(const GArchProcessor *, const vmpa2t *);
+
+
+
 #endif  /* _ARCH_PROCESSOR_H */
-- 
cgit v0.11.2-87-g4458