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" |