From 35a6cd881528b5f77ce09476eccb39d02d9cc634 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 13 Jan 2013 20:23:05 +0000
Subject: Defined the registers allocation needs for each basic block.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@323 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                       |  26 +++
 src/analysis/block-int.h        |   6 +-
 src/analysis/block.c            |  26 +--
 src/analysis/block.h            |  36 +---
 src/analysis/blocks/Makefile.am |   1 +
 src/analysis/blocks/flow.c      | 200 ++++++++++++++-------
 src/analysis/blocks/flow.h      |  24 +++
 src/analysis/blocks/raccess.c   | 387 ++++++++++++++++++++++++++++++++++++++++
 src/analysis/blocks/raccess.h   | 105 +++++++++++
 src/analysis/blocks/virtual.c   |  31 ++--
 src/analysis/decomp/il.c        | 153 +++++++++++++++-
 11 files changed, 851 insertions(+), 144 deletions(-)
 create mode 100644 src/analysis/blocks/raccess.c
 create mode 100644 src/analysis/blocks/raccess.h

diff --git a/ChangeLog b/ChangeLog
index 74e3608..31709b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+13-01-13  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/block.c:
+	* src/analysis/block.h:
+	* src/analysis/block-int.h:
+	Remove all stuff related to registers access. Extend the search of blocks.
+
+	* src/analysis/blocks/flow.c:
+	* src/analysis/blocks/flow.h:
+	Remove all stuff related to registers access. Extend the search of blocks.
+	Implement a design pattern to follow the execution flow.
+
+	* src/analysis/blocks/Makefile.am:
+	Add the 'raccess.[ch]' files to libanalysisblocks_la_SOURCES.
+
+	* src/analysis/blocks/raccess.c:
+	* src/analysis/blocks/raccess.h:
+	New entries: provide an easy access to all registers used in a block.
+
+	* src/analysis/blocks/virtual.c:
+	Remove all stuff related to registers access. Extend the search of blocks.
+
+	* src/analysis/decomp/il.c:
+	Define the registers allocation needs for each basic block. Clean
+	the code a little bit.
+
 13-01-10  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/block.c:
diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h
index f016e35..249aa57 100644
--- a/src/analysis/block-int.h
+++ b/src/analysis/block-int.h
@@ -30,7 +30,7 @@
 
 
 /* Recherche le bloc contenant une adresse donnée. */
-typedef GInstrBlock * (* find_by_addr_fc) (const GInstrBlock *, vmpa_t);
+typedef GInstrBlock * (* find_by_addr_fc) (const GInstrBlock *, vmpa_t, bool);
 
 /* Parcours tous les blocs d'instructions dans un ordre donné. */
 typedef bool (* visit_all_blocks_fc) (GInstrBlock *, instr_block_visitor_cb, void *);
@@ -39,7 +39,7 @@ typedef bool (* visit_all_blocks_fc) (GInstrBlock *, instr_block_visitor_cb, voi
 typedef void (* list_all_blocks_fc) (const GInstrBlock *, GInstrBlock ***, size_t *);
 
 /* Fournit les différents accès aux registres. */
-typedef const reg_access * (* list_regs_accesses_fc) (const GInstrBlock *, size_t *);
+//typedef const reg_access * (* list_regs_accesses_fc) (const GInstrBlock *, size_t *);
 
 
 
@@ -51,7 +51,7 @@ struct _GInstrBlock
     find_by_addr_fc find_by_addr;           /* Recherche par adresse       */
     visit_all_blocks_fc visit_blocks;       /* Visite des différents blocs */
     list_all_blocks_fc list_blocks;         /* Liste de tous les blocs     */
-    list_regs_accesses_fc list_regs;        /* Liste des accès registres   */
+    //list_regs_accesses_fc list_regs;        /* Liste des accès registres   */
 
     GInstrBlock *links_block;               /* Lieu des blocs attachés     */
 
diff --git a/src/analysis/block.c b/src/analysis/block.c
index 1ec9804..d6f3df3 100644
--- a/src/analysis/block.c
+++ b/src/analysis/block.c
@@ -47,27 +47,6 @@ static void g_instr_block_finalize(GInstrBlock *);
 
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : a = premier opérande à consulter.                            *
-*                b = second opérande à consulter.                             *
-*                                                                             *
-*  Description : Compare un accès registre avec un autre.                     *
-*                                                                             *
-*  Retour      : Bilan de la comparaison.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int compare_reg_accesses(const reg_access *a, const reg_access *b)
-{
-    return g_arch_register_compare(a->reg, b->reg);
-
-}
-
-
-
 
 
 
@@ -162,6 +141,7 @@ static void g_instr_block_finalize(GInstrBlock *block)
 *                                                                             *
 *  Paramètres  : block = bloc de départ des recherches.                       *
 *                addr  = ensemble de blocs à parcourir.                       *
+*                final = indique si la cible ou le conteneur est renvoyée.    *
 *                                                                             *
 *  Description : Recherche le bloc contenant une adresse donnée.              *
 *                                                                             *
@@ -171,9 +151,9 @@ static void g_instr_block_finalize(GInstrBlock *block)
 *                                                                             *
 ******************************************************************************/
 
-GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, vmpa_t addr)
+GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *block, vmpa_t addr, bool final)
 {
-    return block->find_by_addr(block, addr);
+    return block->find_by_addr(block, addr, final);
 
 }
 
diff --git a/src/analysis/block.h b/src/analysis/block.h
index 125ff0e..223649f 100644
--- a/src/analysis/block.h
+++ b/src/analysis/block.h
@@ -27,40 +27,10 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <stdbool.h>
 
 
-#include "../arch/register.h"
-
-
-
-
-
-
-
-
-/* Note sur le premier accès */
-typedef enum _RegAccessType
-{
-    RAT_NONE    = (0 << 0),                 /* Registre non rencontré      */
-    RAT_READ    = (1 << 0),                 /* Lecture                     */
-    RAT_WRITE   = (1 << 1)                  /* Ecriture                    */
-
-} RegAccessType;
-
-/* Description minimale des accès à un registre */
-typedef struct _reg_access
-{
-    GArchRegister *reg;                     /* Register concerné           */
-
-    RegAccessType first_access;             /* Type du premier accès       */
-    vmpa_t last_write;                      /* Dernière écriture           */
-
-} reg_access;
-
-
-/* Compare un accès registre avec un autre. */
-int compare_reg_accesses(const reg_access *, const reg_access *);
-
+#include "../arch/archbase.h"
 
 
 
@@ -96,7 +66,7 @@ typedef bool (* instr_block_visitor_cb) (GInstrBlock *, BlockVisitOrder, void *)
 GType g_instr_block_get_type(void);
 
 /* Recherche le bloc contenant une adresse donnée. */
-GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *, vmpa_t);
+GInstrBlock *g_instr_block_find_by_addr(const GInstrBlock *, vmpa_t, bool);
 
 /* Parcours tous les blocs d'instructions dans un ordre donné. */
 bool g_instr_block_visit(GInstrBlock *, instr_block_visitor_cb, void *);
diff --git a/src/analysis/blocks/Makefile.am b/src/analysis/blocks/Makefile.am
index 7a9e371..fe1452a 100755
--- a/src/analysis/blocks/Makefile.am
+++ b/src/analysis/blocks/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES  = libanalysisblocks.la
 
 libanalysisblocks_la_SOURCES =			\
 	flow.h flow.c						\
+	raccess.h raccess.c					\
 	virtual.h virtual.c
 
 libanalysisblocks_la_LIBADD =	
diff --git a/src/analysis/blocks/flow.c b/src/analysis/blocks/flow.c
index 6fb5849..6f56f9d 100644
--- a/src/analysis/blocks/flow.c
+++ b/src/analysis/blocks/flow.c
@@ -40,8 +40,8 @@ struct _GFlowBlock
     GArchInstruction *first;                /* Première instruction        */
     GArchInstruction *last;                 /* Dernière instruction        */
 
-    reg_access *accesses;                   /* Commodités d'accès #1       */
-    size_t count;                           /* Commodités d'accès #2       */
+    GRAccessList *regs;                     /* Accès aux registres         */
+    GRAccessList *awaited;                  /* Registres définis pour après*/
 
 };
 
@@ -66,7 +66,7 @@ static void g_flow_block_dispose(GFlowBlock *);
 static void g_flow_block_finalize(GFlowBlock *);
 
 /* Recherche le bloc contenant une adresse donnée. */
-static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, vmpa_t);
+static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *, vmpa_t, bool);
 
 /* Parcours le bloc d'instructions dans un ordre donné. */
 static bool g_flow_block_visit(GFlowBlock *, instr_block_visitor_cb, void *);
@@ -81,7 +81,7 @@ static void g_flow_block_memorize_access(GFlowBlock *, GArchRegister *, RegAcces
 static void g_flow_block_compute_regs_access(GFlowBlock *);
 
 /* Fournit les différents accès aux registres. */
-static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *, size_t *);
+//static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *, size_t *);
 
 
 
@@ -134,7 +134,10 @@ static void g_flow_block_init(GFlowBlock *block)
     parent->find_by_addr = (find_by_addr_fc)g_flow_block_find_by_addr;
     parent->visit_blocks = (visit_all_blocks_fc)g_flow_block_visit;
     parent->list_blocks = (list_all_blocks_fc)g_flow_block_list_all_blocks;
-    parent->list_regs = (list_regs_accesses_fc)g_flow_block_list_regs_accesses;
+    //parent->list_regs = (list_regs_accesses_fc)g_flow_block_list_regs_accesses;
+
+    block->regs = g_raccess_list_new();
+    block->awaited = g_raccess_list_new();
 
 }
 
@@ -153,14 +156,12 @@ static void g_flow_block_init(GFlowBlock *block)
 
 static void g_flow_block_dispose(GFlowBlock *block)
 {
-    size_t i;                               /* Boucle de parcours          */
-
     g_object_unref(G_OBJECT(block->instrs));
     g_object_unref(G_OBJECT(block->first));
     g_object_unref(G_OBJECT(block->last));
 
-    for (i = 0; i < block->count; i++)
-        g_object_unref(G_OBJECT(block->accesses[i].reg));
+    g_object_unref(G_OBJECT(block->regs));
+    g_object_unref(G_OBJECT(block->awaited));
 
     G_OBJECT_CLASS(g_flow_block_parent_class)->dispose(G_OBJECT(block));
 
@@ -181,9 +182,6 @@ static void g_flow_block_dispose(GFlowBlock *block)
 
 static void g_flow_block_finalize(GFlowBlock *block)
 {
-    if (block->accesses != NULL)
-        free(block->accesses);
-
     G_OBJECT_CLASS(g_flow_block_parent_class)->finalize(G_OBJECT(block));
 
 }
@@ -242,6 +240,7 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first,
 *                                                                             *
 *  Paramètres  : block = bloc de départ des recherches.                       *
 *                addr  = ensemble de blocs à parcourir.                       *
+*                final = indique si la cible ou le conteneur est renvoyée.    *
 *                                                                             *
 *  Description : Recherche le bloc contenant une adresse donnée.              *
 *                                                                             *
@@ -251,7 +250,7 @@ GInstrBlock *g_flow_block_new(GArchInstruction *instrs, GArchInstruction *first,
 *                                                                             *
 ******************************************************************************/
 
-static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, vmpa_t addr)
+static GInstrBlock *g_flow_block_find_by_addr(const GFlowBlock *block, vmpa_t addr, bool final)
 {
     GInstrBlock *result;                    /* Resultat à retourner        */
     vmpa_t start;                           /* Adresse de début du bloc    */
@@ -331,47 +330,28 @@ static void g_flow_block_list_all_blocks(const GFlowBlock *block, GInstrBlock **
 
 static void g_flow_block_memorize_access(GFlowBlock *block, GArchRegister *reg, RegAccessType type, vmpa_t addr)
 {
-    reg_access **accesses;                  /* Commodités d'accès #1       */
-    size_t *count;                          /* Commodités d'accès #2       */
-    reg_access *access;                     /* Accès à manipuler           */
-    bool need_sort;                         /* Insertion donc tri à faire  */
-
-    accesses = &block->accesses;
-    count = &block->count;
-
-    /* Recherche de l'élément à mettre à jour */
+    reg_access *found;                      /* Accès à mettre à jour       */
+    reg_access access;                      /* Accès à mettre en place     */
 
-    access = bsearch((reg_access []) { { .reg = reg } }, *accesses, *count, sizeof(reg_access),
-                     (__compar_fn_t)compare_reg_accesses);
+    found = g_raccess_list_find(block->regs, reg);
 
-    if (access == NULL)
+    /* Simpple mise à jour ? */
+    if (found != NULL)
     {
-        *accesses = (reg_access *)realloc(*accesses, ++(*count) * sizeof(reg_access));
-        access = &(*accesses)[*count - 1];
-
-        g_object_ref(G_OBJECT(reg));
-
-        access->reg = reg;
-        access->first_access = RAT_NONE;
-        access->last_write = VMPA_MAX;
-
-        need_sort = true;
-
+        if (type == RAT_WRITE)
+            found->last_write = addr;
     }
-    else need_sort = false;
-
-    /* Mise à jour */
-
-    if (access->first_access == RAT_NONE)
-        access->first_access = type;
 
-    if (type == RAT_WRITE)
-        access->last_write = addr;
+    /* Ou ajout pur et simple ? */
+    else
+    {
+        access.reg = reg;
+        access.first_access = type;
+        access.last_write = (type == RAT_WRITE ? addr : VMPA_MAX);
 
-    /* Remise en conditions éventuelle */
+        g_raccess_list_add(block->regs, &access);
 
-    if (need_sort)
-        qsort(*accesses, *count, sizeof(reg_access), (__compar_fn_t)compare_reg_accesses);
+    }
 
 }
 
@@ -433,28 +413,6 @@ static void g_flow_block_compute_regs_access(GFlowBlock *block)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : block = bloc d'instructions à consulter.                     *
-*                count = nombre de registres consignés. [OUT]                 *
-*                                                                             *
-*  Description : Fournit les différents accès aux registres.                  *
-*                                                                             *
-*  Retour      : Liste des accès aux registres.                               *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static const reg_access *g_flow_block_list_regs_accesses(const GFlowBlock *block, size_t *count)
-{
-    *count = block->count;
-
-    return block->accesses;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : block = bloc d'instructions à consulter.                     *
 *                                                                             *
 *  Description : Fournit la liste d'appartenance des instructions du bloc.    *
 *                                                                             *
@@ -519,3 +477,107 @@ void g_flow_block_get_boundary_addresses(const GFlowBlock *block, vmpa_t *start,
         g_arch_instruction_get_location(block->last, NULL, NULL, end);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block    = bloc d'instructions démarrant la visite.          *
+*                list     = ensemble des blocs basiques à parcourir.          *
+*                mask     = points de passage à marquer.                      *
+*                callback = ensemble de blocs à parcourir.                    *
+*                data     = donnée utilisateur à associer au parcours.        *
+*                                                                             *
+*  Description : Suit le flot d'excution bloc par bloc.                       *
+*                                                                             *
+*  Retour      : true si le parcours a été jusqu'à son terme, false sinon.    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_flow_block_follow(GFlowBlock *block, const GInstrBlock *list, BlockFollowPosition mask, flow_block_follow_cb callback, void *data)
+{
+    bool result;                            /* Bilan à retourner           */
+    GArchInstruction **dests;               /* Instr. visée par une autre  */
+    InstructionLinkType *types;             /* Type de lien entre lignes   */
+    size_t dcount;                          /* Nombre de liens de dest.    */
+    size_t i;                               /* Boucle de parcours          */
+    vmpa_t addr;                            /* Adresse de la destination   */
+    GInstrBlock *next;                      /* Bloc suivant à visiter      */
+
+    result = true;
+
+    if (mask & BFP_ENTER)
+        result = callback(block, BFP_ENTER, data);
+
+    dcount = g_arch_instruction_get_destinations(block->last, &dests, &types);
+
+    for (i = 0; i < dcount && result; i++)
+        switch (types[i])
+        {
+            case ILT_EXEC_FLOW:
+            case ILT_JUMP:
+            case ILT_CASE_JUMP:
+            case ILT_JUMP_IF_TRUE:
+            case ILT_JUMP_IF_FALSE:
+
+                g_arch_instruction_get_location(dests[i], NULL, NULL, &addr);
+                next = g_instr_block_find_by_addr(list, addr, true);
+
+                if (next)
+                {
+                    result = callback(block, BFP_FOLLOW, data);
+                    result &= g_flow_block_follow(G_FLOW_BLOCK(next), list, mask, callback, data);
+                    result &= callback(block, BFP_BACK, data);
+                }
+                break;
+
+            default:
+                break;
+
+        }
+
+    if (mask & BFP_EXIT)
+        result &= callback(block, BFP_EXIT, data);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                                                                             *
+*  Description : Fournit les différents accès aux registres.                  *
+*                                                                             *
+*  Retour      : Liste des accès aux registres.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const GRAccessList *g_flow_block_list_regs_accesses(const GFlowBlock *block)
+{
+    return block->regs;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = bloc d'instructions à consulter.                     *
+*                                                                             *
+*  Description : Fournit les registres écrits par le bloc et utilisées après. *
+*                                                                             *
+*  Retour      : Liste des accès aux registres.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GRAccessList *g_flow_block_list_awaited_regs(const GFlowBlock *block)
+{
+    return block->awaited;
+
+}
diff --git a/src/analysis/blocks/flow.h b/src/analysis/blocks/flow.h
index 28fb5a9..a01ef64 100644
--- a/src/analysis/blocks/flow.h
+++ b/src/analysis/blocks/flow.h
@@ -29,6 +29,7 @@
 #include <glib-object.h>
 
 
+#include "raccess.h"
 #include "../block.h"
 #include "../../arch/instruction.h"
 
@@ -49,6 +50,20 @@ typedef struct _GFlowBlock GFlowBlock;
 typedef struct _GFlowBlockClass GFlowBlockClass;
 
 
+/* Position au cours d'une visite */
+typedef enum _BlockFollowPosition
+{
+    BFP_ENTER   = (1 << 0),                 /* Entrée dans le bloc         */
+    BFP_FOLLOW  = (1 << 1),                 /* Suivi des liens : aller...  */
+    BFP_BACK    = (1 << 2),                 /* Suivi des liens : retour !  */
+    BFP_EXIT    = (1 << 3)                  /* Sortie du bloc              */
+
+} BlockFollowPosition;
+
+/* Rappel à chaque bloc visité */
+typedef bool (* flow_block_follow_cb) (GFlowBlock *, BlockFollowPosition, void *);
+
+
 /* Indique le type défini pour un bloc d'exécution d'instructions. */
 GType g_flow_block_get_type(void);
 
@@ -64,6 +79,15 @@ void g_flow_block_get_boundary(const GFlowBlock *, GArchInstruction **, GArchIns
 /* Fournit les adresses limites d'un bloc d'exécution. */
 void g_flow_block_get_boundary_addresses(const GFlowBlock *, vmpa_t *, vmpa_t *);
 
+/* Suit le flot d'excution bloc par bloc. */
+bool g_flow_block_follow(GFlowBlock *, const GInstrBlock *, BlockFollowPosition, flow_block_follow_cb, void *);
+
+/* Fournit les différents accès aux registres. */
+const GRAccessList *g_flow_block_list_regs_accesses(const GFlowBlock *);
+
+/* Fournit les registres écrits par le bloc et utilisées après. */
+GRAccessList *g_flow_block_list_awaited_regs(const GFlowBlock *);
+
 
 
 #endif  /* _ANALYSIS_BLOCKS_FLOW_H */
diff --git a/src/analysis/blocks/raccess.c b/src/analysis/blocks/raccess.c
new file mode 100644
index 0000000..7fe084c
--- /dev/null
+++ b/src/analysis/blocks/raccess.c
@@ -0,0 +1,387 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * raccess.c - suivi des accès aux registres
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 "raccess.h"
+
+
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* Description d'une liste d'accès à des registres (instance) */
+struct _GRAccessList
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    reg_access *accesses;                   /* Liste des accès             */
+    size_t count;                           /* Taille de cette liste       */
+
+};
+
+/* Description d'une liste d'accès à des registres (classe) */
+struct _GRAccessListClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des listes d'accès aux registres. */
+static void g_raccess_list_class_init(GRAccessListClass *);
+
+/* Initialise une liste d'accès aux registres. */
+static void g_raccess_list_init(GRAccessList *);
+
+/* Supprime toutes les références externes. */
+static void g_raccess_list_dispose(GRAccessList *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_raccess_list_finalize(GRAccessList *);
+
+
+
+/* Indique le type défini pour une liste d'accès à des registres. */
+G_DEFINE_TYPE(GRAccessList, g_raccess_list, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des listes d'accès aux registres.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_raccess_list_class_init(GRAccessListClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_raccess_list_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_raccess_list_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une liste d'accès aux registres.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_raccess_list_init(GRAccessList *list)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_raccess_list_dispose(GRAccessList *list)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < list->count; i++)
+        g_object_unref(G_OBJECT(list->accesses[i].reg));
+
+    if (list->accesses != NULL)
+        free(list->accesses);
+
+    G_OBJECT_CLASS(g_raccess_list_parent_class)->dispose(G_OBJECT(list));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_raccess_list_finalize(GRAccessList *list)
+{
+    G_OBJECT_CLASS(g_raccess_list_parent_class)->finalize(G_OBJECT(list));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une liste d'accès à des registres.                      *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GRAccessList *g_raccess_list_new(void)
+{
+    GRAccessList *result;                     /* Liste à retourner           */
+
+    result = g_object_new(G_TYPE_RACCESS_LIST, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = liste des accès à venir grossir.                      *
+*                src  = liste dont les accès sont à reprendre.                *
+*                                                                             *
+*  Description : Intègre une liste d'accès à des registres dans une autre.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_raccess_list_merge(GRAccessList *list, GRAccessList *src)
+{
+    size_t count;                           /* Taille d'un parcours        */
+    size_t i;                               /* Boucle de parcours          */
+    reg_access *access;                     /* Accès à un registre         */
+
+    count = g_raccess_list_count(src);
+
+    for (i = 0; i < count; i++)
+    {
+        access = g_raccess_list_get(src, i);
+
+        if (g_raccess_list_find(list, access->reg) == NULL)
+            g_raccess_list_add(list, access);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier opérande à consulter.                            *
+*                b = second opérande à consulter.                             *
+*                                                                             *
+*  Description : Compare un accès registre avec un autre.                     *
+*                                                                             *
+*  Retour      : Bilan de la comparaison.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int compare_reg_accesses(const reg_access *a, const reg_access *b)
+{
+    return g_arch_register_compare(a->reg, b->reg);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = ensemble d'accès à consulter.                         *
+*                reg  = registre matériel à rechercher.                       *
+*                                                                             *
+*  Description : Recherche des informations existantes sur un registre.       *
+*                                                                             *
+*  Retour      : Bilan de la recherche.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+reg_access *g_raccess_list_find(const GRAccessList *list, GArchRegister *reg)
+{
+    reg_access *result;                     /* Trouaille à retourner       */
+
+    result = bsearch((reg_access []) { { .reg = reg } }, list->accesses, list->count,
+                     sizeof(reg_access), (__compar_fn_t)compare_reg_accesses);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list     = ensemble d'accès à mettre à jour.                 *
+*                template = patron de l'accès à intégrer.                     *
+*                                                                             *
+*  Description : Recherche des informations existantes sur un registre.       *
+*                                                                             *
+*  Retour      : Bilan de la recherche.                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_raccess_list_add(GRAccessList *list, const reg_access *template)
+{
+    g_object_ref(G_OBJECT(template->reg));
+
+    list->accesses = (reg_access *)realloc(list->accesses, ++list->count * sizeof(reg_access));
+    list->accesses[list->count - 1] = *template;
+
+    qsort(list->accesses, list->count, sizeof(reg_access), (__compar_fn_t)compare_reg_accesses);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = ensemble d'accès à consulter.                         *
+*                                                                             *
+*  Description : Dénombre les accès aux registres comptabilisés.              *
+*                                                                             *
+*  Retour      : Quantité d'accès pris en compte.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_raccess_list_count(const GRAccessList *list)
+{
+    return list->count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = ensemble d'accès à consulter.                        *
+*                index = indice de l'accès recherché.                         *
+*                                                                             *
+*  Description : Fournit un accès donné de la liste.                          *
+*                                                                             *
+*  Retour      : Accès à un registre.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+reg_access *g_raccess_list_get(const GRAccessList *list, size_t index)
+{
+    reg_access *result;                     /* Accès à renvoyer            */
+
+    if (index >= list->count)
+        result = NULL;
+    else
+        result = &list->accesses[index];
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list   = ensemble d'accès à mettre à jour.                   *
+*                access = accès visé par la procédure.                        *
+*                                                                             *
+*  Description : Retire un accès donné de la liste.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_raccess_list_delete(GRAccessList *list, reg_access *access)
+{
+    size_t index;                           /* Indice correspondant        */
+
+    if (list->count > 0)
+    {
+        index = (access - list->accesses) / sizeof(reg_access);
+        g_raccess_list_delete_by_index(list, index);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list   = ensemble d'accès à mettre à jour.                   *
+*                index = indice de l'accès visé par la procédure.             *
+*                                                                             *
+*  Description : Retire un accès donné de la liste.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_raccess_list_delete_by_index(GRAccessList *list, size_t index)
+{
+    if (index >= list->count)
+        return;
+
+    if ((index + 1) < list->count)
+        memmove(&list->accesses[index], &list->accesses[index + 1],
+                (list->count - index - 1) * sizeof(reg_access));
+
+    list->count--;
+
+    if (list->count == 0)
+    {
+        free(list->accesses);
+        list->accesses = NULL;
+    }
+    else
+        list->accesses = (reg_access *)realloc(list->accesses, list->count * sizeof(reg_access));
+
+}
diff --git a/src/analysis/blocks/raccess.h b/src/analysis/blocks/raccess.h
new file mode 100644
index 0000000..cc2fd00
--- /dev/null
+++ b/src/analysis/blocks/raccess.h
@@ -0,0 +1,105 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * raccess.h - prototypes pour le suivi des accès aux registres
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ *  This file is part of OpenIDA.
+ *
+ *  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 _ANALYSIS_BLOCKS_RACCESS_H
+#define _ANALYSIS_BLOCKS_RACCESS_H
+
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <stdbool.h>
+
+
+#include "../../arch/register.h"
+
+
+
+/* Note sur le premier accès */
+typedef enum _RegAccessType
+{
+    RAT_NONE    = (0 << 0),                 /* Registre non rencontré      */
+    RAT_READ    = (1 << 0),                 /* Lecture                     */
+    RAT_WRITE   = (1 << 1)                  /* Ecriture                    */
+
+} RegAccessType;
+
+/* Description minimale des accès à un registre */
+typedef struct _reg_access
+{
+    GArchRegister *reg;                     /* Register concerné           */
+
+    RegAccessType first_access;             /* Type du premier accès       */
+    vmpa_t last_write;                      /* Dernière écriture           */
+
+} reg_access;
+
+
+#define G_TYPE_RACCESS_LIST               g_raccess_list_get_type()
+#define G_RACCESS_LIST(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_raccess_list_get_type(), GRAccessList))
+#define G_IS_RACCESS_LIST(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_raccess_list_get_type()))
+#define G_RACCESS_LIST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RACCESS_LIST, GRAccessListClass))
+#define G_IS_RACCESS_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RACCESS_LIST))
+#define G_RACCESS_LIST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RACCESS_LIST, GRAccessListClass))
+
+
+/* Description d'une liste d'accès à des registres (instance) */
+typedef struct _GRAccessList GRAccessList;
+
+/* Description d'une liste d'accès à des registres (classe) */
+typedef struct _GRAccessListClass GRAccessListClass;
+
+
+/* Indique le type défini pour une liste d'accès à des registres. */
+GType g_raccess_list_get_type(void);
+
+/* Crée une liste d'accès à des registres. */
+GRAccessList *g_raccess_list_new(void);
+
+/* Intègre une liste d'accès à des registres dans une autre. */
+void g_raccess_list_merge(GRAccessList *, GRAccessList *);
+
+/* Compare un accès registre avec un autre. */
+int compare_reg_accesses(const reg_access *, const reg_access *);
+
+/* Recherche des informations existantes sur un registre. */
+reg_access *g_raccess_list_find(const GRAccessList *, GArchRegister *);
+
+/* Recherche des informations existantes sur un registre. */
+void g_raccess_list_add(GRAccessList *, const reg_access *);
+
+/* Dénombre les accès aux registres comptabilisés. */
+size_t g_raccess_list_count(const GRAccessList *);
+
+/* Fournit un accès donné de la liste. */
+reg_access *g_raccess_list_get(const GRAccessList *, size_t);
+
+/* Retire un accès donné de la liste. */
+void g_raccess_list_delete(GRAccessList *, reg_access *);
+
+/* Retire un accès donné de la liste. */
+void g_raccess_list_delete_by_index(GRAccessList *, size_t);
+
+
+
+#endif  /* _ANALYSIS_BLOCKS_RACCESS_H */
diff --git a/src/analysis/blocks/virtual.c b/src/analysis/blocks/virtual.c
index 2385f67..584e57d 100644
--- a/src/analysis/blocks/virtual.c
+++ b/src/analysis/blocks/virtual.c
@@ -43,9 +43,10 @@ struct _GVirtualBlock
     GInstrBlock **children;                 /* Sous-blocs intégrés         */
     size_t children_count;                  /* Nombre de ces sous-blocs    */
 
+#if 0
     reg_access *accesses;                   /* Commodités d'accès #1       */
     size_t count;                           /* Commodités d'accès #2       */
-
+#endif
 
 };
 
@@ -70,7 +71,7 @@ static void g_virtual_block_dispose(GVirtualBlock *);
 static void g_virtual_block_finalize(GVirtualBlock *);
 
 /* Recherche le bloc contenant une adresse donnée. */
-static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *, vmpa_t);
+static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *, vmpa_t, bool);
 
 /* Parcours le bloc d'instructions dans un ordre donné. */
 static bool g_virtual_block_visit(GVirtualBlock *, instr_block_visitor_cb, void *);
@@ -79,7 +80,7 @@ static bool g_virtual_block_visit(GVirtualBlock *, instr_block_visitor_cb, void
 static void g_virtual_block_list_all_blocks(const GVirtualBlock *, GInstrBlock ***, size_t *);
 
 /* Fournit les différents accès aux registres. */
-static const reg_access *g_virtual_block_list_regs_accesses(const GVirtualBlock *, size_t *);
+//static const reg_access *g_virtual_block_list_regs_accesses(const GVirtualBlock *, size_t *);
 
 
 
@@ -132,7 +133,7 @@ static void g_virtual_block_init(GVirtualBlock *block)
     parent->find_by_addr = (find_by_addr_fc)g_virtual_block_find_by_addr;
     parent->visit_blocks = (visit_all_blocks_fc)g_virtual_block_visit;
     parent->list_blocks = (list_all_blocks_fc)g_virtual_block_list_all_blocks;
-    parent->list_regs = (list_regs_accesses_fc)g_virtual_block_list_regs_accesses;
+    //parent->list_regs = (list_regs_accesses_fc)g_virtual_block_list_regs_accesses;
 
 }
 
@@ -175,9 +176,6 @@ static void g_virtual_block_dispose(GVirtualBlock *block)
 
 static void g_virtual_block_finalize(GVirtualBlock *block)
 {
-    if (block->accesses != NULL)
-        free(block->accesses);
-
     if (block->children != NULL)
         free(block->children);
 
@@ -213,6 +211,7 @@ GInstrBlock *g_virtual_block_new(void)
 *                                                                             *
 *  Paramètres  : block = bloc de départ des recherches.                       *
 *                addr  = ensemble de blocs à parcourir.                       *
+*                final = indique si la cible ou le conteneur est renvoyée.    *
 *                                                                             *
 *  Description : Recherche le bloc contenant une adresse donnée.              *
 *                                                                             *
@@ -222,16 +221,25 @@ GInstrBlock *g_virtual_block_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, vmpa_t addr)
+static GInstrBlock *g_virtual_block_find_by_addr(const GVirtualBlock *block, vmpa_t addr, bool final)
 {
     GInstrBlock *result;                    /* Resultat à retourner        */
     size_t i;                               /* Boucle de parcours          */
+    GInstrBlock *ret;                       /* Retour des inspections      */
 
     result = NULL;
 
     for (i = 0; i < block->children_count && result == NULL; i++)
-        if (g_instr_block_find_by_addr(block->children[i], addr))
-            result = block->children[i];
+    {
+        ret = g_instr_block_find_by_addr(block->children[i], addr, final);
+
+        if (ret != NULL)
+        {
+            if (final) result = ret;
+            else result = block->children[i];
+        }
+
+    }
 
     return result;
 
@@ -292,7 +300,7 @@ static void g_virtual_block_list_all_blocks(const GVirtualBlock *block, GInstrBl
 
 }
 
-
+#if 0
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : block = bloc d'instructions à consulter.                     *
@@ -313,6 +321,7 @@ static const reg_access *g_virtual_block_list_regs_accesses(const GVirtualBlock
     return NULL;
 
 }
+#endif
 
 
 /******************************************************************************
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c
index f3c2265..6333216 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -34,6 +34,9 @@
 /* --------------------- GESTION DES CONTEXTES DE DECOMPILATION --------------------- */
 
 
+/* Détermine les registres utilisés avant leur initialisation. */
+static bool track_used_registers(GFlowBlock *, BlockFollowPosition, GRAccessList **);
+
 
 
 
@@ -61,9 +64,144 @@ static GDecInstruction *decompiled_basic_block(GInstrBlock *, GDecContext *);
 /* ---------------------------------------------------------------------------------- */
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : block  = bloc d'instructions visité.                         *
+*                pos    = indication sur la position du parcours.             *
+*                needed = suivi de l'usage des registres entre les blocs.     *
+*                                                                             *
+*  Description : Détermine les registres utilisés avant leur initialisation.  *
+*                                                                             *
+*  Retour      : true pour mener un parcours complet.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool track_used_registers(GFlowBlock *block, BlockFollowPosition pos, GRAccessList **needed)
+{
+    GRAccessList *old;                      /* Ancienne liste remplacée    */
+    const GRAccessList *accesses;           /* Accès divers aux registres  */
+    size_t count;                           /* Taille d'un parcours        */
+    GRAccessList *awaited;                  /* Satisfactions des besoins   */
+    reg_access *access;                     /* Accès à un registre         */
+    size_t i;                               /* Boucle de parcours          */
+    reg_access *found;                      /* Besoin trouvé ou non        */
+
+    switch (pos)
+    {
+        case BFP_ENTER:
+            g_object_set_data(G_OBJECT(block), "needed_regs", *needed);
+            break;
+
+        case BFP_FOLLOW:
+            *needed = g_raccess_list_new();
+            break;
+
+        case BFP_BACK:
+
+            old = *needed;
+            *needed = G_RACCESS_LIST(g_object_get_data(G_OBJECT(block), "needed_regs"));
+
+            g_raccess_list_merge(*needed, old);
+            g_object_unref(G_OBJECT(old));
 
+            break;
 
+        case BFP_EXIT:
 
+            g_object_set_data(G_OBJECT(block), "needed_regs", NULL);
+
+            accesses = g_flow_block_list_regs_accesses(block);
+            count = g_raccess_list_count(accesses);
+
+            awaited = g_flow_block_list_awaited_regs(block);
+
+            for (i = 0; i < count; i++)
+            {
+                access = g_raccess_list_get(accesses, i);
+
+                /* Enregistrement des contributions possibles */
+
+                found = g_raccess_list_find(*needed, access->reg);
+
+                if (found != NULL)
+                {
+                    /**
+                     * Si un autre bloc avait déjà un besoin, on ne prend note
+                     * qu'une seule fois !
+                     */
+                    if (g_raccess_list_find(awaited, access->reg) == NULL)
+                        g_raccess_list_add(awaited, access);
+
+                    g_raccess_list_delete(*needed, found);
+
+                }
+
+                /* Ajoute les besoins du bloc */
+                if (access->first_access == RAT_READ)
+                    g_raccess_list_add(*needed, access);
+
+            }
+
+            /*
+            do
+            {
+                vmpa_t start, end;
+
+                g_flow_block_get_boundary_addresses(block, &start, &end);
+
+                printf(" -> flow (%d) : 0x%08x - 0x%08x  |  needed = %zu - provided = %zu\n",
+                       pos, start, end,
+                       g_raccess_list_count(*needed), g_raccess_list_count(awaited));
+
+            }
+            while (0);
+            */
+
+            break;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list  = ensemble des instructions d'assemblage à traiter.    *
+*                start = adresse de départ de la routine visée.               *
+*                                                                             *
+*  Description : Procède à la décompilation d'une routinée déterminée.        *
+*                                                                             *
+*  Retour      : Instructions créées ou NULL si erreur.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GDecContext *init_decomp_context(const GInstrBlock *list, vmpa_t start)
+{
+    GDecContext *result;                    /* Contexte pour la décompil.  */
+    GInstrBlock *first;                     /* Bloc de départ du flot      */
+    GRAccessList *needed;                   /* Registres inter-blocs       */
+
+    result = NULL;
+
+    first = g_instr_block_find_by_addr(list, start, true);
+
+    needed = g_raccess_list_new();
+
+    g_flow_block_follow(G_FLOW_BLOCK(first), list, BFP_ENTER | BFP_EXIT | BFP_EXIT,
+                        (flow_block_follow_cb)track_used_registers, &needed);
+
+    g_object_unref(G_OBJECT(needed));
+
+
+    return result;
+
+}
 
 
 
@@ -165,14 +303,15 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
     {
         next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_TRUE);
 
-        printf("@ 0x%08llx : true : %p\n", max, next);
+        //printf("@ 0x%08llx : true : %p\n", max, next);
 
         true_dinstr = NULL;
 
         if (next != NULL)
         {
             g_arch_instruction_get_location(next, NULL, NULL, &next_addr);
-            next_block = g_instr_block_find_by_addr(g_instr_block_get_links_block(block), next_addr);
+            next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block));
+            next_block = g_instr_block_find_by_addr(next_parent, next_addr, false);
 
             if (next_block != NULL)
                 true_dinstr = decompiled_basic_block(next_block, ctx);
@@ -181,26 +320,28 @@ static GDecInstruction *decompiled_instructions_block(GFlowBlock *block, GDecCon
 
         next = g_arch_instruction_get_given_destination(last, ILT_JUMP_IF_FALSE);
 
-        printf("@ 0x%08llx : false : %p\n", max, next);
+        //printf("@ 0x%08llx : false : %p\n", max, next);
 
         false_dinstr = NULL;
 
         if (next != NULL)
         {
             g_arch_instruction_get_location(next, NULL, NULL, &next_addr);
-            next_block = g_instr_block_find_by_addr(g_instr_block_get_links_block(block), next_addr);
+            next_parent = g_instr_block_get_links_block(G_INSTR_BLOCK(block));
+            next_block = g_instr_block_find_by_addr(next_parent, next_addr, false);
 
             if (next_block != NULL)
                 false_dinstr = decompiled_basic_block(next_block, ctx);
 
         }
 
+        /*
         printf(" -> ite : %p + %p\n", true_dinstr, false_dinstr);
 
         printf(" -> ite : %s + %s\n",
                true_dinstr ? g_type_name(G_TYPE_FROM_INSTANCE(true_dinstr)) : "none",
                false_dinstr ? g_type_name(G_TYPE_FROM_INSTANCE(false_dinstr)) : "none");
-
+        */
 
         g_ite_instruction_set_branches(G_ITE_INSTRUCTION(decomp), true_dinstr, false_dinstr);
 
@@ -327,6 +468,8 @@ GDecInstruction *decompiled_routine_instructions(GBinRoutine *routine, GExeForma
 
     blocks = g_binary_routine_get_basic_blocks(routine);
 
+    init_decomp_context(blocks, g_binary_routine_get_address(routine));
+
     result = decompiled_basic_block(blocks, context);
 
     g_object_unref(context);
-- 
cgit v0.11.2-87-g4458