diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2018-05-28 17:37:46 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2018-05-28 17:37:46 (GMT) | 
| commit | 9f5ed46de568d3db882c939c8ca9d0117bff3369 (patch) | |
| tree | 9d2090cd640e54379dc1b982e03dc284b2d23ae7 /src | |
| parent | 2fd186a84cba4f39f6f1bb8bd34d52b4e1d4f814 (diff) | |
Relied on register objects as often as possible.
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/Makefile.am | 5 | ||||
| -rw-r--r-- | src/arch/operands/Makefile.am | 23 | ||||
| -rw-r--r-- | src/arch/operands/register-int.h | 54 | ||||
| -rw-r--r-- | src/arch/operands/register.c | 382 | ||||
| -rw-r--r-- | src/arch/operands/register.h | 69 | ||||
| -rw-r--r-- | src/arch/register-int.h | 30 | ||||
| -rw-r--r-- | src/arch/register.c | 285 | ||||
| -rw-r--r-- | src/arch/register.h | 41 | ||||
| -rw-r--r-- | src/arch/storage.c | 76 | ||||
| -rw-r--r-- | src/arch/storage.h | 27 | ||||
| -rw-r--r-- | src/core/processors.c | 2 | 
11 files changed, 686 insertions, 308 deletions
| diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am index c9cc63b..8710b13 100644 --- a/src/arch/Makefile.am +++ b/src/arch/Makefile.am @@ -30,7 +30,8 @@ libarch_la_SOURCES =					\  # 	mips/libarchmips.la					\  # 	x86/libarchx86.la -libarch_la_LIBADD =	 +libarch_la_LIBADD =						\ +	operands/libarchoperands.la  libarch_la_LDFLAGS =  @@ -46,4 +47,4 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)  #SUBDIRS = arm dalvik jvm mips x86 -SUBDIRS =  +SUBDIRS = operands diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am new file mode 100644 index 0000000..fb43a22 --- /dev/null +++ b/src/arch/operands/Makefile.am @@ -0,0 +1,23 @@ + +noinst_LTLIBRARIES = libarchoperands.la + +libarchoperands_la_SOURCES =			\ +	register-int.h						\ +	register.h register.c + +libarchoperands_la_LIBADD =	 + +libarchoperands_la_LDFLAGS =  + + +devdir = $(includedir)/chrysalide/$(subdir:src/%=%) + +dev_HEADERS = $(libarchoperands_la_SOURCES:%c=) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + + +SUBDIRS =  diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h new file mode 100644 index 0000000..348e2a3 --- /dev/null +++ b/src/arch/operands/register-int.h @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register-int.h - définitions internes pour la représentation générique d'un registre + * + * Copyright (C) 2012-2017 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_REGISTER_INT_H +#define _ARCH_OPERANDS_REGISTER_INT_H + + +#include "register.h" + + +#include "../operand-int.h" + + + +/* Définition d'un opérande visant un registre (instance) */ +struct _GRegisterOperand +{ +    GArchOperand parent;                    /* Instance parente            */ + +    GArchRegister *reg;                     /* Registre représenté         */ +    bool is_written;                        /* Changement de contenu       */ + +}; + +/* Définition d'un opérande visant un registre (classe) */ +struct _GRegisterOperandClass +{ +    GArchOperandClass parent;               /* Classe parente              */ + +}; + + + +#endif  /* _ARCH_OPERANDS_REGISTER_INT_H */ diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c new file mode 100644 index 0000000..e890fd6 --- /dev/null +++ b/src/arch/operands/register.c @@ -0,0 +1,382 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * registers.c - aides auxiliaires relatives aux registres Dalvik + * + * Copyright (C) 2012-2017 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "register.h" + + +#include "register-int.h" +#include "../storage.h" + + + +/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ + + +/* Initialise la classe des opérandes de registre. */ +static void g_register_operand_class_init(GRegisterOperandClass *); + +/* Initialise une instance d'opérande de registre. */ +static void g_register_operand_init(GRegisterOperand *); + +/* Supprime toutes les références externes. */ +static void g_register_operand_dispose(GRegisterOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_register_operand_finalize(GRegisterOperand *); + +/* Compare un opérande avec un autre. */ +static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void g_register_operand_print(const GRegisterOperand *, GBufferLine *, AsmSyntax); + + + +/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ + + +/* Charge un opérande depuis une mémoire tampon. */ +static bool g_register_operand_unserialize(GRegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde un opérande dans une mémoire tampon. */ +static bool g_register_operand_serialize(const GRegisterOperand *, GAsmStorage *, packed_buffer *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                           REGISTRE SOUS FORME D'OPERANDE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ +G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des opérandes de registre Dalvik.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_class_init(GRegisterOperandClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GArchOperandClass *operand;             /* Version de classe parente   */ + +    object = G_OBJECT_CLASS(klass); +    operand = G_ARCH_OPERAND_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_register_operand_dispose; +    object->finalize = (GObjectFinalizeFunc)g_register_operand_finalize; + +    operand = G_ARCH_OPERAND_CLASS(klass); + +    operand->compare = (operand_compare_fc)g_register_operand_compare; +    operand->print = (operand_print_fc)g_register_operand_print; + +    operand->unserialize = (unserialize_operand_fc)g_register_operand_unserialize; +    operand->serialize = (serialize_operand_fc)g_register_operand_serialize; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise une instance d'opérande de registre Dalvik.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_init(GRegisterOperand *operand) +{ +    operand->reg = NULL; +    operand->is_written = false; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_dispose(GRegisterOperand *operand) +{ +    if (operand->reg != NULL) +        g_object_unref(G_OBJECT(operand->reg)); + +    G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary = instance d'objet GLib à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_finalize(GRegisterOperand *operand) +{ +    G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premier opérande à consulter.                            * +*                b = second opérande à consulter.                             * +*                                                                             * +*  Description : Compare un opérande avec un autre.                           * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b) +{ +    int result;                             /* Bilan à retourner           */ + +    result = g_arch_register_compare(a->reg, b->reg); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à traiter.                                * +*                line    = ligne tampon où imprimer l'opérande donné.         * +*                syntax  = type de représentation demandée.                   * +*                                                                             * +*  Description : Traduit un opérande en version humainement lisible.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line, AsmSyntax syntax) +{ +    g_arch_register_print(operand->reg, line, syntax); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande représentant un registre.                 * +*                                                                             * +*  Description : Fournit le registre Dalvik associé à l'opérande.             * +*                                                                             * +*  Retour      : Représentation interne du registre.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand) +{ +    GArchRegister *result;                  /* Instance à retourner        */ + +    result = operand->reg; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande représentant un registre à mettre à jour. * +*                                                                             * +*  Description : Marque l'opérande comme étant écrit plutôt que consulté.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_register_operand_mark_as_written(GRegisterOperand *operand) +{ +    operand->is_written = true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande représentant un registre à consulter.     * +*                                                                             * +*  Description : Indique le type d'accès réalisé sur l'opérande.              * +*                                                                             * +*  Retour      : Type d'accès : true en cas d'écriture, false sinon.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_register_operand_is_written(const GRegisterOperand *operand) +{ +    return operand->is_written; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande d'assemblage à constituer.                * +*                storage = mécanisme de sauvegarde à manipuler.               * +*                format  = format binaire chargé associé à l'architecture.    * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Charge un opérande depuis une mémoire tampon.                * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    off64_t pos;                            /* Position dans le flux       */ +    packed_buffer reg_pbuf;                 /* Tampon des données à écrire */ +    GArchRegister *reg;                     /* Registre restauré           */ + +    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); + +    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + +    if (result) +        result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + +    if (result) +    { +        init_packed_buffer(®_pbuf); + +        result = g_asm_storage_load_register_data(storage, ®_pbuf, pos); + +        if (result) +        { +            reg = g_arch_register_load(storage, ®_pbuf); +            result = (reg != NULL); +        } + +        if (result) +            operand->reg = reg; + +        exit_packed_buffer(®_pbuf); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande d'assemblage à consulter.                 * +*                storage = mécanisme de sauvegarde à manipuler.               * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_register_operand_serialize(const GRegisterOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchOperandClass *parent;              /* Classe parente à consulter  */ +    off64_t pos;                            /* Position dans le flux       */ +    packed_buffer reg_pbuf;                 /* Tampon des données à écrire */ + +    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); + +    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + +    if (result) +    { +        init_packed_buffer(®_pbuf); + +        result = g_arch_register_store(operand->reg, storage, ®_pbuf); + +        if (result) +            result = g_asm_storage_store_register_data(storage, ®_pbuf, &pos); + +        if (result) +            result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + +        exit_packed_buffer(®_pbuf); + +    } + +    return result; + +} diff --git a/src/arch/operands/register.h b/src/arch/operands/register.h new file mode 100644 index 0000000..e4693b1 --- /dev/null +++ b/src/arch/operands/register.h @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register.h - prototypes pour les aides auxiliaires relatives aux registres Dalvik + * + * Copyright (C) 2012-2017 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_REGISTER_H +#define _ARCH_OPERANDS_REGISTER_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../operand.h" +#include "../register.h" + + + +/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ + + +#define G_TYPE_REGISTER_OPERAND            g_register_operand_get_type() +#define G_REGISTER_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand)) +#define G_IS_REGISTER_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND)) +#define G_REGISTER_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_REGISTER_OPERAND, GRegisterOperandClass)) +#define G_IS_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_REGISTER_OPERAND)) +#define G_REGISTER_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperandClass)) + + +/* Définition d'un opérande visant un registre (instance) */ +typedef struct _GRegisterOperand GRegisterOperand; + +/* Définition d'un opérande visant un registre (classe) */ +typedef struct _GRegisterOperandClass GRegisterOperandClass; + + +/* Indique le type défini par la GLib pour un opérande de registre. */ +GType g_register_operand_get_type(void); + +/* Fournit le registre associé à l'opérande. */ +GArchRegister *g_register_operand_get_register(const GRegisterOperand *); + +/* Marque l'opérande comme étant écrit plutôt que consulté. */ +void g_register_operand_mark_as_written(GRegisterOperand *); + +/* Indique le type d'accès réalisé sur l'opérande. */ +bool g_register_operand_is_written(const GRegisterOperand *); + + + +#endif  /* _ARCH_OPERANDS_REGISTER_H */ diff --git a/src/arch/register-int.h b/src/arch/register-int.h index 173e6e0..fb9534b 100644 --- a/src/arch/register-int.h +++ b/src/arch/register-int.h @@ -47,6 +47,11 @@ typedef bool (* reg_is_base_pointer_fc) (const GArchRegister *);  /* Indique si le registre correspond à esp ou similaire. */  typedef bool (* reg_is_stack_pointer_fc) (const GArchRegister *); +/* Charge un registre depuis une mémoire tampon. */ +typedef GArchRegister * (* reg_unserialize_fc) (GArchRegister *, GAsmStorage *, packed_buffer *); + +/* Sauvegarde un registre dans une mémoire tampon. */ +typedef bool (* reg_serialize_fc) (const GArchRegister *, GAsmStorage *, packed_buffer *);  /* Représentation d'un registre (instance) */ @@ -56,7 +61,6 @@ struct _GArchRegister  }; -  /* Représentation d'un registre (classe) */  struct _GArchRegisterClass  { @@ -68,28 +72,8 @@ struct _GArchRegisterClass      reg_is_base_pointer_fc is_bp;           /* Correspondance avec ebp     */      reg_is_stack_pointer_fc is_sp;          /* Correspondance avec esp     */ -}; - - - -/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ - - -/* Définition d'un opérande visant un registre (instance) */ -struct _GRegisterOperand -{ -    GArchOperand parent;                    /* Instance parente            */ - -    GArchRegister *reg;                     /* Registre représenté         */ -    bool is_written;                        /* Changement de contenu       */ - -}; - - -/* Définition d'un opérande visant un registre (classe) */ -struct _GRegisterOperandClass -{ -    GArchOperandClass parent;               /* Classe parente              */ +    reg_unserialize_fc unserialize;         /* Chargement depuis un tampon */ +    reg_serialize_fc serialize;             /* Conservation dans un tampon */  }; diff --git a/src/arch/register.c b/src/arch/register.c index 7e1bcc2..f678327 100644 --- a/src/arch/register.c +++ b/src/arch/register.c @@ -25,6 +25,7 @@  #include "register-int.h" +#include "storage.h" @@ -44,37 +45,15 @@ static void g_arch_register_dispose(GArchRegister *);  static void g_arch_register_finalize(GArchRegister *); -/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ +/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ -/* Initialise la classe des opérandes de registre. */ -static void g_register_operand_class_init(GRegisterOperandClass *); -/* Initialise une instance d'opérande de registre. */ -static void g_register_operand_init(GRegisterOperand *); +/* Charge un registre depuis une mémoire tampon. */ +static GArchRegister *g_arch_register_unserialize(GArchRegister *, GAsmStorage *, packed_buffer *); -/* Supprime toutes les références externes. */ -static void g_register_operand_dispose(GRegisterOperand *); - -/* Procède à la libération totale de la mémoire. */ -static void g_register_operand_finalize(GRegisterOperand *); - -/* Compare un opérande avec un autre. */ -static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *); - -/* Traduit un opérande en version humainement lisible. */ -static void g_register_operand_print(const GRegisterOperand *, GBufferLine *, AsmSyntax); - - - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_register_operand_unserialize(GRegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_register_operand_serialize(const GRegisterOperand *, GAsmStorage *, packed_buffer *); +/* Sauvegarde un registre dans une mémoire tampon. */ +static bool g_arch_register_serialize(const GArchRegister *, GAsmStorage *, packed_buffer *); @@ -108,6 +87,9 @@ static void g_arch_register_class_init(GArchRegisterClass *klass)      object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_register_dispose;      object->finalize = (GObjectFinalizeFunc)g_arch_register_finalize; +    klass->unserialize = (reg_unserialize_fc)g_arch_register_unserialize; +    klass->serialize = (reg_serialize_fc)g_arch_register_serialize; +  } @@ -281,127 +263,29 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *reg)  /* ---------------------------------------------------------------------------------- */ -/*                           REGISTRE SOUS FORME D'OPERANDE                           */ +/*                       TRANSPOSITIONS VIA CACHE DES REGISTRES                       */  /* ---------------------------------------------------------------------------------- */ -/* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ -G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND); - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : klass = classe à initialiser.                                * -*                                                                             * -*  Description : Initialise la classe des opérandes de registre Dalvik.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_class_init(GRegisterOperandClass *klass) -{ -    GObjectClass *object;                   /* Autre version de la classe  */ -    GArchOperandClass *operand;             /* Version de classe parente   */ - -    object = G_OBJECT_CLASS(klass); -    operand = G_ARCH_OPERAND_CLASS(klass); - -    object->dispose = (GObjectFinalizeFunc/* ! */)g_register_operand_dispose; -    object->finalize = (GObjectFinalizeFunc)g_register_operand_finalize; - -    operand = G_ARCH_OPERAND_CLASS(klass); - -    operand->compare = (operand_compare_fc)g_register_operand_compare; -    operand->print = (operand_print_fc)g_register_operand_print; - -    operand->unserialize = (unserialize_operand_fc)g_register_operand_unserialize; -    operand->serialize = (serialize_operand_fc)g_register_operand_serialize; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = instance à initialiser.                            * -*                                                                             * -*  Description : Initialise une instance d'opérande de registre Dalvik.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_init(GRegisterOperand *operand) -{ -    operand->reg = NULL; -    operand->is_written = false; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : binary = instance d'objet GLib à traiter.                    * -*                                                                             * -*  Description : Supprime toutes les références externes.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_dispose(GRegisterOperand *operand) -{ -    if (operand->reg != NULL) -        g_object_unref(G_OBJECT(operand->reg)); - -    G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(G_OBJECT(operand)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : binary = instance d'objet GLib à traiter.                    * -*                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_finalize(GRegisterOperand *operand) -{ -    G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(G_OBJECT(operand)); - -} - -  /******************************************************************************  *                                                                             * -*  Paramètres  : a = premier opérande à consulter.                            * -*                b = second opérande à consulter.                             * +*  Paramètres  : reg     = registre d'architecture à constituer.              * +*                storage = mécanisme de sauvegarde à manipuler.               * +*                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Compare un opérande avec un autre.                           * +*  Description : Charge un registre depuis une mémoire tampon.                *  *                                                                             * -*  Retour      : Bilan de la comparaison.                                     * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b) +static GArchRegister *g_arch_register_unserialize(GArchRegister *reg, GAsmStorage *storage, packed_buffer *pbuf)  { -    int result;                             /* Bilan à retourner           */ +    GArchRegister *result;                  /* Instance à retourner        */ -    result = g_arch_register_compare(a->reg, b->reg); +    result = reg;      return result; @@ -410,123 +294,49 @@ static int g_register_operand_compare(const GRegisterOperand *a, const GRegister  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                line    = ligne tampon où imprimer l'opérande donné.         * -*                syntax  = type de représentation demandée.                   * -*                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line, AsmSyntax syntax) -{ -    g_arch_register_print(operand->reg, line, syntax); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : reg = registre déjà en place.                                * -*                                                                             * -*  Description : Crée un opérande visant un registre.                         * -*                                                                             * -*  Retour      : Opérande mis en place.                                       * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GArchOperand *g_register_operand_new(GArchRegister *reg) -{ -    GRegisterOperand *result;         /* Structure à retourner       */ - -    result = g_object_new(G_TYPE_REGISTER_OPERAND, NULL); - -    result->reg = reg; - -    return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande représentant un registre.                 * +*  Paramètres  : storage = mécanisme de sauvegarde à manipuler.               * +*                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Fournit le registre Dalvik associé à l'opérande.             * +*  Description : Charge un registre depuis une mémoire tampon.                *  *                                                                             * -*  Retour      : Représentation interne du registre.                          * +*  Retour      : Registre d'architecture constitué ou NULL en cas d'échec.    *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand) +GArchRegister *g_arch_register_load(GAsmStorage *storage, packed_buffer *pbuf)  { -    g_object_ref(G_OBJECT(operand->reg)); +    GArchRegister *result;                  /* Instance à retourner        */ +    GArchRegister *dummy;                   /* Patron du type de registre  */ -    return operand->reg; +    dummy = G_ARCH_REGISTER(g_asm_storage_create_object(storage, pbuf)); -} +    if (dummy != NULL) +    { +        result = G_ARCH_REGISTER_GET_CLASS(dummy)->unserialize(dummy, storage, pbuf); +        /* Si personne ne l'a fait avant... */ +        if (result != NULL) +            g_object_unref(G_OBJECT(dummy)); -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande représentant un registre à mettre à jour. * -*                                                                             * -*  Description : Marque l'opérande comme étant écrit plutôt que consulté.     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_register_operand_mark_as_written(GRegisterOperand *operand) -{ -    operand->is_written = true; +    } -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande représentant un registre à consulter.     * -*                                                                             * -*  Description : Indique le type d'accès réalisé sur l'opérande.              * -*                                                                             * -*  Retour      : Type d'accès : true en cas d'écriture, false sinon.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    else +        result = NULL; -bool g_register_operand_is_written(const GRegisterOperand *operand) -{ -    return operand->is_written; +    return result;  } - -/* ---------------------------------------------------------------------------------- */ -/*                       TRANSPOSITIONS VIA CACHE DES OPERANDES                       */ -/* ---------------------------------------------------------------------------------- */ - -  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à constituer.                * +*  Paramètres  : reg     = registre d'architecture à consulter.               *  *                storage = mécanisme de sauvegarde à manipuler.               * -*                format  = format binaire chargé associé à l'architecture.    *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Charge un opérande depuis une mémoire tampon.                * +*  Description : Sauvegarde un registre dans une mémoire tampon.              *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -534,14 +344,11 @@ bool g_register_operand_is_written(const GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +static bool g_arch_register_serialize(const GArchRegister *reg, GAsmStorage *storage, packed_buffer *pbuf)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ - -    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); -    result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); +    result = true;      return result; @@ -550,11 +357,11 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande d'assemblage à consulter.                 * +*  Paramètres  : reg     = registre d'architecture à consulter.               *  *                storage = mécanisme de sauvegarde à manipuler.               *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * -*  Description : Sauvegarde un opérande dans une mémoire tampon.              * +*  Description : Sauvegarde un registre dans une mémoire tampon.              *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -562,14 +369,14 @@ static bool g_register_operand_unserialize(GRegisterOperand *operand, GAsmStorag  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_serialize(const GRegisterOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) +bool g_arch_register_store(const GArchRegister *reg, GAsmStorage *storage, packed_buffer *pbuf)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +    result = g_asm_storage_store_object_gtype(storage, G_OBJECT(reg), pbuf); -    result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); +    if (result) +        result = G_ARCH_REGISTER_GET_CLASS(reg)->serialize(reg, storage, pbuf);      return result; diff --git a/src/arch/register.h b/src/arch/register.h index fb3741e..5a97682 100644 --- a/src/arch/register.h +++ b/src/arch/register.h @@ -21,8 +21,8 @@   */ -#ifndef _ARCH_ARCH_REGISTER_H -#define _ARCH_ARCH_REGISTER_H +#ifndef _ARCH_REGISTER_H +#define _ARCH_REGISTER_H  #include <glib-object.h> @@ -30,7 +30,6 @@  #include "archbase.h" -#include "operand.h"  #include "../glibext/gbufferline.h" @@ -73,39 +72,19 @@ bool g_arch_register_is_stack_pointer(const GArchRegister *); -/* ------------------------- REGISTRE SOUS FORME D'OPERANDE ------------------------- */ +/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ -#define G_TYPE_REGISTER_OPERAND            g_register_operand_get_type() -#define G_REGISTER_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperand)) -#define G_IS_REGISTER_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_REGISTER_OPERAND)) -#define G_REGISTER_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_REGISTER_OPERAND, GRegisterOperandClass)) -#define G_IS_REGISTER_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_REGISTER_OPERAND)) -#define G_REGISTER_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_REGISTER_OPERAND, GRegisterOperandClass)) +/* Depuis "storage.h" : définition d'une conservation d'instructions d'assemblage (instance) */ +typedef struct _GAsmStorage GAsmStorage; -/* Définition d'un opérande visant un registre (instance) */ -typedef struct _GRegisterOperand GRegisterOperand; +/* Charge un registre depuis une mémoire tampon. */ +GArchRegister *g_arch_register_load(GAsmStorage *, packed_buffer *); -/* Définition d'un opérande visant un registre (classe) */ -typedef struct _GRegisterOperandClass GRegisterOperandClass; +/* Sauvegarde un registre dans une mémoire tampon. */ +bool g_arch_register_store(const GArchRegister *, GAsmStorage *, packed_buffer *); -/* Indique le type défini par la GLib pour un opérande de registre. */ -GType g_register_operand_get_type(void); -/* Crée un opérande visant un registre. */ -GArchOperand *g_register_operand_new(GArchRegister *); - -/* Fournit le registre associé à l'opérande. */ -GArchRegister *g_register_operand_get_register(const GRegisterOperand *); - -/* Marque l'opérande comme étant écrit plutôt que consulté. */ -void g_register_operand_mark_as_written(GRegisterOperand *); - -/* Indique le type d'accès réalisé sur l'opérande. */ -bool g_register_operand_is_written(const GRegisterOperand *); - - - -#endif  /* _ARCH_ARCH_REGISTER_H */ +#endif  /* _ARCH_REGISTER_H */ diff --git a/src/arch/storage.c b/src/arch/storage.c index ac1c878..217d327 100644 --- a/src/arch/storage.c +++ b/src/arch/storage.c @@ -131,11 +131,13 @@ struct _GAsmStorage      char *idx_filename;                     /* Fichier pour l'indexage     */      char *ins_filename;                     /* Fichier pour instructions   */      char *op_filename;                      /* Fichier pour les opérandes  */ +    char *reg_filename;                     /* Fichier pour les registres  */      char *tp_filename;                      /* Fichier pour les types      */      int idx_fd;                             /* Flux pour l'indexage        */      int ins_fd;                             /* Flux pour les instructions  */      int op_fd;                              /* Flux pour les opérandes     */ +    int reg_fd;                             /* Flux pour les registres     */      int tp_fd;                              /* Flux pour les types         */      /** @@ -602,11 +604,13 @@ static void g_asm_storage_init(GAsmStorage *storage)      storage->idx_filename = NULL;      storage->ins_filename = NULL;      storage->op_filename = NULL; +    storage->reg_filename = NULL;      storage->tp_filename = NULL;      storage->idx_fd = -1;      storage->ins_fd = -1;      storage->op_fd = -1; +    storage->reg_fd = -1;      storage->tp_fd = -1;      storage->gtypes = NULL; @@ -693,6 +697,7 @@ static void g_asm_storage_finalize(GAsmStorage *storage)      finalize_storage_file(storage->idx_filename);      finalize_storage_file(storage->ins_filename);      finalize_storage_file(storage->op_filename); +    finalize_storage_file(storage->reg_filename);      finalize_storage_file(storage->tp_filename);      if (storage->idx_fd != -1) @@ -704,6 +709,9 @@ static void g_asm_storage_finalize(GAsmStorage *storage)      if (storage->op_fd != -1)          close(storage->op_fd); +    if (storage->reg_fd != -1) +        close(storage->reg_fd); +      if (storage->gtypes != NULL)          free(storage->gtypes); @@ -757,6 +765,7 @@ GAsmStorage *g_asm_storage_new_compressed(GArchProcessor *proc, const gchar *id)      asprintf(&result->idx_filename, "%s.%s-%s", basedir, id, "index.bin");      asprintf(&result->ins_filename, "%s.%s-%s", basedir, id, "instructions.bin");      asprintf(&result->op_filename, "%s.%s-%s", basedir, id, "operands.bin"); +    asprintf(&result->reg_filename, "%s.%s-%s", basedir, id, "registers.bin");      asprintf(&result->tp_filename, "%s.%s-%s", basedir, id, "types.bin");      free(basedir); @@ -891,6 +900,11 @@ static bool g_asm_storage_decompress(const GAsmStorage *storage)              if (!dump_archive_entry_into_file(in, entry, storage->op_filename))                  goto gasd_exit;          } +        else if (strcmp(path, "registers.bin") == 0) +        { +            if (!dump_archive_entry_into_file(in, entry, storage->reg_filename)) +                goto gasd_exit; +        }          else if (strcmp(path, "types.bin") == 0)          {              if (!dump_archive_entry_into_file(in, entry, storage->tp_filename)) @@ -958,6 +972,9 @@ static bool g_asm_storage_compress(const GAsmStorage *storage)      status = add_file_into_archive(out, storage->op_filename, "operands.bin");      if (status != CPE_NO_ERROR) goto gasc_exit; +    status = add_file_into_archive(out, storage->reg_filename, "registers.bin"); +    if (status != CPE_NO_ERROR) goto gasc_exit; +      status = add_file_into_archive(out, storage->tp_filename, "types.bin");      if (status != CPE_NO_ERROR) goto gasc_exit; @@ -1212,7 +1229,7 @@ static bool g_asm_storage_write_types(GAsmStorage *storage)  /******************************************************************************  *                                                                             *  *  Paramètres  : storage = gestionnaire à manipuler.                          * -*                ins     = true si les données viennent d'une instruction.    * +*                type    = type du fichier de destination.                    *  *                pbuf    = zone tampon à remplir.                             *  *                pos     = tête de lecture avant écriture.                    *  *                                                                             * @@ -1224,13 +1241,33 @@ static bool g_asm_storage_write_types(GAsmStorage *storage)  *                                                                             *  ******************************************************************************/ -bool _g_asm_storage_load_data(const GAsmStorage *storage, bool ins, packed_buffer *pbuf, off64_t pos) +bool _g_asm_storage_load_data(const GAsmStorage *storage, StorageFileType type, packed_buffer *pbuf, off64_t pos)  {      bool result;                            /* Bilan à retourner           */      int fd;                                 /* Flux ciblé                  */      off64_t new;                            /* Nouvelle position de lecture*/ -    fd = ins ? storage->ins_fd : storage->op_fd; +    switch (type) +    { +        case SFT_INSTRUCTION: +            fd = storage->ins_fd; +            break; +        case SFT_OPERAND: +            fd = storage->op_fd; +            break; +        case SFT_REGISTER: +            fd = storage->reg_fd; +            break; +        default: +            fd = -1; +            break; +    } + +    if (fd == -1) +    { +        result = false; +        goto type_error; +    }      new = lseek64(fd, pos, SEEK_SET); @@ -1243,6 +1280,8 @@ bool _g_asm_storage_load_data(const GAsmStorage *storage, bool ins, packed_buffe          result = read_packed_buffer(pbuf, fd);      } + type_error: +      return result;  } @@ -1251,7 +1290,7 @@ bool _g_asm_storage_load_data(const GAsmStorage *storage, bool ins, packed_buffe  /******************************************************************************  *                                                                             *  *  Paramètres  : storage = gestionnaire à manipuler.                          * -*                ins     = true si les données viennent d'une instruction.    * +*                type    = type du fichier de destination.                    *  *                pbuf    = zone tampon à lire.                                *  *                pos     = tête de lecture avant écriture. [OUT]              *  *                                                                             * @@ -1263,12 +1302,32 @@ bool _g_asm_storage_load_data(const GAsmStorage *storage, bool ins, packed_buffe  *                                                                             *  ******************************************************************************/ -bool _g_asm_storage_store_data(const GAsmStorage *storage, bool ins, packed_buffer *pbuf, off64_t *pos) +bool _g_asm_storage_store_data(const GAsmStorage *storage, StorageFileType type, packed_buffer *pbuf, off64_t *pos)  {      bool result;                            /* Bilan à retourner           */      int fd;                                 /* Flux ciblé                  */ -    fd = ins ? storage->ins_fd : storage->op_fd; +    switch (type) +    { +        case SFT_INSTRUCTION: +            fd = storage->ins_fd; +            break; +        case SFT_OPERAND: +            fd = storage->op_fd; +            break; +        case SFT_REGISTER: +            fd = storage->reg_fd; +            break; +        default: +            fd = -1; +            break; +    } + +    if (fd == -1) +    { +        result = false; +        goto type_error; +    }      *pos = lseek64(fd, 0, SEEK_CUR); @@ -1281,6 +1340,8 @@ bool _g_asm_storage_store_data(const GAsmStorage *storage, bool ins, packed_buff          reset_packed_buffer(pbuf);      } + type_error: +      return result;  } @@ -1326,6 +1387,9 @@ static bool g_asm_storage_open_files(GAsmStorage *storage, int flags)          result = open_file(storage->op_filename, storage->op_fd);      if (result) +        result = open_file(storage->reg_filename, storage->reg_fd); + +    if (result)          result = open_file(storage->tp_filename, storage->tp_fd);      return result; diff --git a/src/arch/storage.h b/src/arch/storage.h index 002897a..35e3a7d 100644 --- a/src/arch/storage.h +++ b/src/arch/storage.h @@ -72,23 +72,38 @@ GObject *g_asm_storage_create_object(GAsmStorage *, packed_buffer *);  /* Sauvegarde le type d'un objet instancié. */  bool g_asm_storage_store_object_gtype(GAsmStorage *, GObject *, packed_buffer *); +/* Type de fichier intermédiaire */ +typedef enum _StorageFileType +{ +    SFT_INSTRUCTION,                        /* Pour instructions           */ +    SFT_OPERAND,                            /* Pour opérandes              */ +    SFT_REGISTER                            /* Pour registres              */ + +} StorageFileType; +  /* Charge des données rassemblées. */ -bool _g_asm_storage_load_data(const GAsmStorage *, bool, packed_buffer *, off64_t); +bool _g_asm_storage_load_data(const GAsmStorage *, StorageFileType, packed_buffer *, off64_t);  #define g_asm_storage_load_instruction_data(s, b, p) \ -    _g_asm_storage_load_data(s, true, b, p) +    _g_asm_storage_load_data(s, SFT_INSTRUCTION, b, p)  #define g_asm_storage_load_operand_data(s, b, p) \ -    _g_asm_storage_load_data(s, false, b, p) +    _g_asm_storage_load_data(s, SFT_OPERAND, b, p) + +#define g_asm_storage_load_register_data(s, b, p) \ +    _g_asm_storage_load_data(s, SFT_REGISTER, b, p)  /* Sauvegarde des données rassemblées. */ -bool _g_asm_storage_store_data(const GAsmStorage *, bool, packed_buffer *, off64_t *); +bool _g_asm_storage_store_data(const GAsmStorage *, StorageFileType, packed_buffer *, off64_t *);  #define g_asm_storage_store_instruction_data(s, b, p) \ -    _g_asm_storage_store_data(s, true, b, p) +    _g_asm_storage_store_data(s, SFT_INSTRUCTION, b, p)  #define g_asm_storage_store_operand_data(s, b, p) \ -    _g_asm_storage_store_data(s, false, b, p) +    _g_asm_storage_store_data(s, SFT_OPERAND, b, p) + +#define g_asm_storage_store_register_data(s, b, p) \ +    _g_asm_storage_store_data(s, SFT_REGISTER, b, p)  /* Lance une restauration complète d'unsauvegarde compressée. */  bool g_asm_storage_open(GAsmStorage *, GBinFormat *, wgroup_id_t); diff --git a/src/core/processors.c b/src/core/processors.c index 12c63cf..68fd0f6 100644 --- a/src/core/processors.c +++ b/src/core/processors.c @@ -31,9 +31,9 @@  #include "../arch/immediate.h"  #include "../arch/raw.h" -#include "../arch/register.h"  #include "../arch/target.h"  #include "../arch/undefined.h" +#include "../arch/operands/register.h"  //#include "../arch/jvm/processor.h" | 
