summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-28 17:37:46 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-28 17:37:46 (GMT)
commit9f5ed46de568d3db882c939c8ca9d0117bff3369 (patch)
tree9d2090cd640e54379dc1b982e03dc284b2d23ae7 /src/arch
parent2fd186a84cba4f39f6f1bb8bd34d52b4e1d4f814 (diff)
Relied on register objects as often as possible.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/Makefile.am5
-rw-r--r--src/arch/operands/Makefile.am23
-rw-r--r--src/arch/operands/register-int.h54
-rw-r--r--src/arch/operands/register.c382
-rw-r--r--src/arch/operands/register.h69
-rw-r--r--src/arch/register-int.h30
-rw-r--r--src/arch/register.c285
-rw-r--r--src/arch/register.h41
-rw-r--r--src/arch/storage.c76
-rw-r--r--src/arch/storage.h27
10 files changed, 685 insertions, 307 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(&reg_pbuf);
+
+ result = g_asm_storage_load_register_data(storage, &reg_pbuf, pos);
+
+ if (result)
+ {
+ reg = g_arch_register_load(storage, &reg_pbuf);
+ result = (reg != NULL);
+ }
+
+ if (result)
+ operand->reg = reg;
+
+ exit_packed_buffer(&reg_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(&reg_pbuf);
+
+ result = g_arch_register_store(operand->reg, storage, &reg_pbuf);
+
+ if (result)
+ result = g_asm_storage_store_register_data(storage, &reg_pbuf, &pos);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
+
+ exit_packed_buffer(&reg_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);