From 7d6d3acb65586ad9512a38b58c16b9a21cdf98e0 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 28 Nov 2016 00:35:47 +0100
Subject: Saved memory space by sharing arch GObjects.

---
 ChangeLog                           |  45 +++++++
 configure.ac                        |   1 +
 src/arch/Makefile.am                |   5 +-
 src/arch/arm/v7/Makefile.am         |   1 +
 src/arch/arm/v7/core.c              |  66 ++++++++++
 src/arch/arm/v7/core.h              |  40 ++++++
 src/arch/dalvik/Makefile.am         |   1 +
 src/arch/dalvik/core.c              |  72 +++++++++++
 src/arch/dalvik/core.h              |  40 ++++++
 src/arch/dalvik/operands/register.c |   5 +-
 src/arch/dalvik/register.c          | 148 ++++++++++++++++++++--
 src/arch/dalvik/register.h          |  16 ++-
 src/arch/register-int.h             |   6 +
 src/arch/register.c                 | 152 +++++++++++++++++++++-
 src/arch/sharing/Makefile.am        |  14 ++
 src/arch/sharing/instance-int.h     |  73 +++++++++++
 src/arch/sharing/instance.c         | 210 ++++++++++++++++++++++++++++++
 src/arch/sharing/instance.h         |  71 +++++++++++
 src/arch/sharing/manager.c          | 246 ++++++++++++++++++++++++++++++++++++
 src/arch/sharing/manager.h          |  66 ++++++++++
 src/core/processors.c               |  63 ++++++---
 src/core/processors.h               |   9 +-
 src/glibext/gwidthtracker.c         |   5 -
 23 files changed, 1312 insertions(+), 43 deletions(-)
 create mode 100644 src/arch/arm/v7/core.c
 create mode 100644 src/arch/arm/v7/core.h
 create mode 100644 src/arch/dalvik/core.c
 create mode 100644 src/arch/dalvik/core.h
 create mode 100644 src/arch/sharing/Makefile.am
 create mode 100644 src/arch/sharing/instance-int.h
 create mode 100644 src/arch/sharing/instance.c
 create mode 100644 src/arch/sharing/instance.h
 create mode 100644 src/arch/sharing/manager.c
 create mode 100644 src/arch/sharing/manager.h

diff --git a/ChangeLog b/ChangeLog
index b0b2b61..1c9fa76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+16-11-28  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Add the new Makefile from the 'src/arch/sharing' directory.
+
+	* src/arch/Makefile.am:
+	Add 'dalvik/libarchdalvik.la' to libarch_la_LIBADD and
+	'sharing' to SUBDIRS.
+
+	* src/arch/arm/v7/Makefile.am:
+	Add the new 'core.[ch]' files to libarcharmv7_la_SOURCES.
+
+	* src/arch/arm/v7/core.c:
+	* src/arch/arm/v7/core.h:
+	New entries: register and unregister internal ARMv7 mechanisms.
+
+	* src/arch/dalvik/Makefile.am:
+	Add the new 'core.[ch]' files to libarchdalvik_la_SOURCES.
+
+	* src/arch/dalvik/core.c:
+	* src/arch/dalvik/core.h:
+	New entries: register and unregister internal Dalvik mechanisms.
+
+	* src/arch/dalvik/operands/register.c:
+	* src/arch/dalvik/register.c:
+	* src/arch/dalvik/register.h:
+	* src/arch/register-int.h:
+	* src/arch/register.c:
+	Update code.
+
+	* src/arch/sharing/Makefile.am:
+	* src/arch/sharing/instance-int.h:
+	* src/arch/sharing/instance.c:
+	* src/arch/sharing/instance.h:
+	* src/arch/sharing/manager.c:
+	* src/arch/sharing/manager.h:
+	New entries: save memory space by sharing arch GObjects.
+
+	* src/core/processors.c:
+	* src/core/processors.h:
+	Register and unregister internal arch mechanisms.
+
+	* src/glibext/gwidthtracker.c:
+	Typo.
+
 16-11-09  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/gtkext/gtkdisplaypanel.c:
diff --git a/configure.ac b/configure.ac
index bfca0b6..7d5aa74 100644
--- a/configure.ac
+++ b/configure.ac
@@ -358,6 +358,7 @@ AC_CONFIG_FILES([Makefile
                  src/arch/dalvik/pseudo/Makefile
                  src/arch/jvm/Makefile
                  src/arch/mips/Makefile
+                 src/arch/sharing/Makefile
                  src/arch/x86/Makefile
                  src/arch/x86/opcodes/Makefile
                  src/arch/x86/operands/Makefile
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index f7508f4..030ee87 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -31,7 +31,8 @@ libarch_la_SOURCES =					\
 
 libarch_la_LIBADD =						\
 	arm/libarcharm.la					\
-	dalvik/libarchdalvik.la
+	dalvik/libarchdalvik.la				\
+	sharing/libarchsharing.la
 
 libarch_la_LDFLAGS = 
 
@@ -42,4 +43,4 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
 
 #SUBDIRS = arm dalvik jvm mips x86
-SUBDIRS = arm dalvik
+SUBDIRS = arm dalvik sharing
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am
index 564716d..339bc29 100644
--- a/src/arch/arm/v7/Makefile.am
+++ b/src/arch/arm/v7/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libarcharmv7.la
 libarcharmv7_la_SOURCES =				\
 	arm.h arm.c							\
 	context.h context.c					\
+	core.h core.c						\
 	cregister.h cregister.c				\
 	fetch.h fetch.c						\
 	helpers.h helpers.c					\
diff --git a/src/arch/arm/v7/core.c b/src/arch/arm/v7/core.c
new file mode 100644
index 0000000..97fdb3d
--- /dev/null
+++ b/src/arch/arm/v7/core.c
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - chargement et déchargement des mécanismes internes de l'architecture ARMv7
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "core.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Met en place les mécanismes internes de l'architecture ARMv7.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool init_armv7_core(void)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = true;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Supprime les mécanismes internes de l'architecture ARMv7.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_armv7_core(void)
+{
+
+}
diff --git a/src/arch/arm/v7/core.h b/src/arch/arm/v7/core.h
new file mode 100644
index 0000000..ff0bcf7
--- /dev/null
+++ b/src/arch/arm/v7/core.h
@@ -0,0 +1,40 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour le chargement et le déchargement des mécanismes internes de l'architecture ARMv7
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_CORE_H
+#define _ARCH_ARM_V7_CORE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Met en place les mécanismes internes de l'architecture ARMv7. */
+bool init_armv7_core(void);
+
+/* Supprime les mécanismes internes de l'architecture ARMv7. */
+void exit_armv7_core(void);
+
+
+
+#endif  /* _ARCH_ARM_V7_CORE_H */
diff --git a/src/arch/dalvik/Makefile.am b/src/arch/dalvik/Makefile.am
index 0d1fa88..b97e7d8 100644
--- a/src/arch/dalvik/Makefile.am
+++ b/src/arch/dalvik/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libarchdalvik.la
 
 libarchdalvik_la_SOURCES =				\
 	context.h context.c					\
+	core.h core.c						\
 	fetch.h fetch.c						\
 	helpers.h							\
 	instruction-def.h					\
diff --git a/src/arch/dalvik/core.c b/src/arch/dalvik/core.c
new file mode 100644
index 0000000..ba07c97
--- /dev/null
+++ b/src/arch/dalvik/core.c
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - chargement et déchargement des mécanismes internes de l'architecture Dalvik
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "core.h"
+
+
+#include "register.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Met en place les mécanismes internes de l'architecture.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool init_dalvik_core(void)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = true;
+
+    result &= init_dalvik_register_sharing();
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Supprime les mécanismes internes de l'architecture Dalvik.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_dalvik_core(void)
+{
+    exit_dalvik_register_sharing();
+
+}
diff --git a/src/arch/dalvik/core.h b/src/arch/dalvik/core.h
new file mode 100644
index 0000000..e7a5e1e
--- /dev/null
+++ b/src/arch/dalvik/core.h
@@ -0,0 +1,40 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour le chargement et le déchargement des mécanismes internes de l'architecture Dalvik
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_DALVIK_CORE_H
+#define _ARCH_DALVIK_CORE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Met en place les mécanismes internes de l'architecture. */
+bool init_dalvik_core(void);
+
+/* Supprime les mécanismes internes de l'architecture Dalvik. */
+void exit_dalvik_core(void);
+
+
+
+#endif  /* _ARCH_DALVIK_CORE_H */
diff --git a/src/arch/dalvik/operands/register.c b/src/arch/dalvik/operands/register.c
index 61961a7..1fc5782 100644
--- a/src/arch/dalvik/operands/register.c
+++ b/src/arch/dalvik/operands/register.c
@@ -25,6 +25,7 @@
 
 
 #include "../../operand-int.h"
+#include "../../register.h"
 
 
 
@@ -278,7 +279,7 @@ GDalvikRegister *g_dalvik_register_operand_get(const GDalvikRegisterOperand *ope
 
 static bool g_dalvik_register_operand_compare(const GDalvikRegisterOperand *a, const GDalvikRegisterOperand *b)
 {
-    return (g_dalvik_register_compare(a->reg, b->reg) == 0);
+    return (g_arch_register_compare(G_ARCH_REGISTER(a->reg), G_ARCH_REGISTER(b->reg)) == 0);
 
 }
 
@@ -299,7 +300,7 @@ static bool g_dalvik_register_operand_compare(const GDalvikRegisterOperand *a, c
 
 static void g_dalvik_register_operand_print(const GDalvikRegisterOperand *operand, GBufferLine *line, AsmSyntax syntax)
 {
-    g_dalvik_register_print(operand->reg, line, syntax);
+    g_arch_register_print(G_ARCH_REGISTER(operand->reg), line, syntax);
 
 }
 
diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c
index ed1b8c6..d112a86 100644
--- a/src/arch/dalvik/register.c
+++ b/src/arch/dalvik/register.c
@@ -28,9 +28,13 @@
 
 
 #include "../register-int.h"
+#include "../sharing/manager.h"
 
 
 
+/* ------------------------- ENCADREMENT DE REGISTRES BRUTS ------------------------- */
+
+
 /* Représentation d'un registre Dalvik (instance) */
 struct _GDalvikRegister
 {
@@ -58,9 +62,34 @@ static void g_dalvik_register_class_init(GDalvikRegisterClass *);
 /* Initialise une instance de registre Dalvik. */
 static void g_dalvik_register_init(GDalvikRegister *);
 
+/* Initialise un nouvel objet partagé avec des informations. */
+static bool g_dalvik_register_do_init(GDalvikRegister *, const uint16_t *);
+
+/* Indique l'objet partagé correspond à une description donnée. */
+static gboolean g_dalvik_register_compare_info(const GDalvikRegister *, const uint16_t *);
+
 /* Produit une empreinte à partir d'un registre. */
 static guint g_dalvik_register_hash(const GDalvikRegister *);
 
+/* Compare un registre avec un autre. */
+static int g_dalvik_register_compare(const GDalvikRegister *, const GDalvikRegister *);
+
+/* Traduit un registre en version humainement lisible. */
+static void g_dalvik_register_print(const GDalvikRegister *, GBufferLine *, AsmSyntax);
+
+
+
+/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */
+
+
+/* Gestionnaire des partages d'instances */
+static GShareManager *_dalvik_register_manager = NULL;
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           ENCADREMENT DE REGISTRES BRUTS                           */
+/* ---------------------------------------------------------------------------------- */
 
 
 /* Indique le type défini pour une représentation d'un registre Dalvik. */
@@ -85,6 +114,9 @@ static void g_dalvik_register_class_init(GDalvikRegisterClass *klass)
 
     register_class = G_ARCH_REGISTER_CLASS(klass);
 
+    register_class->init = (init_shared_fc)g_dalvik_register_do_init;
+    register_class->cmp_info = (compare_shared_info_fc)g_dalvik_register_compare_info;
+
     register_class->hash = (reg_hash_fc)g_dalvik_register_hash;
     register_class->compare = (reg_compare_fc)g_dalvik_register_compare;
     register_class->print = (reg_print_fc)g_dalvik_register_print;
@@ -126,9 +158,11 @@ GDalvikRegister *g_dalvik_register_new(uint16_t index)
 {
     GDalvikRegister *result;                /* Structure à retourner       */
 
-    result = g_object_new(G_TYPE_DALVIK_REGISTER, NULL);
+    result = G_DALVIK_REGISTER(g_share_manager_get(_dalvik_register_manager, &index));
+
+    //result = g_object_new(G_TYPE_DALVIK_REGISTER, NULL);
 
-    result->index = index;
+    //result->index = index;
 
     return result;
 
@@ -137,19 +171,46 @@ GDalvikRegister *g_dalvik_register_new(uint16_t index)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : reg = registre à consulter.                                  *
+*  Paramètres  : reg   = objet partagé à initialiser.                         *
+*                index = indice du registre correspondant.                    *
 *                                                                             *
-*  Description : Fournit l'indice d'un registre Dalvik.                       *
+*  Description : Initialise un nouvel objet partagé avec des informations.    *
 *                                                                             *
-*  Retour      : Inditifiant représentant le registre.                        *
+*  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-uint16_t g_dalvik_register_get_index(const GDalvikRegister *reg)
+static bool g_dalvik_register_do_init(GDalvikRegister *reg, const uint16_t *index)
 {
-    return reg->index;
+    reg->index = *index;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg   = objet partagé à consulter.                           *
+*                index = indice du registre correspondant.                    *
+*                                                                             *
+*  Description : Indique l'objet partagé correspond à une description donnée. *
+*                                                                             *
+*  Retour      : true si les détails centraux sont partagés, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean g_dalvik_register_compare_info(const GDalvikRegister *reg, const uint16_t *index)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = (reg->index == *index);
+
+    return result;
 
 }
 
@@ -186,14 +247,16 @@ static guint g_dalvik_register_hash(const GDalvikRegister *reg)
 *                                                                             *
 ******************************************************************************/
 
-int g_dalvik_register_compare(const GDalvikRegister *a, const GDalvikRegister *b)
+static int g_dalvik_register_compare(const GDalvikRegister *a, const GDalvikRegister *b)
 {
     int result;                             /* Bilan à retourner           */
 
     if (a->index < b->index)
         result = -1;
+
     else if (a->index > b->index)
         result = 1;
+
     else
         result = 0;
 
@@ -216,7 +279,7 @@ int g_dalvik_register_compare(const GDalvikRegister *a, const GDalvikRegister *b
 *                                                                             *
 ******************************************************************************/
 
-void g_dalvik_register_print(const GDalvikRegister *reg, GBufferLine *line, AsmSyntax syntax)
+static void g_dalvik_register_print(const GDalvikRegister *reg, GBufferLine *line, AsmSyntax syntax)
 {
     char key[MAX_REGNAME_LEN];              /* Mot clef principal          */
     size_t klen;                            /* Taille de ce mot clef       */
@@ -240,3 +303,70 @@ void g_dalvik_register_print(const GDalvikRegister *reg, GBufferLine *line, AsmS
     g_buffer_line_append_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg = registre à consulter.                                  *
+*                                                                             *
+*  Description : Fournit l'indice d'un registre Dalvik.                       *
+*                                                                             *
+*  Retour      : Inditifiant représentant le registre.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint16_t g_dalvik_register_get_index(const GDalvikRegister *reg)
+{
+    return reg->index;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            PARTAGES DE CONTENUS UNIQUES                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Met en place les mécanismes de partage des registres Dalvik. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool init_dalvik_register_sharing(void)
+{
+    _dalvik_register_manager = g_share_manager_new(G_TYPE_DALVIK_REGISTER);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Supprime les mécanismes de partage des registres Dalvik.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_dalvik_register_sharing(void)
+{
+
+
+
+
+}
diff --git a/src/arch/dalvik/register.h b/src/arch/dalvik/register.h
index 989df6c..ab7368f 100644
--- a/src/arch/dalvik/register.h
+++ b/src/arch/dalvik/register.h
@@ -34,6 +34,9 @@
 
 
 
+/* ------------------------- ENCADREMENT DE REGISTRES BRUTS ------------------------- */
+
+
 #define G_TYPE_DALVIK_REGISTER               g_dalvik_register_get_type()
 #define G_DALVIK_REGISTER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dalvik_register_get_type(), GDalvikRegister))
 #define G_IS_DALVIK_REGISTER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dalvik_register_get_type()))
@@ -58,11 +61,16 @@ GDalvikRegister *g_dalvik_register_new(uint16_t);
 /* Fournit l'indice d'un registre Dalvik. */
 uint16_t g_dalvik_register_get_index(const GDalvikRegister *);
 
-/* Compare un registre avec un autre. */
-int g_dalvik_register_compare(const GDalvikRegister *, const GDalvikRegister *);
 
-/* Traduit un registre en version humainement lisible. */
-void g_dalvik_register_print(const GDalvikRegister *, GBufferLine *, AsmSyntax);
+
+/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */
+
+
+/* Met en place les mécanismes de partage des registres Dalvik. */
+bool init_dalvik_register_sharing(void);
+
+/* Supprime les mécanismes de partage des registres Dalvik. */
+void exit_dalvik_register_sharing(void);
 
 
 
diff --git a/src/arch/register-int.h b/src/arch/register-int.h
index f9b19b0..72c1f84 100644
--- a/src/arch/register-int.h
+++ b/src/arch/register-int.h
@@ -29,6 +29,7 @@
 
 
 #include "operand-int.h"
+#include "sharing/instance-int.h"
 
 
 
@@ -57,6 +58,8 @@ struct _GArchRegister
 {
     GObject parent;                         /* A laisser en premier        */
 
+    unsigned int shared_count;              /* Compteur de partages        */
+
 };
 
 
@@ -65,6 +68,9 @@ struct _GArchRegisterClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    init_shared_fc init;                    /* Mise en place via interface */
+    compare_shared_info_fc cmp_info;        /* Comparaison des détails     */
+
     reg_hash_fc hash;                       /* Production d'empreinte      */
     reg_compare_fc compare;                 /* Comparaison de registres    */
     reg_print_fc print;                     /* Impression du registre      */
diff --git a/src/arch/register.c b/src/arch/register.c
index 0b381a1..ef593b4 100644
--- a/src/arch/register.c
+++ b/src/arch/register.c
@@ -37,12 +37,30 @@ static void g_arch_register_class_init(GArchRegisterClass *);
 /* Initialise une instance de registre. */
 static void g_arch_register_init(GArchRegister *);
 
+/* Procède à l'initialisation de l'interface de partage. */
+static void g_arch_register_interface_init(GSharedInstanceInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_arch_register_dispose(GArchRegister *);
 
 /* Procède à la libération totale de la mémoire. */
 static void g_arch_register_finalize(GArchRegister *);
 
+/* Initialise un nouvel objet partagé avec des informations. */
+static bool g_arch_register_do_init(GArchRegister *, const void *);
+
+/* Fournit la valeur du compteur de partage. */
+static unsigned int g_arch_register_get_references(const GArchRegister *);
+
+/* Incrémente le compteur de partage. */
+static void g_arch_register_inc_references(GArchRegister *);
+
+/* Décrémente le compteur de partage. */
+static void g_arch_register_dec_references(GArchRegister *);
+
+/* Indique l'objet partagé correspond à une description donnée. */
+static gboolean g_arch_register_compare_info(const GArchRegister *, const void *);
+
 
 
 /* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */
@@ -74,7 +92,8 @@ static void g_register_operand_print(const GRegisterOperand *, GBufferLine *, As
 
 
 /* Indique le type défini pour une représentation d'un registre. */
-G_DEFINE_TYPE(GArchRegister, g_arch_register, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GArchRegister, g_arch_register, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_SHARED_INSTANCE, g_arch_register_interface_init));
 
 
 /******************************************************************************
@@ -121,6 +140,32 @@ static void g_arch_register_init(GArchRegister *reg)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de partage.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_register_interface_init(GSharedInstanceInterface *iface)
+{
+    iface->init = (init_shared_fc)g_arch_register_do_init;
+
+    iface->get_ref = (get_shared_ref_fc)g_arch_register_get_references;
+    iface->inc_ref = (inc_shared_ref_fc)g_arch_register_inc_references;
+    iface->dec_ref = (dec_shared_ref_fc)g_arch_register_dec_references;
+
+    iface->cmp_info = (compare_shared_info_fc)g_arch_register_compare_info;
+    iface->is_equal = (is_shared_equal_fc)g_arch_register_equal;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : binary = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -159,6 +204,111 @@ static void g_arch_register_finalize(GArchRegister *reg)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : reg  = objet partagé à initialiser.                          *
+*                info = information à utiliser pour la mise en place.         *
+*                                                                             *
+*  Description : Initialise un nouvel objet partagé avec des informations.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_arch_register_do_init(GArchRegister *reg, const void *info)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_ARCH_REGISTER_GET_CLASS(reg)->init(G_SHARED_INSTANCE(reg), info);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg = objet partagé à consulter.                             *
+*                                                                             *
+*  Description : Fournit la valeur du compteur de partage.                    *
+*                                                                             *
+*  Retour      : Nombre de partages courant.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static unsigned int g_arch_register_get_references(const GArchRegister *reg)
+{
+    return reg->shared_count;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg = objet partagé à modifier.                              *
+*                                                                             *
+*  Description : Incrémente le compteur de partage.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_register_inc_references(GArchRegister *reg)
+{
+    reg->shared_count++;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg = objet partagé à modifier.                              *
+*                                                                             *
+*  Description : Décrémente le compteur de partage.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_arch_register_dec_references(GArchRegister *reg)
+{
+    reg->shared_count--;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : reg  = objet partagé à consulter.                            *
+*                info = compilation de d'information à analyser.              *
+*                                                                             *
+*  Description : Indique l'objet partagé correspond à une description donnée. *
+*                                                                             *
+*  Retour      : true si les détails centraux sont partagés, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean g_arch_register_compare_info(const GArchRegister *reg, const void *info)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_ARCH_REGISTER_GET_CLASS(reg)->cmp_info(G_SHARED_INSTANCE(reg), info);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : reg = opérande à consulter pour le calcul.                   *
 *                                                                             *
 *  Description : Produit une empreinte à partir d'un registre.                *
diff --git a/src/arch/sharing/Makefile.am b/src/arch/sharing/Makefile.am
new file mode 100644
index 0000000..46496c2
--- /dev/null
+++ b/src/arch/sharing/Makefile.am
@@ -0,0 +1,14 @@
+
+noinst_LTLIBRARIES = libarchsharing.la
+
+libarchsharing_la_SOURCES =				\
+	instance-int.h						\
+	instance.h instance.c				\
+	manager.h manager.c
+
+libarchdalvik_la_CFLAGS = $(AM_CFLAGS)
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/src/arch/sharing/instance-int.h b/src/arch/sharing/instance-int.h
new file mode 100644
index 0000000..0b57cc4
--- /dev/null
+++ b/src/arch/sharing/instance-int.h
@@ -0,0 +1,73 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instance-int.h - définitions internes propres aux instances partagées
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_SHARING_INSTANCE_INT_H
+#define _ARCH_SHARING_INSTANCE_INT_H
+
+
+#include "instance.h"
+
+
+
+/* Initialise un nouvel objet partagé avec des informations. */
+typedef bool (* init_shared_fc) (GSharedInstance *, const void *);
+
+/* Fournit la valeur du compteur de partage. */
+typedef unsigned int (* get_shared_ref_fc) (const GSharedInstance *);
+
+/* Incrémente le compteur de partage. */
+typedef void (* inc_shared_ref_fc) (GSharedInstance *);
+
+/* Décrémente le compteur de partage. */
+typedef void (* dec_shared_ref_fc) (GSharedInstance *);
+
+/* Indique l'objet partagé correspond à une description donnée. */
+typedef bool (* compare_shared_info_fc) (const GSharedInstance *, const void *);
+
+/* Détermine si deux instances partagées sont identiques. */
+typedef gboolean (* is_shared_equal_fc) (const GSharedInstance *, const GSharedInstance *);
+
+
+/* Règles de partage d'une instance GObject (interface) */
+struct _GSharedInstanceIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    init_shared_fc init;                    /* Initialisation de l'objet   */
+
+    get_shared_ref_fc get_ref;              /* Obtention du compteur       */
+    inc_shared_ref_fc inc_ref;              /* Incrémentation du compteur  */
+    dec_shared_ref_fc dec_ref;              /* Décrémentation du compteur  */
+
+    compare_shared_info_fc cmp_info;        /* Comparaison des détails     */
+    is_shared_equal_fc is_equal;            /* Comparaison d'instance      */
+
+};
+
+
+/* Redéfinition */
+typedef GSharedInstanceIface GSharedInstanceInterface;
+
+
+
+#endif  /* _ARCH_SHARING_INSTANCE_INT_H */
diff --git a/src/arch/sharing/instance.c b/src/arch/sharing/instance.c
new file mode 100644
index 0000000..b737206
--- /dev/null
+++ b/src/arch/sharing/instance.c
@@ -0,0 +1,210 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * content.c - lecture de données binaires quelconques
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "instance.h"
+
+
+#include <assert.h>
+
+
+#include "instance-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de partage. */
+static void g_shared_instance_default_init(GSharedInstanceInterface *);
+
+
+
+/* Détermine le type d'une interface pour le partage d'instance. */
+G_DEFINE_INTERFACE(GSharedInstance, g_shared_instance, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de partage.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_shared_instance_default_init(GSharedInstanceInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à initialiser.                      *
+*                info     = information à utiliser pour la mise en place.     *
+*                                                                             *
+*  Description : Initialise un nouvel objet partagé avec des informations.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_shared_instance_init(GSharedInstance *instance, const void *info)
+{
+    bool result;                            /* Bilan à retourner           */
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    result = iface->init(instance, info);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à consulter.                        *
+*                                                                             *
+*  Description : Fournit la valeur du compteur de partage.                    *
+*                                                                             *
+*  Retour      : Nombre de partages courant.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_shared_instance_get_references(const GSharedInstance *instance)
+{
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    return iface->get_ref(instance);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à modifier.                         *
+*                                                                             *
+*  Description : Incrémente le compteur de partage.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_shared_instance_inc_references(GSharedInstance *instance)
+{
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    iface->inc_ref(instance);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à modifier.                         *
+*                                                                             *
+*  Description : Décrémente le compteur de partage.                           *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_shared_instance_dec_references(GSharedInstance *instance)
+{
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    iface->dec_ref(instance);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instance = objet partagé à consulter.                        *
+*                info     = compilation de d'information à analyser.          *
+*                                                                             *
+*  Description : Indique l'objet partagé correspond à une description donnée. *
+*                                                                             *
+*  Retour      : true si les détails centraux sont partagés, false sinon.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gboolean g_shared_instance_compare_info(const GSharedInstance *instance, const void *info)
+{
+    bool result;                            /* Bilan à retourner           */
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(instance);
+
+    result = iface->cmp_info(instance, info);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = première instance d'objet partagé à comparer.            *
+*                b = second instance d'objet partagé à comparer.              *
+*                                                                             *
+*  Description : Détermine si deux instances partagées sont identiques.       *
+*                                                                             *
+*  Retour      : TRUE si les deux éléments partagés sont identiques, ou FALSE.*
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gboolean g_shared_instance_is_equal(const GSharedInstance *a, const GSharedInstance *b)
+{
+    gboolean result;                        /* Bilan à retourner           */
+    GSharedInstanceIface *iface;            /* Interface utilisée          */
+
+    assert(G_OBJECT_TYPE(a) == G_OBJECT_TYPE(b));
+
+    iface = G_SHARED_INSTANCE_GET_IFACE(a);
+
+    result = iface->is_equal(a, b);
+
+    return result;
+
+}
diff --git a/src/arch/sharing/instance.h b/src/arch/sharing/instance.h
new file mode 100644
index 0000000..fc7fa30
--- /dev/null
+++ b/src/arch/sharing/instance.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * content.h - prototypes pour la lecture de données binaires quelconques
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_SHARING_INSTANCE_H
+#define _ARCH_SHARING_INSTANCE_H
+
+
+#include <stdbool.h>
+#include <glib-object.h>
+
+
+
+#define G_TYPE_SHARED_INSTANCE               (g_shared_instance_get_type())
+#define G_SHARED_INSTANCE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SHARED_INSTANCE, GSharedInstance))
+#define G_SHARED_INSTANCE_CLASS(vtable)      (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_SHARED_INSTANCE, GSharedInstanceIface))
+#define GTK_IS_SHARED_INSTANCE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SHARED_INSTANCE))
+#define GTK_IS_SHARED_INSTANCE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_SHARED_INSTANCE))
+#define G_SHARED_INSTANCE_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_SHARED_INSTANCE, GSharedInstanceIface))
+
+
+/* Règles de partage d'une instance GObject (coquille vide) */
+typedef struct _GSharedInstance GSharedInstance;
+
+/* Règles de partage d'une instance GObject (interface) */
+typedef struct _GSharedInstanceIface GSharedInstanceIface;
+
+
+/* Détermine le type d'une interface pour le partage d'instance. */
+GType g_shared_instance_get_type(void) G_GNUC_CONST;
+
+/* Initialise un nouvel objet partagé avec des informations. */
+bool g_shared_instance_init(GSharedInstance *, const void *);
+
+/* Fournit la valeur du compteur de partage. */
+unsigned int g_shared_instance_get_references(const GSharedInstance *);
+
+/* Incrémente le compteur de partage. */
+void g_shared_instance_inc_references(GSharedInstance *);
+
+/* Décrémente le compteur de partage. */
+void g_shared_instance_dec_references(GSharedInstance *);
+
+/* Indique l'objet partagé correspond à une description donnée. */
+gboolean g_shared_instance_compare_info(const GSharedInstance *, const void *);
+
+/* Détermine si deux instances partagées sont identiques. */
+gboolean g_shared_instance_is_equal(const GSharedInstance *, const GSharedInstance *);
+
+
+
+#endif  /* _ARCH_SHARING_INSTANCE_H */
diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c
new file mode 100644
index 0000000..9f6ec39
--- /dev/null
+++ b/src/arch/sharing/manager.c
@@ -0,0 +1,246 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.c - collecte et gestion des instances partagées
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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 "manager.h"
+
+
+#include <assert.h>
+
+
+
+/* Gestionnaire d'instances de type identique partagées (instance) */
+struct _GShareManager
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GHashTable *table;                      /* Collection de partages      */
+
+    GType managed;                          /* Type d'instances gérées     */
+
+};
+
+/* Gestionnaire d'instances de type identique partagées (classe) */
+struct _GShareManagerClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Procède à l'initialisation d'une classe de suivi de largeurs. */
+static void g_share_manager_class_init(GShareManagerClass *);
+
+/* Procède à l'initialisation d'un suivi de largeurs de lignes. */
+static void g_share_manager_init(GShareManager *);
+
+/* Supprime toutes les références externes. */
+static void g_share_manager_dispose(GShareManager *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_share_manager_finalize(GShareManager *);
+
+
+
+/* Détermine le type du gestionnaire d'instances partagées. */
+G_DEFINE_TYPE(GShareManager, g_share_manager, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : class = classe de composant GTK à initialiser.               *
+*                                                                             *
+*  Description : Procède à l'initialisation d'une classe de suivi de largeurs.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_share_manager_class_init(GShareManagerClass *class)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_share_manager_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_share_manager_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager = composant GLib à initialiser.                      *
+*                                                                             *
+*  Description : Procède à l'initialisation d'un suivi de largeurs de lignes. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_share_manager_init(GShareManager *manager)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_share_manager_dispose(GShareManager *manager)
+{
+    g_hash_table_unref(manager->table);
+
+    G_OBJECT_CLASS(g_share_manager_parent_class)->dispose(G_OBJECT(manager));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_share_manager_finalize(GShareManager *manager)
+{
+    G_OBJECT_CLASS(g_share_manager_parent_class)->finalize(G_OBJECT(manager));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type d'instances encadrées ici.                       *
+*                                                                             *
+*  Description : Crée un nouveau gestionnaire d'instances partagées.          *
+*                                                                             *
+*  Retour      : Composant GLib créé.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GShareManager *g_share_manager_new(GType type)
+{
+    GShareManager *result;                  /* Gestionnaire à renvoyer     */
+
+    result = g_object_new(G_TYPE_SHARE_MANAGER, NULL);
+
+    result->table = g_hash_table_new_full((GHashFunc)g_direct_hash,
+                                          (GEqualFunc)g_shared_instance_is_equal,
+                                          (GDestroyNotify)g_object_unref,
+                                          (GDestroyNotify)NULL);
+
+    result->managed = type;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : manager = gestionnaire d'instance à consulter.               *
+*                info    = informations à retrouver intégralement.            *
+*                                                                             *
+*  Description : Retrouve ou crée une instance partagée.                      *
+*                                                                             *
+*  Retour      : Instance existante déjà partagée ou nouvellement créée.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *info)
+{
+    GSharedInstance *result;                /* Trouvaille à retourner      */
+    gpointer found;                         /* Elément correspondant ?     */
+    bool status;                            /* Conclusion d'initialisation */
+#ifndef NDEBUG
+    gboolean new;                           /* Présence de partage existant*/
+#endif
+
+    gboolean find_shared_matching_info(const GSharedInstance *key, gpointer unused, const void *nfo)
+    {
+        return g_shared_instance_compare_info(key, nfo);
+    }
+
+    found = g_hash_table_find(manager->table, (GHRFunc)find_shared_matching_info, (void *)info);
+
+    if (found == NULL)
+    {
+        result = g_object_new(manager->managed, NULL);
+
+        status = g_shared_instance_init(result, info);
+
+        if (!status)
+        {
+            g_object_unref(result);
+            result = NULL;
+        }
+
+        else
+        {
+
+#ifndef NDEBUG
+            new = g_hash_table_add(manager->table, result);
+            assert(new);
+#else
+            g_hash_table_add(manager->table, result);
+#endif
+
+        }
+
+    }
+
+    else
+        result = G_SHARED_INSTANCE(found);
+
+    if (result != NULL)
+    {
+        g_object_ref(G_OBJECT(result));
+        g_shared_instance_inc_references(result);
+    }
+
+    return result;
+
+}
diff --git a/src/arch/sharing/manager.h b/src/arch/sharing/manager.h
new file mode 100644
index 0000000..85f4b1f
--- /dev/null
+++ b/src/arch/sharing/manager.h
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * manager.h - prototypes pour la collecte et la gestion des instances partagées
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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.
+ *
+ *  Chrysalide 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_SHARING_MANAGER_H
+#define _ARCH_SHARING_MANAGER_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "instance.h"
+
+
+
+/* Compare une instance avec des informations similaires. */
+typedef gboolean (* compare_with_info_fc) (const GSharedInstance *, const void *);
+
+
+#define G_TYPE_SHARE_MANAGER            (g_share_manager_get_type())
+#define G_SHARE_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SHARE_MANAGER, GShareManager))
+#define G_SHARE_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_SHARE_MANAGER, GShareManagerClass))
+#define G_IS_SHARE_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SHARE_MANAGER))
+#define G_IS_SHARE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_SHARE_MANAGER))
+#define G_SHARE_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_SHARE_MANAGER, GShareManagerClass))
+
+
+/* Gestionnaire d'instances de type identique partagées (instance) */
+typedef struct _GShareManager GShareManager;
+
+/* Gestionnaire d'instances de type identique partagées (classe) */
+typedef struct _GShareManagerClass GShareManagerClass;
+
+
+/* Détermine le type du gestionnaire d'instances partagées. */
+GType g_share_manager_get_type(void);
+
+/* Crée un nouveau gestionnaire d'instances partagées. */
+GShareManager *g_share_manager_new(GType);
+
+/* Retrouve ou crée une instance partagée. */
+GSharedInstance *g_share_manager_get(const GShareManager *, const void *);
+
+
+
+#endif  /* _ARCH_SHARING_MANAGER_H */
diff --git a/src/core/processors.c b/src/core/processors.c
index e82d254..9c67a87 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -29,7 +29,9 @@
 #include <string.h>
 
 
+#include "../arch/arm/v7/core.h"
 #include "../arch/arm/v7/processor.h"
+#include "../arch/dalvik/core.h"
 #include "../arch/dalvik/processor.h"
 #include "../arch/jvm/processor.h"
 
@@ -42,6 +44,9 @@ typedef struct _proc_t
     char *name;                             /* Désignation humaine         */
     GType instance;                         /* Type à manipuler en interne */
 
+    init_arch_fc init;                      /* Phase d'intialisation       */
+    exit_arch_fc exit;                      /* Phase de relâchement        */
+
 } proc_t;
 
 
@@ -50,7 +55,7 @@ static proc_t *_processors_definitions = NULL;
 static size_t _processors_definitions_count = 0;
 
 /* Verrou pour des accès atomiques */
-/* ... */
+G_LOCK_DEFINE_STATIC(_pdef_access);
 
 
 /* Retrouve l'enregistrement correspondant à une architecture. */
@@ -63,6 +68,8 @@ static proc_t *find_processor_by_key(const char *);
 *  Paramètres  : key      = désignation rapide et interne d'un processeur.    *
 *                name     = désignation humaine de l'architecture.            *
 *                instance = type GLib représentant le type à instancier.      *
+*                init     = procédure d'initialisation de mécanismes internes.*
+*                exit     = procédure de suppression de mécanismes internes.  *
 *                                                                             *
 *  Description : Enregistre un processeur pour une architecture donnée.       *
 *                                                                             *
@@ -72,26 +79,38 @@ static proc_t *find_processor_by_key(const char *);
 *                                                                             *
 ******************************************************************************/
 
-bool register_processor_type(const char *key, const char *name, GType instance)
+bool register_processor_type(const char *key, const char *name, GType instance, init_arch_fc init, exit_arch_fc exit)
 {
+    bool result;                            /* Bilan à retourner           */
     proc_t *new;                            /* Nouvel élément à définir    */
 
-    /* TODO : if find()... -> unref(), ret false */
+    G_LOCK(_pdef_access);
+
+    new = find_processor_by_key(key);
+
+    result = (new == NULL);
+
+    result &= init();
+
+    if (result)
+    {
+        _processors_definitions = (proc_t *)realloc(_processors_definitions,
+                                                    ++_processors_definitions_count * sizeof(proc_t));
 
-    /* TODO : lock */
+        new = &_processors_definitions[_processors_definitions_count - 1];
 
-    _processors_definitions = (proc_t *)realloc(_processors_definitions,
-                                                  ++_processors_definitions_count * sizeof(proc_t));
+        new->key = strdup(key);
+        new->name = strdup(name);
+        new->instance = instance;
 
-    new = &_processors_definitions[_processors_definitions_count - 1];
+        new->init = init;
+        new->exit = exit;
 
-    new->key = strdup(key);
-    new->name = strdup(name);
-    new->instance = instance;
+    }
 
-    /* TODO : unlock */
+    G_UNLOCK(_pdef_access);
 
-    return true;
+    return result;
 
 }
 
@@ -114,9 +133,11 @@ bool load_hard_coded_processors_definitions(void)
 
     result = true;
 
-    result &= register_processor_type("armv7", "ARM v7", G_TYPE_ARMV7_PROCESSOR);
+    result &= register_processor_type("armv7", "ARM v7", G_TYPE_ARMV7_PROCESSOR,
+                                      init_armv7_core, exit_armv7_core);
 
-    result &= register_processor_type("dalvik", "Dalvik Virtual Machine", G_TYPE_DALVIK_PROCESSOR);
+    result &= register_processor_type("dalvik", "Dalvik Virtual Machine", G_TYPE_DALVIK_PROCESSOR,
+                                      init_dalvik_core, exit_dalvik_core);
 
     //result &= register_processor_type("jvm", "Java Virtual Machine", G_TYPE_JVM_PROCESSOR);
 
@@ -141,6 +162,8 @@ void unload_processors_definitions(void)
 {
     size_t i;                               /* Boucle de parcours          */
 
+    G_LOCK(_pdef_access);
+
     for (i = 0; i < _processors_definitions_count; i++)
     {
         free(_processors_definitions[i].key);
@@ -153,6 +176,8 @@ void unload_processors_definitions(void)
     _processors_definitions = NULL;
     _processors_definitions_count = 0;
 
+    G_UNLOCK(_pdef_access);
+
 }
 
 
@@ -206,7 +231,7 @@ const char *get_arch_processor_name(const char *key)
     const char *result;                     /* Description à retourner     */
     proc_t *def;                            /* Définition d'architecture   */
 
-    /* TODO : lock */
+    G_LOCK(_pdef_access);
 
     def = find_processor_by_key(key);
 
@@ -214,8 +239,8 @@ const char *get_arch_processor_name(const char *key)
         result = NULL;
     else
         result = def->name;
-
-    /* TODO : unlock */
+    
+    G_UNLOCK(_pdef_access);
 
     return result;
 
@@ -239,7 +264,7 @@ GArchProcessor *get_arch_processor_for_type(const char *key)
     GArchProcessor *result;                 /* Instance à retourner        */
     proc_t *def;                            /* Définition d'architecture   */
 
-    /* TODO : lock */
+    G_LOCK(_pdef_access);
 
     def = find_processor_by_key(key);
 
@@ -248,7 +273,7 @@ GArchProcessor *get_arch_processor_for_type(const char *key)
     else
         result = g_object_new(def->instance, NULL);
 
-    /* TODO : unlock */
+    G_UNLOCK(_pdef_access);
 
     return result;
 
diff --git a/src/core/processors.h b/src/core/processors.h
index b2e9cd5..4f82dc3 100644
--- a/src/core/processors.h
+++ b/src/core/processors.h
@@ -33,8 +33,15 @@
 
 
 
+/* Mise en place de mécanismes internes */
+typedef bool (* init_arch_fc) (void);
+
+/* Suppression de mécanismes internes */
+typedef void (* exit_arch_fc) (void);
+
+
 /* Enregistre un processeur pour une architecture donnée. */
-bool register_processor_type(const char *, const char *, GType);
+bool register_processor_type(const char *, const char *, GType, init_arch_fc, exit_arch_fc);
 
 /* Charge les définitions de processeurs "natifs". */
 bool load_hard_coded_processors_definitions(void);
diff --git a/src/glibext/gwidthtracker.c b/src/glibext/gwidthtracker.c
index 73f56df..3a1863e 100644
--- a/src/glibext/gwidthtracker.c
+++ b/src/glibext/gwidthtracker.c
@@ -98,11 +98,6 @@ static void g_width_tracker_ensure_valid_required_widths(GWidthTracker *);
 
 
 
-/* ---------------------------------------------------------------------------------- */
-/*                            TAMPON POUR CODE DESASSEMBLE                            */
-/* ---------------------------------------------------------------------------------- */
-
-
 /* Détermine le type du gestionnaire de largeurs associées aux lignes. */
 G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT);
 
-- 
cgit v0.11.2-87-g4458