diff options
Diffstat (limited to 'src/arch/operands')
| -rw-r--r-- | src/arch/operands/Makefile.am | 38 | ||||
| -rw-r--r-- | src/arch/operands/immediate-int.h | 66 | ||||
| -rw-r--r-- | src/arch/operands/immediate-ui.c | 184 | ||||
| -rw-r--r-- | src/arch/operands/immediate-ui.h | 37 | ||||
| -rw-r--r-- | src/arch/operands/immediate.c | 1320 | ||||
| -rw-r--r-- | src/arch/operands/immediate.h | 86 | ||||
| -rw-r--r-- | src/arch/operands/known-int.h | 55 | ||||
| -rw-r--r-- | src/arch/operands/known-ui.c | 79 | ||||
| -rw-r--r-- | src/arch/operands/known-ui.h | 37 | ||||
| -rw-r--r-- | src/arch/operands/known.c | 433 | ||||
| -rw-r--r-- | src/arch/operands/known.h | 26 | ||||
| -rw-r--r-- | src/arch/operands/register-int.h | 6 | ||||
| -rw-r--r-- | src/arch/operands/register-ui.c | 93 | ||||
| -rw-r--r-- | src/arch/operands/register-ui.h | 37 | ||||
| -rw-r--r-- | src/arch/operands/register.c | 371 | 
15 files changed, 1667 insertions, 1201 deletions
| diff --git a/src/arch/operands/Makefile.am b/src/arch/operands/Makefile.am index f2a8767..9dc3b2f 100644 --- a/src/arch/operands/Makefile.am +++ b/src/arch/operands/Makefile.am @@ -1,26 +1,36 @@ -noinst_LTLIBRARIES = libarchoperands.la +noinst_LTLIBRARIES = libarchoperands.la libarchoperandsui.la + +# libarchoperands_la_SOURCES =			\ +# 	feeder-int.h						\ +# 	feeder.h feeder.c					\ +# 	proxy-int.h							\ +# 	proxy.h proxy.c						\ +# 	rename-int.h						\ +# 	rename.h rename.c					\ +# 	target-int.h						\ +# 	target.h target.c					\ +# 	targetable-int.h					\ +# 	targetable.h targetable.c  libarchoperands_la_SOURCES =			\ -	feeder-int.h						\ -	feeder.h feeder.c					\  	immediate-int.h						\  	immediate.h immediate.c				\ +	known-int.h							\  	known.h known.c						\  	register-int.h						\ -	register.h register.c				\ -	proxy-int.h							\ -	proxy.h proxy.c						\ -	rename-int.h						\ -	rename.h rename.c					\ -	target-int.h						\ -	target.h target.c					\ -	targetable-int.h					\ -	targetable.h targetable.c +	register.h register.c + +libarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) + +libarchoperandsui_la_SOURCES =			\ +	immediate-ui.h immediate-ui.c		\ +	known-ui.h known-ui.c				\ +	register-ui.h register-ui.c -libarchoperands_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) +libarchoperandsui_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBGTK4_CFLAGS)  devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) -dev_HEADERS = $(libarchoperands_la_SOURCES:%c=) +dev_HEADERS = $(libarchoperands_la_SOURCES:%c=) $(libarchoperandsui_la_SOURCES:%c=) diff --git a/src/arch/operands/immediate-int.h b/src/arch/operands/immediate-int.h index d2313f5..3d60c7d 100644 --- a/src/arch/operands/immediate-int.h +++ b/src/arch/operands/immediate-int.h @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * immediate-int.h - définitions internes propres aux opérandes représentant des valeurs numériques   * - * Copyright (C) 2021 Cyrille Bagard + * Copyright (C) 2021-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -30,27 +30,8 @@ -/* Informations glissées dans la structure GObject de GArchOperand */ -typedef struct _immop_extra_data_t -{ -    operand_extra_data_t parent;            /* A laisser en premier        */ - -    MemoryDataSize size;                    /* Taille de l'opérande        */ - -    /** -     * Les deux éléments suivants sont de type ImmOperandDisplay ; -     * leur espace de conservation est réduit au maximum afin d'éviter -     * un recouvrement . -     */ - -    unsigned int def_display : 3;           /* Type par défaut d'affichage */ -    unsigned int display : 3;               /* Format général d'affichage  */ - -} immop_extra_data_t; - -  /* Définition d'un opérande de valeur numérique (instance) */ -struct _GImmOperand +struct _GImmediateOperand  {      GArchOperand parent;                    /* Instance parente            */ @@ -59,7 +40,7 @@ struct _GImmOperand  };  /* Définition d'un opérande de valeur numérique (classe) */ -struct _GImmOperandClass +struct _GImmediateOperandClass  {      GArchOperandClass parent;               /* Classe parente              */ @@ -70,15 +51,46 @@ struct _GImmOperandClass   * Accès aux informations éventuellement déportées.   */ -#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__ +/* Informations glissées dans la structure GObject de GArchOperand */ +typedef struct _immop_extra_data_t +{ +    ARCH_OPERAND_EXTRA_DATA(3);             /* Informations pour l'opérande*/ -#   define GET_IMM_OP_EXTRA(op) ((immop_extra_data_t *)&((GArchOperand *)op)->extra) +    /** +     * MemoryDataSize +     */ +    unsigned int size : 4;                  /* Taille de l'opérande        */ + +    /** +     * ImmOperandDisplay x 2 +     */ +    unsigned int def_display : 3;           /* Type par défaut d'affichage */ +    unsigned int display : 3;               /* Format général d'affichage  */ + +} immop_extra_data_t; + + +#define GET_IMM_OP_EXTRA(op) \ +    GET_GOBJECT_EXTRA(op, immop_extra_data_t) + +#define SET_IMM_OP_EXTRA(op, data) \ +    SET_GOBJECT_EXTRA(op, immop_extra_data_t, data) -#else -#   define GET_IMM_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), immop_extra_data_t) +/*  Met en place un opérande réprésentant une valeur numérique. */ +bool g_immediate_operand_create_from_value(GImmediateOperand *, MemoryDataSize, uint64_t); + +/* Crée un opérande réprésentant une valeur numérique. */ +bool g_immediate_operand_create_from_data(GImmediateOperand *, MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian); + +/** + * La taille d'impression d'un opérande n'est pas VMPA_MAX_SIZE, + * mais 1 + 64 caractères + octet nul final en cas d'impression en binaire. + */ +#define IMM_MAX_SIZE 66 -#endif +/* Construit la chaîne de caractères correspondant à l'opérande. */ +size_t _g_immediate_operand_to_string(const GImmediateOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); diff --git a/src/arch/operands/immediate-ui.c b/src/arch/operands/immediate-ui.c new file mode 100644 index 0000000..a6b4ae7 --- /dev/null +++ b/src/arch/operands/immediate-ui.c @@ -0,0 +1,184 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * immediate-ui.c - opérandes représentant des valeurs numériques sous forme graphique + * + * Copyright (C) 2024 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 "immediate-ui.h" + + +#include <i18n.h> + + +#include "immediate-int.h" +#include "../../common/extstr.h" +#include "../../glibext/tokenstyle.h" +#include "../../glibext/options/disass.h" + + + +/* Traduit un opérande en version humainement lisible. */ +static void g_immediate_operand_ui_print(const GImmediateOperand *, GBufferLine *); + +/* Construit un petit résumé concis de l'opérande. */ +static char *g_immediate_operand_ui_build_tooltip(const GImmediateOperand *, const GLoadedBinary *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface d'opérande UI.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_immediate_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *iface) +{ +    iface->print = (print_operand_ui_fc)g_immediate_operand_ui_print; +    iface->build_tooltip = (build_operand_ui_tooltip_fc)g_immediate_operand_ui_build_tooltip; + +} + + +/****************************************************************************** +*                                                                             * +*  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_immediate_operand_ui_print(const GImmediateOperand *operand, GBufferLine *line) +{ +    GImmediateOperand *base;                /* Version d'instance basique  */ +    ImmOperandDisplay display;              /* Type d'affichage courant    */ +    char value[IMM_MAX_SIZE];               /* Chaîne à imprimer           */ +    size_t len;                             /* Taille de l'élément inséré  */ + +    base = G_IMMEDIATE_OPERAND(operand); + +    display = g_immediate_operand_get_display(base); + +    len = _g_immediate_operand_to_string(base, display, value); + +    g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_IMMEDIATE, value, len, NULL, G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à consulter.                              * +*                binary  = informations relatives au binaire chargé.          * +*                                                                             * +*  Description : Construit un petit résumé concis de l'opérande.              * +*                                                                             * +*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_immediate_operand_ui_build_tooltip(const GImmediateOperand *operand, const GLoadedBinary *binary) +{ +    char *result;                           /* Description à retourner     */ +    GImmediateOperand *base;                /* Version d'instance basique  */ +    char value[IMM_MAX_SIZE];               /* Conversion artificielle     */ +    char *conv;                             /* Affichage de la Conversion  */ + +    base = G_IMMEDIATE_OPERAND(operand); + +    if (base->raw <= UCHAR_MAX && isprint(base->raw)) +        switch (base->raw) +        { +            case '&': +                asprintf(&result, _("Character: '&'")); +                break; +            case '<': +                asprintf(&result, _("Character: '<'")); +                break; +            case '>': +                asprintf(&result, _("Character: '>'")); +                break; +            default: +                asprintf(&result, _("Character: '%c'"), (char)base->raw); +                break; +        } + +    else +        asprintf(&result, _("Character: <not printable>")); + +    /* Binaire */ + +    _g_immediate_operand_to_string(base, IOD_BIN, value); + +    asprintf(&conv, _("Binary: %s"), value); + +    result = stradd(result, "\n"); +    result = stradd(result, conv); + +    free(conv); + +    /* Octal */ + +    _g_immediate_operand_to_string(base, IOD_OCT, value); + +    asprintf(&conv, _("Octal: %s"), value); + +    result = stradd(result, "\n"); +    result = stradd(result, conv); + +    free(conv); + +    /* Décimal */ + +    _g_immediate_operand_to_string(base, IOD_DEC, value); + +    asprintf(&conv, _("Decimal: %s"), value); + +    result = stradd(result, "\n"); +    result = stradd(result, conv); + +    free(conv); + +    /* Hexadécimal */ + +    _g_immediate_operand_to_string(base, IOD_HEX, value); + +    asprintf(&conv, _("Hexadecimal: %s"), value); + +    result = stradd(result, "\n"); +    result = stradd(result, conv); + +    free(conv); + +    return result; + +} diff --git a/src/arch/operands/immediate-ui.h b/src/arch/operands/immediate-ui.h new file mode 100644 index 0000000..4dbddae --- /dev/null +++ b/src/arch/operands/immediate-ui.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * immediate-ui.h - prototypes pour les opérandes représentant des valeurs numériques sous forme graphique + * + * Copyright (C) 2024 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_IMMEDIATE_UI_H +#define _ARCH_OPERANDS_IMMEDIATE_UI_H + + +#include "../operand-ui-int.h" + + + +/* Procède à l'initialisation de l'interface d'opérande UI. */ +void g_immediate_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *); + + + +#endif  /* _ARCH_OPERANDS_IMMEDIATE_UI_H */ diff --git a/src/arch/operands/immediate.c b/src/arch/operands/immediate.c index f40c645..7ec5ebd 100644 --- a/src/arch/operands/immediate.c +++ b/src/arch/operands/immediate.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * immediate.c - opérandes représentant des valeurs numériques   * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -25,25 +25,32 @@  #include <assert.h> +#include <stdarg.h> + + + +#if 0 +  #include <ctype.h>  #include <inttypes.h>  #include <limits.h>  #include <malloc.h> -#include <stdarg.h>  #include <stdio.h>  #include <i18n.h> +#endif + +  #include "immediate-int.h" -#include "known.h" -#include "rename-int.h" -#include "targetable-int.h"  #include "../../common/asm.h" -#include "../../common/extstr.h"  #include "../../common/sort.h" -#include "../../core/columns.h" +#include "../../glibext/comparable-int.h" +#include "../../glibext/hashable-int.h" +#include "../../glibext/serialize-int.h" +#include "../../glibext/strbuilder-int.h" @@ -51,68 +58,75 @@  /* Initialise la classe des opérandes de valeur immédiate. */ -static void g_imm_operand_class_init(GImmOperandClass *); +static void g_immediate_operand_class_init(GImmediateOperandClass *); -/* Initialise un opérande de valeur immédiate. */ -static void g_imm_operand_init(GImmOperand *); +/* Procède à l'initialisation de l'interface de comparaison. */ +static void g_immediate_operand_comparable_object_iface_init(GComparableObjectInterface *); + +/* Procède à l'initialisation de l'interface de détermination. */ +static void g_immediate_operand_hashable_object_iface_init(GHashableObjectInterface *); + +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_immediate_operand_serializable_iface_init(GSerializableObjectInterface *); + +/* Procède à l'initialisation de l'interface d'exportation. */ +static void g_immediate_operand_string_builder_iface_init(GStringBuilderInterface *, gpointer); + +#if 0  /* Procède à l'initialisation de l'interface de ciblage. */ -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *); +static void g_immediate_operand_targetable_interface_init(GTargetableOperandInterface *);  /* Procède à l'initialisation de l'interface de renommage. */ -static void g_imm_operand_renameable_interface_init(GRenameableOperandInterface *); +static void g_immediate_operand_renameable_interface_init(GRenameableOperandInterface *); + +#endif + +/* Initialise un opérande de valeur immédiate. */ +static void g_immediate_operand_init(GImmediateOperand *);  /* Supprime toutes les références externes. */ -static void g_imm_operand_dispose(GImmOperand *); +static void g_immediate_operand_dispose(GObject *);  /* Procède à la libération totale de la mémoire. */ -static void g_imm_operand_finalize(GImmOperand *); +static void g_immediate_operand_finalize(GObject *); -/* Construit la chaîne de caractères correspondant à l'opérande. */ -static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); -/* Traduit un opérande en version humainement lisible. */ -static void g_imm_operand_print(const GImmOperand *, GBufferLine *); +/* ---------------------- COMPARAISON DETAILLEE DE DEUX OBJETS ---------------------- */ -/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Réalise une comparaison étendue entre objets. */ +static int g_immediate_operand_compare(const GComparableObject *, const GComparableObject *); -/* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *, bool); -#ifdef INCLUDE_GTK_SUPPORT +/* ---------------------- CALCUL D'UNE EMPREINTE DE L'INSTANCE ---------------------- */ -/* Construit un petit résumé concis de l'opérande. */ -static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); -#endif +/* Calcule l'empreinte sur 32 bits d'un objet. */ +static guint g_immediate_operand_hash(const GHashableObject *); -/* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_imm_operand_hash(const GImmOperand *, bool); -/* Charge un contenu depuis une mémoire tampon. */ -static bool g_imm_operand_load(GImmOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un contenu dans une mémoire tampon. */ -static bool g_imm_operand_store(GImmOperand *, GObjectStorage *, packed_buffer_t *); +/* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */ +/* Charge un objet depuis un flux de données. */ +static bool g_immediate_operand_load(GSerializableObject *, GObjectStorage *, int); -/* ---------------------- COMMUNICATION D'UN CIBLAGE POTENTIEL ---------------------- */ +/* Sauvegarde un objet dans un flux de données. */ +static bool g_immediate_operand_store(const GSerializableObject *, GObjectStorage *, int); -/* Obtient l'adresse de la cible visée par un opérande. */ -static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); +/* ----------------- EXPORTATION SOUS FORME DE CHAINE DE CARACTERES ----------------- */ -/* ---------------------- CONSTRUCTION D'UN CONTENU ALTERNATIF ---------------------- */ +/* Exporte une chaîne de caractères à partir d'un objet. */ +static bool g_immediate_operand_to_string(const GStringBuilder *, unsigned int, sized_binary_t *); -/* Construit un opérande de représentation alternative. */ -static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *); @@ -122,9 +136,12 @@ static GRenamedOperand *g_imm_operand_build(const GImmOperand *, const char *);  /* Indique le type défini pour un opérande de valeur numérique. */ -G_DEFINE_TYPE_WITH_CODE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND, -                        G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_imm_operand_targetable_interface_init) -                        G_IMPLEMENT_INTERFACE(G_TYPE_RENAMEABLE_OPERAND, g_imm_operand_renameable_interface_init)); +G_DEFINE_TYPE_WITH_CODE(GImmediateOperand, g_immediate_operand, G_TYPE_ARCH_OPERAND, +                        G_IMPLEMENT_INTERFACE(G_TYPE_COMPARABLE_OBJECT, g_immediate_operand_comparable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_HASHABLE_OBJECT, g_immediate_operand_hashable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_immediate_operand_serializable_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_STRING_BUILDER, g_immediate_operand_string_builder_iface_init) +                        G_IMPLEMENT_INTERFACE_IF_SYM(g_arch_operand_ui_get_type, g_immediate_operand_ui_arch_operand_ui_iface_init));  /****************************************************************************** @@ -139,36 +156,42 @@ G_DEFINE_TYPE_WITH_CODE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND,  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_class_init(GImmOperandClass *klass) +static void g_immediate_operand_class_init(GImmediateOperandClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */ -    GArchOperandClass *operand;             /* Version de classe parente   */      object = G_OBJECT_CLASS(klass); -    operand = G_ARCH_OPERAND_CLASS(klass); -    object->dispose = (GObjectFinalizeFunc/* ! */)g_imm_operand_dispose; -    object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize; +    object->dispose = g_immediate_operand_dispose; +    object->finalize = g_immediate_operand_finalize; -    operand->compare = (operand_compare_fc)g_imm_operand_compare; -    operand->print = (operand_print_fc)g_imm_operand_print; -#ifdef INCLUDE_GTK_SUPPORT -    operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; -#endif +} -    operand->hash = (operand_hash_fc)g_imm_operand_hash; -    operand->load = (load_operand_fc)g_imm_operand_load; -    operand->store = (store_operand_fc)g_imm_operand_store; +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de comparaison.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_immediate_operand_comparable_object_iface_init(GComparableObjectInterface *iface) +{ +    iface->compare = g_immediate_operand_compare;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance à initialiser.                            * +*  Paramètres  : iface = interface GLib à initialiser.                        *  *                                                                             * -*  Description : Initialise un opérande de valeur immédiate.                  * +*  Description : Procède à l'initialisation de l'interface de détermination.  *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -176,23 +199,39 @@ static void g_imm_operand_class_init(GImmOperandClass *klass)  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_init(GImmOperand *operand) +static void g_immediate_operand_hashable_object_iface_init(GHashableObjectInterface *iface)  { -    GET_IMM_OP_EXTRA(operand)->size = MDS_UNDEFINED; +    iface->hash = g_immediate_operand_hash; -    GET_IMM_OP_EXTRA(operand)->def_display = IOD_HEX; -    GET_IMM_OP_EXTRA(operand)->display = IOD_COUNT; +} -    operand->raw = 0; + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_immediate_operand_serializable_iface_init(GSerializableObjectInterface *iface) +{ +    iface->load = g_immediate_operand_load; +    iface->store = g_immediate_operand_store;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : iface = interface GLib à initialiser.                        * +*  Paramètres  : iface  = interface GLib à initialiser.                       * +*                unused = pointeur non utilisé ici.                           *  *                                                                             * -*  Description : Procède à l'initialisation de l'interface de ciblage.        * +*  Description : Procède à l'initialisation de l'interface d'exportation.     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -200,18 +239,18 @@ static void g_imm_operand_init(GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *iface) +static void g_immediate_operand_string_builder_iface_init(GStringBuilderInterface *iface, gpointer unused)  { -    iface->get_addr = (get_targetable_addr_fc)g_imm_operand_get_addr; +    iface->to_string = g_immediate_operand_to_string;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : iface = interface GLib à initialiser.                        * +*  Paramètres  : operand = instance à initialiser.                            *  *                                                                             * -*  Description : Procède à l'initialisation de l'interface de renommage.      * +*  Description : Initialise un opérande de valeur immédiate.                  *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -219,16 +258,27 @@ static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_renameable_interface_init(GRenameableOperandInterface *iface) +static void g_immediate_operand_init(GImmediateOperand *operand)  { -    iface->build = (build_renameable_fc)g_imm_operand_build; +    immop_extra_data_t extra;               /* Données insérées à consulter*/ + +    extra = GET_IMM_OP_EXTRA(operand); + +    extra.size = MDS_UNDEFINED; + +    extra.def_display = IOD_HEX; +    extra.display = IOD_COUNT; + +    SET_IMM_OP_EXTRA(operand, &extra); + +    operand->raw = 0;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             *  *  Description : Supprime toutes les références externes.                     *  *                                                                             * @@ -238,16 +288,16 @@ static void g_imm_operand_renameable_interface_init(GRenameableOperandInterface  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_dispose(GImmOperand *operand) +static void g_immediate_operand_dispose(GObject *object)  { -    G_OBJECT_CLASS(g_imm_operand_parent_class)->dispose(G_OBJECT(operand)); +    G_OBJECT_CLASS(g_immediate_operand_parent_class)->dispose(object);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             *  *  Description : Procède à la libération totale de la mémoire.                *  *                                                                             * @@ -257,9 +307,74 @@ static void g_imm_operand_dispose(GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_imm_operand_finalize(GImmOperand *operand) +static void g_immediate_operand_finalize(GObject *object) +{ +    G_OBJECT_CLASS(g_immediate_operand_parent_class)->finalize(object); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : size  = taille de l'opérande souhaitée.                      * +*                value = valeur sur x bits à venir récupérer.                 * +*                                                                             * +*  Description : Crée un opérande réprésentant une valeur numérique.          * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchOperand *g_immediate_operand_new_from_value(MemoryDataSize size, uint64_t value)  { -    G_OBJECT_CLASS(g_imm_operand_parent_class)->finalize(G_OBJECT(operand)); +    GImmediateOperand *result;                    /* Opérande à retourner        */ + +    result = g_object_new(G_TYPE_IMMEDIATE_OPERAND, NULL); + +    if (!g_immediate_operand_create_from_value(result, size, value)) +        g_clear_object(&result); + +    return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser pleinement.                 * +*                size    = taille de l'opérande souhaitée.                    * +*                value   = valeur sur x bits à venir récupérer.               * +*                                                                             * +*  Description : Met en place un opérande réprésentant une valeur numérique.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_immediate_operand_create_from_value(GImmediateOperand *operand, MemoryDataSize size, uint64_t value) +{ +    bool result;                            /* Bilan à retourner           */ +    immop_extra_data_t extra;               /* Données insérées à consulter*/ + +    result = (size != MDS_UNDEFINED); + +    if (result) +    { +        extra = GET_IMM_OP_EXTRA(operand); + +        extra.size = size; + +        operand->raw = value; + +        SET_IMM_OP_EXTRA(operand, &extra); + +    } + +    return result;  } @@ -280,10 +395,41 @@ static void g_imm_operand_finalize(GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) +GArchOperand *g_immediate_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian)  { -    GImmOperand *result;                    /* Opérande à retourner        */ -    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    GImmediateOperand *result;                    /* Opérande à retourner        */ + +    result = g_object_new(G_TYPE_IMMEDIATE_OPERAND, NULL); + +    if (!g_immediate_operand_create_from_data(result, size, content, addr, low, endian)) +        g_clear_object(&result); + +    return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser pleinement.                 * +*                size    = taille de l'opérande souhaitée.                    * +*                content = flux de données à analyser.                        * +*                addr    = position courante dans ce flux. [OUT]              * +*                low     = position éventuelle des 4 bits visés. [OUT]        * +*                endian  = ordre des bits dans la source.                     * +*                                                                             * +*  Description : Crée un opérande réprésentant une valeur numérique.          * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_immediate_operand_create_from_data(GImmediateOperand *operand, MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) +{ +    bool result;                            /* Bilan à retourner           */ +    uint64_t raw;                           /* Valeur brute lue            */      uint8_t uval8;                          /* Valeur sur 8 bits           */      uint16_t uval16;                        /* Valeur sur 16 bits          */      uint32_t uval32;                        /* Valeur sur 32 bits          */ @@ -293,125 +439,78 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinConten      int32_t sval32;                         /* Valeur sur 32 bits          */      int64_t sval64;                         /* Valeur sur 64 bits          */ -    result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - -    extra = GET_IMM_OP_EXTRA(result); - -    extra->size = size; -      switch (size)      {          case MDS_4_BITS_UNSIGNED: -            if (!g_binary_content_read_u4(content, addr, low, &uval8)) -                goto gionfd_error; -            result->raw = uval8; +            result = g_binary_content_read_u4(content, addr, low, &uval8); +            if (result) +                raw = uval8;              break;          case MDS_8_BITS_UNSIGNED: -            if (!g_binary_content_read_u8(content, addr, &uval8)) -                goto gionfd_error; -            result->raw = uval8; +            result = g_binary_content_read_u8(content, addr, &uval8); +            if (result) +                raw = uval8;              break;          case MDS_16_BITS_UNSIGNED: -            if (!g_binary_content_read_u16(content, addr, endian, &uval16)) -                goto gionfd_error; -            result->raw = uval16; +            result = g_binary_content_read_u16(content, addr, endian, &uval16); +            if (result) +                raw = uval16;              break;          case MDS_32_BITS_UNSIGNED: -            if (!g_binary_content_read_u32(content, addr, endian, &uval32)) -                goto gionfd_error; -            result->raw = uval32; +            result = g_binary_content_read_u32(content, addr, endian, &uval32); +            if (result) +                raw = uval32;              break;          case MDS_64_BITS_UNSIGNED: -            if (!g_binary_content_read_u64(content, addr, endian, &uval64)) -                goto gionfd_error; -            result->raw = uval64; +            result = g_binary_content_read_u64(content, addr, endian, &uval64); +            if (result) +                raw = uval64;              break;          case MDS_4_BITS_SIGNED: -            if (!g_binary_content_read_s4(content, addr, low, &sval8)) -                goto gionfd_error; -            result->raw = sval8; +            result = g_binary_content_read_s4(content, addr, low, &sval8); +            if (result) +                raw = sval8;              break;          case MDS_8_BITS_SIGNED: -            if (!g_binary_content_read_s8(content, addr, &sval8)) -                goto gionfd_error; -            result->raw = sval8; +            result = g_binary_content_read_s8(content, addr, &sval8); +            if (result) +                raw = sval8;              break;          case MDS_16_BITS_SIGNED: -            if (!g_binary_content_read_s16(content, addr, endian, &sval16)) -                goto gionfd_error; -            result->raw = sval16; +            result = g_binary_content_read_s16(content, addr, endian, &sval16); +            if (result) +                raw = sval16;              break;          case MDS_32_BITS_SIGNED: -            if (!g_binary_content_read_s32(content, addr, endian, &sval32)) -                goto gionfd_error; -            result->raw = sval32; +            result = g_binary_content_read_s32(content, addr, endian, &sval32); +            if (result) +                raw = sval32;              break;          case MDS_64_BITS_SIGNED: -            if (!g_binary_content_read_s64(content, addr, endian, &sval64)) -                goto gionfd_error; -            result->raw = sval64; +            result = g_binary_content_read_s64(content, addr, endian, &sval64); +            if (result) +                raw = sval64;              break;          case MDS_UNDEFINED: -            goto gionfd_error; +            result = false;              break;      } -    return G_ARCH_OPERAND(result); - - gionfd_error: - -    g_object_unref(G_OBJECT(result)); - -    return NULL; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : size  = taille de l'opérande souhaitée.                      * -*                value = valeur sur x bits à venir récupérer.                 * -*                                                                             * -*  Description : Crée un opérande réprésentant une valeur numérique.          * -*                                                                             * -*  Retour      : Instruction mise en place.                                   * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) -{ -    GImmOperand *result;                    /* Opérande à retourner        */ -    immop_extra_data_t *extra;              /* Données insérées à modifier */ - -    if (size == MDS_UNDEFINED) -        result = NULL; - -    else -    { -        result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - -        extra = GET_IMM_OP_EXTRA(result); - -        extra->size = size; - -        result->raw = value; - -    } +    if (result) +        result = g_immediate_operand_create_from_value(operand, size, raw); -    return (result != NULL ? G_ARCH_OPERAND(result) : NULL); +    return result;  } @@ -428,18 +527,14 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  *                                                                             *  ******************************************************************************/ -MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) +MemoryDataSize g_immediate_operand_get_size(const GImmediateOperand *operand)  {      MemoryDataSize result;                  /* Taille à retourner          */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); - -    result = extra->size; - -    UNLOCK_GOBJECT_EXTRA(extra); +    result = extra.size;      return result; @@ -460,10 +555,10 @@ MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...) +bool g_immediate_operand_get_value(const GImmediateOperand *operand, MemoryDataSize size, ...)  {      bool result;                            /* Bilan à retourner           */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      va_list ap;                             /* Liste des compléments       */      uint8_t *uval8;                         /* Valeur sur 8 bits           */      uint16_t *uval16;                       /* Valeur sur 16 bits          */ @@ -478,9 +573,7 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); - -    if (extra->size != size) +    if (extra.size != size)          goto exit;      va_start(ap, size); @@ -533,8 +626,6 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..   exit: -    UNLOCK_GOBJECT_EXTRA(extra); -      return result;  } @@ -542,6 +633,37 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..  /******************************************************************************  *                                                                             * +*  Paramètres  : operand = structure dont le contenu est à actualiser. [OUT]  * +*                size    = taille de l'opérande souhaitée.                    * +*                value   = valeur sur x bits à venir récupérer.               * +*                                                                             * +*  Description : Définit la nouvelle valeur de l'opérande à une valeur.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_immediate_operand_set_value(GImmediateOperand *operand, MemoryDataSize size, uint64_t value) +{ +    immop_extra_data_t extra;               /* Données insérées à consulter*/ + +    assert(size != MDS_UNDEFINED); + +    extra = GET_IMM_OP_EXTRA(operand); + +    extra.size = size; + +    operand->raw = value; + +    SET_IMM_OP_EXTRA(operand, &extra); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à consulter.                              *  *                                                                             *  *  Description : Fournit la valeur brute représentée par l'opérande.          * @@ -552,42 +674,55 @@ bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ..  *                                                                             *  ******************************************************************************/ -uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand) +uint64_t g_immediate_operand_get_raw_value(const GImmediateOperand *operand)  { -    return operand->raw; +    uint64_t result;                        /* Valeur brute à retourner    */ + +    result = operand->raw; + +    return result;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = structure dont le contenu est à actualiser. [OUT]  * -*                size    = taille de l'opérande souhaitée.                    * -*                value   = valeur sur x bits à venir récupérer.               * +*  Paramètres  : operand = structure dont le contenu est à consulter.         *  *                                                                             * -*  Description : Définit la nouvelle valeur de l'opérande à une valeur.       * +*  Description : Indique le signe d'une valeur immédiate.                     *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : true si la valeur est strictement négative, false sinon.     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value) +bool g_immediate_operand_is_negative(const GImmediateOperand *operand)  { -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ - -    assert(size != MDS_UNDEFINED); +    bool result;                            /* Bilan à renvoyer            */ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); - -    extra->size = size; - -    operand->raw = value; +    switch (extra.size) +    { +        case MDS_4_BITS_SIGNED: +        case MDS_8_BITS_SIGNED: +        case MDS_16_BITS_SIGNED: +        case MDS_32_BITS_SIGNED: +        case MDS_64_BITS_SIGNED: +            /** +             * Pour les valeurs plus petites que 64 bits, le compilateur +             * réalise une extension de signe lors du transtypage. +             */ +            result = (operand->raw & 0x8000000000000000ll); +            break; +        default: +            result = false; +            break; +    } -    UNLOCK_GOBJECT_EXTRA(extra); +    return result;  } @@ -605,17 +740,15 @@ void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t  *                                                                             *  ******************************************************************************/ -void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display) +void g_immediate_operand_set_default_display(GImmediateOperand *operand, ImmOperandDisplay display)  { -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); +    extra.def_display = display; -    extra->def_display = display; - -    UNLOCK_GOBJECT_EXTRA(extra); +    SET_IMM_OP_EXTRA(operand, &extra);  } @@ -632,18 +765,14 @@ void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay d  *                                                                             *  ******************************************************************************/ -ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) +ImmOperandDisplay g_immediate_operand_get_default_display(const GImmediateOperand *operand)  {      ImmOperandDisplay result;               /* Affichage à retourner       */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); - -    result = extra->def_display; - -    UNLOCK_GOBJECT_EXTRA(extra); +    result = extra.def_display;      return result; @@ -663,17 +792,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) +void g_immediate_operand_set_display(GImmediateOperand *operand, ImmOperandDisplay display)  { -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); +    extra.display = display; -    extra->display = display; - -    UNLOCK_GOBJECT_EXTRA(extra); +    SET_IMM_OP_EXTRA(operand, &extra);  } @@ -690,94 +817,225 @@ void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display)  *                                                                             *  ******************************************************************************/ -ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) +ImmOperandDisplay g_immediate_operand_get_display(const GImmediateOperand *operand)  {      ImmOperandDisplay result;               /* Affichage à retourner       */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      extra = GET_IMM_OP_EXTRA(operand); -    LOCK_GOBJECT_EXTRA(extra); - -    if (extra->display != IOD_COUNT) -        result = extra->display; +    if (extra.display != IOD_COUNT) +        result = extra.display;      else -        result = extra->def_display; - -    UNLOCK_GOBJECT_EXTRA(extra); +        result = extra.def_display;      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                        COMPARAISON DETAILLEE DE DEUX OBJETS                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = structure dont le contenu est à consulter.         * +*  Paramètres  : object = premier objet à consulter pour une comparaison.     * +*                other  = second objet à consulter pour une comparaison.      *  *                                                                             * -*  Description : Indique le signe d'une valeur immédiate.                     * +*  Description : Réalise une comparaison étendue entre objets.                *  *                                                                             * -*  Retour      : true si la valeur est strictement négative, false sinon.     * +*  Retour      : Bilan de la comparaison.                                     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool g_imm_operand_is_negative(const GImmOperand *operand) +static int g_immediate_operand_compare(const GComparableObject *object, const GComparableObject *other)  { -    bool result;                            /* Bilan à renvoyer            */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    int result;                             /* Bilan à retourner           */ +    GComparableObjectInterface *iface;      /* Interface utilisée          */ +    GComparableObjectInterface *parent_iface; /* Interface parente         */ +    GImmediateOperand *operand_a;           /* Version spécialisée #0      */ +    GImmediateOperand *operand_b;           /* Version spécialisée #1      */ +    immop_extra_data_t extra_a;             /* Données insérées à consulter*/ +    immop_extra_data_t extra_b;             /* Données insérées à consulter*/ -    extra = GET_IMM_OP_EXTRA(operand); +    iface = G_COMPARABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); -    LOCK_GOBJECT_EXTRA(extra); +    result = parent_iface->compare(object, other); -    switch (extra->size) +    if (result == 0)      { -        case MDS_4_BITS_SIGNED: -        case MDS_8_BITS_SIGNED: -        case MDS_16_BITS_SIGNED: -        case MDS_32_BITS_SIGNED: -        case MDS_64_BITS_SIGNED: -            /** -             * Pour les valeurs plus petites que 64 bits, le compilateur -             * réalise une extension de signe lors du transtypage. -             */ -            result = (operand->raw & 0x8000000000000000ll); -            break; -        default: -            result = false; -            break; +        operand_a = G_IMMEDIATE_OPERAND(object); + +        extra_a = GET_IMM_OP_EXTRA(operand_a); + +        operand_b = G_IMMEDIATE_OPERAND(other); + +        extra_b = GET_IMM_OP_EXTRA(operand_b); + +        result = sort_unsigned_long(extra_a.size, extra_b.size); + +        if (result == 0) +            sort_uint64_t(operand_a->raw, operand_b->raw); + +        if (result == 0) +            result = sort_unsigned_long(extra_a.def_display, extra_b.def_display); + +        if (result == 0) +            result = sort_unsigned_long(extra_a.display, extra_b.display); +      } -    UNLOCK_GOBJECT_EXTRA(extra); +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                        CALCUL D'UNE EMPREINTE DE L'INSTANCE                        */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : object = objet dont l'instance est à consulter.              * +*                                                                             * +*  Description : Calcule l'empreinte sur 32 bits d'un objet.                  * +*                                                                             * +*  Retour      : Valeur de représentation, unique pour l'objet ou non.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static guint g_immediate_operand_hash(const GHashableObject *object) +{ +    guint result;                           /* Valeur à retourner          */ +    GHashableObjectInterface *iface;        /* Interface utilisée          */ +    GHashableObjectInterface *parent_iface; /* Interface parente           */ +    GImmediateOperand *operand;             /* Version spécialisée         */ + +    iface = G_HASHABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->hash(object); + +    operand = G_IMMEDIATE_OPERAND(object); + +    result ^= (operand->raw & 0xffffffff); +    result ^= (operand->raw >> 32);      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                     MECANISMES DE CONSERVATION ET RESTAURATION                     */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = structure dont le contenu est à consulter.         * +*  Paramètres  : object  = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en lecture.                            *  *                                                                             * -*  Description : Indique si une valeur immédiate est nulle ou non.            * +*  Description : Charge un objet depuis un flux de données.                   *  *                                                                             * -*  Retour      : true si la valeur est nulle, false sinon.                    * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -bool g_imm_operand_is_null(const GImmOperand *operand) +static bool g_immediate_operand_load(GSerializableObject *object, GObjectStorage *storage, int fd)  { -    return (operand->raw == 0ll); +    bool result;                            /* Bilan à retourner           */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ +    uleb128_t val;                          /* Valeur sauvegardée          */ +    GImmediateOperand *operand;             /* Version spécialisée         */ + +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->load(object, storage, fd); + +    if (result) +    { +        result = load_uleb128(&val, fd); + +        if (result) +        { +            operand = G_IMMEDIATE_OPERAND(object); +            operand->raw = val; +        } + +    } + +    return result;  }  /******************************************************************************  *                                                                             * +*  Paramètres  : object  = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en écriture.                           * +*                                                                             * +*  Description : Sauvegarde un objet dans un flux de données.                 * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_immediate_operand_store(const GSerializableObject *object, GObjectStorage *storage, int fd) +{ +    bool result;                            /* Bilan à retourner           */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ +    GImmediateOperand *operand;             /* Version spécialisée         */ + +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->store(object, storage, fd); +    if (!result) goto exit; + +    operand = G_IMMEDIATE_OPERAND(object); + +    result = store_uleb128((uleb128_t []) { operand->raw }, fd); + + exit: + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                   EXPORTATION SOUS FORME DE CHAINE DE CARACTERES                   */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : operand = opérande à transcrire.                             *  *                display = type d'affichage demandé.                          *  *                value   = valeur portée par l'opérande transcrite. [OUT]     * @@ -790,10 +1048,10 @@ bool g_imm_operand_is_null(const GImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) +size_t _g_immediate_operand_to_string(const GImmediateOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE])  {      size_t result;                          /* Longueur à retourner        */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ +    immop_extra_data_t extra;               /* Données insérées à consulter*/      unsigned int range;                     /* Catégorie de la taille      */      const char *prefix;                     /* Entrée en matière           */      const char *suffix;                     /* Sortie de matière           */ @@ -813,13 +1071,11 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      static const char *conv_si_defs[] = { "", "o", "d", "x", "c" };      static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; -    assert(display <= IOD_LAST_VALID); +    assert(display < IOD_COUNT);      extra = GET_IMM_OP_EXTRA(operand); -    //LOCK_GOBJECT_EXTRA(extra); - -    range = MDS_RANGE(extra->size); +    range = MDS_RANGE(extra.size);      /* Encadrement pour les caractères */      if (display == IOD_CHAR) @@ -862,10 +1118,10 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      if (do_padding)      { -        if (extra->display != IOD_COUNT) -            do_padding = (extra->display != IOD_BIN && extra->display != IOD_HEX); +        if (extra.display != IOD_COUNT) +            do_padding = (extra.display == IOD_BIN || extra.display == IOD_HEX);          else -            do_padding = (extra->def_display != IOD_BIN && extra->def_display != IOD_HEX); +            do_padding = (extra.def_display == IOD_BIN || extra.def_display == IOD_HEX);      }      switch (display) @@ -892,7 +1148,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      if (display != IOD_BIN)      { -        if (MDS_IS_SIGNED(extra->size)) +        if (MDS_IS_SIGNED(extra.size))              conv = conv_si_defs[display];          else              conv = conv_us_defs[display]; @@ -929,7 +1185,7 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix); -    switch (extra->size) +    switch (extra.size)      {          case MDS_UNDEFINED:              result = snprintf(value, IMM_MAX_SIZE, "<? undef value ?>"); @@ -982,8 +1238,6 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis      } -    //UNLOCK_GOBJECT_EXTRA(extra); -      assert(result > 0);      return result; @@ -993,555 +1247,37 @@ static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDis  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à transcrire.                             * -*                syntax  = type de représentation demandée.                   * -*                value   = valeur portée par l'opérande transcrite. [OUT]     * +*  Paramètres  : builder = objet dont l'instance est exportable.              * +*                flags   = éventuelles indications pour l'opération.          * +*                out     = chaîne de caractères mise en place. [OUT]          *  *                                                                             * -*  Description : Construit la chaîne de caractères correspondant à l'opérande.* +*  Description : Exporte une chaîne de caractères à partir d'un objet.        *  *                                                                             * -*  Retour      : Nombre de caractères utilisés.                               * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             * -*  Remarques   : -                                                            * +*  Remarques   : La sortie out est à nettoyer avec exit_sized_binary() après  * +*                usage.                                                       *  *                                                                             *  ******************************************************************************/ -size_t g_imm_operand_to_string(const GImmOperand *operand, char value[IMM_MAX_SIZE]) +static bool g_immediate_operand_to_string(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)  { -    size_t result;                          /* Longueur à retourner        */ +    bool result;                            /* Bilan à retourner           */ +    const GImmediateOperand *operand;       /* Version spécialisée         */      ImmOperandDisplay display;              /* Type d'affichage courant    */ - -    display = g_imm_operand_get_display(operand); - -    result = _g_imm_operand_to_string(operand, display, value); - -    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_imm_operand_print(const GImmOperand *operand, GBufferLine *line) -{      char value[IMM_MAX_SIZE];               /* Chaîne à imprimer           */      size_t len;                             /* Taille de l'élément inséré  */ -    len = g_imm_operand_to_string(operand, value); - -    g_buffer_line_append_text(line, DLC_ASSEMBLY, value, len, RTT_IMMEDIATE, G_OBJECT(operand)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                pos     = valeur résultante. [OUT]                           * -*                                                                             * -*  Description : Convertit une valeur immédiate en position de type phys_t.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) -{ -    bool result;                            /* Bilan à renvoyer            */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ - -    extra = GET_IMM_OP_EXTRA(operand); - -    LOCK_GOBJECT_EXTRA(extra); - -    result = !MDS_IS_SIGNED(extra->size); - -    if (result) -        *pos = operand->raw; - -    UNLOCK_GOBJECT_EXTRA(extra); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                addr    = valeur résultante. [OUT]                           * -*                                                                             * -*  Description : Convertit une valeur immédiate en adresse de type virt_t.    * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) -{ -    bool result;                            /* Bilan à renvoyer            */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ - -    extra = GET_IMM_OP_EXTRA(operand); - -    LOCK_GOBJECT_EXTRA(extra); - -    result = !MDS_IS_SIGNED(extra->size); - -    if (result) -        *addr = operand->raw; - -    UNLOCK_GOBJECT_EXTRA(extra); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                val     = valeur résultante. [OUT]                           * -*                                                                             * -*  Description : Convertit une valeur immédiate en valeur de type leb128_t.   * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) -{ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ - -    extra = GET_IMM_OP_EXTRA(operand); - -    LOCK_GOBJECT_EXTRA(extra); - -    *val = operand->raw; - -    UNLOCK_GOBJECT_EXTRA(extra); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                val     = valeur résultante. [OUT]                           * -*                                                                             * -*  Description : Convertit une valeur immédiate en valeur de type uleb128_t.  * -*                                                                             * -*  Retour      : Bilan de l'opération.                                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) -{ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ - -    extra = GET_IMM_OP_EXTRA(operand); - -    LOCK_GOBJECT_EXTRA(extra); - -    *val = operand->raw; - -    UNLOCK_GOBJECT_EXTRA(extra); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                       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.                           * -*                                                                             * -*  Retour      : Bilan de la comparaison.                                     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b, bool lock) -{ -    int result;                             /* Bilan à retourner           */ -    immop_extra_data_t *ea;                 /* Données insérées à modifier */ -    immop_extra_data_t *eb;                 /* Données insérées à modifier */ -    GArchOperandClass *class;               /* Classe parente normalisée   */ - -    ea = GET_IMM_OP_EXTRA(a); -    eb = GET_IMM_OP_EXTRA(b); - -    if (lock) -    { -        LOCK_GOBJECT_EXTRA(ea); -        LOCK_GOBJECT_EXTRA(eb); -    } - -    result = sort_unsigned_long(ea->size, eb->size); - -    if (result == 0) -        sort_uint64_t(a->raw, b->raw); - -    if (result == 0) -        result = sort_unsigned_long(ea->def_display, eb->def_display); - -    if (result == 0) -        result = sort_unsigned_long(ea->display, eb->display); - -    if (result == 0) -    { -        class = G_ARCH_OPERAND_CLASS(g_imm_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; - -} - - -#ifdef INCLUDE_GTK_SUPPORT - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = opérande à consulter.                              * -*                binary  = informations relatives au binaire chargé.          * -*                                                                             * -*  Description : Construit un petit résumé concis de l'opérande.              * -*                                                                             * -*  Retour      : Chaîne de caractères à libérer après usage ou NULL.          * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) -{ -    char *result;                           /* Description à retourner     */ -    char value[IMM_MAX_SIZE];               /* Conversion artificielle     */ -    char *conv;                             /* Affichage de la Conversion  */ - -    if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) -        switch (operand->raw) -        { -            case '&': -                asprintf(&result, _("Character: '&'")); -                break; -            case '<': -                asprintf(&result, _("Character: '<'")); -                break; -            case '>': -                asprintf(&result, _("Character: '>'")); -                break; -            default: -                asprintf(&result, _("Character: '%c'"), (char)operand->raw); -                break; -        } - -    else -        asprintf(&result, _("Character: <not printable>")); - -    /* Binaire */ - -    _g_imm_operand_to_string(operand, IOD_BIN, value); - -    asprintf(&conv, _("Binary: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Octal */ - -    _g_imm_operand_to_string(operand, IOD_OCT, value); - -    asprintf(&conv, _("Octal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Décimal */ - -    _g_imm_operand_to_string(operand, IOD_DEC, value); - -    asprintf(&conv, _("Decimal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    /* Hexadécimal */ - -    _g_imm_operand_to_string(operand, IOD_HEX, value); - -    asprintf(&conv, _("Hexadecimal: %s"), value); - -    result = stradd(result, "\n"); -    result = stradd(result, conv); - -    free(conv); - -    return result; - -} - - -#endif - - -/****************************************************************************** -*                                                                             * -*  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_imm_operand_hash(const GImmOperand *operand, bool lock) -{ -    guint result;                           /* Valeur à retourner          */ -    immop_extra_data_t *extra;              /* Données insérées à modifier */ -    GArchOperandClass *class;               /* Classe parente normalisée   */ - -    extra = GET_IMM_OP_EXTRA(operand); - -    if (lock) -        LOCK_GOBJECT_EXTRA(extra); - -    class = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); -    result = class->hash(G_ARCH_OPERAND(operand), false); - -    result ^= (operand->raw & 0xffffffff); -    result ^= (operand->raw >> 32); - -    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   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_imm_operand_load(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_extra_data_t *extra;              /* Données insérées à modifier */ -    uleb128_t value;                        /* Valeur ULEB128 à charger    */ -    uint8_t val;                            /* Champ de bits manipulé      */ - -    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - -    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); - -    if (result) -    { -        extra = GET_IMM_OP_EXTRA(operand); - -        LOCK_GOBJECT_EXTRA(extra); - -        result = unpack_uleb128(&value, pbuf); - -        if (result) -            extra->size = value; - -        if (result) -        { -            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); - -            if (result) -                extra->def_display = val; - -        } - -        if (result) -        { -            result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); - -            if (result) -                extra->display = val; - -        } - -        UNLOCK_GOBJECT_EXTRA(extra); - -    } - -    if (result) -        result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  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_imm_operand_store(GImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) -{ -    bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    immop_extra_data_t *extra;              /* Données insérées à modifier */ +    operand = G_IMMEDIATE_OPERAND(builder); -    parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); +    display = g_immediate_operand_get_display(operand); -    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); +    len =  _g_immediate_operand_to_string(operand, display, value); -    if (result) -    { -        extra = GET_IMM_OP_EXTRA(operand); - -        LOCK_GOBJECT_EXTRA(extra); - -        result = pack_uleb128((uleb128_t []){ extra->size }, pbuf); - -        if (result) -            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->def_display }, sizeof(uint8_t), false); - -        if (result) -            result = extend_packed_buffer(pbuf, (uint8_t []) { extra->display }, sizeof(uint8_t), false); - -        UNLOCK_GOBJECT_EXTRA(extra); - -    } +    result = (len > 0);      if (result) -        result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - -    return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                        COMMUNICATION D'UN CIBLAGE POTENTIEL                        */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = operande à consulter.                              * -*                src     = localisation de l'instruction mère.                * -*                format  = format reconnu pour le binaire chargé.             * -*                proc    = architecture associée à ce même binaire.           * -*                addr    = localisation de la cible. [OUT]                    * -*                                                                             * -*  Description : Obtient l'adresse de la cible visée par un opérande.         * -*                                                                             * -*  Retour      : true si la cible est valide, false sinon.                    * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) -{ -    bool result;                            /* Bilan à retourner           */ -    virt_t virt;                            /* Adresse virtuelle           */ - -    result = g_imm_operand_to_virt_t(operand, &virt); - -    if (result) -        result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); - -    return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/*                        CONSTRUCTION D'UN CONTENU ALTERNATIF                        */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : operand = operande à consulter.                              * -*                text    = texte alternatif de représentation.                * -*                                                                             * -*  Description : Construit un opérande de représentation alternative.         * -*                                                                             * -*  Retour      : Nouvel opérande, en version renommée.                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static GRenamedOperand *g_imm_operand_build(const GImmOperand *operand, const char *text) -{ -    GRenamedOperand *result;                /* Instance à retourner        */ - -    result = G_RENAMED_OPERAND(g_known_imm_operand_new(operand, text)); +        add_to_sized_binary(out, value, len);      return result; diff --git a/src/arch/operands/immediate.h b/src/arch/operands/immediate.h index 7c1ff03..d66349a 100644 --- a/src/arch/operands/immediate.h +++ b/src/arch/operands/immediate.h @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * immediate.h - prototypes pour les opérandes représentant des valeurs numériques   * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -25,17 +25,22 @@  #define _ARCH_OPERANDS_IMMEDIATE_H -#include <glib-object.h>  #include <stdbool.h>  #include <stdint.h> -#include "../archbase.h"  #include "../operand.h"  #include "../../analysis/content.h" +#include "../../common/datatypes.h" +#include "../../glibext/helpers.h" +#define G_TYPE_IMMEDIATE_OPERAND (g_immediate_operand_get_type()) + +DECLARE_GTYPE(GImmediateOperand, g_immediate_operand, G, IMMEDIATE_OPERAND); + +  /* Etats particuliers d'un opérande de valeur immédiate */  typedef enum _ImmOpFlag  { @@ -57,86 +62,39 @@ typedef enum _ImmOperandDisplay  } ImmOperandDisplay; -#define IOD_LAST_VALID IOD_CHAR - - -#define G_TYPE_IMM_OPERAND            g_imm_operand_get_type() -#define G_IMM_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_IMM_OPERAND, GImmOperand)) -#define G_IS_IMM_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_IMM_OPERAND)) -#define G_IMM_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_IMM_OPERAND, GImmOperandClass)) -#define G_IS_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_IMM_OPERAND)) -#define G_IMM_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_IMM_OPERAND, GImmOperandClass)) - - -/* Définition d'un opérande de valeur numérique (instance) */ -typedef struct _GImmOperand GImmOperand; - -/* Définition d'un opérande de valeur numérique (classe) */ -typedef struct _GImmOperandClass GImmOperandClass; - - -/* Indique le type défini pour un opérande d'architecture. */ -GType g_imm_operand_get_type(void);  /* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian); - -#define g_imm_operand_new_from_data(size, content, addr, endian) \ -    _g_imm_operand_new_from_data(size, content, addr, NULL, endian) +GArchOperand *g_immediate_operand_new_from_value(MemoryDataSize, uint64_t);  /* Crée un opérande réprésentant une valeur numérique. */ -GArchOperand *g_imm_operand_new_from_value(MemoryDataSize, uint64_t); +GArchOperand *g_immediate_operand_new_from_data(MemoryDataSize, const GBinContent *, vmpa2t *, bool *, SourceEndian);  /* Renseigne la taille de la valeur indiquée à la construction. */ -MemoryDataSize g_imm_operand_get_size(const GImmOperand *); +MemoryDataSize g_immediate_operand_get_size(const GImmediateOperand *);  /* Fournit la valeur portée par une opérande numérique. */ -bool g_imm_operand_get_value(const GImmOperand *, MemoryDataSize, ...); +bool g_immediate_operand_get_value(const GImmediateOperand *, MemoryDataSize, ...); + +/* Définit la nouvelle valeur de l'opérande à une valeur. */ +void g_immediate_operand_set_value(GImmediateOperand *, MemoryDataSize, uint64_t);  /* Fournit la valeur brute représentée par l'opérande. */ -uint64_t g_imm_operand_get_raw_value(const GImmOperand *); +uint64_t g_immediate_operand_get_raw_value(const GImmediateOperand *); -/* Définit la nouvelle valeur de l'opérande à une valeur. */ -void g_imm_operand_set_value(GImmOperand *, MemoryDataSize, uint64_t); +/* Indique le signe d'une valeur immédiate. */ +bool g_immediate_operand_is_negative(const GImmediateOperand *);  /* Définit le format textuel par défaut de la valeur. */ -void g_imm_operand_set_default_display(GImmOperand *, ImmOperandDisplay); +void g_immediate_operand_set_default_display(GImmediateOperand *, ImmOperandDisplay);  /* Indique le format textuel par défaut de la valeur. */ -ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *); +ImmOperandDisplay g_immediate_operand_get_default_display(const GImmediateOperand *);  /* Définit la grande ligne du format textuel de la valeur. */ -void g_imm_operand_set_display(GImmOperand *, ImmOperandDisplay); +void g_immediate_operand_set_display(GImmediateOperand *, ImmOperandDisplay);  /* Indique la grande ligne du format textuel de la valeur. */ -ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *); - -/* Indique le signe d'une valeur immédiate. */ -bool g_imm_operand_is_negative(const GImmOperand *); - -/* Indique si une valeur immédiate est nulle ou non. */ -bool g_imm_operand_is_null(const GImmOperand *); - -/** - * La taille d'impression d'un opérande n'est pas VMPA_MAX_SIZE, - * mais 1 + 64 caractères + octet nul final en cas d'impression en binaire. - */ -#define IMM_MAX_SIZE 66 - -/* Construit la chaîne de caractères correspondant à l'opérande. */ -size_t g_imm_operand_to_string(const GImmOperand *, char [IMM_MAX_SIZE]); - -/* Convertit une valeur immédiate en position de type phys_t. */ -bool g_imm_operand_to_phys_t(const GImmOperand *, phys_t *); - -/* Convertit une valeur immédiate en adresse de type virt_t. */ -bool g_imm_operand_to_virt_t(const GImmOperand *, virt_t *); - -/* Convertit une valeur immédiate en valeur de type leb128_t. */ -void g_imm_operand_as_leb128(const GImmOperand *, leb128_t *); - -/* Convertit une valeur immédiate en valeur de type uleb128_t. */ -void g_imm_operand_as_uleb128(const GImmOperand *, uleb128_t *); +ImmOperandDisplay g_immediate_operand_get_display(const GImmediateOperand *); diff --git a/src/arch/operands/known-int.h b/src/arch/operands/known-int.h new file mode 100644 index 0000000..021fbf2 --- /dev/null +++ b/src/arch/operands/known-int.h @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * known-int.h - définitions internes pour les opérandes représentant des valeurs numériques avec sémantique + * + * Copyright (C) 2025 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_KNOWN_INT_H +#define _ARCH_OPERANDS_KNOWN_INT_H + + +#include "immediate-int.h" +#include "known.h" + + + +/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ +struct _GKnownImmediateOperand +{ +    GImmediateOperand parent;               /* Instance parente            */ + +    char *alt_text;                         /* Alternative humaine         */ + +}; + +/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ +struct _GKnownImmediateOperandClass +{ +    GImmediateOperandClass parent;          /* Classe parente              */ + +}; + + +/* Met en place un opérande remplaçant visuellement une valeur. */ +bool g_known_immediate_operand_create(GKnownImmediateOperand *, const GImmediateOperand *, const char *); + + + +#endif  /* _ARCH_OPERANDS_KNOWN_INT_H */ diff --git a/src/arch/operands/known-ui.c b/src/arch/operands/known-ui.c new file mode 100644 index 0000000..b68e60c --- /dev/null +++ b/src/arch/operands/known-ui.c @@ -0,0 +1,79 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * known-ui.c - opérandes représentant des valeurs numériques avec sémantique sous forme graphique + * + * Copyright (C) 2025 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 "known-ui.h" + + +#include "known-int.h" +#include "../../common/cpp.h" +#include "../../glibext/options/disass.h" + + + +/* Traduit un opérande en version humainement lisible. */ +static void g_known_immediate_operand_ui_print(const GArchOperandUI *, GBufferLine *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface d'opérande UI.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_known_immediate_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *iface) +{ +    iface->print = g_known_immediate_operand_ui_print; +    iface->build_tooltip = NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  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_known_immediate_operand_ui_print(const GArchOperandUI *operand, GBufferLine *line) +{ +    GKnownImmediateOperand *known;          /* Version de base             */ + +    known = G_KNOWN_IMMEDIATE_OPERAND(operand); + +    g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_IMMEDIATE, SL(known->alt_text), NULL, G_OBJECT(operand)); + +} diff --git a/src/arch/operands/known-ui.h b/src/arch/operands/known-ui.h new file mode 100644 index 0000000..fa2dc62 --- /dev/null +++ b/src/arch/operands/known-ui.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * known-ui.h - prototypes pour les opérandes représentant des valeurs numériques avec sémantique sous forme graphique + * + * Copyright (C) 2025 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_KNOWN_UI_H +#define _ARCH_OPERANDS_KNOWN_UI_H + + +#include "../operand-ui-int.h" + + + +/* Procède à l'initialisation de l'interface d'opérande UI. */ +void g_known_immediate_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *); + + + +#endif  /* _ARCH_OPERANDS_KNOWN_UI_H */ diff --git a/src/arch/operands/known.c b/src/arch/operands/known.c index 5402879..adb700d 100644 --- a/src/arch/operands/known.c +++ b/src/arch/operands/known.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * known.c - opérandes représentant des valeurs numériques avec sémantique   * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2025 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -24,81 +24,80 @@  #include "known.h" -#include <assert.h>  #include <malloc.h>  #include <string.h> -#include "immediate-int.h" -#include "rename-int.h" -#include "../../analysis/db/misc/rlestr.h" -#include "../../core/columns.h" -#include "../../core/logs.h" +#include "known-int.h" +#include "../../common/cpp.h" +#include "../../glibext/comparable-int.h" +#include "../../glibext/hashable-int.h" +#include "../../glibext/serialize-int.h" +#include "../../glibext/strbuilder-int.h"  /* ----------------------- REMPLACEMENT DE VALEURS IMMEDIATES ----------------------- */ -/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ -struct _GKnownImmOperand -{ -    GImmOperand parent;                     /* Instance parente            */ +/* Initialise la classe des remplacements d'opérandes. */ +static void g_known_immediate_operand_class_init(GKnownImmediateOperandClass *); -    char *alt_text;                         /* Alternative humaine         */ +/* Procède à l'initialisation de l'interface de comparaison. */ +static void g_known_immediate_operand_comparable_object_iface_init(GComparableObjectInterface *); -}; +/* Procède à l'initialisation de l'interface de détermination. */ +static void g_known_immediate_operand_hashable_object_iface_init(GHashableObjectInterface *); -/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ -struct _GKnownImmOperandClass -{ -    GImmOperandClass parent;                /* Classe parente              */ +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_known_immediate_operand_serializable_iface_init(GSerializableObjectInterface *); -}; - - -/* Initialise la classe des remplacements d'opérandes. */ -static void g_known_imm_operand_class_init(GKnownImmOperandClass *); +/* Procède à l'initialisation de l'interface d'exportation. */ +static void g_known_immediate_operand_string_builder_iface_init(GStringBuilderInterface *);  /* Initialise un remplacement d'opérande de valeur immédiate. */ -static void g_known_imm_operand_init(GKnownImmOperand *); - -/* Procède à l'initialisation de l'interface de renommage. */ -static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *); +static void g_known_immediate_operand_init(GKnownImmediateOperand *);  /* Supprime toutes les références externes. */ -static void g_known_imm_operand_dispose(GKnownImmOperand *); +static void g_known_immediate_operand_dispose(GObject *);  /* Procède à la libération totale de la mémoire. */ -static void g_known_imm_operand_finalize(GKnownImmOperand *); +static void g_known_immediate_operand_finalize(GObject *); + + +/* ---------------------- COMPARAISON DETAILLEE DE DEUX OBJETS ---------------------- */ -/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Réalise une comparaison étendue entre objets. */ +static int g_known_immediate_operand_compare(const GComparableObject *, const GComparableObject *); -/* Compare un opérande avec un autre. */ -static int g_known_imm_operand_compare(const GKnownImmOperand *, const GKnownImmOperand *, bool); -/* Traduit un opérande en version humainement lisible. */ -static void g_known_imm_operand_print(const GKnownImmOperand *, GBufferLine *); +/* ---------------------- CALCUL D'UNE EMPREINTE DE L'INSTANCE ---------------------- */ -/* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_known_imm_operand_hash(const GKnownImmOperand *, bool); -/* Charge un contenu depuis une mémoire tampon. */ -static bool g_known_imm_operand_load(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *); +/* Calcule l'empreinte sur 32 bits d'un objet. */ +static guint g_known_immediate_operand_hash(const GHashableObject *); -/* Sauvegarde un contenu dans une mémoire tampon. */ -static bool g_known_imm_operand_store(GKnownImmOperand *, GObjectStorage *, packed_buffer_t *); +/* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */ -/* ------------------------- AFFICHAGE D'UN CONTENU RENOMME ------------------------- */ +/* Charge un objet depuis un flux de données. */ +static bool g_known_immediate_operand_load(GSerializableObject *, GObjectStorage *, int); -/* Fournit un texte comme représentation alternative d'opérande. */ -static const char *g_known_imm_operand_get_text(const GKnownImmOperand *); +/* Sauvegarde un objet dans un flux de données. */ +static bool g_known_immediate_operand_store(const GSerializableObject *, GObjectStorage *, int); + + + +/* ----------------- EXPORTATION SOUS FORME DE CHAINE DE CARACTERES ----------------- */ + + +/* Exporte une chaîne de caractères à partir d'un objet. */ +static bool g_known_immediate_operand_to_string(const GStringBuilder *, unsigned int, sized_binary_t *); @@ -108,8 +107,12 @@ static const char *g_known_imm_operand_get_text(const GKnownImmOperand *);  /* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ -G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAND, -                        G_IMPLEMENT_INTERFACE(G_TYPE_RENAMED_OPERAND, g_known_imm_operand_renamed_interface_init)); +G_DEFINE_TYPE_WITH_CODE(GKnownImmediateOperand, g_known_immediate_operand, G_TYPE_IMMEDIATE_OPERAND, +                        G_IMPLEMENT_INTERFACE(G_TYPE_COMPARABLE_OBJECT, g_known_immediate_operand_comparable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_HASHABLE_OBJECT, g_known_immediate_operand_hashable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_known_immediate_operand_serializable_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_STRING_BUILDER, g_known_immediate_operand_string_builder_iface_init) +                        G_IMPLEMENT_INTERFACE_IF_SYM(g_arch_operand_ui_get_type, g_known_immediate_operand_ui_arch_operand_ui_iface_init));  /****************************************************************************** @@ -124,33 +127,42 @@ G_DEFINE_TYPE_WITH_CODE(GKnownImmOperand, g_known_imm_operand, G_TYPE_IMM_OPERAN  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass) +static void g_known_immediate_operand_class_init(GKnownImmediateOperandClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */ -    GArchOperandClass *operand;             /* Version de classe parente   */      object = G_OBJECT_CLASS(klass); -    operand = G_ARCH_OPERAND_CLASS(klass); -    object->dispose = (GObjectFinalizeFunc/* ! */)g_known_imm_operand_dispose; -    object->finalize = (GObjectFinalizeFunc)g_known_imm_operand_finalize; +    object->dispose = g_known_immediate_operand_dispose; +    object->finalize = g_known_immediate_operand_finalize; + +} -    operand->compare = (operand_compare_fc)g_known_imm_operand_compare; -    operand->print = (operand_print_fc)g_known_imm_operand_print; -    operand->hash = (operand_hash_fc)g_known_imm_operand_hash; +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de comparaison.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    operand->load = (load_operand_fc)g_known_imm_operand_load; -    operand->store = (store_operand_fc)g_known_imm_operand_store; +static void g_known_immediate_operand_comparable_object_iface_init(GComparableObjectInterface *iface) +{ +    iface->compare = g_known_immediate_operand_compare;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance à initialiser.                            * +*  Paramètres  : iface = interface GLib à initialiser.                        *  *                                                                             * -*  Description : Initialise un remplacement d'opérande de valeur immédiate.   * +*  Description : Procède à l'initialisation de l'interface de détermination.  *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -158,9 +170,9 @@ static void g_known_imm_operand_class_init(GKnownImmOperandClass *klass)  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_init(GKnownImmOperand *operand) +static void g_known_immediate_operand_hashable_object_iface_init(GHashableObjectInterface *iface)  { -    operand->alt_text = NULL; +    iface->hash = g_known_immediate_operand_hash;  } @@ -169,7 +181,7 @@ static void g_known_imm_operand_init(GKnownImmOperand *operand)  *                                                                             *  *  Paramètres  : iface = interface GLib à initialiser.                        *  *                                                                             * -*  Description : Procède à l'initialisation de l'interface de renommage.      * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -177,18 +189,19 @@ static void g_known_imm_operand_init(GKnownImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface *iface) +static void g_known_immediate_operand_serializable_iface_init(GSerializableObjectInterface *iface)  { -    iface->get_text = (get_renamed_text_fc)g_known_imm_operand_get_text; +    iface->load = g_known_immediate_operand_load; +    iface->store = g_known_immediate_operand_store;  }  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*  Paramètres  : iface = interface GLib à initialiser.                        *  *                                                                             * -*  Description : Supprime toutes les références externes.                     * +*  Description : Procède à l'initialisation de l'interface d'exportation.     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -196,12 +209,28 @@ static void g_known_imm_operand_renamed_interface_init(GRenamedOperandInterface  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_dispose(GKnownImmOperand *operand) +static void g_known_immediate_operand_string_builder_iface_init(GStringBuilderInterface *iface)  { -    if (operand->alt_text != NULL) -        free(operand->alt_text); +    iface->to_string = g_known_immediate_operand_to_string; -    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->dispose(G_OBJECT(operand)); +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise un remplacement d'opérande de valeur immédiate.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_known_immediate_operand_init(GKnownImmediateOperand *operand) +{ +    operand->alt_text = NULL;  } @@ -210,7 +239,7 @@ static void g_known_imm_operand_dispose(GKnownImmOperand *operand)  *                                                                             *  *  Paramètres  : operand = instance d'objet GLib à traiter.                   *  *                                                                             * -*  Description : Procède à la libération totale de la mémoire.                * +*  Description : Supprime toutes les références externes.                     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -218,180 +247,199 @@ static void g_known_imm_operand_dispose(GKnownImmOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_finalize(GKnownImmOperand *operand) +static void g_known_immediate_operand_dispose(GObject *object)  { -    G_OBJECT_CLASS(g_known_imm_operand_parent_class)->finalize(G_OBJECT(operand)); +    G_OBJECT_CLASS(g_known_immediate_operand_parent_class)->dispose(object);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : old = opérande à venir copier avant son remplacement.        * -*                alt = texte alternatif à présenter pour l'impression.        * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             * -*  Description : Crée un opérande remplaçant visuellement une valeur.         * +*  Description : Procède à la libération totale de la mémoire.                *  *                                                                             * -*  Retour      : Instruction mise en place.                                   * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -GArchOperand *g_known_imm_operand_new(const GImmOperand *old, const char *alt) +static void g_known_immediate_operand_finalize(GObject *object)  { -    GKnownImmOperand *result;               /* Remplacement à retourner    */ -    immop_extra_data_t *src;                /* Données insérées à consulter*/ -    immop_extra_data_t *dest;               /* Données insérées à modifier */ +    GKnownImmediateOperand *operand;        /* Version spécialisée         */ -    result = g_object_new(G_TYPE_KNOWN_IMM_OPERAND, NULL); +    operand = G_KNOWN_IMMEDIATE_OPERAND(object); -    result->parent.raw = old->raw; +    if (operand->alt_text != NULL) +        free(operand->alt_text); -    src = GET_IMM_OP_EXTRA(old); -    dest = GET_IMM_OP_EXTRA(&result->parent); +    G_OBJECT_CLASS(g_known_immediate_operand_parent_class)->finalize(object); -    LOCK_GOBJECT_EXTRA(src); +} -    *(&dest->parent) = *(&src->parent); -    dest->size = src->size; +/****************************************************************************** +*                                                                             * +*  Paramètres  : old = opérande à venir copier avant son remplacement.        * +*                alt = texte alternatif à présenter pour l'impression.        * +*                                                                             * +*  Description : Crée un opérande remplaçant visuellement une valeur.         * +*                                                                             * +*  Retour      : Instruction mise en place.                                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    dest->def_display = src->def_display; -    dest->display = src->display; +GArchOperand *g_known_immediate_operand_new(const GImmediateOperand *old, const char *alt) +{ +    GKnownImmediateOperand *result;         /* Remplacement à retourner    */ -    UNLOCK_GOBJECT_EXTRA(src); +    result = g_object_new(G_TYPE_KNOWN_IMMEDIATE_OPERAND, NULL); -    result->alt_text = strdup(alt); +    if (!g_known_immediate_operand_create(result, old, alt)) +        g_clear_object(&result);      return G_ARCH_OPERAND(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.                    * +*  Paramètres  : operand = instance à initialiser pleinement.                 * +*                old = opérande à venir copier avant son remplacement.        * +*                alt = texte alternatif à présenter pour l'impression.        *  *                                                                             * -*  Description : Compare un opérande avec un autre.                           * +*  Description : Met en place un opérande remplaçant visuellement une valeur. *  *                                                                             * -*  Retour      : Bilan de la comparaison.                                     * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static int g_known_imm_operand_compare(const GKnownImmOperand *a, const GKnownImmOperand *b, bool lock) +bool g_known_immediate_operand_create(GKnownImmediateOperand *operand, const GImmediateOperand *old, const char *alt)  { -    int result;                             /* Bilan à retourner           */ -    immop_extra_data_t *ea;                 /* Données insérées à consulter*/ -    immop_extra_data_t *eb;                 /* Données insérées à consulter*/ -    GArchOperandClass *class;               /* Classe parente normalisée   */ +    bool result;                            /* Bilan à retourner           */ +    immop_extra_data_t extra;               /* Données insérées à consulter*/ -    ea = GET_IMM_OP_EXTRA(G_IMM_OPERAND(a)); -    eb = GET_IMM_OP_EXTRA(G_IMM_OPERAND(b)); +    result = true; -    if (lock) -    { -        LOCK_GOBJECT_EXTRA(ea); -        LOCK_GOBJECT_EXTRA(eb); -    } +    extra = GET_IMM_OP_EXTRA(old); -    result = strcmp(a->alt_text, b->alt_text); +    SET_IMM_OP_EXTRA(operand, &extra); -    if (result == 0) -    { -        class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); -        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); -    } +    G_IMMEDIATE_OPERAND(operand)->raw = G_IMMEDIATE_OPERAND(old)->raw; -    if (lock) -    { -        UNLOCK_GOBJECT_EXTRA(eb); -        UNLOCK_GOBJECT_EXTRA(ea); -    } +    operand->alt_text = strdup(alt);      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                        COMPARAISON DETAILLEE DE DEUX OBJETS                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                line    = ligne tampon où imprimer l'opérande donné.         * +*  Paramètres  : object = premier objet à consulter pour une comparaison.     * +*                other  = second objet à consulter pour une comparaison.      *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Réalise une comparaison étendue entre objets.                *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Bilan de la comparaison.                                     *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_known_imm_operand_print(const GKnownImmOperand *operand, GBufferLine *line) +static int g_known_immediate_operand_compare(const GComparableObject *object, const GComparableObject *other)  { -    size_t len;                             /* Taille de l'élément inséré  */ +    int result;                             /* Bilan à retourner           */ +    GComparableObjectInterface *iface;      /* Interface utilisée          */ +    GComparableObjectInterface *parent_iface; /* Interface parente         */ +    GKnownImmediateOperand *operand_a;      /* Version spécialisée #0      */ +    GKnownImmediateOperand *operand_b;      /* Version spécialisée #1      */ + +    iface = G_COMPARABLE_OBJECT_GET_IFACE(object); -    len = strlen(operand->alt_text); +    parent_iface = g_type_interface_peek_parent(iface); -    g_buffer_line_append_text(line, DLC_ASSEMBLY, operand->alt_text, len, RTT_IMMEDIATE, G_OBJECT(operand)); +    result = parent_iface->compare(object, other); + +    if (result == 0) +    { +        operand_a = G_KNOWN_IMMEDIATE_OPERAND(object); +        operand_b = G_KNOWN_IMMEDIATE_OPERAND(other); + +        result = strcmp(operand_a->alt_text, operand_b->alt_text); + +    } + +    return result;  } +/* ---------------------------------------------------------------------------------- */ +/*                        CALCUL D'UNE EMPREINTE DE L'INSTANCE                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = objet dont l'instance se veut unique.              * -*                lock    = précise le besoin en verrouillage.                 * +*  Paramètres  : object = objet dont l'instance est à consulter.              *  *                                                                             * -*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*  Description : Calcule l'empreinte sur 32 bits d'un objet.                  *  *                                                                             * -*  Retour      : Empreinte de l'élément représenté.                           * +*  Retour      : Valeur de représentation, unique pour l'objet ou non.        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock) +static guint g_known_immediate_operand_hash(const GHashableObject *object)  {      guint result;                           /* Valeur à retourner          */ -    immop_extra_data_t *extra;              /* Données insérées à consulter*/ -    GArchOperandClass *class;               /* Classe parente normalisée   */ +    GHashableObjectInterface *iface;        /* Interface utilisée          */ +    GHashableObjectInterface *parent_iface; /* Interface parente           */ +    GKnownImmediateOperand *operand;        /* Version spécialisée         */ -    extra = GET_IMM_OP_EXTRA(G_IMM_OPERAND(operand)); +    iface = G_HASHABLE_OBJECT_GET_IFACE(object); -    if (lock) -        LOCK_GOBJECT_EXTRA(extra); +    parent_iface = g_type_interface_peek_parent(iface); -    class = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); -    result = class->hash(G_ARCH_OPERAND(operand), false); +    result = parent_iface->hash(object); -    result ^= g_str_hash(operand->alt_text); +    operand = G_KNOWN_IMMEDIATE_OPERAND(object); -    if (lock) -        UNLOCK_GOBJECT_EXTRA(extra); +    result ^= g_str_hash(operand->alt_text);      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                     MECANISMES DE CONSERVATION ET RESTAURATION                     */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = élément GLib à constuire.                          * -*                storage = conservateur de données à manipuler ou NULL.       * -*                pbuf    = zone tampon à lire.                                * +*  Paramètres  : object  = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en lecture.                            *  *                                                                             * -*  Description : Charge un contenu depuis une mémoire tampon.                 * +*  Description : Charge un objet depuis un flux de données.                   *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -399,30 +447,31 @@ static guint g_known_imm_operand_hash(const GKnownImmOperand *operand, bool lock  *                                                                             *  ******************************************************************************/ -static bool g_known_imm_operand_load(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +static bool g_known_immediate_operand_load(GSerializableObject *object, GObjectStorage *storage, int fd)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    rle_string str;                         /* Chaîne à charger            */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ +    sized_binary_t str;                     /* Texte alternatif rechargé   */ +    GKnownImmediateOperand *operand;        /* Version spécialisée         */ + +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); -    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    parent_iface = g_type_interface_peek_parent(iface); -    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); +    result = parent_iface->load(object, storage, fd);      if (result)      { -        setup_empty_rle_string(&str); +        init_sized_binary(&str); -        result = unpack_rle_string(&str, pbuf); +        load_sized_binary_as_string(&str, fd); -        if (result) -        { -            if (get_rle_string(&str) != NULL) -                operand->alt_text = strdup(get_rle_string(&str)); +        operand = G_KNOWN_IMMEDIATE_OPERAND(object); -            exit_rle_string(&str); +        operand->alt_text = strdup(str.static_data); -        } +        exit_sized_binary(&str);      } @@ -433,11 +482,11 @@ static bool g_known_imm_operand_load(GKnownImmOperand *operand, GObjectStorage *  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = élément GLib à consulter.                          * -*                storage = conservateur de données à manipuler ou NULL.       * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : object  = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en écriture.                           *  *                                                                             * -*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*  Description : Sauvegarde un objet dans un flux de données.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -445,54 +494,64 @@ static bool g_known_imm_operand_load(GKnownImmOperand *operand, GObjectStorage *  *                                                                             *  ******************************************************************************/ -static bool g_known_imm_operand_store(GKnownImmOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +static bool g_known_immediate_operand_store(const GSerializableObject *object, GObjectStorage *storage, int fd)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    rle_string str;                         /* Chaîne à conserver          */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ +    GKnownImmediateOperand *operand;        /* Version spécialisée         */ +    sized_binary_t str;                     /* Texte alternatif à conserver*/ -    parent = G_ARCH_OPERAND_CLASS(g_known_imm_operand_parent_class); +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); -    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); +    parent_iface = g_type_interface_peek_parent(iface); -    if (result) -    { -        init_static_rle_string(&str, operand->alt_text); +    result = parent_iface->store(object, storage, fd); +    if (!result) goto exit; -        result = pack_rle_string(&str, pbuf); +    operand = G_KNOWN_IMMEDIATE_OPERAND(object); -        exit_rle_string(&str); +    setup_sized_binary_from_static_string(&str, operand->alt_text); -    } +    result = store_sized_binary_as_string(&str, fd); + + exit:      return result;  } -  /* ---------------------------------------------------------------------------------- */ -/*                           AFFICHAGE D'UN CONTENU RENOMME                           */ +/*                   EXPORTATION SOUS FORME DE CHAINE DE CARACTERES                   */  /* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = operande à consulter.                              * +*  Paramètres  : builder = objet dont l'instance est exportable.              * +*                flags   = éventuelles indications pour l'opération.          * +*                out     = chaîne de caractères mise en place. [OUT]          *  *                                                                             * -*  Description : Fournit un texte comme représentation alternative d'opérande.* +*  Description : Exporte une chaîne de caractères à partir d'un objet.        *  *                                                                             * -*  Retour      : Chaîne de caractère de représentation alternative.           * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             * -*  Remarques   : -                                                            * +*  Remarques   : La sortie out est à nettoyer avec exit_sized_binary() après  * +*                usage.                                                       *  *                                                                             *  ******************************************************************************/ -static const char *g_known_imm_operand_get_text(const GKnownImmOperand *operand) +static bool g_known_immediate_operand_to_string(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)  { -    const char *result;                     /* Texte à retourner           */ +    bool result;                            /* Bilan à retourner           */ +    const GKnownImmediateOperand *operand;  /* Version spécialisée         */ + +    result = true; + +    operand = G_KNOWN_IMMEDIATE_OPERAND(builder); -    result = operand->alt_text; +    add_to_sized_binary(out, operand->alt_text, strlen(operand->alt_text));      return result; diff --git a/src/arch/operands/known.h b/src/arch/operands/known.h index eb84d3b..a8b563f 100644 --- a/src/arch/operands/known.h +++ b/src/arch/operands/known.h @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * known.h - prototypes pour les opérandes représentant des valeurs numériques avec sémantique   * - * Copyright (C) 2021 Cyrille Bagard + * Copyright (C) 2021-2025 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -25,34 +25,18 @@  #define _ARCH_OPERANDS_KNOWN_H -#include <glib-object.h> - -  #include "immediate.h" -#include "../operand.h" - - - -#define G_TYPE_KNOWN_IMM_OPERAND            g_known_imm_operand_get_type() -#define G_KNOWN_IMM_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperand)) -#define G_IS_KNOWN_IMM_OPERAND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_KNOWN_IMM_OPERAND)) -#define G_KNOWN_IMM_OPERAND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) -#define G_IS_KNOWN_IMM_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_KNOWN_IMM_OPERAND)) -#define G_KNOWN_IMM_OPERAND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_KNOWN_IMM_OPERAND, GKnownImmOperandClass)) +#include "../../glibext/helpers.h" -/* Définition d'un remplacement d'opérande de valeur numérique (instance) */ -typedef struct _GKnownImmOperand GKnownImmOperand; -/* Définition d'un remplacement d'opérande de valeur numérique (classe) */ -typedef struct _GKnownImmOperandClass GKnownImmOperandClass; +#define G_TYPE_KNOWN_IMMEDIATE_OPERAND (g_known_immediate_operand_get_type()) +DECLARE_GTYPE(GKnownImmediateOperand, g_known_immediate_operand, G, KNOWN_IMMEDIATE_OPERAND); -/* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ -GType g_known_imm_operand_get_type(void);  /* Crée un opérande remplaçant visuellement une valeur. */ -GArchOperand *g_known_imm_operand_new(const GImmOperand *, const char *); +GArchOperand *g_known_immediate_operand_new(const GImmediateOperand *, const char *); diff --git a/src/arch/operands/register-int.h b/src/arch/operands/register-int.h index a887567..93cf025 100644 --- a/src/arch/operands/register-int.h +++ b/src/arch/operands/register-int.h @@ -26,8 +26,6 @@  #include "register.h" - -  #include "../operand-int.h" @@ -49,5 +47,9 @@ struct _GRegisterOperandClass  }; +/* Met en place un opérande réprésentant une valeur numérique. */ +bool g_register_operand_create(GRegisterOperand *, GArchRegister *); + +  #endif  /* _ARCH_OPERANDS_REGISTER_INT_H */ diff --git a/src/arch/operands/register-ui.c b/src/arch/operands/register-ui.c new file mode 100644 index 0000000..c5469e1 --- /dev/null +++ b/src/arch/operands/register-ui.c @@ -0,0 +1,93 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register-ui.c - opérandes représentant des registres sous forme graphique + * + * Copyright (C) 2025 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "register-ui.h" + + +#include "register.h" +#include "../../glibext/strbuilder.h" +#include "../../glibext/options/disass.h" + + + +/* Traduit un opérande en version humainement lisible. */ +static void g_register_operand_ui_print(const GArchOperandUI *, GBufferLine *); + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface d'opérande UI.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_register_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *iface) +{ +    iface->print = g_register_operand_ui_print; +    iface->build_tooltip = NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  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_register_operand_ui_print(const GArchOperandUI *operand, GBufferLine *line) +{ +    GStringBuilder *builder;                /* Autre version de l'opérande */ +    sized_binary_t str;                     /* Chaîne équivalente produite */ +    bool status;                            /* Bilan d'une conversion      */ + +    builder = G_STRING_BUILDER(operand); + +    init_sized_binary(&str); + +    status = g_string_builder_to_string(builder, 0 /* flags */, &str); + +    if (status) +        g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_REGISTER, +                                  str.static_data, str.size, NULL, G_OBJECT(operand)); + +    else +        g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_REGISTER, +                                  "??", 2, NULL, G_OBJECT(operand)); + +    exit_sized_binary(&str); + +} diff --git a/src/arch/operands/register-ui.h b/src/arch/operands/register-ui.h new file mode 100644 index 0000000..711f450 --- /dev/null +++ b/src/arch/operands/register-ui.h @@ -0,0 +1,37 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * register-ui.h - prototypes pour les opérandes représentant des registres sous forme graphique + * + * Copyright (C) 2025 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  Chrysalide is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  Chrysalide is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_OPERANDS_REGISTER_UI_H +#define _ARCH_OPERANDS_REGISTER_UI_H + + +#include "../operand-ui-int.h" + + + +/* Procède à l'initialisation de l'interface d'opérande UI. */ +void g_register_operand_ui_arch_operand_ui_iface_init(GArchOperandUIInterface *); + + + +#endif  /* _ARCH_OPERANDS_REGISTER_UI_H */ diff --git a/src/arch/operands/register.c b/src/arch/operands/register.c index 4615a99..07e35c4 100644 --- a/src/arch/operands/register.c +++ b/src/arch/operands/register.c @@ -28,7 +28,10 @@  #include "register-int.h" -#include "../storage.h" +#include "../../glibext/comparable-int.h" +#include "../../glibext/hashable-int.h" +#include "../../glibext/serialize-int.h" +#include "../../glibext/strbuilder-int.h" @@ -38,34 +41,61 @@  /* Initialise la classe des opérandes de registre. */  static void g_register_operand_class_init(GRegisterOperandClass *); +/* Procède à l'initialisation de l'interface de comparaison. */ +static void g_register_operand_comparable_object_iface_init(GComparableObjectInterface *); + +/* Procède à l'initialisation de l'interface de détermination. */ +static void g_register_operand_hashable_object_iface_init(GHashableObjectInterface *); + +/* Procède à l'initialisation de l'interface de sérialisation. */ +static void g_register_operand_serializable_iface_init(GSerializableObjectInterface *); + +/* Procède à l'initialisation de l'interface d'exportation. */ +static void g_register_operand_string_builder_iface_init(GStringBuilderInterface *); +  /* Initialise une instance d'opérande de registre. */  static void g_register_operand_init(GRegisterOperand *);  /* Supprime toutes les références externes. */ -static void g_register_operand_dispose(GRegisterOperand *); +static void g_register_operand_dispose(GObject *);  /* Procède à la libération totale de la mémoire. */ -static void g_register_operand_finalize(GRegisterOperand *); +static void g_register_operand_finalize(GObject *); + + + +/* ---------------------- COMPARAISON DETAILLEE DE DEUX OBJETS ---------------------- */ + + +/* Réalise une comparaison étendue entre objets. */ +static int g_register_operand_compare(const GComparableObject *, const GComparableObject *); + +/* ---------------------- CALCUL D'UNE EMPREINTE DE L'INSTANCE ---------------------- */ -/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* Calcule l'empreinte sur 32 bits d'un objet. */ +static guint g_register_operand_hash(const GHashableObject *); -/* Compare un opérande avec un autre. */ -static int g_register_operand_compare(const GRegisterOperand *, const GRegisterOperand *, bool); -/* Traduit un opérande en version humainement lisible. */ -static void g_register_operand_print(const GRegisterOperand *, GBufferLine *); -/* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint g_register_operand_hash(const GRegisterOperand *, bool); +/* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */ -/* Charge un contenu depuis une mémoire tampon. */ -static bool g_register_operand_load(GRegisterOperand *, GObjectStorage *, packed_buffer_t *); -/* Sauvegarde un contenu dans une mémoire tampon. */ -static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packed_buffer_t *); +/* Charge un objet depuis un flux de données. */ +static bool g_register_operand_load(GSerializableObject *, GObjectStorage *, int); + +/* Sauvegarde un objet dans un flux de données. */ +static bool g_register_operand_store(const GSerializableObject *, GObjectStorage *, int); + + + +/* ----------------- EXPORTATION SOUS FORME DE CHAINE DE CARACTERES ----------------- */ + + +/* Exporte une chaîne de caractères à partir d'un objet. */ +static bool g_register_operand_to_string(const GStringBuilder *, unsigned int, sized_binary_t *); @@ -75,7 +105,12 @@ static bool g_register_operand_store(GRegisterOperand *, GObjectStorage *, packe  /* Indique le type défini par la GLib pour un opérande de registre Dalvik. */ -G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND); +G_DEFINE_TYPE_WITH_CODE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND, +                        G_IMPLEMENT_INTERFACE(G_TYPE_COMPARABLE_OBJECT, g_register_operand_comparable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_HASHABLE_OBJECT, g_register_operand_hashable_object_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_register_operand_serializable_iface_init) +                        G_IMPLEMENT_INTERFACE(G_TYPE_STRING_BUILDER, g_register_operand_string_builder_iface_init) +                        G_IMPLEMENT_INTERFACE_IF_SYM(g_arch_operand_ui_get_type, g_register_operand_ui_arch_operand_ui_iface_init));  /****************************************************************************** @@ -93,23 +128,88 @@ G_DEFINE_TYPE(GRegisterOperand, g_register_operand, G_TYPE_ARCH_OPERAND);  static void g_register_operand_class_init(GRegisterOperandClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */ -    GArchOperandClass *operand;             /* Version de classe parente   */      object = G_OBJECT_CLASS(klass); -    operand = G_ARCH_OPERAND_CLASS(klass); -    object->dispose = (GObjectFinalizeFunc/* ! */)g_register_operand_dispose; -    object->finalize = (GObjectFinalizeFunc)g_register_operand_finalize; +    object->dispose = g_register_operand_dispose; +    object->finalize = g_register_operand_finalize; -    operand = G_ARCH_OPERAND_CLASS(klass); +} -    operand->compare = (operand_compare_fc)g_register_operand_compare; -    operand->print = (operand_print_fc)g_register_operand_print; -    operand->hash = (operand_hash_fc)g_register_operand_hash; +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de comparaison.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    operand->load = (load_operand_fc)g_register_operand_load; -    operand->store = (store_operand_fc)g_register_operand_store; +static void g_register_operand_comparable_object_iface_init(GComparableObjectInterface *iface) +{ +    iface->compare = g_register_operand_compare; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de détermination.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_hashable_object_iface_init(GHashableObjectInterface *iface) +{ +    iface->hash = g_register_operand_hash; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface de sérialisation.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_serializable_iface_init(GSerializableObjectInterface *iface) +{ +    iface->load = g_register_operand_load; +    iface->store = g_register_operand_store; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : iface = interface GLib à initialiser.                        * +*                                                                             * +*  Description : Procède à l'initialisation de l'interface d'exportation.     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_register_operand_string_builder_iface_init(GStringBuilderInterface *iface) +{ +    iface->to_string = g_register_operand_to_string;  } @@ -135,7 +235,7 @@ static void g_register_operand_init(GRegisterOperand *operand)  /******************************************************************************  *                                                                             * -*  Paramètres  : binary = instance d'objet GLib à traiter.                    * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             *  *  Description : Supprime toutes les références externes.                     *  *                                                                             * @@ -145,18 +245,22 @@ static void g_register_operand_init(GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_register_operand_dispose(GRegisterOperand *operand) +static void g_register_operand_dispose(GObject *object)  { +    GRegisterOperand *operand;              /* Version spécialisée         */ + +    operand = G_REGISTER_OPERAND(object); +      g_clear_object(&operand->reg); -    G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(G_OBJECT(operand)); +    G_OBJECT_CLASS(g_register_operand_parent_class)->dispose(object);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : binary = instance d'objet GLib à traiter.                    * +*  Paramètres  : object = instance d'objet GLib à traiter.                    *  *                                                                             *  *  Description : Procède à la libération totale de la mémoire.                *  *                                                                             * @@ -166,9 +270,36 @@ static void g_register_operand_dispose(GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static void g_register_operand_finalize(GRegisterOperand *operand) +static void g_register_operand_finalize(GObject *object) +{ +    G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(object); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser pleinement.                 * +*                reg     = registre matériel à représenter.                   * +*                                                                             * +*  Description : Met en place un opérande réprésentant une valeur numérique.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_register_operand_create(GRegisterOperand *operand, GArchRegister *reg)  { -    G_OBJECT_CLASS(g_register_operand_parent_class)->finalize(G_OBJECT(operand)); +    bool result;                            /* Bilan à retourner           */ + +    result = true; + +    operand->reg = reg; +    ref_object(reg); + +    return result;  } @@ -190,8 +321,7 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)      GArchRegister *result;                  /* Instance à retourner        */      result = operand->reg; - -    g_object_ref(G_OBJECT(result)); +    ref_object(result);      return result; @@ -200,17 +330,16 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  /* ---------------------------------------------------------------------------------- */ -/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/*                        COMPARAISON DETAILLEE DE DEUX OBJETS                        */  /* ---------------------------------------------------------------------------------- */  /******************************************************************************  *                                                                             * -*  Paramètres  : a    = premier opérande à consulter.                         * -*                b    = second opérande à consulter.                          * -*                lock = précise le besoin en verrouillage.                    * +*  Paramètres  : object = premier objet à consulter pour une comparaison.     * +*                other  = second objet à consulter pour une comparaison.      *  *                                                                             * -*  Description : Compare un opérande avec un autre.                           * +*  Description : Réalise une comparaison étendue entre objets.                *  *                                                                             *  *  Retour      : Bilan de la comparaison.                                     *  *                                                                             * @@ -218,17 +347,25 @@ GArchRegister *g_register_operand_get_register(const GRegisterOperand *operand)  *                                                                             *  ******************************************************************************/ -static int g_register_operand_compare(const GRegisterOperand *a, const GRegisterOperand *b, bool lock) +static int g_register_operand_compare(const GComparableObject *object, const GComparableObject *other)  {      int result;                             /* Bilan à retourner           */ -    GArchOperandClass *class;               /* Classe parente normalisée   */ +    GComparableObjectInterface *iface;      /* Interface utilisée          */ +    GComparableObjectInterface *parent_iface; /* Interface parente         */ +    GRegisterOperand *operand;              /* Version spécialisée         */ + +    iface = G_COMPARABLE_OBJECT_GET_IFACE(object); -    result = g_arch_register_compare(a->reg, b->reg); +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->compare(object, other);      if (result == 0)      { -        class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); -        result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false); +        operand = G_REGISTER_OPERAND(object); + +        result = g_comparable_object_compare(G_COMPARABLE_OBJECT(operand->reg), other); +      }      return result; @@ -236,53 +373,96 @@ static int g_register_operand_compare(const GRegisterOperand *a, const GRegister  } + +/* ---------------------------------------------------------------------------------- */ +/*                        CALCUL D'UNE EMPREINTE DE L'INSTANCE                        */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande à traiter.                                * -*                line    = ligne tampon où imprimer l'opérande donné.         * +*  Paramètres  : object = objet dont l'instance est à consulter.              *  *                                                                             * -*  Description : Traduit un opérande en version humainement lisible.          * +*  Description : Calcule l'empreinte sur 32 bits d'un objet.                  *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Valeur de représentation, unique pour l'objet ou non.        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_register_operand_print(const GRegisterOperand *operand, GBufferLine *line) +static guint g_register_operand_hash(const GHashableObject *object)  { -    g_arch_register_print(operand->reg, line); +    guint result;                           /* Valeur à retourner          */ +    GHashableObjectInterface *iface;        /* Interface utilisée          */ +    GHashableObjectInterface *parent_iface; /* Interface parente           */ +    GRegisterOperand *operand;              /* Version spécialisée         */ + +    iface = G_HASHABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->hash(object); + +    operand = G_REGISTER_OPERAND(object); + +    result ^= g_hashable_object_hash(G_HASHABLE_OBJECT(operand->reg)); + +    return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                     MECANISMES DE CONSERVATION ET RESTAURATION                     */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = objet dont l'instance se veut unique.              * -*                lock    = précise le besoin en verrouillage.                 * +*  Paramètres  : object  = élément GLib à constuire.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en lecture.                            *  *                                                                             * -*  Description : Fournit l'empreinte d'un candidat à une centralisation.      * +*  Description : Charge un objet depuis un flux de données.                   *  *                                                                             * -*  Retour      : Empreinte de l'élément représenté.                           * +*  Retour      : Bilan de l'opération.                                        *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock) +static bool g_register_operand_load(GSerializableObject *object, GObjectStorage *storage, int fd)  { -    guint result;                           /* Valeur à retourner          */ -    GArchOperandClass *class;               /* Classe parente normalisée   */ -    GArchRegister *reg;                     /* Registre visé par l'opérande*/ +    bool result;                            /* Bilan à retourner           */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ +    GSerializableObject *reg;               /* Registre récupéré           */ +    GRegisterOperand *operand;              /* Version spécialisée         */ + +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); + +    parent_iface = g_type_interface_peek_parent(iface); + +    result = parent_iface->load(object, storage, fd); + +    if (result) +    { +        reg = g_object_storage_unpack_object(storage, fd, "registers"); -    class = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); -    result = class->hash(G_ARCH_OPERAND(operand), false); +        if (reg == NULL) +            result = false; -    reg = g_register_operand_get_register(operand); +        else +        { +            operand = G_REGISTER_OPERAND(object); -    result ^= g_arch_register_hash(reg); +            operand->reg = G_ARCH_REGISTER(reg); + +        } -    g_object_unref(G_OBJECT(reg)); +    }      return result; @@ -291,11 +471,11 @@ static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = élément GLib à constuire.                          * -*                storage = conservateur de données à manipuler ou NULL.       * -*                pbuf    = zone tampon à lire.                                * +*  Paramètres  : object  = élément GLib à consulter.                          * +*                storage = conservateur de données à manipuler.               * +*                fd      = flux ouvert en écriture.                           *  *                                                                             * -*  Description : Charge un contenu depuis une mémoire tampon.                 * +*  Description : Sauvegarde un objet dans un flux de données.                 *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * @@ -303,61 +483,64 @@ static guint g_register_operand_hash(const GRegisterOperand *operand, bool lock)  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_load(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +static bool g_register_operand_store(const GSerializableObject *object, GObjectStorage *storage, int fd)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */ -    GSerializableObject *reg;               /* Registre manipulé           */ +    GRegisterOperand *operand;              /* Version spécialisée         */ +    off64_t reg_pos;                        /* Position renvoyant au reg.  */ +    GSerializableObjectInterface *iface;    /* Interface utilisée          */ +    GSerializableObjectInterface *parent_iface; /* Interface parente       */ -    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +    operand = G_REGISTER_OPERAND(object); -    result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf); +    result = g_object_storage_store_object(storage, "registers", G_SERIALIZABLE_OBJECT(operand->reg), ®_pos); +    if (!result) goto exit; -    if (result) -    { -        reg = g_object_storage_unpack_object(storage, "registers", pbuf); +    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object); -        result = (reg != NULL); +    parent_iface = g_type_interface_peek_parent(iface); -        if (result) -            operand->reg = G_ARCH_REGISTER(reg); +    result = parent_iface->store(object, storage, fd); +    if (!result) goto exit; -    } +    result = store_uleb128((uleb128_t []) { reg_pos }, fd); + + exit:      return result;  } + +/* ---------------------------------------------------------------------------------- */ +/*                   EXPORTATION SOUS FORME DE CHAINE DE CARACTERES                   */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = élément GLib à consulter.                          * -*                storage = conservateur de données à manipuler ou NULL.       * -*                pbuf    = zone tampon à remplir.                             * +*  Paramètres  : builder = objet dont l'instance est exportable.              * +*                flags   = éventuelles indications pour l'opération.          * +*                out     = chaîne de caractères mise en place. [OUT]          *  *                                                                             * -*  Description : Sauvegarde un contenu dans une mémoire tampon.               * +*  Description : Exporte une chaîne de caractères à partir d'un objet.        *  *                                                                             *  *  Retour      : Bilan de l'opération.                                        *  *                                                                             * -*  Remarques   : -                                                            * +*  Remarques   : La sortie out est à nettoyer avec exit_sized_binary() après  * +*                usage.                                                       *  *                                                                             *  ******************************************************************************/ -static bool g_register_operand_store(GRegisterOperand *operand, GObjectStorage *storage, packed_buffer_t *pbuf) +static bool g_register_operand_to_string(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)  {      bool result;                            /* Bilan à retourner           */ -    GArchOperandClass *parent;              /* Classe parente à consulter  */  -    GSerializableObject *reg;               /* Registre manipulé           */ +    const GRegisterOperand *operand;        /* Version spécialisée         */ -    parent = G_ARCH_OPERAND_CLASS(g_register_operand_parent_class); +    operand = G_REGISTER_OPERAND(builder); -    result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf); - -    if (result) -    { -        reg = G_SERIALIZABLE_OBJECT(operand->reg); -        result = g_object_storage_pack_object(storage, "registers", reg, pbuf); -    } +    result = g_string_builder_to_string(G_STRING_BUILDER(operand->reg), flags, out);      return result; | 
