From 7d6d3acb65586ad9512a38b58c16b9a21cdf98e0 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard 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 + + * 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 * 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 . + */ + + +#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 . + */ + + +#ifndef _ARCH_ARM_V7_CORE_H +#define _ARCH_ARM_V7_CORE_H + + +#include + + + +/* 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 . + */ + + +#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 . + */ + + +#ifndef _ARCH_DALVIK_CORE_H +#define _ARCH_DALVIK_CORE_H + + +#include + + + +/* 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 . + */ + + +#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 . + */ + + +#include "instance.h" + + +#include + + +#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 . + */ + + +#ifndef _ARCH_SHARING_INSTANCE_H +#define _ARCH_SHARING_INSTANCE_H + + +#include +#include + + + +#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 . + */ + + +#include "manager.h" + + +#include + + + +/* 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 . + */ + + +#ifndef _ARCH_SHARING_MANAGER_H +#define _ARCH_SHARING_MANAGER_H + + +#include +#include + + +#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 +#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