diff options
Diffstat (limited to 'plugins/arm/v7')
28 files changed, 2188 insertions, 1762 deletions
diff --git a/plugins/arm/v7/Makefile.am b/plugins/arm/v7/Makefile.am index 5d30876..d87373a 100644 --- a/plugins/arm/v7/Makefile.am +++ b/plugins/arm/v7/Makefile.am @@ -1,36 +1,35 @@ noinst_LTLIBRARIES = libarmv7.la -libarmv7_la_SOURCES = \ - arm.h arm.c \ - context.h context.c \ - core.h core.c \ - fetch.h fetch.c \ - helpers.h \ - instruction.h instruction.c \ - link.h link.c \ - post.h post.c \ - processor.h processor.c \ - pseudo.h pseudo.c \ - register-int.h \ - register.h register.c \ - thumb_16.h thumb_16.c \ +libarmv7_la_SOURCES = \ + arm.h arm.c \ + context.h context.c \ + core.h core.c \ + fetch.h fetch.c \ + helpers.h \ + instruction.h instruction.c \ + link.h link.c \ + operand-int.h \ + operand.h operand.c \ + post.h post.c \ + processor.h processor.c \ + pseudo.h pseudo.c \ + register-int.h \ + register.h register.c \ + thumb_16.h thumb_16.c \ thumb_32.h thumb_32.c -libarmv7_la_LIBADD = \ - opcodes/libarmv7opcodes.la \ - operands/libarmv7operands.la \ +libarmv7_la_LIBADD = \ + opcodes/libarmv7opcodes.la \ + operands/libarmv7operands.la \ registers/libarmv7registers.la +libarmv7_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src + devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libarmv7_la_SOURCES:%c=) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - - SUBDIRS = opdefs opcodes operands registers diff --git a/plugins/arm/v7/instruction.c b/plugins/arm/v7/instruction.c index 30a5bd8..eb4a082 100644 --- a/plugins/arm/v7/instruction.c +++ b/plugins/arm/v7/instruction.c @@ -97,6 +97,17 @@ static bool g_armv7_instruction_serialize(GArmV7Instruction *, GAsmStorage *, pa +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_instruction_load(GArmV7Instruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_instruction_store(GArmV7Instruction *, GObjectStorage *, packed_buffer_t *); + + + /* Indique le type défini pour une représentation d'une instruction ARMv7. */ G_DEFINE_TYPE(GArmV7Instruction, g_armv7_instruction, G_TYPE_ARM_INSTRUCTION); @@ -132,6 +143,9 @@ static void g_armv7_instruction_class_init(GArmV7InstructionClass *klass) instr->unserialize = (unserialize_instruction_fc)g_armv7_instruction_unserialize; instr->serialize = (serialize_instruction_fc)g_armv7_instruction_serialize; + instr->load = (load_instruction_fc)g_armv7_instruction_load; + instr->store = (store_instruction_fc)g_armv7_instruction_store; + } @@ -506,3 +520,98 @@ static bool g_armv7_instruction_serialize(GArmV7Instruction *instr, GAsmStorage return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : instr = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un contenu depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_instruction_load(GArmV7Instruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + uleb128_t value; /* Valeur ULEB128 à charger */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + + result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf); + + if (result) + result = unpack_uleb128(&value, pbuf); + + if (result) + instr->sid = value; + + if (result) + result = extract_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + + if (result) + { + result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + + if (result) + instr->setflags = (boolean == 1 ? true : false); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un contenu dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_instruction_store(GArmV7Instruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchInstructionClass *parent; /* Classe parente à consulter */ + uint8_t boolean; /* Valeur booléenne */ + + parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + + result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf); + + if (result) + result = pack_uleb128((uleb128_t []){ instr->sid }, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + + if (result) + { + boolean = (instr->setflags ? 1 : 0); + result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + } + + return result; + +} diff --git a/plugins/arm/v7/opcodes/Makefile.am b/plugins/arm/v7/opcodes/Makefile.am index 7a35ff9..c7fa4cc 100644 --- a/plugins/arm/v7/opcodes/Makefile.am +++ b/plugins/arm/v7/opcodes/Makefile.am @@ -13,7 +13,7 @@ noinst_LTLIBRARIES = libarmv7opcodes.la libarmv7opcodes_la_SOURCES = $(GENERATED_FILES) -libarmv7opcodes_la_LIBADD = +libarmv7opcodes_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src devdir = $(includedir)/chrysalide/$(subdir) @@ -21,11 +21,6 @@ devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libarmv7opcodes_la_SOURCES:%c=) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -I$(top_srcdir)/src - - CLEANFILES = $(GENERATED_FILES) dist-hook: diff --git a/plugins/arm/v7/operand-int.h b/plugins/arm/v7/operand-int.h new file mode 100644 index 0000000..1832c32 --- /dev/null +++ b/plugins/arm/v7/operand-int.h @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand-int.h - prototypes pour la définition interne des opérandes ARMv7 + * + * Copyright (C) 2021 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 _PLUGINS_ARM_V7_OPERAND_INT_H +#define _PLUGINS_ARM_V7_OPERAND_INT_H + + +#include "operand.h" + + +#include <arch/operand-int.h> + + + +/* Définition générique d'un opérande ARMv7 (instance) */ +struct _GArmV7Operand +{ + GArchOperand parent; /* A laisser en premier */ + +}; + +/* Définition générique d'un opérande ARMv7 (classe) */ +struct _GArmV7OperandClass +{ + GArchOperandClass parent; /* A laisser en premier */ + +}; + + + +#endif /* _PLUGINS_ARM_V7_OPERAND_INT_H */ diff --git a/plugins/arm/v7/operand.c b/plugins/arm/v7/operand.c new file mode 100644 index 0000000..ad7b572 --- /dev/null +++ b/plugins/arm/v7/operand.c @@ -0,0 +1,188 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand.c - opérandes ARMv7 + * + * Copyright (C) 2021 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 "operand.h" + + +#include "operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Initialise la classe des affichages de boutisme. */ +static void g_armv7_operand_class_init(GArmV7OperandClass *); + +/* Initialise une instance d'affichage de boutisme. */ +static void g_armv7_operand_init(GArmV7Operand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_operand_dispose(GArmV7Operand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_operand_finalize(GArmV7Operand *); + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_operand_hash(const GArmV7Operand *, bool); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour une de domaine et d'accès. */ +G_DEFINE_TYPE(GArmV7Operand, g_armv7_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des affichages de boutisme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_operand_class_init(GArmV7OperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_operand_finalize; + + operand = G_ARCH_OPERAND_CLASS(klass); + + operand->hash = (operand_hash_fc)g_armv7_operand_hash; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'affichage de boutisme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_operand_init(GArmV7Operand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_operand_dispose(GArmV7Operand *operand) +{ + G_OBJECT_CLASS(g_armv7_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_operand_finalize(GArmV7Operand *operand) +{ + G_OBJECT_CLASS(g_armv7_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_armv7_operand_hash(const GArmV7Operand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + operand_extra_data_t *extra; /* Données insérées à modifier */ + GArchOperandClass *class; /* Classe parente normalisée */ + + extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand)); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_armv7_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} diff --git a/plugins/arm/v7/operand.h b/plugins/arm/v7/operand.h new file mode 100644 index 0000000..8c80365 --- /dev/null +++ b/plugins/arm/v7/operand.h @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * operand.h - prototypes pour les opérandes ARMv7 + * + * Copyright (C) 2017-2018 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 _PLUGINS_ARM_V7_OPERAND_H +#define _PLUGINS_ARM_V7_OPERAND_H + + +#include <glib-object.h> + + +#include <arch/operand.h> + + + +#define G_TYPE_ARMV7_OPERAND g_armv7_operand_get_type() +#define G_ARMV7_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OPERAND, GArmV7Operand)) +#define G_IS_ARMV7_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OPERAND)) +#define G_ARMV7_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_OPERAND, GArmV7OperandClass)) +#define G_IS_ARMV7_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_OPERAND)) +#define G_ARMV7_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_OPERAND, GArmV7OperandClass)) + + +/* Définition générique d'un opérande ARMv7 (instance) */ +typedef struct _GArmV7Operand GArmV7Operand; + +/* Définition générique d'un opérande ARMv7 (classe) */ +typedef struct _GArmV7OperandClass GArmV7OperandClass; + + +/* Indique le type défini par la GLib pour un opérande ARMv7. */ +GType g_armv7_operand_get_type(void); + + + +#endif /* _PLUGINS_ARM_V7_OPERAND_H */ diff --git a/plugins/arm/v7/operands/Makefile.am b/plugins/arm/v7/operands/Makefile.am index 31f6a8a..fa7ab8b 100644 --- a/plugins/arm/v7/operands/Makefile.am +++ b/plugins/arm/v7/operands/Makefile.am @@ -1,26 +1,21 @@ noinst_LTLIBRARIES = libarmv7operands.la -libarmv7operands_la_SOURCES = \ - estate.h estate.c \ - iflags.h iflags.c \ - it.h it.c \ - limitation.h limitation.c \ - maccess.h maccess.c \ - offset.h offset.c \ - register.h register.c \ - reglist.h reglist.c \ - rotation.h rotation.c \ +libarmv7operands_la_SOURCES = \ + estate.h estate.c \ + iflags.h iflags.c \ + it.h it.c \ + limitation.h limitation.c \ + maccess.h maccess.c \ + offset.h offset.c \ + register.h register.c \ + reglist.h reglist.c \ + rotation.h rotation.c \ shift.h shift.c -libarmv7operands_la_LIBADD = +libarmv7operands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libarmv7operands_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/arm/v7/operands/estate.c b/plugins/arm/v7/operands/estate.c index a76b464..accde6d 100644 --- a/plugins/arm/v7/operands/estate.c +++ b/plugins/arm/v7/operands/estate.c @@ -24,18 +24,20 @@ #include "estate.h" -#include <arch/operand-int.h> -#include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + /* Définition d'un opérande affichant le choix d'un boutisme (instance) */ struct _GArmV7EndianOperand { - GArchOperand parent; /* Instance parente */ - - bool big; /* Grand boutisme à afficher ? */ + GArmV7Operand parent; /* Instance parente */ }; @@ -43,7 +45,7 @@ struct _GArmV7EndianOperand /* Définition d'un opérande affichant le choix d'un boutisme (classe) */ struct _GArmV7EndianOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -60,27 +62,23 @@ static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *); -/* Compare un opérande avec un autre. */ -static int g_armv7_endian_operand_compare(const GArmV7EndianOperand *, const GArmV7EndianOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_endian_operand_unserialize(GArmV7EndianOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une endian de domaine et d'accès. */ -G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -106,12 +104,8 @@ static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_endian_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_armv7_endian_operand_finalize; - operand->compare = (operand_compare_fc)g_armv7_endian_operand_compare; operand->print = (operand_print_fc)g_armv7_endian_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_endian_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_endian_operand_serialize; - } @@ -173,53 +167,6 @@ static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *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_armv7_endian_operand_compare(const GArmV7EndianOperand *a, const GArmV7EndianOperand *b) -{ - int result; /* Bilan à faire remonter */ - - result = sort_boolean(a->big, b->big); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line) -{ - if (operand->big) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL); - else - g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : big = indication sur le boutisme à représenter. * * * * Description : Crée une représentation de boutisme ARMv7. * @@ -236,107 +183,38 @@ GArchOperand *g_armv7_endian_operand_new(bool big) result = g_object_new(G_TYPE_ARMV7_ENDIAN_OPERAND, NULL); - result->big = big; + if (big) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7ESOF_BIG); return G_ARCH_OPERAND(result); } -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le type de boutisme représenté. * -* * -* Retour : Type de boutisme. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *operand) -{ - return operand->big; - -} - - /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* 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_armv7_endian_operand_unserialize(GArmV7EndianOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t big; /* Grand boutisme à afficher ? */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - result = extract_packed_buffer(pbuf, &big, sizeof(uint8_t), false); - - if (result) - operand->big = (big == 1 ? true : false); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_endian_operand_serialize(const GArmV7EndianOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t big; /* Grand boutisme à afficher ? */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_endian_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - { - big = (operand->big ? 1 : 0); - result = extend_packed_buffer(pbuf, &big, sizeof(uint8_t), false); - } - - return result; + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ESOF_BIG)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD, NULL); + else + g_buffer_line_append_text(line, DLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD, NULL); } diff --git a/plugins/arm/v7/operands/estate.h b/plugins/arm/v7/operands/estate.h index d049357..9b75f9c 100644 --- a/plugins/arm/v7/operands/estate.h +++ b/plugins/arm/v7/operands/estate.h @@ -32,6 +32,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7EStateOpFlag +{ + A7ESOF_BIG = AOF_USER_FLAG(0), /* Grand boutisme à afficher ? */ + +} A7EStateOpFlag; + + #define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type() #define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperand)) #define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_ENDIAN_OPERAND)) @@ -53,9 +61,6 @@ GType g_armv7_endian_operand_get_type(void); /* Crée une représentation de boutisme ARMv7. */ GArchOperand *g_armv7_endian_operand_new(bool); -/* Indique le type de boutisme représenté. */ -bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *); - #endif /* _PLUGINS_ARM_V7_OPERANDS_ESTATE_H */ diff --git a/plugins/arm/v7/operands/iflags.c b/plugins/arm/v7/operands/iflags.c index 019fd21..f0a5e07 100644 --- a/plugins/arm/v7/operands/iflags.c +++ b/plugins/arm/v7/operands/iflags.c @@ -24,19 +24,20 @@ #include "iflags.h" -#include <arch/operand-int.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + /* Définition d'un opérande précisant un masque d'interruption ARMv7 (instance) */ struct _GArmV7IFlagsOperand { - GArchOperand parent; /* Instance parente */ - - bool abort_bit; /* Interruption d'arrêt async. */ - bool irq_bit; /* Interruption IRQ */ - bool fiq_bit; /* Interruption FIQ */ + GArmV7Operand parent; /* Instance parente */ }; @@ -44,7 +45,7 @@ struct _GArmV7IFlagsOperand /* Définition d'un opérande précisant un masque d'interruption ARMv7 (classe) */ struct _GArmV7IFlagsOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -61,24 +62,22 @@ static void g_armv7_iflags_operand_dispose(GArmV7IFlagsOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *); -/* Traduit un opérande en version humainement lisible. */ -static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *, GBufferLine *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un opérande de masque d'interruption ARMv7. */ -G_DEFINE_TYPE(GArmV7IFlagsOperand, g_armv7_iflags_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7IFlagsOperand, g_armv7_iflags_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -107,9 +106,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass) operand->print = (operand_print_fc)g_armv7_iflags_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_iflags_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_iflags_operand_serialize; - } @@ -127,9 +123,6 @@ static void g_armv7_iflags_operand_class_init(GArmV7IFlagsOperandClass *klass) static void g_armv7_iflags_operand_init(GArmV7IFlagsOperand *operand) { - operand->abort_bit = false; - operand->irq_bit = false; - operand->fiq_bit = false; } @@ -174,33 +167,6 @@ static void g_armv7_iflags_operand_finalize(GArmV7IFlagsOperand *operand) /****************************************************************************** * * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line) -{ - if (operand->abort_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL); - - if (operand->irq_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL); - - if (operand->fiq_bit) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : a = bit d'arrêt asynchrone. * * i = bit d'interruption IRQ. * * f = bit d'interruption FIQ. * @@ -219,119 +185,48 @@ GArchOperand *g_armv7_iflags_operand_new(bool a, bool i, bool f) result = g_object_new(G_TYPE_ARMV7_IFLAGS_OPERAND, NULL); - result->abort_bit = a; - result->irq_bit = i; - result->fiq_bit = f; + if (a) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_ABORT); + + if (i) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_IRQ); + + if (f) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7IFOF_FIQ); return G_ARCH_OPERAND(result); } + /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* 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_armv7_iflags_operand_unserialize(GArmV7IFlagsOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->abort_bit = (boolean == 1 ? true : false); - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->irq_bit = (boolean == 1 ? true : false); - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->fiq_bit = (boolean == 1 ? true : false); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Traduit un opérande en version humainement lisible. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_iflags_operand_serialize(const GArmV7IFlagsOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_iflags_operand_print(const GArmV7IFlagsOperand *operand, GBufferLine *line) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_iflags_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - { - boolean = (operand->abort_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } - - if (result) - { - boolean = (operand->irq_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_ABORT)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "A", 1, RTT_REGISTER, NULL); - if (result) - { - boolean = (operand->fiq_bit ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_IRQ)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "I", 1, RTT_REGISTER, NULL); - return result; + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7IFOF_FIQ)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "F", 1, RTT_REGISTER, NULL); } diff --git a/plugins/arm/v7/operands/iflags.h b/plugins/arm/v7/operands/iflags.h index c0155a1..a198c85 100644 --- a/plugins/arm/v7/operands/iflags.h +++ b/plugins/arm/v7/operands/iflags.h @@ -33,6 +33,16 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7IFlagsOpFlag +{ + A7IFOF_ABORT = AOF_USER_FLAG(0), /* Interruption d'arrêt async. */ + A7IFOF_IRQ = AOF_USER_FLAG(1), /* Interruption IRQ */ + A7IFOF_FIQ = AOF_USER_FLAG(2), /* Interruption FIQ */ + +} A7IFlagsOpFlag; + + #define G_TYPE_ARMV7_IFLAGS_OPERAND g_armv7_iflags_operand_get_type() #define G_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_IFLAGS_OPERAND, GArmV7IFlagsOperand)) #define G_IS_ARMV7_IFLAGS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_IFLAGS_OPERAND)) diff --git a/plugins/arm/v7/operands/it.c b/plugins/arm/v7/operands/it.c index 6fab598..46e1b4c 100644 --- a/plugins/arm/v7/operands/it.c +++ b/plugins/arm/v7/operands/it.c @@ -27,27 +27,55 @@ #include <assert.h> -#include <arch/operand-int.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" -/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */ -struct _GArmV7ITCondOperand + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7itcop_extra_data_t { - GArchOperand parent; /* Instance parente */ + operand_extra_data_t parent; /* A laisser en premier */ ArmCondCode firstcond; /* Condition première */ uint8_t mask; /* Masque de l'interprétation */ +} a7itcop_extra_data_t; + + +/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */ +struct _GArmV7ITCondOperand +{ + GArmV7Operand parent; /* Instance parente */ + }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_ITCOND_OP_EXTRA(op) ((a7itcop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_ARMV7_ITCOND_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7itcop_extra_data_t) + +#endif + + /* Définition d'un opérande organisant l'application d'une instruction IT (classe) */ struct _GArmV7ITCondOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -64,27 +92,35 @@ static void g_armv7_itcond_operand_dispose(GArmV7ITCondOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *); +static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GArmV7ITCondOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour l'application d'une instruction IT. */ -G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -105,16 +141,20 @@ static void g_armv7_itcond_operand_class_init(GArmV7ITCondOperandClass *klass) GArchOperandClass *operand; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_itcond_operand_dispose; object->finalize = (GObjectFinalizeFunc)g_armv7_itcond_operand_finalize; + operand = G_ARCH_OPERAND_CLASS(klass); + operand->compare = (operand_compare_fc)g_armv7_itcond_operand_compare; + operand->print = (operand_print_fc)g_armv7_itcond_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_itcond_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_itcond_operand_serialize; + operand->hash = (operand_hash_fc)g_armv7_itcond_operand_hash; + + operand->load = (load_operand_fc)g_armv7_itcond_operand_load; + operand->store = (store_operand_fc)g_armv7_itcond_operand_store; } @@ -177,8 +217,100 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : firstcond = valeur brute de la condition d'exécution. * +* mask = masque d'interprétation pour l'instruction. * +* * +* Description : Crée un opérande lié à une instruction IT. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask) +{ + GArmV7ITCondOperand *result; /* Structure à retourner */ + a7itcop_extra_data_t *extra; /* Données insérées à modifier */ + + if (firstcond > ACC_NV) + return NULL; + + result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL); + + extra = GET_ARMV7_ITCOND_OP_EXTRA(result); + + extra->firstcond = firstcond; + extra->mask = mask; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Fournit la condition associée à l'opérande. * +* * +* Retour : Condition classique pour ARMv7. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand) +{ + ArmCondCode result; /* Condition à renvoyer */ + a7itcop_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); + + result = extra->firstcond; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Fournit le masque d'interprétation de la condition. * +* * +* Retour : Masque de bits. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) +{ + uint8_t result; /* Valeur à retourner */ + a7itcop_extra_data_t *extra; /* Données insérées à modifier */ + + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); + + result = extra->mask; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -188,14 +320,38 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand) * * ******************************************************************************/ -static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b) +static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + a7itcop_extra_data_t *ea; /* Données insérées à consulter*/ + a7itcop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + ea = GET_ARMV7_ITCOND_OP_EXTRA(a); + eb = GET_ARMV7_ITCOND_OP_EXTRA(b); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + + result = sort_boolean(ea->firstcond, eb->firstcond); - result = sort_boolean(a->firstcond, b->firstcond); + if (result == 0) + result = sort_unsigned_long(ea->mask, eb->mask); if (result == 0) - result = sort_unsigned_long(a->mask, b->mask); + { + class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; @@ -217,9 +373,12 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GA static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBufferLine *line) { + a7itcop_extra_data_t *extra; /* Données insérées à consulter*/ const char *kw; /* Mot clef à imprimer */ - switch (operand->firstcond) + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); + + switch (extra->firstcond) { case ACC_EQ: kw = "EQ"; break; case ACC_NE: kw = "NE"; break; @@ -253,51 +412,37 @@ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBu /****************************************************************************** * * -* Paramètres : firstcond = valeur brute de la condition d'exécution. * -* mask = masque d'interprétation pour l'instruction. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Crée un opérande lié à une instruction IT. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Opérande mis en place. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask) +static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *operand, bool lock) { - GArmV7ITCondOperand *result; /* Structure à retourner */ + guint result; /* Valeur à retourner */ + a7itcop_extra_data_t *extra; /* Données internes à manipuler*/ + GArchOperandClass *class; /* Classe parente normalisée */ - if (firstcond > ACC_NV) - return NULL; + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); - result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL); + if (lock) + LOCK_GOBJECT_EXTRA(extra); - result->firstcond = firstcond; - result->mask = mask; + class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - return G_ARCH_OPERAND(result); + result ^= extra->firstcond; -} + result ^= extra->mask; - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Fournit la condition associée à l'opérande. * -* * -* Retour : Condition classique pour ARMv7. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand) -{ - ArmCondCode result; /* Condition à renvoyer */ - - result = operand->firstcond; + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); return result; @@ -306,41 +451,11 @@ ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *oper /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Fournit le masque d'interprétation de la condition. * -* * -* Retour : Masque de bits. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Remarques : - * -* * -******************************************************************************/ - -uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) -{ - uint8_t result; /* Valeur à retourner */ - - result = operand->mask; - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -348,20 +463,30 @@ uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand) * * ******************************************************************************/ -static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + uleb128_t value; /* Valeur ULEB128 à charger */ + a7itcop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true); + { + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); - if (result) - result = extract_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false); + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->firstcond = value; + + if (result) + result = extract_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false); + + } return result; @@ -370,11 +495,11 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -382,20 +507,26 @@ static bool g_armv7_itcond_operand_unserialize(GArmV7ITCondOperand *operand, GAs * * ******************************************************************************/ -static bool g_armv7_itcond_operand_serialize(const GArmV7ITCondOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7itcop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true); + { + extra = GET_ARMV7_ITCOND_OP_EXTRA(operand); - if (result) - result = extend_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false); + result = pack_uleb128((uleb128_t []){ extra->firstcond }, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false); + + } return result; diff --git a/plugins/arm/v7/operands/limitation.c b/plugins/arm/v7/operands/limitation.c index 0d29545..d9e11cf 100644 --- a/plugins/arm/v7/operands/limitation.c +++ b/plugins/arm/v7/operands/limitation.c @@ -26,28 +26,57 @@ #include <arch/operand-int.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" -/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ -struct _GArmV7LimitationOperand + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7limop_extra_data_t { - GArchOperand parent; /* Instance parente */ + operand_extra_data_t parent; /* A laisser en premier */ BarrierLimitationType type; /* Type de limitation */ +} a7limop_extra_data_t; + + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ +struct _GArmV7LimitationOperand +{ + GArmV7Operand parent; /* Instance parente */ + }; /* Définition d'un opérande déterminant une limitation de domaine et d'accès (classe) */ struct _GArmV7LimitationOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_LIMITATION_OP_EXTRA(op) ((a7limop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_ARMV7_LIMITATION_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7limop_extra_data_t) + +#endif + + /* Initialise la classe des co-processeurs ARM. */ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *); @@ -60,27 +89,35 @@ static void g_armv7_limitation_operand_dispose(GArmV7LimitationOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *); +static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *, const GArmV7LimitationOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */ -G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -107,10 +144,13 @@ static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass * object->finalize = (GObjectFinalizeFunc)g_armv7_limitation_operand_finalize; operand->compare = (operand_compare_fc)g_armv7_limitation_operand_compare; + operand->print = (operand_print_fc)g_armv7_limitation_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_limitation_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_limitation_operand_serialize; + operand->hash = (operand_hash_fc)g_armv7_limitation_operand_hash; + + operand->load = (load_operand_fc)g_armv7_limitation_operand_load; + operand->store = (store_operand_fc)g_armv7_limitation_operand_store; } @@ -173,8 +213,77 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : raw = valeur brute de la limitation à considérer. * +* * +* Description : Crée une représentation d'une limitation pour barrière. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +{ + GArmV7LimitationOperand *result; /* Structure à retourner */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ + + result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + + extra = GET_ARMV7_LIMITATION_OP_EXTRA(result); + + if (raw < 0b0010 || raw > 0b1111) + extra->type = BLT_RESERVED; + + else + extra->type = raw; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique le type de limitation représentée. * +* * +* Retour : Type de limitation d'accès et de domaine. * +* * +* Remarques : - * +* * +******************************************************************************/ + +BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand) +{ + BarrierLimitationType result; /* Type à retourner */ + a7limop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->type; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -184,11 +293,35 @@ static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand * * ******************************************************************************/ -static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b) +static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, const GArmV7LimitationOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + a7limop_extra_data_t *ea; /* Données insérées à consulter*/ + a7limop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ - result = sort_unsigned_long(a->type, b->type); + ea = GET_ARMV7_LIMITATION_OP_EXTRA(a); + eb = GET_ARMV7_LIMITATION_OP_EXTRA(b); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + + result = sort_unsigned_long(ea->type, eb->type); + + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; @@ -210,7 +343,11 @@ static int g_armv7_limitation_operand_compare(const GArmV7LimitationOperand *a, static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *operand, GBufferLine *line) { - switch (operand->type) + BarrierLimitationType type; /* Type porté par l'opérande */ + + type = g_armv7_limitation_operand_get_value(operand); + + switch (type) { case BLT_SY: g_buffer_line_append_text(line, DLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD, NULL); @@ -255,66 +392,48 @@ static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *oper /****************************************************************************** * * -* Paramètres : raw = valeur brute de la limitation à considérer. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Crée une représentation d'une limitation pour barrière. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Opérande mis en place. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +static guint g_armv7_limitation_operand_hash(const GArmV7LimitationOperand *operand, bool lock) { - GArmV7LimitationOperand *result; /* Structure à retourner */ + guint result; /* Valeur à retourner */ + a7limop_extra_data_t *extra; /* Données internes à manipuler*/ + GArchOperandClass *class; /* Classe parente normalisée */ - result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); - if (raw < 0b0010 || raw > 0b1111) - result->type = BLT_RESERVED; + if (lock) + LOCK_GOBJECT_EXTRA(extra); - else - result->type = raw; + class = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - return G_ARCH_OPERAND(result); + result ^= extra->type; -} + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le type de limitation représentée. * -* * -* Retour : Type de limitation d'accès et de domaine. * -* * -* Remarques : - * -* * -******************************************************************************/ - -BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand) -{ - return operand->type; + return result; } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -322,17 +441,27 @@ BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7Limitatio * * ******************************************************************************/ -static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_limitation_operand_load(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extract_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + result = unpack_uleb128(&value, pbuf); + + if (result) + extra->type = value; + + } return result; @@ -341,11 +470,11 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -353,17 +482,23 @@ static bool g_armv7_limitation_operand_unserialize(GArmV7LimitationOperand *oper * * ******************************************************************************/ -static bool g_armv7_limitation_operand_serialize(const GArmV7LimitationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_limitation_operand_store(GArmV7LimitationOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7limop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_armv7_limitation_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->type, sizeof(BarrierLimitationType), true); + { + extra = GET_ARMV7_LIMITATION_OP_EXTRA(operand); + + result = pack_uleb128((uleb128_t []){ extra->type }, pbuf); + + } return result; diff --git a/plugins/arm/v7/operands/maccess.c b/plugins/arm/v7/operands/maccess.c index 07f38a6..77d031f 100644 --- a/plugins/arm/v7/operands/maccess.c +++ b/plugins/arm/v7/operands/maccess.c @@ -29,24 +29,26 @@ #include <stdlib.h> -#include <arch/operand-int.h> #include <common/cpp.h> -#include <common/sort.h> +#include <core/columns.h> #include <core/logs.h> -#include <gtkext/gtkblockdisplay.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + /* Définition d'un opérande offrant un accès à la mémoire depuis une base (instance) */ struct _GArmV7MAccessOperand { - GArchOperand parent; /* Instance parente */ + GArmV7Operand parent; /* Instance parente */ GArchOperand *base; /* Base de l'accès en mémoire */ GArchOperand *offset; /* Décalage pour l'adresse */ GArchOperand *shift; /* Décalage supplémentaire ? */ - bool post_indexed; /* Position du décalage */ - bool write_back; /* Mise à jour de la base */ }; @@ -54,7 +56,7 @@ struct _GArmV7MAccessOperand /* Définition d'un opérande offrant un accès à la mémoire depuis une base (classe) */ struct _GArmV7MAccessOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -71,8 +73,13 @@ static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *); +static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *, const GArmV7MAccessOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_maccess_operand_find_inner_operand_path(const GArmV7MAccessOperand *, const GArchOperand *); @@ -83,21 +90,24 @@ static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const G /* Traduit un opérande en version humainement lisible. */ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *, GBufferLine *); +/* Fournit une liste de candidats embarqués par un candidat. */ +static GArchOperand **g_armv7_maccess_operand_list_inner_instances(const GArmV7MAccessOperand *, size_t *); +/* Met à jour une liste de candidats embarqués par un candidat. */ +static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand *, GArchOperand **, size_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *, bool); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un accès à la mémoire depuis une base. */ -G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7MAccessOperand, g_armv7_maccess_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -130,8 +140,12 @@ static void g_armv7_maccess_operand_class_init(GArmV7MAccessOperandClass *klass) operand->print = (operand_print_fc)g_armv7_maccess_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_maccess_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_maccess_operand_serialize; + operand->list_inner = (operand_list_inners_fc)g_armv7_maccess_operand_list_inner_instances; + operand->update_inner = (operand_update_inners_fc)g_armv7_maccess_operand_update_inner_instances; + operand->hash = (operand_hash_fc)g_armv7_maccess_operand_hash; + + operand->load = g_arch_operand_load_generic_fixed_3; + operand->store = g_arch_operand_store_generic_fixed; } @@ -171,14 +185,9 @@ static void g_armv7_maccess_operand_init(GArmV7MAccessOperand *operand) static void g_armv7_maccess_operand_dispose(GArmV7MAccessOperand *operand) { - if (operand->base != NULL) - g_object_unref(G_OBJECT(operand->base)); - - if (operand->offset != NULL) - g_object_unref(G_OBJECT(operand->offset)); - - if (operand->shift != NULL) - g_object_unref(G_OBJECT(operand->shift)); + g_clear_object(&operand->base); + g_clear_object(&operand->offset); + g_clear_object(&operand->shift); G_OBJECT_CLASS(g_armv7_maccess_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -206,8 +215,109 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : base = représente le registre de la base d'accès. * +* offset = détermine le décalage entre l'adresse et la base. * +* shift = opération de décalage pour jouer sur le décalage. * +* post = précise la forme donnée au décalage à appliquer. * +* wback = indique une mise à jour de la base après usage. * +* * +* Description : Crée un accès à la mémoire depuis une base et un décalage. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback) +{ + GArmV7MAccessOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL); + + result->base = base; + result->offset = offset; + result->shift = shift; + + if (post) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_POST_INDEXED); + + if (wback) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7MAOF_WRITE_BACK); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la base d'un accès à la mémoire. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand) +{ + return operand->base; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit le décalage d'un accès à la mémoire depuis la base. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand) +{ + return operand->offset; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit le décalage d'un décalage pour un accès mémoire. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand) +{ + return operand->shift; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -217,25 +327,24 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) * * ******************************************************************************/ -static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b) +static int g_armv7_maccess_operand_compare(const GArmV7MAccessOperand *a, const GArmV7MAccessOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->base, b->base); - if (result != 0) goto gamoc_done; - - result = sort_pointer(a->offset, b->offset, (__compar_fn_t)g_arch_operand_compare); - if (result != 0) goto gamoc_done; - - result = sort_pointer(a->shift, b->shift, (__compar_fn_t)g_arch_operand_compare); - if (result != 0) goto gamoc_done; - result = sort_boolean(a->post_indexed, b->post_indexed); - if (result != 0) goto gamoc_done; + if (result) + result = g_arch_operand_compare(a->offset, b->offset); - result = sort_boolean(a->write_back, b->write_back); + if (result) + result = g_arch_operand_compare(a->shift, b->shift); - gamoc_done: + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } return result; @@ -392,11 +501,17 @@ static GArchOperand *g_armv7_maccess_operand_get_inner_operand_from_path(const G static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, GBufferLine *line) { + bool post; /* Forme post-indexée ? */ + bool wback; /* Ecriture après coup ? */ + + post = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_POST_INDEXED); + wback = g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7MAOF_WRITE_BACK); + g_buffer_line_append_text(line, DLC_ASSEMBLY, "[", 1, RTT_HOOK, NULL); g_arch_operand_print(operand->base, line); - if (operand->post_indexed) + if (post) g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); if (operand->offset != NULL) @@ -417,10 +532,10 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G } - if (!operand->post_indexed) + if (!post) g_buffer_line_append_text(line, DLC_ASSEMBLY, "]", 1, RTT_HOOK, NULL); - if (operand->post_indexed && operand->write_back) + if (post && wback) g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); } @@ -428,306 +543,169 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G /****************************************************************************** * * -* Paramètres : base = représente le registre de la base d'accès. * -* offset = détermine le décalage entre l'adresse et la base. * -* shift = opération de décalage pour jouer sur le décalage. * -* post = précise la forme donnée au décalage à appliquer. * -* wback = indique une mise à jour de la base après usage. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Crée un accès à la mémoire depuis une base et un décalage. * +* Description : Fournit une liste de candidats embarqués par un candidat. * * * -* Retour : Opérande mis en place. * +* Retour : Liste de candidats internes ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool post, bool wback) +static GArchOperand **g_armv7_maccess_operand_list_inner_instances(const GArmV7MAccessOperand *operand, size_t *count) { - GArmV7MAccessOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_MACCESS_OPERAND, NULL); - - result->base = base; - result->offset = offset; - result->shift = shift; - - result->post_indexed = post; - result->write_back = wback; - - return G_ARCH_OPERAND(result); - -} + GArchOperand **result; /* Instances à retourner */ + size_t idx; /* Indice de traitement */ + *count = 1; -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la base d'un accès à la mémoire. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *operand) -{ - return operand->base; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit le décalage d'un accès à la mémoire depuis la base. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *operand) -{ - return operand->offset; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit le décalage d'un décalage pour un accès mémoire. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *operand) -{ - return operand->shift; + if (operand->offset != NULL) + (*count)++; -} + if (operand->shift != NULL) + (*count)++; + result = malloc(*count * sizeof(GArchOperand *)); -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique si le décalage est post-indexé. * -* * -* Retour : Statut des opérations menées. * -* * -* Remarques : - * -* * -******************************************************************************/ + result[0] = operand->base; + g_object_ref(G_OBJECT(result[0])); -bool g_armv7_maccess_operand_is_post_indexed(const GArmV7MAccessOperand *operand) -{ - return operand->post_indexed; + if (operand->offset != NULL) + { + result[1] = operand->offset; + g_object_ref(G_OBJECT(result[1])); -} + idx = 2; + } + else + idx = 1; -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique si la base est mise à jour après usage. * -* * -* Retour : Statut des opérations menées. * -* * -* Remarques : - * -* * -******************************************************************************/ + if (operand->shift != NULL) + { + result[idx] = operand->shift; + g_object_ref(G_OBJECT(result[idx])); + } -bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *operand) -{ - return operand->write_back; + return result; } - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* instances = liste de candidats internes devenus singletons. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Met à jour une liste de candidats embarqués par un candidat. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_maccess_operand_unserialize(GArmV7MAccessOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static void g_armv7_maccess_operand_update_inner_instances(GArmV7MAccessOperand *operand, GArchOperand **instances, size_t count) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *subop; /* Sous-opérande à intégrer */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - subop = g_arch_operand_load(storage, format, pbuf); - - if (subop == NULL) - result = false; - - else - operand->base = subop; - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result && boolean == 1) - { - subop = g_arch_operand_load(storage, format, pbuf); +#ifndef NDEBUG + size_t idx_check; /* Décompte des éléments utiles*/ +#endif + size_t i; /* Boucle de parcours */ - if (subop == NULL) - result = false; +#ifndef NDEBUG + idx_check = 1; - else - operand->offset = subop; + if (operand->offset != NULL) + (idx_check)++; - } + if (operand->shift != NULL) + (idx_check)++; - } + assert(count == idx_check); +#endif - if (result) + for (i = 0; i < count; i++) { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result && boolean == 1) + switch (i) { - subop = g_arch_operand_load(storage, format, pbuf); - - if (subop == NULL) - result = false; - - else - operand->shift = subop; + case 0: + g_clear_object(&operand->base); + operand->base = instances[i]; + break; + + case 1: + if (operand->offset != NULL) + { + g_clear_object(&operand->offset); + operand->offset = instances[i]; + } + else + { + assert(count == 2); + + g_clear_object(&operand->shift); + operand->shift = instances[i]; + + } + break; + + case 2: + g_clear_object(&operand->shift); + operand->shift = instances[i]; + break; } - } - - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->post_indexed = (boolean == 1 ? true : false); + g_object_ref(G_OBJECT(instances[i])); } - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - - if (result) - operand->write_back = (boolean == 1 ? true : false); - - } - - return result; - } /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Bilan de l'opération. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_maccess_operand_serialize(const GArmV7MAccessOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static guint g_armv7_maccess_operand_hash(const GArmV7MAccessOperand *operand, bool lock) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - result = g_arch_operand_store(operand->base, storage, pbuf); - - if (result) - { - if (operand->offset == NULL) - result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); - - else - { - result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); + guint result; /* Valeur à retourner */ + operand_extra_data_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + size_t count; /* Quantité d'éléments utiles */ - if (result) - result = g_arch_operand_store(operand->offset, storage, pbuf); + extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand)); - } + if (lock) + LOCK_GOBJECT_EXTRA(extra); - } + class = G_ARCH_OPERAND_CLASS(g_armv7_maccess_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - if (result) - { - if (operand->shift == NULL) - result = extend_packed_buffer(pbuf, (uint8_t []) { 0 }, sizeof(uint8_t), false); + count = 1; - else - { - result = extend_packed_buffer(pbuf, (uint8_t []) { 1 }, sizeof(uint8_t), false); - - if (result) - result = g_arch_operand_store(operand->shift, storage, pbuf); - - } + if (operand->offset != NULL) + (count)++; - } + if (operand->shift != NULL) + (count)++; - if (result) - { - boolean = (operand->post_indexed ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + result ^= count; - if (result) - { - boolean = (operand->write_back ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); return result; diff --git a/plugins/arm/v7/operands/maccess.h b/plugins/arm/v7/operands/maccess.h index bc80cfa..eb39c30 100644 --- a/plugins/arm/v7/operands/maccess.h +++ b/plugins/arm/v7/operands/maccess.h @@ -36,6 +36,15 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7MAccessOpFlag +{ + A7MAOF_POST_INDEXED = AOF_USER_FLAG(0), /* Position du décalage */ + A7MAOF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour de la base */ + +} A7MAccessOpFlag; + + #define G_TYPE_ARMV7_MACCESS_OPERAND g_armv7_maccess_operand_get_type() #define G_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_MACCESS_OPERAND, GArmV7MAccessOperand)) #define G_IS_ARMV7_MACCESS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_MACCESS_OPERAND)) diff --git a/plugins/arm/v7/operands/offset.c b/plugins/arm/v7/operands/offset.c index 615e296..724523d 100644 --- a/plugins/arm/v7/operands/offset.c +++ b/plugins/arm/v7/operands/offset.c @@ -24,22 +24,26 @@ #include "offset.h" +#include <assert.h> #include <stdio.h> #include <string.h> -#include <arch/operand-int.h> -#include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + /* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (instance) */ struct _GArmV7OffsetOperand { - GArchOperand parent; /* Instance parente */ + GArmV7Operand parent; /* Instance parente */ - bool positive; /* Sens du décalage */ GArchOperand *value; /* Valeur du décalage */ }; @@ -48,7 +52,7 @@ struct _GArmV7OffsetOperand /* Définition d'un opérande visant à constituer un décalage relatif ARMv7 (classe) */ struct _GArmV7OffsetOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -65,8 +69,13 @@ static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *); +static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *, const GArmV7OffsetOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_offset_operand_find_inner_operand_path(const GArmV7OffsetOperand *, const GArchOperand *); @@ -77,21 +86,21 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA /* Traduit un opérande en version humainement lisible. */ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *, GBufferLine *); +/* Fournit une liste de candidats embarqués par un candidat. */ +static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *, size_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Met à jour une liste de candidats embarqués par un candidat. */ +static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *, GArchOperand **, size_t); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un décalage relatif ARMv7. */ -G_DEFINE_TYPE(GArmV7OffsetOperand, g_armv7_offset_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7OffsetOperand, g_armv7_offset_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -124,8 +133,11 @@ static void g_armv7_offset_operand_class_init(GArmV7OffsetOperandClass *klass) operand->print = (operand_print_fc)g_armv7_offset_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_offset_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_offset_operand_serialize; + operand->list_inner = (operand_list_inners_fc)g_armv7_offset_operand_list_inner_instances; + operand->update_inner = (operand_update_inners_fc)g_armv7_offset_operand_update_inner_instances; + + operand->load = g_arch_operand_load_generic_fixed_1; + operand->store = g_arch_operand_store_generic_fixed; } @@ -163,8 +175,7 @@ static void g_armv7_offset_operand_init(GArmV7OffsetOperand *operand) static void g_armv7_offset_operand_dispose(GArmV7OffsetOperand *operand) { - if (operand->value != NULL) - g_object_unref(G_OBJECT(operand->value)); + g_clear_object(&operand->value); G_OBJECT_CLASS(g_armv7_offset_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -192,8 +203,69 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : positive = indique si la quantité doit être ajoutée ou non. * +* value = valeur du décalage à appliquer. * +* * +* Description : Crée un décalage selon un sens et une valeur donnés. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value) +{ + GArmV7OffsetOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL); + + if (positive) + g_arch_operand_set_flag(G_ARCH_OPERAND(result), A7OOF_POSITIVE); + + result->value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour un décalage. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -203,16 +275,18 @@ static void g_armv7_offset_operand_finalize(GArmV7OffsetOperand *operand) * * ******************************************************************************/ -static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b) +static int g_armv7_offset_operand_compare(const GArmV7OffsetOperand *a, const GArmV7OffsetOperand *b, bool lock) { int result; /* Bilan à faire remonter */ - - result = sort_boolean(a->positive, b->positive); - if (result != 0) goto gaooc_done; + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->value, b->value); - gaooc_done: + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } return result; @@ -299,7 +373,7 @@ static GArchOperand *g_armv7_offset_operand_get_inner_operand_from_path(const GA static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBufferLine *line) { - if (!operand->positive) + if (!g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7OOF_POSITIVE)) g_buffer_line_append_text(line, DLC_ASSEMBLY, "-", 1, RTT_KEY_WORD, NULL); g_arch_operand_print(operand->value, line); @@ -309,127 +383,27 @@ static void g_armv7_offset_operand_print(const GArmV7OffsetOperand *operand, GBu /****************************************************************************** * * -* Paramètres : positive = indique si la quantité doit être ajoutée ou non. * -* value = valeur du décalage à appliquer. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Crée un décalage selon un sens et une valeur donnés. * +* Description : Fournit une liste de candidats embarqués par un candidat. * * * -* Retour : Opérande mis en place. * +* Retour : Liste de candidats internes ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_offset_operand_new(bool positive, GArchOperand *value) +static GArchOperand **g_armv7_offset_operand_list_inner_instances(const GArmV7OffsetOperand *operand, size_t *count) { - GArmV7OffsetOperand *result; /* Structure à retourner */ + GArchOperand **result; /* Instances à retourner */ - result = g_object_new(G_TYPE_ARMV7_OFFSET_OPERAND, NULL); + *count = 1; - result->positive = positive; - result->value = value; + result = malloc(*count * sizeof(GArchOperand *)); - return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Indique le sens du décalage représenté. * -* * -* Retour : Indication d'ajout ou de retrait. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *operand) -{ - return operand->positive; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la valeur utilisée pour un décalage. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *operand) -{ - GArchOperand *result; /* Instance à retourner */ - - result = operand->value; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* 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_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ - uint8_t positive; /* Sens du décalage */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - value = g_arch_operand_load(storage, format, pbuf); - - if (value == NULL) - result = false; - - else - operand->value = value; - - } - - if (result) - { - result = extract_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); - - if (result) - operand->positive = (positive == 1 ? true : false); - - } + result[0] = operand->value; + g_object_ref(G_OBJECT(result[0])); return result; @@ -438,37 +412,25 @@ static bool g_armv7_offset_operand_unserialize(GArmV7OffsetOperand *operand, GAs /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* instances = liste de candidats internes devenus singletons. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Met à jour une liste de candidats embarqués par un candidat. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_offset_operand_serialize(const GArmV7OffsetOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_offset_operand_update_inner_instances(GArmV7OffsetOperand *operand, GArchOperand **instances, size_t count) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t positive; /* Sens du décalage */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_offset_operand_parent_class); + assert(count == 1); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + g_clear_object(&operand->value); - if (result) - { - positive = (operand->positive ? 1 : 0); - result = extend_packed_buffer(pbuf, &positive, sizeof(uint8_t), false); - } - - if (result) - result = g_arch_operand_store(operand->value, storage, pbuf); - - return result; + operand->value = instances[0]; + g_object_ref(G_OBJECT(instances[0])); } diff --git a/plugins/arm/v7/operands/offset.h b/plugins/arm/v7/operands/offset.h index aa4df5e..0b5f1bf 100644 --- a/plugins/arm/v7/operands/offset.h +++ b/plugins/arm/v7/operands/offset.h @@ -36,6 +36,14 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7OffOpFlag +{ + A7OOF_POSITIVE = AOF_USER_FLAG(0), /* Sens du décalage */ + +} A7OffOpFlag; + + #define G_TYPE_ARMV7_OFFSET_OPERAND g_armv7_offset_operand_get_type() #define G_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_OFFSET_OPERAND, GArmV7OffsetOperand)) #define G_IS_ARMV7_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_OFFSET_OPERAND)) @@ -57,9 +65,6 @@ GType g_armv7_offset_operand_get_type(void); /* Crée un décalage selon un sens et une valeur donnés. */ GArchOperand *g_armv7_offset_operand_new(bool, GArchOperand *); -/* Indique le sens du décalage représenté. */ -bool g_armv7_offset_operand_is_positive(const GArmV7OffsetOperand *); - /* Founit la valeur utilisée pour un décalage. */ GArchOperand *g_armv7_offset_operand_get_value(const GArmV7OffsetOperand *); diff --git a/plugins/arm/v7/operands/register.c b/plugins/arm/v7/operands/register.c index bfbaa70..fa5b887 100644 --- a/plugins/arm/v7/operands/register.c +++ b/plugins/arm/v7/operands/register.c @@ -25,20 +25,29 @@ #include <arch/operands/register-int.h> -#include <gtkext/gtkblockdisplay.h> +#include <common/sort.h> +#include <core/columns.h> +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7regop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + uint8_t alignment; /* Eventuel alignement */ + +} a7regop_extra_data_t; + + /* Définition d'un opérande visant un registre ARMv7 (instance) */ struct _GArmV7RegisterOperand { GRegisterOperand parent; /* Instance parente */ - unsigned int alignment; /* Eventuel alignement */ - bool has_alignment; /* Validité du champ */ - - bool write_back; /* Mise à jour du registre ? */ - }; @@ -50,6 +59,21 @@ struct _GArmV7RegisterOperandClass }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_REGISTER_OP_EXTRA(op) ((a7regop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_ARMV7_REGISTER_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7regop_extra_data_t) + +#endif + + /* Initialise la classe des opérandes de registre ARMv7. */ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *); @@ -62,20 +86,31 @@ static void g_armv7_register_operand_dispose(GArmV7RegisterOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Compare un opérande avec un autre. */ +static int g_armv7_register_operand_compare(const GArmV7RegisterOperand *, const GArmV7RegisterOperand *, bool); + /* Traduit un opérande en version humainement lisible. */ static void g_armv7_register_operand_print(const GArmV7RegisterOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_register_operand_hash(const GArmV7RegisterOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_register_operand_load(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_register_operand_store(GArmV7RegisterOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour un opérande de registre ARMv7. */ @@ -106,10 +141,14 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas operand = G_ARCH_OPERAND_CLASS(klass); + operand->compare = (operand_compare_fc)g_armv7_register_operand_compare; + operand->print = (operand_print_fc)g_armv7_register_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_register_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_register_operand_serialize; + operand->hash = (operand_hash_fc)g_armv7_register_operand_hash; + + operand->load = (load_operand_fc)g_armv7_register_operand_load; + operand->store = (store_operand_fc)g_armv7_register_operand_store; } @@ -128,7 +167,6 @@ static void g_armv7_register_operand_class_init(GArmV7RegisterOperandClass *klas static void g_armv7_register_operand_init(GArmV7RegisterOperand *operand) { - operand->write_back = false; } @@ -173,33 +211,6 @@ static void g_armv7_register_operand_finalize(GArmV7RegisterOperand *operand) /****************************************************************************** * * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line) -{ - GArchOperandClass *parent; /* Classe parente */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); - - parent->print(G_ARCH_OPERAND(operand), line); - - if (operand->write_back) - g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : reg = registre déjà en place. * * * * Description : Crée un opérande visant un registre ARMv7. * @@ -238,9 +249,20 @@ GArchOperand *g_armv7_register_operand_new(GArmV7Register *reg) void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand, unsigned int align) { - operand->alignment = align; + a7regop_extra_data_t *extra; /* Données internes à manipuler*/ + + extra = GET_ARMV7_REGISTER_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + extra->alignment = align; - operand->has_alignment = true; + if (align > 0) + _g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT, false); + else + _g_arch_operand_unset_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT, false); + + UNLOCK_GOBJECT_EXTRA(extra); } @@ -260,83 +282,159 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *operand, void g_armv7_register_operand_write_back(GArmV7RegisterOperand *operand, bool wback) { - operand->write_back = wback; + g_arch_operand_set_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK); } + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : operand = opérande représentant un registre. * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * -* Description : Indique si le registre est mis à jour après coup. * +* Description : Compare un opérande avec un autre. * * * -* Retour : Evolution du registre. * +* Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ -bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *operand) +static int g_armv7_register_operand_compare(const GArmV7RegisterOperand *a, const GArmV7RegisterOperand *b, bool lock) { - bool result; /* Statut à retourner */ + int result; /* Bilan à faire remonter */ + a7regop_extra_data_t *ea; /* Données insérées à consulter*/ + a7regop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + ea = GET_ARMV7_REGISTER_OP_EXTRA(a); + eb = GET_ARMV7_REGISTER_OP_EXTRA(b); - result = operand->write_back; + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + + result = sort_unsigned_long(ea->alignment, eb->alignment); + + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; } +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_register_operand_print(const GArmV7RegisterOperand *operand, GBufferLine *line) +{ + GArchOperandClass *parent; /* Classe parente */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + + parent->print(G_ARCH_OPERAND(operand), line); -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ + if (g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_WRITE_BACK)) + g_buffer_line_append_text(line, DLC_ASSEMBLY, "!", 1, RTT_PUNCT, NULL); + +} /****************************************************************************** * * -* 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. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Bilan de l'opération. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static guint g_armv7_register_operand_hash(const GArmV7RegisterOperand *operand, bool lock) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ + guint result; /* Valeur à retourner */ + a7regop_extra_data_t *extra; /* Données internes à manipuler*/ + GArchOperandClass *class; /* Classe parente normalisée */ - parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + extra = GET_ARMV7_REGISTER_OP_EXTRA(operand); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + if (lock) + LOCK_GOBJECT_EXTRA(extra); - if (result) - { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + class = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); - if (result) - operand->has_alignment = (boolean == 1 ? true : false); + result ^= extra->alignment; - } + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un contenu depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ - if (result && operand->has_alignment) - result = extract_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true); +static bool g_armv7_register_operand_load(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + a7regop_extra_data_t *extra; /* Données internes à manipuler*/ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); + + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); - if (result) + if (result && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT)) { - result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + extra = GET_ARMV7_REGISTER_OP_EXTRA(operand); - if (result) - operand->write_back = (boolean == 1 ? true : false); + result = extract_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false); } @@ -347,11 +445,11 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -359,29 +457,22 @@ static bool g_armv7_register_operand_unserialize(GArmV7RegisterOperand *operand, * * ******************************************************************************/ -static bool g_armv7_register_operand_serialize(const GArmV7RegisterOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_register_operand_store(GArmV7RegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - uint8_t boolean; /* Valeur booléenne */ + a7regop_extra_data_t *extra; /* Données internes à manipuler*/ parent = G_ARCH_OPERAND_CLASS(g_armv7_register_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); - if (result) + if (result && g_arch_operand_has_flag(G_ARCH_OPERAND(operand), A7ROF_HAS_ALIGNMENT)) { - boolean = (operand->has_alignment ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); - } + extra = GET_ARMV7_REGISTER_OP_EXTRA(operand); - if (result && operand->has_alignment) - result = extend_packed_buffer(pbuf, &operand->alignment, sizeof(unsigned int), true); + result = extend_packed_buffer(pbuf, &extra->alignment, sizeof(uint8_t), false); - if (result) - { - boolean = (operand->write_back ? 1 : 0); - result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); } return result; diff --git a/plugins/arm/v7/operands/register.h b/plugins/arm/v7/operands/register.h index 241c101..26e03c0 100644 --- a/plugins/arm/v7/operands/register.h +++ b/plugins/arm/v7/operands/register.h @@ -36,6 +36,15 @@ +/* Etats particuliers d'un opérande de valeur immédiate */ +typedef enum _A7RegOpFlag +{ + A7ROF_HAS_ALIGNMENT = AOF_USER_FLAG(0), /* Validité de l'alignement */ + A7ROF_WRITE_BACK = AOF_USER_FLAG(1), /* Mise à jour du registre ? */ + +} A7RegOpFlag; + + #define G_TYPE_ARMV7_REGISTER_OPERAND g_armv7_register_operand_get_type() #define G_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARMV7_REGISTER_OPERAND, GArmV7RegisterOperand)) #define G_IS_ARMV7_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARMV7_REGISTER_OPERAND)) @@ -63,9 +72,6 @@ void g_armv7_register_operand_define_alignement(GArmV7RegisterOperand *, unsigne /* Détermine si le registre est mis à jour après l'opération. */ void g_armv7_register_operand_write_back(GArmV7RegisterOperand *, bool); -/* Indique si le registre est mis à jour après coup. */ -bool g_armv7_register_operand_is_written_back(const GArmV7RegisterOperand *); - #endif /* _PLUGINS_ARM_V7_OPERANDS_REGISTER_H */ diff --git a/plugins/arm/v7/operands/reglist.c b/plugins/arm/v7/operands/reglist.c index 9b9a817..b525f28 100644 --- a/plugins/arm/v7/operands/reglist.c +++ b/plugins/arm/v7/operands/reglist.c @@ -28,21 +28,24 @@ #include <malloc.h> -#include <arch/operand-int.h> #include <arch/register.h> #include <arch/storage.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" #include "../registers/basic.h" +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + /* Définition d'un opérande listant une série de registres ARM (instance) */ struct _GArmV7RegListOperand { - GArchOperand parent; /* Instance parente */ + GArmV7Operand parent; /* Instance parente */ GArmV7Register **registers; /* Liste de registres intégrés */ size_t count; /* Taille de cette liste */ @@ -53,7 +56,7 @@ struct _GArmV7RegListOperand /* Définition d'un opérande listant une série de registres ARM (classe) */ struct _GArmV7RegListOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -70,27 +73,35 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *); +static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *, const GArmV7RegListOperand *, bool); /* Traduit un opérande en version humainement lisible. */ static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *, GBufferLine *); +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_reglist_operand_hash(const GArmV7RegListOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une liste de registres ARM. */ -G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -119,8 +130,10 @@ static void g_armv7_reglist_operand_class_init(GArmV7RegListOperandClass *klass) operand->compare = (operand_compare_fc)g_armv7_reglist_operand_compare; operand->print = (operand_print_fc)g_armv7_reglist_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_reglist_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_reglist_operand_serialize; + operand->hash = (operand_hash_fc)g_armv7_reglist_operand_hash; + + operand->load = (load_operand_fc)g_armv7_reglist_operand_load; + operand->store = (store_operand_fc)g_armv7_reglist_operand_store; } @@ -162,7 +175,7 @@ static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *operand) size_t i; /* Boucle de parcours */ for (i = 0; i < operand->count; i++) - g_object_unref(G_OBJECT(operand->registers[i])); + g_clear_object(&operand->registers[i]); G_OBJECT_CLASS(g_armv7_reglist_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -193,88 +206,6 @@ static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *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_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b) -{ - int result; /* Bilan à faire remonter */ - size_t i; /* Boucle de parcours */ - GArchRegister *ra; /* Registre de la liste A */ - GArchRegister *rb; /* Registre de la liste B */ - - /* Création de l'objet... */ - if (b == NULL) - { - result = 1; - goto garoc_done; - } - - result = sort_unsigned_long(a->count, b->count); - if (result != 0) goto garoc_done; - - for (i = 0; i < a->count && result == 0; i++) - { - ra = G_ARCH_REGISTER(a->registers[i]); - rb = G_ARCH_REGISTER(b->registers[i]); - - result = g_arch_register_compare(ra, rb); - - } - - garoc_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line) -{ - size_t i; /* Boucle de parcours */ - - g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); - - for (i = 0; i < operand->count; i++) - { - if (i > 0) - { - g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); - g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); - } - - g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line); - - } - - g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : selected = masque de bits pour les registres à intégrer. * * * * Description : Crée une liste vierge de registres ARM. * @@ -322,8 +253,7 @@ GArchOperand *g_armv7_reglist_operand_new(uint16_t selected) void g_armv7_reglist_add_register(GArmV7RegListOperand *operand, GArmV7Register *reg) { - operand->registers = (GArmV7Register **)realloc(operand->registers, - ++operand->count * sizeof(GArmV7Register *)); + operand->registers = realloc(operand->registers, ++operand->count * sizeof(GArmV7Register *)); operand->registers[operand->count - 1] = reg; @@ -408,68 +338,135 @@ bool g_armv7_reglist_operand_has_register(const GArmV7RegListOperand *operand, c /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* 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. * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Compare un opérande avec un autre. * * * -* Retour : Bilan de l'opération. * +* Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static int g_armv7_reglist_operand_compare(const GArmV7RegListOperand *a, const GArmV7RegListOperand *b, bool lock) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - size_t count; /* Quantité de registres */ - packed_buffer_t reg_pbuf; /* Tampon des données à écrire */ + int result; /* Bilan à faire remonter */ size_t i; /* Boucle de parcours */ - off64_t pos; /* Position dans le flux */ - GArchRegister *reg; /* Registre restauré */ + GArchRegister *ra; /* Registre de la liste A */ + GArchRegister *rb; /* Registre de la liste B */ + GArchOperandClass *class; /* Classe parente normalisée */ - parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + /* Création de l'objet... */ + if (b == NULL) + { + result = 1; + goto done; + } - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); + result = sort_unsigned_long(a->count, b->count); - if (result) - result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); + for (i = 0; i < a->count && result == 0; i++) + { + ra = G_ARCH_REGISTER(a->registers[i]); + rb = G_ARCH_REGISTER(b->registers[i]); - if (result) + result = g_arch_register_compare(ra, rb); + + } + + if (result == 0) { - init_packed_buffer(®_pbuf); + class = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } - for (i = 0; i < count && result; i++) - { - result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + done: - if (result) - result = g_asm_storage_load_register_data(storage, ®_pbuf, pos); + return result; - if (result) - { - reg = g_arch_register_load(storage, ®_pbuf); - result = (reg != NULL); - } +} - if (result) - g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg)); +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line) +{ + size_t i; /* Boucle de parcours */ + + g_buffer_line_append_text(line, DLC_ASSEMBLY, "{", 1, RTT_HOOK, NULL); + + for (i = 0; i < operand->count; i++) + { + if (i > 0) + { + g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL); + g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL); } - exit_packed_buffer(®_pbuf); + g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line); } + g_buffer_line_append_text(line, DLC_ASSEMBLY, "}", 1, RTT_HOOK, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * +* * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * +* * +* Retour : Empreinte de l'élément représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_armv7_reglist_operand_hash(const GArmV7RegListOperand *operand, bool lock) +{ + guint result; /* Valeur à retourner */ + operand_extra_data_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + size_t i; /* Boucle de parcours */ + + extra = GET_ARCH_OP_EXTRA(G_ARCH_OPERAND(operand)); + + if (lock) + LOCK_GOBJECT_EXTRA(extra); + + class = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); + + result ^= operand->count; + + for (i = 0; i < operand->count; i++) + result ^= g_arch_register_hash(G_ARCH_REGISTER(operand->registers[i])); + + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); + return result; } @@ -477,11 +474,11 @@ static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, G /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -489,39 +486,69 @@ static bool g_armv7_reglist_operand_unserialize(GArmV7RegListOperand *operand, G * * ******************************************************************************/ -static bool g_armv7_reglist_operand_serialize(const GArmV7RegListOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_reglist_operand_load(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + size_t count; /* Quantité de registres */ size_t i; /* Boucle de parcours */ - off64_t pos; /* Position dans le flux */ - packed_buffer_t reg_pbuf; /* Tampon des données à écrire */ + GSerializableObject *reg; /* Registre de la liste */ parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true); - if (result) + for (i = 0; i < count && result; i++) { - init_packed_buffer(®_pbuf); + reg = g_object_storage_unpack_object(storage, "registers", pbuf); - for (i = 0; i < operand->count && result; i++) - { - result = g_arch_register_store(G_ARCH_REGISTER(operand->registers[i]), storage, ®_pbuf); + result = (reg != NULL); - if (result) - result = g_asm_storage_store_register_data(storage, ®_pbuf, &pos); + if (result) + g_armv7_reglist_add_register(operand, G_ARMV7_REGISTER(reg)); - if (result) - result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true); + } - } + return result; - exit_packed_buffer(®_pbuf); +} + + +/****************************************************************************** +* * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à remplir. * +* * +* Description : Sauvegarde un contenu dans une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +static bool g_armv7_reglist_operand_store(GArmV7RegListOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchOperandClass *parent; /* Classe parente à consulter */ + size_t i; /* Boucle de parcours */ + GSerializableObject *reg; /* Registre de la liste */ + + parent = G_ARCH_OPERAND_CLASS(g_armv7_reglist_operand_parent_class); + + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); + + if (result) + result = extend_packed_buffer(pbuf, &operand->count, sizeof(size_t), true); + + for (i = 0; i < operand->count && result; i++) + { + reg = G_SERIALIZABLE_OBJECT(operand->registers[i]); + result = g_object_storage_pack_object(storage, "registers", reg, pbuf); } return result; diff --git a/plugins/arm/v7/operands/rotation.c b/plugins/arm/v7/operands/rotation.c index 05889f4..418e5a4 100644 --- a/plugins/arm/v7/operands/rotation.c +++ b/plugins/arm/v7/operands/rotation.c @@ -24,20 +24,26 @@ #include "rotation.h" +#include <assert.h> #include <stdio.h> #include <string.h> -#include <arch/operand-int.h> +#include <core/columns.h> #include <core/logs.h> -#include <gtkext/gtkblockdisplay.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + /* Définition d'un opérande visant une opérande de rotation ARMv7 (instance) */ struct _GArmV7RotationOperand { - GArchOperand parent; /* Instance parente */ + GArmV7Operand parent; /* Instance parente */ GArchOperand *value; /* Valeur du décalage */ @@ -47,7 +53,7 @@ struct _GArmV7RotationOperand /* Définition d'un opérande visant une opérande de rotation ARMv7 (classe) */ struct _GArmV7RotationOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; @@ -64,8 +70,13 @@ static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *); +static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *, const GArmV7RotationOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_rotation_operand_find_inner_operand_path(const GArmV7RotationOperand *, const GArchOperand *); @@ -76,21 +87,21 @@ static GArchOperand *g_armv7_rotation_operand_get_inner_operand_from_path(const /* Traduit un opérande en version humainement lisible. */ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *, GBufferLine *); +/* Fournit une liste de candidats embarqués par un candidat. */ +static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7RotationOperand *, size_t *); - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Met à jour une liste de candidats embarqués par un candidat. */ +static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *, GArchOperand **, size_t); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini par la GLib pour une opérande de rotation ARMv7. */ -G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7RotationOperand, g_armv7_rotation_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -123,8 +134,11 @@ static void g_armv7_rotation_operand_class_init(GArmV7RotationOperandClass *klas operand->print = (operand_print_fc)g_armv7_rotation_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_rotation_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_rotation_operand_serialize; + operand->list_inner = (operand_list_inners_fc)g_armv7_rotation_operand_list_inner_instances; + operand->update_inner = (operand_update_inners_fc)g_armv7_rotation_operand_update_inner_instances; + + operand->load = g_arch_operand_load_generic_fixed_1; + operand->store = g_arch_operand_store_generic_fixed; } @@ -162,8 +176,7 @@ static void g_armv7_rotation_operand_init(GArmV7RotationOperand *operand) static void g_armv7_rotation_operand_dispose(GArmV7RotationOperand *operand) { - if (operand->value != NULL) - g_object_unref(G_OBJECT(operand->value)); + g_clear_object(&operand->value); G_OBJECT_CLASS(g_armv7_rotation_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -191,8 +204,65 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérandes de rotation ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value) +{ + GArmV7RotationOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL); + + result->value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour une rotation. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -202,12 +272,19 @@ static void g_armv7_rotation_operand_finalize(GArmV7RotationOperand *operand) * * ******************************************************************************/ -static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b) +static int g_armv7_rotation_operand_compare(const GArmV7RotationOperand *a, const GArmV7RotationOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + GArchOperandClass *class; /* Classe parente normalisée */ result = g_arch_operand_compare(a->value, b->value); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } + return result; } @@ -326,96 +403,27 @@ static void g_armv7_rotation_operand_print(const GArmV7RotationOperand *operand, /****************************************************************************** * * -* Paramètres : - * -* * -* Description : Crée un réceptacle pour opérandes de rotation ARMv7. * -* * -* Retour : Opérande mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_rotation_operand_new(GArchOperand *value) -{ - GArmV7RotationOperand *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ARMV7_ROTATION_OPERAND, NULL); - - result->value = value; - - return G_ARCH_OPERAND(result); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Founit la valeur utilisée pour une rotation. * -* * -* Retour : Opérande en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_armv7_rotation_operand_get_value(const GArmV7RotationOperand *operand) -{ - GArchOperand *result; /* Instance à retourner */ - - result = operand->value; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* 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. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Fournit une liste de candidats embarqués par un candidat. * * * -* Retour : Bilan de l'opération. * +* Retour : Liste de candidats internes ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static GArchOperand **g_armv7_rotation_operand_list_inner_instances(const GArmV7RotationOperand *operand, size_t *count) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ + GArchOperand **result; /* Instances à retourner */ - parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + *count = 1; - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - { - value = g_arch_operand_load(storage, format, pbuf); + result = malloc(*count * sizeof(GArchOperand *)); - if (value == NULL) - result = false; - - else - operand->value = value; - - } + result[0] = operand->value; + g_object_ref(G_OBJECT(result[0])); return result; @@ -424,30 +432,25 @@ static bool g_armv7_rotation_operand_unserialize(GArmV7RotationOperand *operand, /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* instances = liste de candidats internes devenus singletons. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Met à jour une liste de candidats embarqués par un candidat. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool g_armv7_rotation_operand_serialize(const GArmV7RotationOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_rotation_operand_update_inner_instances(GArmV7RotationOperand *operand, GArchOperand **instances, size_t count) { - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_armv7_rotation_operand_parent_class); + assert(count == 1); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + g_clear_object(&operand->value); - if (result) - result = g_arch_operand_store(operand->value, storage, pbuf); - - return result; + operand->value = instances[0]; + g_object_ref(G_OBJECT(instances[0])); } diff --git a/plugins/arm/v7/operands/shift.c b/plugins/arm/v7/operands/shift.c index 852e677..ee18cf0 100644 --- a/plugins/arm/v7/operands/shift.c +++ b/plugins/arm/v7/operands/shift.c @@ -24,22 +24,37 @@ #include "shift.h" +#include <assert.h> #include <stdio.h> #include <string.h> -#include <arch/operand-int.h> #include <common/sort.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> +#include "../operand-int.h" + + + +/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */ + + +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _a7shiftop_extra_data_t +{ + operand_extra_data_t parent; /* A laisser en premier */ + + SRType shift_type; /* Type de décalage */ + +} a7shiftop_extra_data_t; + /* Définition d'un opérande visant une opérande de décalage ARMv7 (instance) */ struct _GArmV7ShiftOperand { - GArchOperand parent; /* Instance parente */ + GArmV7Operand parent; /* Instance parente */ - SRType shift_type; /* Type de décalage */ GArchOperand *shift_value; /* Valeur du décalage */ }; @@ -48,11 +63,26 @@ struct _GArmV7ShiftOperand /* Définition d'un opérande visant une opérande de décalage ARMv7 (classe) */ struct _GArmV7ShiftOperandClass { - GArchOperandClass parent; /* Classe parente */ + GArmV7OperandClass parent; /* Classe parente */ }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ + +# define GET_ARMV7_SHIFT_OP_EXTRA(op) ((a7shiftop_extra_data_t *)&((GArchOperand *)op)->extra) + +#else + +# define GET_ARMV7_SHIFT_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7shiftop_extra_data_t) + +#endif + + /* Initialise la classe des opérandes de décalage ARMv7. */ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *); @@ -65,8 +95,13 @@ static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *); + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + /* Compare un opérande avec un autre. */ -static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *); +static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *, const GArmV7ShiftOperand *, bool); /* Détermine le chemin conduisant à un opérande interne. */ static char *g_armv7_shift_operand_find_inner_operand_path(const GArmV7ShiftOperand *, const GArchOperand *); @@ -77,21 +112,30 @@ static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GAr /* Traduit un opérande en version humainement lisible. */ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *, GBufferLine *); +/* Fournit une liste de candidats embarqués par un candidat. */ +static GArchOperand **g_armv7_shift_operand_list_inner_instances(const GArmV7ShiftOperand *, size_t *); +/* Met à jour une liste de candidats embarqués par un candidat. */ +static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *, GArchOperand **, size_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ +/* Fournit l'empreinte d'un candidat à une centralisation. */ +static guint g_armv7_shift_operand_hash(const GArmV7ShiftOperand *, bool); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *); -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *, GAsmStorage *, GBinFormat *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *, GAsmStorage *, packed_buffer_t *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEAU TYPE */ +/* ---------------------------------------------------------------------------------- */ + /* Indique le type défini par la GLib pour une opérande de décalage ARMv7. */ -G_DEFINE_TYPE(GArmV7ShiftOperand, g_armv7_shift_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE(GArmV7ShiftOperand, g_armv7_shift_operand, G_TYPE_ARMV7_OPERAND); /****************************************************************************** @@ -124,8 +168,12 @@ static void g_armv7_shift_operand_class_init(GArmV7ShiftOperandClass *klass) operand->print = (operand_print_fc)g_armv7_shift_operand_print; - operand->unserialize = (unserialize_operand_fc)g_armv7_shift_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_armv7_shift_operand_serialize; + operand->list_inner = (operand_list_inners_fc)g_armv7_shift_operand_list_inner_instances; + operand->update_inner = (operand_update_inners_fc)g_armv7_shift_operand_update_inner_instances; + operand->hash = (operand_hash_fc)g_armv7_shift_operand_hash; + + operand->load = (load_operand_fc)g_armv7_shift_operand_load; + operand->store = (store_operand_fc)g_armv7_shift_operand_store; } @@ -163,8 +211,7 @@ static void g_armv7_shift_operand_init(GArmV7ShiftOperand *operand) static void g_armv7_shift_operand_dispose(GArmV7ShiftOperand *operand) { - if (operand->shift_value != NULL) - g_object_unref(G_OBJECT(operand->shift_value)); + g_clear_object(&operand->shift_value); G_OBJECT_CLASS(g_armv7_shift_operand_parent_class)->dispose(G_OBJECT(operand)); @@ -192,8 +239,100 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand) /****************************************************************************** * * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * +* Paramètres : - * +* * +* Description : Crée un réceptacle pour opérande de décalage ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value) +{ + GArmV7ShiftOperand *result; /* Structure à retourner */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ + + result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL); + + extra = GET_ARMV7_SHIFT_OP_EXTRA(result); + + extra->shift_type = type; + + result->shift_value = value; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique la forme de décalage représenté. * +* * +* Retour : Type de décalage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand) +{ + SRType result; /* Type à retourner */ + a7shiftop_extra_data_t *extra; /* Données insérées à consulter*/ + + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); + + LOCK_GOBJECT_EXTRA(extra); + + result = extra->shift_type; + + UNLOCK_GOBJECT_EXTRA(extra); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Founit la valeur utilisée pour un décalage. * +* * +* Retour : Opérande en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand) +{ + GArchOperand *result; /* Instance à retourner */ + + result = operand->shift_value; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* lock = précise le besoin en verrouillage. * * * * Description : Compare un opérande avec un autre. * * * @@ -203,16 +342,38 @@ static void g_armv7_shift_operand_finalize(GArmV7ShiftOperand *operand) * * ******************************************************************************/ -static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b) +static int g_armv7_shift_operand_compare(const GArmV7ShiftOperand *a, const GArmV7ShiftOperand *b, bool lock) { int result; /* Bilan à faire remonter */ + a7shiftop_extra_data_t *ea; /* Données insérées à consulter*/ + a7shiftop_extra_data_t *eb; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + + ea = GET_ARMV7_SHIFT_OP_EXTRA(a); + eb = GET_ARMV7_SHIFT_OP_EXTRA(b); + + if (lock) + { + LOCK_GOBJECT_EXTRA(ea); + LOCK_GOBJECT_EXTRA(eb); + } + + result = sort_unsigned_long(ea->shift_type, eb->shift_type); - result = sort_unsigned_long(a->shift_type, b->shift_type); - if (result != 0) goto gasoc_done; + if (result == 0) + result = g_arch_operand_compare(a->shift_value, b->shift_value); - result = g_arch_operand_compare(a->shift_value, b->shift_value); + if (result == 0) + { + class = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); + result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); + } - gasoc_done: + if (lock) + { + UNLOCK_GOBJECT_EXTRA(eb); + UNLOCK_GOBJECT_EXTRA(ea); + } return result; @@ -299,7 +460,11 @@ static GArchOperand *g_armv7_shift_operand_get_inner_operand_from_path(const GAr static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBufferLine *line) { - switch (operand->shift_type) + SRType shift_type; /* Type porté par l'opérande */ + + shift_type = g_armv7_shift_operand_get_shift_type(operand); + + switch (shift_type) { case SRType_LSL: g_buffer_line_append_text(line, DLC_ASSEMBLY, "lsl", 3, RTT_KEY_WORD, NULL); @@ -327,88 +492,106 @@ static void g_armv7_shift_operand_print(const GArmV7ShiftOperand *operand, GBuff /****************************************************************************** * * -* Paramètres : - * +* Paramètres : operand = objet dont l'instance se veut unique. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Crée un réceptacle pour opérande de décalage ARMv7. * +* Description : Fournit une liste de candidats embarqués par un candidat. * * * -* Retour : Opérande mis en place. * +* Retour : Liste de candidats internes ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_shift_operand_new(SRType type, GArchOperand *value) +static GArchOperand **g_armv7_shift_operand_list_inner_instances(const GArmV7ShiftOperand *operand, size_t *count) { - GArmV7ShiftOperand *result; /* Structure à retourner */ + GArchOperand **result; /* Instances à retourner */ - result = g_object_new(G_TYPE_ARMV7_SHIFT_OPERAND, NULL); + *count = 1; - result->shift_type = type; - result->shift_value = value; + result = malloc(*count * sizeof(GArchOperand *)); - return G_ARCH_OPERAND(result); + result[0] = operand->shift_value; + g_object_ref(G_OBJECT(result[0])); + + return result; } /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* instances = liste de candidats internes devenus singletons. * +* count = quantité d'instances à l'unicité internes. * * * -* Description : Indique la forme de décalage représenté. * +* Description : Met à jour une liste de candidats embarqués par un candidat. * * * -* Retour : Type de décalage. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -SRType g_armv7_shift_operand_get_shift_type(const GArmV7ShiftOperand *operand) +static void g_armv7_shift_operand_update_inner_instances(GArmV7ShiftOperand *operand, GArchOperand **instances, size_t count) { - return operand->shift_type; + assert(count == 1); + + g_clear_object(&operand->shift_value); + + operand->shift_value = instances[0]; + g_object_ref(G_OBJECT(instances[0])); } /****************************************************************************** * * -* Paramètres : operand = opérande à consulter. * +* Paramètres : operand = objet dont l'instance se veut unique. * +* lock = précise le besoin en verrouillage. * * * -* Description : Founit la valeur utilisée pour un décalage. * +* Description : Fournit l'empreinte d'un candidat à une centralisation. * * * -* Retour : Opérande en place. * +* Retour : Empreinte de l'élément représenté. * * * * Remarques : - * * * ******************************************************************************/ -GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *operand) +static guint g_armv7_shift_operand_hash(const GArmV7ShiftOperand *operand, bool lock) { - GArchOperand *result; /* Instance à retourner */ + guint result; /* Valeur à retourner */ + a7shiftop_extra_data_t *extra; /* Données insérées à consulter*/ + GArchOperandClass *class; /* Classe parente normalisée */ + a7shiftop_extra_data_t *op_extra; /* Données internes à manipuler*/ - result = operand->shift_value; + extra = GET_ARMV7_SHIFT_OP_EXTRA(G_ARMV7_SHIFT_OPERAND(operand)); - g_object_ref(G_OBJECT(result)); + if (lock) + LOCK_GOBJECT_EXTRA(extra); - return result; + class = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); + result = class->hash(G_ARCH_OPERAND(operand), false); -} + op_extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); + result ^= op_extra->shift_type; + if (lock) + UNLOCK_GOBJECT_EXTRA(extra); -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ + return result; + +} /****************************************************************************** * * -* 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. * +* Paramètres : operand = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * * * -* Description : Charge un opérande depuis une mémoire tampon. * +* Description : Charge un contenu depuis une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -416,31 +599,31 @@ GArchOperand *g_armv7_shift_operand_get_shift_value(const GArmV7ShiftOperand *op * * ******************************************************************************/ -static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +static bool g_armv7_shift_operand_load(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ - GArchOperand *value; /* Valeur à intégrer */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ + uleb128_t value; /* Valeur ULEB128 à charger */ parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - result = extract_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); if (result) { - value = g_arch_operand_load(storage, format, pbuf); + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); - if (value == NULL) - result = false; + result = unpack_uleb128(&value, pbuf); - else - operand->shift_value = value; + if (result) + extra->shift_type = value; } + if (result) + result = _g_arch_operand_load_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, 1); + return result; } @@ -448,11 +631,11 @@ static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmS /****************************************************************************** * * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : operand = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un opérande dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -460,20 +643,26 @@ static bool g_armv7_shift_operand_unserialize(GArmV7ShiftOperand *operand, GAsmS * * ******************************************************************************/ -static bool g_armv7_shift_operand_serialize(const GArmV7ShiftOperand *operand, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_shift_operand_store(GArmV7ShiftOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchOperandClass *parent; /* Classe parente à consulter */ + a7shiftop_extra_data_t *extra; /* Données insérées à modifier */ parent = G_ARCH_OPERAND_CLASS(g_armv7_shift_operand_parent_class); - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); + result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); if (result) - result = extend_packed_buffer(pbuf, &operand->shift_type, sizeof(SRType), true); + { + extra = GET_ARMV7_SHIFT_OP_EXTRA(operand); + + result = pack_uleb128((uleb128_t []){ extra->shift_type }, pbuf); + + } if (result) - result = g_arch_operand_store(operand->shift_value, storage, pbuf); + result = _g_arch_operand_store_inner_instances(G_ARCH_OPERAND(operand), storage, pbuf, true); return result; diff --git a/plugins/arm/v7/registers/Makefile.am b/plugins/arm/v7/registers/Makefile.am index 94edf09..5f731f9 100644 --- a/plugins/arm/v7/registers/Makefile.am +++ b/plugins/arm/v7/registers/Makefile.am @@ -1,21 +1,16 @@ noinst_LTLIBRARIES = libarmv7registers.la -libarmv7registers_la_SOURCES = \ - banked.h banked.c \ - basic.h basic.c \ - coproc.h coproc.c \ - simd.h simd.c \ +libarmv7registers_la_SOURCES = \ + banked.h banked.c \ + basic.h basic.c \ + coproc.h coproc.c \ + simd.h simd.c \ special.h special.c -libarmv7registers_la_LIBADD = +libarmv7registers_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libarmv7registers_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/arm/v7/registers/banked.c b/plugins/arm/v7/registers/banked.c index daeae71..6e9fbf3 100644 --- a/plugins/arm/v7/registers/banked.c +++ b/plugins/arm/v7/registers/banked.c @@ -27,7 +27,7 @@ #include <stdio.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include "../register-int.h" @@ -78,14 +78,6 @@ static GArchRegister *_g_armv7_banked_register_new(BankedRegisterTarget); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ - - -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_armv7_banked_register_unserialize(GArmV7BankedRegister *, GAsmStorage *, packed_buffer_t *); - - - /* ------------------------ GESTION SOUS FORME DE SINGLETONS ------------------------ */ @@ -133,7 +125,6 @@ static void g_armv7_banked_register_class_init(GArmV7BankedRegisterClass *klass) object_class->finalize = (GObjectFinalizeFunc)g_armv7_banked_register_finalize; reg_class->print = (reg_print_fc)g_armv7_banked_register_print; - reg_class->unserialize = (reg_unserialize_fc)g_armv7_banked_register_unserialize; } @@ -567,63 +558,6 @@ BankedRegisterTarget g_armv7_banked_register_get_target(const GArmV7BankedRegist /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : reg = registre d'architecture à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un registre depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchRegister *g_armv7_banked_register_unserialize(GArmV7BankedRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - GArchRegister *result; /* Instance à retourner */ - uint8_t index; /* Indice du registre */ - bool status; /* Bilan d'une extraction */ - GArchRegisterClass *parent; /* Classe parente à consulter */ - - status = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); - - if (status) - { - result = get_armv7_banked_register(index); - - if (result == NULL) - g_object_unref(G_OBJECT(reg)); - - } - - else - { - g_object_unref(G_OBJECT(reg)); - result = NULL; - } - - if (result != NULL) - { - parent = G_ARCH_REGISTER_CLASS(g_armv7_banked_register_parent_class); - - result = parent->unserialize(result, storage, pbuf); - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ /* GESTION SOUS FORME DE SINGLETONS */ /* ---------------------------------------------------------------------------------- */ diff --git a/plugins/arm/v7/registers/basic.c b/plugins/arm/v7/registers/basic.c index d92f74e..358135b 100644 --- a/plugins/arm/v7/registers/basic.c +++ b/plugins/arm/v7/registers/basic.c @@ -27,7 +27,7 @@ #include <stdio.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include "../register-int.h" @@ -75,14 +75,6 @@ static GArchRegister *_g_armv7_basic_register_new(uint8_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ - - -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_armv7_basic_register_unserialize(GArmV7BasicRegister *, GAsmStorage *, packed_buffer_t *); - - - /* ------------------------ GESTION SOUS FORME DE SINGLETONS ------------------------ */ @@ -130,7 +122,6 @@ static void g_armv7_basic_register_class_init(GArmV7BasicRegisterClass *klass) object_class->finalize = (GObjectFinalizeFunc)g_armv7_basic_register_finalize; reg_class->print = (reg_print_fc)g_armv7_basic_register_print; - reg_class->unserialize = (reg_unserialize_fc)g_armv7_basic_register_unserialize; } @@ -302,63 +293,6 @@ GArchRegister *g_armv7_basic_register_new(uint8_t index) /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : reg = registre d'architecture à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un registre depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchRegister *g_armv7_basic_register_unserialize(GArmV7BasicRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - GArchRegister *result; /* Instance à retourner */ - uint8_t index; /* Indice du registre */ - bool status; /* Bilan d'une extraction */ - GArchRegisterClass *parent; /* Classe parente à consulter */ - - status = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); - - if (status) - { - result = get_armv7_basic_register(index); - - if (result == NULL) - g_object_unref(G_OBJECT(reg)); - - } - - else - { - g_object_unref(G_OBJECT(reg)); - result = NULL; - } - - if (result != NULL) - { - parent = G_ARCH_REGISTER_CLASS(g_armv7_basic_register_parent_class); - - result = parent->unserialize(result, storage, pbuf); - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ /* GESTION SOUS FORME DE SINGLETONS */ /* ---------------------------------------------------------------------------------- */ diff --git a/plugins/arm/v7/registers/coproc.c b/plugins/arm/v7/registers/coproc.c index acfbb81..5c256a7 100644 --- a/plugins/arm/v7/registers/coproc.c +++ b/plugins/arm/v7/registers/coproc.c @@ -27,7 +27,7 @@ #include <stdio.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include "../register-int.h" @@ -76,14 +76,6 @@ static GArchRegister *_g_armv7_cp_register_new(uint8_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ - - -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_armv7_cp_register_unserialize(GArmV7CpRegister *, GAsmStorage *, packed_buffer_t *); - - - /* ------------------------ GESTION SOUS FORME DE SINGLETONS ------------------------ */ @@ -131,7 +123,6 @@ static void g_armv7_cp_register_class_init(GArmV7CpRegisterClass *klass) object_class->finalize = (GObjectFinalizeFunc)g_armv7_cp_register_finalize; reg_class->print = (reg_print_fc)g_armv7_cp_register_print; - reg_class->unserialize = (reg_unserialize_fc)g_armv7_cp_register_unserialize; } @@ -282,63 +273,6 @@ GArchRegister *g_armv7_cp_register_new(uint8_t index) /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : reg = registre d'architecture à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un registre depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchRegister *g_armv7_cp_register_unserialize(GArmV7CpRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - GArchRegister *result; /* Instance à retourner */ - uint8_t index; /* Indice du registre */ - bool status; /* Bilan d'une extraction */ - GArchRegisterClass *parent; /* Classe parente à consulter */ - - status = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); - - if (status) - { - result = get_armv7_cp_register(index); - - if (result == NULL) - g_object_unref(G_OBJECT(reg)); - - } - - else - { - g_object_unref(G_OBJECT(reg)); - result = NULL; - } - - if (result != NULL) - { - parent = G_ARCH_REGISTER_CLASS(g_armv7_cp_register_parent_class); - - result = parent->unserialize(result, storage, pbuf); - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ /* GESTION SOUS FORME DE SINGLETONS */ /* ---------------------------------------------------------------------------------- */ diff --git a/plugins/arm/v7/registers/simd.c b/plugins/arm/v7/registers/simd.c index eedd7c8..8c8c653 100644 --- a/plugins/arm/v7/registers/simd.c +++ b/plugins/arm/v7/registers/simd.c @@ -28,7 +28,7 @@ #include <stdio.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include "../register-int.h" @@ -70,22 +70,21 @@ static void g_armv7_simd_register_dispose(GArmV7SIMDRegister *); /* Procède à la libération totale de la mémoire. */ static void g_armv7_simd_register_finalize(GArmV7SIMDRegister *); -/* Traduit un registre en version humainement lisible. */ -static void g_armv7_simd_register_print(const GArmV7SIMDRegister *, GBufferLine *); - /* Crée une réprésentation de registre SIMD ARMv7. */ static GArchRegister *_g_armv7_simd_register_new(SIMDRegisterMapping, uint8_t); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Traduit un registre en version humainement lisible. */ +static void g_armv7_simd_register_print(const GArmV7SIMDRegister *, GBufferLine *); -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_armv7_simd_register_unserialize(GArmV7SIMDRegister *, GAsmStorage *, packed_buffer_t *); +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_simd_register_load(GArmV7SIMDRegister *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un registre dans une mémoire tampon. */ -static bool g_armv7_simd_register_serialize(const GArmV7SIMDRegister *, GAsmStorage *, packed_buffer_t *); +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_simd_register_store(GArmV7SIMDRegister *, GObjectStorage *, packed_buffer_t *); @@ -126,20 +125,20 @@ G_DEFINE_TYPE(GArmV7SIMDRegister, g_armv7_simd_register, G_TYPE_ARMV7_REGISTER); static void g_armv7_simd_register_class_init(GArmV7SIMDRegisterClass *klass) { - GObjectClass *object_class; /* Autre version de la classe */ - GArchRegisterClass *reg_class; /* Classe de haut niveau */ + GObjectClass *object; /* Autre version de la classe */ + GArchRegisterClass *reg; /* Classe de haut niveau */ - object_class = G_OBJECT_CLASS(klass); + object = G_OBJECT_CLASS(klass); - object_class->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_simd_register_dispose; - object_class->finalize = (GObjectFinalizeFunc)g_armv7_simd_register_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_simd_register_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_simd_register_finalize; - reg_class = G_ARCH_REGISTER_CLASS(klass); + reg = G_ARCH_REGISTER_CLASS(klass); - reg_class->print = (reg_print_fc)g_armv7_simd_register_print; - reg_class->unserialize = (reg_unserialize_fc)g_armv7_simd_register_unserialize; - reg_class->serialize = (reg_serialize_fc)g_armv7_simd_register_serialize; + reg->print = (reg_print_fc)g_armv7_simd_register_print; + reg->load = (load_register_fc)g_armv7_simd_register_load; + reg->store = (store_register_fc)g_armv7_simd_register_store; } @@ -202,50 +201,6 @@ static void g_armv7_simd_register_finalize(GArmV7SIMDRegister *reg) /****************************************************************************** * * -* Paramètres : reg = registre à transcrire. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un registre en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_armv7_simd_register_print(const GArmV7SIMDRegister *reg, GBufferLine *line) -{ - char key[MAX_REGNAME_LEN]; /* Mot clef principal */ - size_t klen; /* Taille de ce mot clef */ - - switch (reg->mapping) - { - case SRM_SINGLE_WORD: - klen = snprintf(key, MAX_REGNAME_LEN, "s%hhu", G_ARM_REGISTER(reg)->index); - break; - - case SRM_DOUBLE_WORD: - klen = snprintf(key, MAX_REGNAME_LEN, "d%hhu", G_ARM_REGISTER(reg)->index); - break; - - case SRM_QUAD_WORD: - klen = snprintf(key, MAX_REGNAME_LEN, "q%hhu", G_ARM_REGISTER(reg)->index); - break; - - default: - assert(false); - klen = snprintf(key, MAX_REGNAME_LEN, "x??"); - break; - - } - - g_buffer_line_append_text(line, DLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); - -} - - -/****************************************************************************** -* * * Paramètres : mapping = type de registre demandé. * * index = indice du registre correspondant. * * * @@ -328,57 +283,84 @@ GArchRegister *g_armv7_simd_register_new(SIMDRegisterMapping mapping, uint8_t in /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : reg = registre d'architecture à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * +* Paramètres : reg = registre à transcrire. * +* line = ligne tampon où imprimer l'opérande donné. * * * -* Description : Charge un registre depuis une mémoire tampon. * +* Description : Traduit un registre en version humainement lisible. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static GArchRegister *g_armv7_simd_register_unserialize(GArmV7SIMDRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) +static void g_armv7_simd_register_print(const GArmV7SIMDRegister *reg, GBufferLine *line) { - GArchRegister *result; /* Instance à retourner */ - SIMDRegisterMapping mapping; /* Type de registre */ - bool status; /* Bilan d'une extraction */ - uint8_t index; /* Indice du registre */ - GArchRegisterClass *parent; /* Classe parente à consulter */ + char key[MAX_REGNAME_LEN]; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ - status = extract_packed_buffer(pbuf, &mapping, sizeof(SIMDRegisterMapping), true); + switch (reg->mapping) + { + case SRM_SINGLE_WORD: + klen = snprintf(key, MAX_REGNAME_LEN, "s%hhu", G_ARM_REGISTER(reg)->index); + break; - if (status) - status = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); + case SRM_DOUBLE_WORD: + klen = snprintf(key, MAX_REGNAME_LEN, "d%hhu", G_ARM_REGISTER(reg)->index); + break; - if (status) - { - result = get_armv7_simd_register(mapping, index); + case SRM_QUAD_WORD: + klen = snprintf(key, MAX_REGNAME_LEN, "q%hhu", G_ARM_REGISTER(reg)->index); + break; - if (result == NULL) - g_object_unref(G_OBJECT(reg)); + default: + assert(false); + klen = snprintf(key, MAX_REGNAME_LEN, "x??"); + break; } - else - { - g_object_unref(G_OBJECT(reg)); - result = NULL; - } + g_buffer_line_append_text(line, DLC_ASSEMBLY, key, klen, RTT_REGISTER, NULL); - if (result != NULL) +} + + +/****************************************************************************** +* * +* Paramètres : reg = élément GLib à constuire. * +* storage = conservateur de données à manipuler ou NULL. * +* pbuf = zone tampon à lire. * +* * +* Description : Charge un contenu depuis une mémoire tampon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_armv7_simd_register_load(GArmV7SIMDRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf) +{ + bool result; /* Bilan à retourner */ + GArchRegisterClass *parent; /* Classe parente à consulter */ + uleb128_t value; /* Valeur à charger */ + + parent = G_ARCH_REGISTER_CLASS(g_armv7_simd_register_parent_class); + + result = parent->load(G_ARCH_REGISTER(reg), storage, pbuf); + + if (result) { - parent = G_ARCH_REGISTER_CLASS(g_armv7_simd_register_parent_class); + result = unpack_uleb128(&value, pbuf); - result = parent->unserialize(G_ARCH_REGISTER(reg), storage, pbuf); + if (result) + reg->mapping = value; } @@ -389,11 +371,11 @@ static GArchRegister *g_armv7_simd_register_unserialize(GArmV7SIMDRegister *reg, /****************************************************************************** * * -* Paramètres : reg = registre d'architecture à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * +* Paramètres : reg = élément GLib à consulter. * +* storage = conservateur de données à manipuler ou NULL. * * pbuf = zone tampon à remplir. * * * -* Description : Sauvegarde un registre dans une mémoire tampon. * +* Description : Sauvegarde un contenu dans une mémoire tampon. * * * * Retour : Bilan de l'opération. * * * @@ -401,20 +383,17 @@ static GArchRegister *g_armv7_simd_register_unserialize(GArmV7SIMDRegister *reg, * * ******************************************************************************/ -static bool g_armv7_simd_register_serialize(const GArmV7SIMDRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) +static bool g_armv7_simd_register_store(GArmV7SIMDRegister *reg, GObjectStorage *storage, packed_buffer_t *pbuf) { bool result; /* Bilan à retourner */ GArchRegisterClass *parent; /* Classe parente à consulter */ - result = extend_packed_buffer(pbuf, ®->mapping, sizeof(SIMDRegisterMapping), true); - - if (result) - { - parent = G_ARCH_REGISTER_CLASS(g_armv7_simd_register_parent_class); + parent = G_ARCH_REGISTER_CLASS(g_armv7_simd_register_parent_class); - result = parent->serialize(G_ARCH_REGISTER(reg), storage, pbuf); + result = parent->store(G_ARCH_REGISTER(reg), storage, pbuf); - } + if (result) + result = pack_uleb128((uleb128_t []){ reg->mapping }, pbuf); return result; diff --git a/plugins/arm/v7/registers/special.c b/plugins/arm/v7/registers/special.c index ff46a1e..1fc9eb5 100644 --- a/plugins/arm/v7/registers/special.c +++ b/plugins/arm/v7/registers/special.c @@ -27,7 +27,7 @@ #include <stdio.h> -#include <gtkext/gtkblockdisplay.h> +#include <core/columns.h> #include "../register-int.h" @@ -75,14 +75,6 @@ static GArchRegister *_g_armv7_special_register_new(SpecRegTarget); -/* --------------------- TRANSPOSITIONS VIA CACHE DES REGISTRES --------------------- */ - - -/* Charge un registre depuis une mémoire tampon. */ -static GArchRegister *g_armv7_special_register_unserialize(GArmV7SpecialRegister *, GAsmStorage *, packed_buffer_t *); - - - /* ------------------------ GESTION SOUS FORME DE SINGLETONS ------------------------ */ @@ -130,7 +122,6 @@ static void g_armv7_special_register_class_init(GArmV7SpecialRegisterClass *klas object_class->finalize = (GObjectFinalizeFunc)g_armv7_special_register_finalize; reg_class->print = (reg_print_fc)g_armv7_special_register_print; - reg_class->unserialize = (reg_unserialize_fc)g_armv7_special_register_unserialize; } @@ -326,63 +317,6 @@ GArchRegister *g_armv7_special_register_new(SpecRegTarget target) /* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : reg = registre d'architecture à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un registre depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GArchRegister *g_armv7_special_register_unserialize(GArmV7SpecialRegister *reg, GAsmStorage *storage, packed_buffer_t *pbuf) -{ - GArchRegister *result; /* Instance à retourner */ - uint8_t index; /* Indice du registre */ - bool status; /* Bilan d'une extraction */ - GArchRegisterClass *parent; /* Classe parente à consulter */ - - status = extract_packed_buffer(pbuf, &index, sizeof(uint8_t), false); - - if (status) - { - result = get_armv7_special_register(index); - - if (result == NULL) - g_object_unref(G_OBJECT(reg)); - - } - - else - { - g_object_unref(G_OBJECT(reg)); - result = NULL; - } - - if (result != NULL) - { - parent = G_ARCH_REGISTER_CLASS(g_armv7_special_register_parent_class); - - result = parent->unserialize(result, storage, pbuf); - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ /* GESTION SOUS FORME DE SINGLETONS */ /* ---------------------------------------------------------------------------------- */ |