/* Chrysalide - Outil d'analyse de fichiers binaires * known.c - opérandes représentant des valeurs numériques avec sémantique * * Copyright (C) 2020-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 . */ #include "known.h" #include #include #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 ----------------------- */ /* Initialise la classe des remplacements d'opérandes. */ static void g_known_immediate_operand_class_init(GKnownImmediateOperandClass *); /* 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 *); /* Procède à l'initialisation de l'interface de sérialisation. */ static void g_known_immediate_operand_serializable_iface_init(GSerializableObjectInterface *); /* 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_immediate_operand_init(GKnownImmediateOperand *); /* Supprime toutes les références externes. */ static void g_known_immediate_operand_dispose(GObject *); /* Procède à la libération totale de la mémoire. */ static void g_known_immediate_operand_finalize(GObject *); /* ---------------------- COMPARAISON DETAILLEE DE DEUX OBJETS ---------------------- */ /* Réalise une comparaison étendue entre objets. */ static int g_known_immediate_operand_compare(const GComparableObject *, const GComparableObject *); /* ---------------------- CALCUL D'UNE EMPREINTE DE L'INSTANCE ---------------------- */ /* Calcule l'empreinte sur 32 bits d'un objet. */ static guint g_known_immediate_operand_hash(const GHashableObject *); /* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */ /* Charge un objet depuis un flux de données. */ static bool g_known_immediate_operand_load(GSerializableObject *, GObjectStorage *, int); /* 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 *); /* ---------------------------------------------------------------------------------- */ /* REMPLACEMENT DE VALEURS IMMEDIATES */ /* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour un remplacemet d'opérande de valeur numérique. */ 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)); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des remplacements d'opérandes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_class_init(GKnownImmediateOperandClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = g_known_immediate_operand_dispose; object->finalize = g_known_immediate_operand_finalize; } /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * * Description : Procède à l'initialisation de l'interface de comparaison. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_comparable_object_iface_init(GComparableObjectInterface *iface) { iface->compare = g_known_immediate_operand_compare; } /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * * Description : Procède à l'initialisation de l'interface de détermination. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_hashable_object_iface_init(GHashableObjectInterface *iface) { iface->hash = g_known_immediate_operand_hash; } /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * * Description : Procède à l'initialisation de l'interface de sérialisation. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_serializable_iface_init(GSerializableObjectInterface *iface) { iface->load = g_known_immediate_operand_load; iface->store = g_known_immediate_operand_store; } /****************************************************************************** * * * Paramètres : iface = interface GLib à initialiser. * * * * Description : Procède à l'initialisation de l'interface d'exportation. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_string_builder_iface_init(GStringBuilderInterface *iface) { iface->to_string = g_known_immediate_operand_to_string; } /****************************************************************************** * * * 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; } /****************************************************************************** * * * Paramètres : operand = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_dispose(GObject *object) { G_OBJECT_CLASS(g_known_immediate_operand_parent_class)->dispose(object); } /****************************************************************************** * * * Paramètres : object = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_known_immediate_operand_finalize(GObject *object) { GKnownImmediateOperand *operand; /* Version spécialisée */ operand = G_KNOWN_IMMEDIATE_OPERAND(object); if (operand->alt_text != NULL) free(operand->alt_text); G_OBJECT_CLASS(g_known_immediate_operand_parent_class)->finalize(object); } /****************************************************************************** * * * 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 : - * * * ******************************************************************************/ GArchOperand *g_known_immediate_operand_new(const GImmediateOperand *old, const char *alt) { GKnownImmediateOperand *result; /* Remplacement à retourner */ result = g_object_new(G_TYPE_KNOWN_IMMEDIATE_OPERAND, NULL); if (!g_known_immediate_operand_create(result, old, alt)) g_clear_object(&result); return G_ARCH_OPERAND(result); } /****************************************************************************** * * * Paramètres : operand = instance à initialiser pleinement. * * old = opérande à venir copier avant son remplacement. * * alt = texte alternatif à présenter pour l'impression. * * * * Description : Met en place un opérande remplaçant visuellement une valeur. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool g_known_immediate_operand_create(GKnownImmediateOperand *operand, const GImmediateOperand *old, const char *alt) { bool result; /* Bilan à retourner */ immop_extra_data_t extra; /* Données insérées à consulter*/ result = true; extra = GET_IMM_OP_EXTRA(old); SET_IMM_OP_EXTRA(operand, &extra); G_IMMEDIATE_OPERAND(operand)->raw = G_IMMEDIATE_OPERAND(old)->raw; operand->alt_text = strdup(alt); return result; } /* ---------------------------------------------------------------------------------- */ /* COMPARAISON DETAILLEE DE DEUX OBJETS */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : object = premier objet à consulter pour une comparaison. * * other = second objet à consulter pour une comparaison. * * * * Description : Réalise une comparaison étendue entre objets. * * * * Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ static int g_known_immediate_operand_compare(const GComparableObject *object, const GComparableObject *other) { 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); parent_iface = g_type_interface_peek_parent(iface); 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 : 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_known_immediate_operand_hash(const GHashableObject *object) { guint result; /* Valeur à retourner */ GHashableObjectInterface *iface; /* Interface utilisée */ GHashableObjectInterface *parent_iface; /* Interface parente */ GKnownImmediateOperand *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_KNOWN_IMMEDIATE_OPERAND(object); result ^= g_str_hash(operand->alt_text); return result; } /* ---------------------------------------------------------------------------------- */ /* MECANISMES DE CONSERVATION ET RESTAURATION */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : object = élément GLib à constuire. * * storage = conservateur de données à manipuler. * * fd = flux ouvert en lecture. * * * * Description : Charge un objet depuis un flux de données. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static bool g_known_immediate_operand_load(GSerializableObject *object, GObjectStorage *storage, int fd) { bool result; /* Bilan à retourner */ 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_iface = g_type_interface_peek_parent(iface); result = parent_iface->load(object, storage, fd); if (result) { init_sized_binary(&str); load_sized_binary_as_string(&str, fd); operand = G_KNOWN_IMMEDIATE_OPERAND(object); operand->alt_text = strdup(str.static_data); exit_sized_binary(&str); } 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_known_immediate_operand_store(const GSerializableObject *object, GObjectStorage *storage, int fd) { bool result; /* Bilan à retourner */ GSerializableObjectInterface *iface; /* Interface utilisée */ GSerializableObjectInterface *parent_iface; /* Interface parente */ GKnownImmediateOperand *operand; /* Version spécialisée */ sized_binary_t str; /* Texte alternatif à conserver*/ 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_KNOWN_IMMEDIATE_OPERAND(object); setup_sized_binary_from_static_string(&str, operand->alt_text); result = store_sized_binary_as_string(&str, fd); exit: return result; } /* ---------------------------------------------------------------------------------- */ /* EXPORTATION SOUS FORME DE CHAINE DE CARACTERES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * 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 : Exporte une chaîne de caractères à partir d'un objet. * * * * Retour : Bilan de l'opération. * * * * Remarques : La sortie out est à nettoyer avec exit_sized_binary() après * * usage. * * * ******************************************************************************/ static bool g_known_immediate_operand_to_string(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out) { bool result; /* Bilan à retourner */ const GKnownImmediateOperand *operand; /* Version spécialisée */ result = true; operand = G_KNOWN_IMMEDIATE_OPERAND(builder); add_to_sized_binary(out, operand->alt_text, strlen(operand->alt_text)); return result; }