summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/Makefile.am11
-rw-r--r--src/arch/instruction-int.h126
-rw-r--r--src/arch/instruction-ui-int.h55
-rw-r--r--src/arch/instruction-ui.c254
-rw-r--r--src/arch/instruction-ui.h41
-rw-r--r--src/arch/instruction.c1935
-rw-r--r--src/arch/instruction.h316
-rw-r--r--src/arch/instructions/Makefile.am11
-rw-r--r--src/arch/instructions/raw-int.h56
-rw-r--r--src/arch/instructions/raw-ui.c261
-rw-r--r--src/arch/instructions/raw-ui.h37
-rw-r--r--src/arch/instructions/raw.c696
-rw-r--r--src/arch/instructions/raw.h41
-rw-r--r--src/arch/instructions/undefined-int.h52
-rw-r--r--src/arch/instructions/undefined-ui.c102
-rw-r--r--src/arch/instructions/undefined-ui.h37
-rw-r--r--src/arch/instructions/undefined.c383
-rw-r--r--src/arch/instructions/undefined.h28
-rw-r--r--src/arch/vmpa.h29
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/cpp.h2
-rw-r--r--src/core/Makefile.am3
-rw-r--r--src/core/core.c21
-rw-r--r--src/core/core.h5
-rw-r--r--src/core/processors.c23
-rw-r--r--src/core/processors.h6
-rw-r--r--src/glibext/bufferline.c334
-rw-r--r--src/glibext/bufferline.h14
-rw-r--r--src/glibext/options/asm.h19
29 files changed, 2326 insertions, 2573 deletions
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 127ca4c..6683854 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -13,18 +13,17 @@ noinst_LTLIBRARIES = libarch.la libarchui.la
# libarch_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
# libarch_la_LIBADD = \
-# instructions/libarchinstructions.la \
# operands/libarchoperands.la
-# instruction-int.h \
-# instruction.h instruction.c \
#
# processor-int.h \
# processor.h processor.c \
#
libarch_la_SOURCES = \
+ instruction-int.h \
+ instruction.h instruction.c \
operand-int.h \
operand.h operand.c \
register-int.h \
@@ -34,10 +33,13 @@ libarch_la_SOURCES = \
libarch_la_CFLAGS = $(LIBGOBJ_CFLAGS)
libarch_la_LIBADD = \
+ instructions/libarchinstructions.la \
operands/libarchoperands.la
libarchui_la_SOURCES = \
+ instruction-ui-int.h \
+ instruction-ui.h instruction-ui.c \
operand-ui-int.h \
operand-ui.h operand-ui.c
@@ -52,5 +54,4 @@ devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libarch_la_SOURCES:%c=) $(libarchui_la_SOURCES:%c=)
-#SUBDIRS = instructions operands
-SUBDIRS = operands
+SUBDIRS = instructions operands
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 7dbbe27..d426cea 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* instruction-int.h - prototypes pour la définition générique interne des instructions
*
- * Copyright (C) 2008-2020 Cyrille Bagard
+ * Copyright (C) 2008-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,18 +25,29 @@
#define _ARCH_INSTRUCTION_INT_H
+#include <stdint.h>
+
+
#include "instruction.h"
-#include "../analysis/storage/storage.h"
#include "../common/array.h"
-#include "../glibext/objhole.h"
+#include "../glibext/objhole-int.h"
/* Indique l'encodage d'une instruction de façon détaillée. */
-typedef const char * (* get_instruction_encoding_fc) (const GArchInstruction *);
+typedef char * (* get_instruction_encoding_fc) (const GArchInstruction *);
/* Fournit le nom humain de l'instruction manipulée. */
-typedef const char * (* get_instruction_keyword_fc) (GArchInstruction * );
+typedef char * (* get_instruction_keyword_fc) (const GArchInstruction *);
+
+
+
+#if 0
+
+#include "../analysis/storage/storage.h"
+
+
+
/* Complète un désassemblage accompli pour une instruction. */
typedef void (* call_instruction_hook_fc) (GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GExeFormat *);
@@ -67,80 +78,45 @@ typedef bool (* store_instruction_fc) (GArchInstruction *, GObjectStorage *, pac
-/* Informations glissées dans la structure GObject de GArchOperand */
-typedef struct _instr_extra_data_t
-{
- itid_t uid; /* Identifiant unique du type */
-
- ArchInstrFlag flags; /* Informations complémentaires*/
-
-} instr_extra_data_t;
+#endif
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef union _instr_obj_extra_t
-{
- instr_extra_data_t data; /* Données embarquées */
- lockable_obj_extra_t lockable; /* Gestion d'accès aux fanions */
-} instr_obj_extra_t;
+/* Conservation d'une adresse et de propriétées */
+typedef unsigned long compact_ins_link_t;
/* Définition générique d'une instruction d'architecture (instance) */
struct _GArchInstruction
{
- GObject parent; /* A laisser en premier */
+ GThickObject parent; /* A laisser en premier */
-#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+ GBinaryPortion *rel_area; /* Zone de référence */
+ rel_mrange_t rel_range; /* Emplacement compressé */
/**
- * L'inclusion des informations suivantes dépend de l'architecture.
- *
- * Si la structure GObject possède un trou, on remplit de préférence
- * ce dernier.
+ * A laisser à la suite de la localisation précédente pour éviter
+ * les espaces vide dans la structure.
*/
+ uint16_t link_count; /* Quantité de liens établis */
- instr_obj_extra_t extra; /* Externalisation embarquée */
-
-#endif
-
- mrange_t range; /* Emplacement en mémoire */
+ compact_ins_link_t *links; /* Liste de ces liens */
flat_array_t *operands; /* Liste des opérandes */
- /**
- * Il existe le besoin indéniable d'un verrou pour les accès aux instructions
- * liées. Il faut par ailleurs un verrou distinct pour les sources et les
- * destinations car une même instruction peut boucler sur elle même et la
- * fonction g_arch_instruction_change_link() pose des verrous sur les
- * deux extrémités.
- *
- * La GLib propose les fonctions g_bit_lock() / g_bit_unlock(), légères mais
- * sans distinction entre lectures et écritures. Tant pis : la réduction de
- * l'empreinte mémoire prime !
- *
- * Par contre la documentation indique :
- *
- * """
- * Attempting to lock on two different bits within the same integer is not supported.
- * """
- *
- * Donc on doit bien conserver un compteur distinct pour chaque extrémité.
- * Cela correspond de toute façon à la définition optimisée des tableaux
- * suivante.
- */
-
- flat_array_t *from; /* Origines des références */
- flat_array_t *to; /* Instructions visées */
-
};
/* Définition générique d'une instruction d'architecture (classe) */
struct _GArchInstructionClass
{
- GObjectClass parent; /* A laisser en premier */
+ GThickObjectClass parent; /* A laisser en premier */
get_instruction_encoding_fc get_encoding; /* Obtention de l'encodage */
get_instruction_keyword_fc get_keyword; /* Texte humain équivalent */
+
+#if 0
+
+ //get_instruction_encoding_fc get_encoding; /* Obtention de l'encodage */
+ //get_instruction_keyword_fc get_keyword; /* Texte humain équivalent */
call_instruction_hook_fc call_hook; /* Décrochages éventuels */
build_instruction_tooltip_fc build_tooltip; /* Construction d'une bulle*/
get_instruction_desc_fc get_desc; /* Description assez complète */
@@ -155,22 +131,50 @@ struct _GArchInstructionClass
//get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */
+#endif
+
};
+/* Met en place une instruction d'architecture. */
+bool g_arch_instruction_create(GArchInstruction *, itid_t);
+
+
+
/**
* Accès aux informations éventuellement déportées.
*/
-#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
-# define GET_ARCH_INSTR_EXTRA(ins) (instr_extra_data_t *)&ins->extra
+#define ARCH_INSTRUCTION_EXTRA_DATA \
+ \
+ unsigned int reserved : GOBJECT_RESERVED_EXTRA_BITS; \
+ \
+ /** \
+ * itid_t \
+ */ \
+ unsigned int tid : 16; \
+ \
+ /** \
+ * ArchOperandFlag \
+ */ \
+ unsigned int flags : 8;
-#else
-# define GET_ARCH_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), instr_extra_data_t)
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _instruction_extra_data_t
+{
+ ARCH_INSTRUCTION_EXTRA_DATA; /* Socle commun */
+
+} instruction_extra_data_t;
+
+
+#define GET_ARCH_INSTR_EXTRA(op) \
+ GET_GOBJECT_EXTRA(op, instruction_extra_data_t)
+
+#define SET_ARCH_INSTR_EXTRA(op, data) \
+ SET_GOBJECT_EXTRA(op, instruction_extra_data_t, data)
-#endif
/**
diff --git a/src/arch/instruction-ui-int.h b/src/arch/instruction-ui-int.h
new file mode 100644
index 0000000..b07f40c
--- /dev/null
+++ b/src/arch/instruction-ui-int.h
@@ -0,0 +1,55 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instruction-ui-int.h - prototypes pour la définition générique interne des instructions 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_INSTRUCTION_UI_INT_H
+#define _ARCH_INSTRUCTION_UI_INT_H
+
+
+#include "instruction-ui.h"
+
+
+
+#if 0
+
+/* Traduit un opérande en version humainement lisible. */
+typedef void (* print_operand_ui_fc) (const GArchOperandUI *, GBufferLine *);
+
+/* Construit un petit résumé concis de l'opérande. */
+typedef char * (* build_operand_ui_tooltip_fc) (const GArchOperandUI *, const GLoadedBinary *);
+
+
+
+/* Définition générique d'un opérande d'architecture (interface) */
+struct _GArchOperandUIInterface
+{
+ GTypeInterface base_iface; /* A laisser en premier */
+
+ print_operand_ui_fc print; /* Texte humain équivalent */
+ build_operand_ui_tooltip_fc build_tooltip; /* Définition de description*/
+
+};
+
+#endif
+
+
+#endif /* _ARCH_INSTRUCTION_UI_INT_H */
diff --git a/src/arch/instruction-ui.c b/src/arch/instruction-ui.c
new file mode 100644
index 0000000..7f923d8
--- /dev/null
+++ b/src/arch/instruction-ui.c
@@ -0,0 +1,254 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instruction-ui.c - gestion générique des instructions 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 "instruction-ui.h"
+
+
+#include "instruction-int.h"
+#include "operand-ui.h"
+#include "../analysis/content.h"
+#include "../common/cpp.h"
+#include "../glibext/generator-int.h"
+#include "../glibext/options/asm.h"
+
+
+
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags g_arch_instruction_ui_get_flags(const GTokenGenerator *, size_t, size_t);
+
+/* Etablit dans une ligne de rendu le contenu représenté. */
+static void g_arch_instruction_ui_populate_line(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *);
+
+#if 0
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static void g_arch_instruction_ui_compute_cursor(const GArchInstruction *, gint, size_t, size_t, GLineCursor **);
+
+/* Détermine si le conteneur s'inscrit dans une plage donnée. */
+static int g_arch_instruction_ui_contain_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *);
+
+#endif
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OFFRE DE CAPACITES DE GENERATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *iface)
+{
+ /**
+ * La procédure par défaut de iface->count() ne doit pas être retouchée !
+ */
+
+ iface->get_flags = g_arch_instruction_ui_get_flags;
+ iface->populate = g_arch_instruction_ui_populate_line;
+
+#if 0
+ iface->compute = (linegen_compute_fc)g_arch_instruction_ui_compute_cursor;
+ iface->contain = (linegen_contain_fc)g_arch_instruction_ui_contain_cursor;
+#endif
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* *
+* Description : Renseigne sur les propriétés liées à un générateur. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags g_arch_instruction_ui_get_flags(const GTokenGenerator *generator, size_t index, size_t repeat)
+{
+ BufferLineFlags result; /* Fanions à retourner */
+
+ result = BLF_HAS_CODE;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* line = ligne de rendu à compléter. *
+* data = éventuelle donnée complémentaire fournie. *
+* *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_ui_populate_line(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)
+{
+ GArchInstruction *instr; /* Version spécialisée */
+ GBinContent *content; /* Contenu brut d'origine */
+ mrange_t range; /* Emplacement couvert */
+ char *key; /* Mot clef principal */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+
+ instr = G_ARCH_INSTRUCTION(generator);
+ content = G_BIN_CONTENT(data);
+
+ /* Prologue */
+
+ if (g_arch_instruction_get_range(instr, &range))
+ {
+ g_buffer_line_fill_physical(line, ACO_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ g_buffer_line_fill_virtual(line, ACO_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ g_buffer_line_fill_content(line, ACO_BINARY, content, &range, VMPA_NO_PHYSICAL);
+
+ }
+
+ /* Instruction proprement dite */
+
+ key = g_arch_instruction_get_keyword(instr);
+
+ g_buffer_line_append_text(line, ACO_ASSEMBLY_HEAD, TRT_INSTRUCTION, SL(key), NULL, G_OBJECT(instr));
+
+ free(key);
+
+ /* Liste des opérandes */
+
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ count = g_arch_instruction_count_operands(instr);
+
+ if (count > 0)
+ {
+ op = g_arch_instruction_get_operand(instr, 0);
+ g_arch_operand_ui_print(G_ARCH_OPERAND_UI(op), line);
+ unref_object(op);
+
+ for (i = 1; i < count; i++)
+ {
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_PUNCT, STCSL(","), NULL, NULL);
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_NONE, STCSL(" "), NULL, NULL);
+
+ op = g_arch_instruction_get_operand(instr, i);
+ g_arch_operand_ui_print(G_ARCH_OPERAND_UI(op), line);
+ unref_object(op);
+
+ }
+
+ }
+
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
+
+}
+
+
+#if 0
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* cursor = emplacement à constituer. [OUT] *
+* *
+* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_ui_compute_cursor(const GArchInstruction *instr, gint x, size_t index, size_t repeat, GLineCursor **cursor)
+{
+ *cursor = g_binary_cursor_new();
+
+ g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&instr->range));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = générateur à consulter. *
+* index = indice de cette même ligne dans le tampon global. *
+* repeat = indice d'utilisations successives du générateur. *
+* cursor = emplacement à analyser. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int g_arch_instruction_ui_contain_cursor(const GArchInstruction *instr, size_t index, size_t repeat, const GLineCursor *cursor)
+{
+ int result; /* Conclusion à retourner */
+ vmpa2t addr; /* Autre emplacement à comparer*/
+
+ assert(G_IS_BINARY_CURSOR(cursor));
+
+ g_binary_cursor_retrieve(G_BINARY_CURSOR(cursor), &addr);
+
+ result = cmp_mrange_with_vmpa(&instr->range, &addr);
+
+ return result;
+
+}
+
+
+#endif
diff --git a/src/arch/instruction-ui.h b/src/arch/instruction-ui.h
new file mode 100644
index 0000000..62a52f2
--- /dev/null
+++ b/src/arch/instruction-ui.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * instruction-ui.h - prototypes pour la gestion générique des instructions 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_INSTRUCTION_UI_H
+#define _ARCH_INSTRUCTION_UI_H
+
+
+#include "../glibext/generator.h"
+#include "../glibext/helpers.h"
+
+
+
+/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+void g_arch_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *);
+
+
+
+#endif /* _ARCH_INSTRUCTION_UI_H */
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index cd1e9c7..36bdecb 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* instruction.c - gestion générique des instructions
*
- * Copyright (C) 2008-2020 Cyrille Bagard
+ * Copyright (C) 2008-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,102 +26,93 @@
#include <assert.h>
#include <malloc.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include <limits.h>
#include <string.h>
#include "instruction-int.h"
-#include "storage.h"
-#include "../analysis/storage/serialize-int.h"
-#include "../core/columns.h"
+#include "../common/leb128.h"
#include "../core/logs.h"
#include "../core/processors.h"
-#include "../glibext/gbinarycursor.h"
-#include "../glibext/linegen-int.h"
+#include "../glibext/serialize-int.h"
-/* Initialise la classe générique des instructions. */
-static void g_arch_instruction_class_init(GArchInstructionClass *);
-
-/* Initialise une instance d'opérande d'architecture. */
-static void g_arch_instruction_init(GArchInstruction *);
-/* Procède à l'initialisation de l'interface de génération. */
-static void g_arch_instruction_generator_init(GLineGeneratorInterface *);
-/* Procède à l'initialisation de l'interface de sérialisation. */
-static void g_arch_instruction_serializable_init(GSerializableObjectInterface *);
-
-/* Supprime toutes les références externes. */
-static void g_arch_instruction_dispose(GArchInstruction *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_arch_instruction_finalize(GArchInstruction *);
+/* ----------------------- DEFINITION GENERIQUE D'INSTRUCTION ----------------------- */
+/* Initialise la classe générique des instructions. */
+static void g_arch_instruction_class_init(GArchInstructionClass *);
+/* Procède à l'initialisation de l'interface de sérialisation. */
+static void g_arch_instruction_serializable_object_iface_init(GSerializableObjectInterface *);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_arch_instruction_load_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Initialise une instance d'opérande d'architecture. */
+static void g_arch_instruction_init(GArchInstruction *);
-/* Sauvegarde toutes les destinations d'une instruction. */
-bool g_arch_instruction_store_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Supprime toutes les références externes. */
+static void g_arch_instruction_dispose(GObject *);
+/* Procède à la libération totale de la mémoire. */
+static void g_arch_instruction_finalize(GObject *);
+/* ------------------- DEFINITION DES LIAISONS ENTRE INSTRUCTIONS ------------------- */
-/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
+#define COMPACT_INS_LINK_MASK_DIR (1ul << (__WORDSIZE - 1))
+#define COMPACT_INS_LINK_MASK_TYPE 0xf
+#define COMPACT_INS_LINK_MASK (COMPACT_INS_LINK_MASK_DIR | COMPACT_INS_LINK_MASK_TYPE)
-/* Indique le nombre de ligne prêtes à être générées. */
-static size_t g_arch_instruction_count_lines(const GArchInstruction *);
+#define COMPACT_INS_LINK_FROM (0ul << (__WORDSIZE - 1))
+#define COMPACT_INS_LINK_TO (1ul << (__WORDSIZE - 1))
-#ifdef INCLUDE_GTK_SUPPORT
+#define COMPACT_INS_LINK_DIR(cl) (cl & COMPACT_INS_LINK_MASK_DIR)
+#define COMPACT_INS_LINK_PTR(cl) ((GArchInstruction *)(cl & ~COMPACT_INS_LINK_MASK))
+#define COMPACT_INS_LINK_TYPE(cl) (cl & COMPACT_INS_LINK_MASK_TYPE)
-/* Retrouve l'emplacement correspondant à une position donnée. */
-static void g_arch_instruction_compute_cursor(const GArchInstruction *, gint, size_t, size_t, GLineCursor **);
+#define MAKE_COMPACT_INS_LINK(d, i, t) \
+ (compact_ins_link_t)(d | (unsigned long)i | t)
-/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static int g_arch_instruction_contain_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *);
+/* Détermine si un type de lien existe dans une instruction. */
+static bool _g_arch_instruction_has_link(const GArchInstruction *, compact_ins_link_t, InstructionLinkType);
-#endif
+/* Détermine si un lien existe entre deux instructions. */
+static bool _g_arch_instruction_has_link_with(const GArchInstruction *, compact_ins_link_t, const GArchInstruction *);
-/* Renseigne sur les propriétés liées à un générateur. */
-static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *, size_t, size_t);
+/* Fournit la quantité d'instructions pointant vers une autre. */
+static size_t _g_arch_instruction_count_links(const GArchInstruction *, compact_ins_link_t);
-/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* Fournit les détails d'un lien donné avec une instruction. */
+static GArchInstruction *_g_arch_instruction_get_linked_instruction(const GArchInstruction *, size_t, compact_ins_link_t, InstructionLinkType *);
-/* Imprime dans une ligne de rendu le contenu représenté. */
-static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
-/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+/* ------------------- MECANISMES DE CONSERVATION ET RESTAURATION ------------------- */
-/* Charge un contenu depuis une mémoire tampon. */
-static bool _g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Charge un objet depuis un flux de données. */
+static bool g_arch_instruction_load(GSerializableObject *, GObjectStorage *, int);
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Sauvegarde un objet dans un flux de données. */
+static bool g_arch_instruction_store(const GSerializableObject *, GObjectStorage *, int);
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool _g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_arch_instruction_store(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION GENERIQUE D'INSTRUCTION */
+/* ---------------------------------------------------------------------------------- */
/* Indique le type défini pour une instruction d'architecture. */
-G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_init)
- G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_instruction_serializable_init));
+G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_THICK_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_instruction_serializable_object_iface_init)
+ G_IMPLEMENT_INTERFACE_IF_SYM(g_token_generator_get_type, g_arch_instruction_ui_token_generator_iface_init));
+
/******************************************************************************
@@ -139,28 +130,20 @@ G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
static void g_arch_instruction_class_init(GArchInstructionClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
- GArchInstructionClass *instr; /* Encore une autre vision... */
object = G_OBJECT_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_instruction_dispose;
- object->finalize = (GObjectFinalizeFunc)g_arch_instruction_finalize;
-
- instr = G_ARCH_INSTRUCTION_CLASS(klass);
-
- instr->print = (print_instruction_fc)_g_arch_instruction_print;
-
- instr->load = (load_instruction_fc)_g_arch_instruction_load;
- instr->store = (store_instruction_fc)_g_arch_instruction_store;
+ object->dispose = g_arch_instruction_dispose;
+ object->finalize = g_arch_instruction_finalize;
}
/******************************************************************************
* *
-* Paramètres : instr = instance à initialiser. *
+* Paramètres : iface = interface GLib à initialiser. *
* *
-* Description : Initialise une instance d'instruction d'architecture. *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
* *
* Retour : - *
* *
@@ -168,27 +151,19 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
* *
******************************************************************************/
-static void g_arch_instruction_init(GArchInstruction *instr)
+static void g_arch_instruction_serializable_object_iface_init(GSerializableObjectInterface *iface)
{
- instr_extra_data_t *extra; /* Données insérées à modifier */
-
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- INIT_GOBJECT_EXTRA_LOCK(extra);
-
- instr->operands = NULL;
-
- instr->from = NULL;
- instr->to = NULL;
+ iface->load = g_arch_instruction_load;
+ iface->store = g_arch_instruction_store;
}
/******************************************************************************
* *
-* Paramètres : iface = interface GLib à initialiser. *
+* Paramètres : instr = instance à initialiser. *
* *
-* Description : Procède à l'initialisation de l'interface de génération. *
+* Description : Initialise une instance d'instruction d'architecture. *
* *
* Retour : - *
* *
@@ -196,42 +171,22 @@ static void g_arch_instruction_init(GArchInstruction *instr)
* *
******************************************************************************/
-static void g_arch_instruction_generator_init(GLineGeneratorInterface *iface)
+static void g_arch_instruction_init(GArchInstruction *instr)
{
- iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
-#ifdef INCLUDE_GTK_SUPPORT
- iface->compute = (linegen_compute_fc)g_arch_instruction_compute_cursor;
- iface->contain = (linegen_contain_fc)g_arch_instruction_contain_cursor;
-#endif
- iface->get_flags = (linegen_get_flags_fc)g_arch_instruction_get_flags2;
- iface->print = (linegen_print_fc)g_arch_instruction_print;
-
-}
+ instr->rel_area = NULL;
+ instr->link_count = 0;
-/******************************************************************************
-* *
-* Paramètres : iface = interface GLib à initialiser. *
-* *
-* Description : Procède à l'initialisation de l'interface de sérialisation. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ instr->links = NULL;
-static void g_arch_instruction_serializable_init(GSerializableObjectInterface *iface)
-{
- iface->load = (load_serializable_object_cb)g_arch_instruction_load;
- iface->store = (store_serializable_object_cb)g_arch_instruction_store;
+ instr->operands = NULL;
}
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -241,43 +196,38 @@ static void g_arch_instruction_serializable_init(GSerializableObjectInterface *i
* *
******************************************************************************/
-static void g_arch_instruction_dispose(GArchInstruction *instr)
+static void g_arch_instruction_dispose(GObject *object)
{
+ GArchInstruction *instr; /* Version spécialisée */
size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
GArchOperand *op; /* Opérande à manipuler */
- g_arch_instruction_lock_operands(instr);
+ instr = G_ARCH_INSTRUCTION(object);
+
+ g_clear_object(&instr->rel_area);
+
+ g_arch_instruction_delete_all_links(instr);
- count = _g_arch_instruction_count_operands(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ count = g_arch_instruction_count_operands(instr);
for (i = 0; i < count; i++)
{
- op = _g_arch_instruction_get_operand(instr, 0);
+ op = g_arch_instruction_get_operand(instr, 0);
rem_item_from_flat_array(&instr->operands, 0, sizeof(GArchOperand *));
/**
* Une fois pour l'obtention, une autre pour la libération !
*/
- g_object_unref(G_OBJECT(op));
- g_object_unref(G_OBJECT(op));
+ unref_object(op);
+ unref_object(op);
}
- g_arch_instruction_unlock_operands(instr);
-
-#ifndef NDEBUG
- g_arch_instruction_lock_src(instr);
- assert(count_flat_array_items(instr->from) == 0);
- g_arch_instruction_unlock_src(instr);
-#endif
-
-#ifndef NDEBUG
- g_arch_instruction_lock_dest(instr);
- assert(count_flat_array_items(instr->to) == 0);
- g_arch_instruction_unlock_dest(instr);
-#endif
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr));
@@ -286,7 +236,7 @@ static void g_arch_instruction_dispose(GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -296,38 +246,26 @@ static void g_arch_instruction_dispose(GArchInstruction *instr)
* *
******************************************************************************/
-static void g_arch_instruction_finalize(GArchInstruction *instr)
+static void g_arch_instruction_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr));
+ GArchInstruction *instr; /* Version spécialisée */
-}
+ instr = G_ARCH_INSTRUCTION(object);
+ if (instr->links != NULL)
+ free(instr->links);
-/******************************************************************************
-* *
-* Paramètres : instr = instruction quelconque à consulter. *
-* *
-* Description : Indique l'encodage d'une instruction de façon détaillée. *
-* *
-* Retour : Description humaine de l'encodage utilisé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
-{
- return G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_encoding(instr);
+ G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr));
}
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à modifier. *
-* flag = drapeau d'information complémentaire à planter. *
+* Paramètres : instr = instance à initialiser pleinement. *
+* tid = identifiant associé au type d'instructions ciblé. *
* *
-* Description : Ajoute une information complémentaire à une instruction. *
+* Description : Met en place une instruction d'architecture. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -335,22 +273,18 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
* *
******************************************************************************/
-bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
+bool g_arch_instruction_create(GArchInstruction *instr, itid_t tid)
{
bool result; /* Bilan à retourner */
- instr_extra_data_t *extra; /* Données insérées à modifier */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
- assert(flag <= AIF_HIGH_USER);
+ result = true;
extra = GET_ARCH_INSTR_EXTRA(instr);
- LOCK_GOBJECT_EXTRA(extra);
-
- result = !(extra->flags & flag);
+ extra.tid = tid;
- extra->flags |= flag;
-
- UNLOCK_GOBJECT_EXTRA(extra);
+ SET_ARCH_INSTR_EXTRA(instr, &extra);
return result;
@@ -359,33 +293,24 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à modifier. *
-* flag = drapeau d'information complémentaire à planter. *
+* Paramètres : instr = instruction quelconque à consulter. *
* *
-* Description : Retire une information complémentaire à une instruction. *
+* Description : Fournit l'identifiant correspondant à un type d'instructions.*
* *
-* Retour : Bilan de l'opération. *
+* Retour : Identifiant unique par type d'instruction et architecture. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
+itid_t g_arch_instruction_get_type_id(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- instr_extra_data_t *extra; /* Données insérées à modifier */
-
- assert(flag <= AIF_HIGH_USER);
+ itid_t result; /* Numéro à retourner */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- LOCK_GOBJECT_EXTRA(extra);
-
- result = (extra->flags & flag);
-
- extra->flags &= ~flag;
-
- UNLOCK_GOBJECT_EXTRA(extra);
+ result = extra.tid;
return result;
@@ -395,30 +320,23 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
/******************************************************************************
* *
* Paramètres : instr = instruction quelconque à consulter. *
-* flag = drapeau d'information à rechercher. *
* *
-* Description : Détermine si une instruction possède un fanion particulier. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Bilan de la détection. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
+char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- instr_extra_data_t *extra; /* Données insérées à modifier */
-
- assert(flag <= AIF_HIGH_USER);
-
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
+ char *result; /* Encodage à retourner */
+ GArchInstructionClass *class; /* Classe des instructions */
- result = (extra->flags & flag);
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
- UNLOCK_GOBJECT_EXTRA(extra);
+ result = class->get_encoding(instr);
return result;
@@ -427,28 +345,24 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à modifier. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Fournit les informations complémentaires d'une instruction. *
+* Description : Fournit le nom humain de l'instruction manipulée. *
* *
-* Retour : Eventuels drapeaux d'information complémentaire à plantés. *
+* Retour : Mot clef de bas niveau. *
* *
* Remarques : - *
* *
******************************************************************************/
-ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
+char *g_arch_instruction_get_keyword(const GArchInstruction *instr)
{
- ArchInstrFlag result; /* Fanions à retourner */
- instr_extra_data_t *extra; /* Données insérées à modifier */
-
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
+ char *result; /* Etiquette à retourner */
+ GArchInstructionClass *class; /* Classe des instructions */
- result = extra->flags;
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
- UNLOCK_GOBJECT_EXTRA(extra);
+ result = class->get_keyword(instr);
return result;
@@ -457,10 +371,12 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à consulter. *
-* uid = identifiant unique par type d'instruction. *
+* Paramètres : instr = instruction quelconque à compléter. *
+* area = portion de binaire incluant l'instruction. *
+* start = adresse virtuelle et/ou position physique. *
+* length = taille de l'instruction. *
* *
-* Description : Définit l'identifiant unique pour un ensemble d'instructions.*
+* Description : Calcule la localisation d'une instruction. *
* *
* Retour : - *
* *
@@ -468,358 +384,214 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
* *
******************************************************************************/
-void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
+void g_arch_instruction_compute_range(GArchInstruction *instr, GBinaryPortion *area, const vmpa2t *start, phys_t length)
{
- instr_extra_data_t *extra; /* Données insérées à modifier */
+ const mrange_t *a_range; /* Couverture de la portion */
+ phys_t diff; /* Décalage à appliquer */
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
+ a_range = g_binary_portion_get_range(area);
- extra->uid = uid;
+ assert(mrange_contains_addr(a_range, start));
- UNLOCK_GOBJECT_EXTRA(extra);
+ diff = compute_vmpa_diff(get_mrange_addr(a_range), start);
-}
+ instr->rel_area = area;
+ ref_object(area);
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction quelconque à consulter. *
-* *
-* Description : Fournit l'identifiant unique pour un ensemble d'instructions.*
-* *
-* Retour : Identifiant unique par type d'instruction et architecture. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
-{
- itid_t result; /* Numéro à retourner */
- instr_extra_data_t *extra; /* Données insérées à consulter*/
-
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
-
- result = extra->uid;
-
- UNLOCK_GOBJECT_EXTRA(extra);
-
- return result;
+ init_rel_mrange(&instr->rel_range, diff, length);
}
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à traiter. *
-* type = type de procédure à utiliser. *
-* proc = représentation de l'architecture utilisée. *
-* context = contexte associé à la phase de désassemblage. *
-* format = accès aux données du binaire d'origine. *
+* Paramètres : instr = instruction quelconque à consulter. *
+* range = localisation de l'instruction. [OUT] *
* *
-* Description : Complète un désassemblage accompli pour une instruction. *
+* Description : Fournit la place mémoire d'une instruction. *
* *
-* Retour : - *
+* Retour : Validité de la localisation : existence d'une définition ? *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
+bool g_arch_instruction_get_range(const GArchInstruction *instr, mrange_t *range)
{
- GArchInstructionClass *class; /* Classe des instructions */
+ bool result; /* Statut à retourner */
+ const mrange_t *a_range; /* Couverture de la portion */
+ vmpa2t start; /* Position de départ complète */
- class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+ result = (instr->rel_area != NULL);
- if (class->call_hook != NULL)
- class->call_hook(instr, type, proc, context, format);
+ if (result)
+ {
+ a_range = g_binary_portion_get_range(instr->rel_area);
-}
+ copy_vmpa(&start, get_mrange_addr(a_range));
+ advance_vmpa(&start, get_rel_mrange_offset(&instr->rel_range));
+ init_mrange(range, &start, get_rel_mrange_length(&instr->rel_range));
-/******************************************************************************
-* *
-* Paramètres : instr = instruction quelconque à modifier. *
-* address = adresse virtuelle et/ou position physique. *
-* length = taille de l'instruction. *
-* *
-* Description : Définit la localisation d'une instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ }
-void g_arch_instruction_set_range(GArchInstruction *instr, const mrange_t *range)
-{
- copy_mrange(&instr->range, range);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à consulter. *
+* Paramètres : instr = instruction à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
* *
-* Description : Fournit la place mémoire d'une instruction. *
+* Description : Ajoute une information complémentaire à une instruction. *
* *
-* Retour : Zone mémoire couverte par l'instruction. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-const mrange_t *g_arch_instruction_get_range(const GArchInstruction *instr)
+bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstructionFlag flag)
{
- return &instr->range;
+ bool result; /* Bilan à retourner */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
-}
+ assert(flag <= AIF_HIGH_USER);
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+ result = !(extra.flags & flag);
-/******************************************************************************
-* *
-* Paramètres : instr = instruction quelconque à consulter. *
-* offset = position physique dans le code binaire/NULL. [OUT] *
-* length = taille de l'instruction ou NULL. [OUT] *
-* address = adresse virtuelle ou position physique/NULL. [OUT] *
-* *
-* Description : Fournit la localisation d'une instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ extra.flags |= flag;
-void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offset, off_t *length, vmpa_t *address)
-{
- //if (offset != NULL) *offset = instr->offset;
- //if (length != NULL) *length = instr->length;
+ SET_ARCH_INSTR_EXTRA(instr, &extra);
- //if (address != NULL) *address = instr->address;
+ return result;
}
-
/******************************************************************************
* *
-* Paramètres : instr = instruction à consulter. *
-* rregs = liste des rgistres lus. [OUT] *
-* rcount = nombre de registres lus. [OUT] *
-* wregs = liste des rgistres écrits. [OUT] *
-* wcount = nombre de registres écrits. [OUT] *
+* Paramètres : instr = instruction à venir modifier. *
+* flag = drapeau d'information complémentaire à planter. *
* *
-* Description : Liste les registres lus et écrits par l'instruction. *
+* Description : Retire une information complémentaire à une instruction. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
-* Remarques : Les compteurs de références sont à décrémenter après usage ! *
+* Remarques : - *
* *
******************************************************************************/
-void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount)
+bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstructionFlag flag)
{
-#if 0
+ bool result; /* Bilan à retourner */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
- size_t i; /* Boucle de parcours */
+ assert(flag <= AIF_HIGH_USER);
- *rregs = NULL;
- *rcount = 0;
- *wregs = NULL;
- *wcount = 0;
+ extra = GET_ARCH_INSTR_EXTRA(instr);
- instr->get_rw_regs(instr, rregs, rcount, wregs, wcount);
+ result = (extra.flags & flag);
- for (i = 0; i < *rcount; i++)
- g_object_ref(G_OBJECT((*rregs)[i]));
+ extra.flags &= ~flag;
- for (i = 0; i < *wcount; i++)
- g_object_ref(G_OBJECT((*wregs)[i]));
+ SET_ARCH_INSTR_EXTRA(instr, &extra);
-#endif
+ return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* MANIPULATION DES OPERANDES */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction à mettre à jour. *
+* Paramètres : instr = instruction à venir consulter. *
+* flag = drapeau d'information à rechercher. *
* *
-* Description : Verrouille les accès à la liste des opérandes. *
+* Description : Détermine si une instruction possède un fanion particulier. *
* *
-* Retour : - *
+* Retour : Bilan de la détection. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_arch_instruction_lock_operands(GArchInstruction *instr)
+bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstructionFlag flag)
{
- lock_flat_array(&instr->operands);
+ bool result; /* Bilan à retourner */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
-}
+ assert(flag <= AIF_HIGH_USER);
+ extra = GET_ARCH_INSTR_EXTRA(instr);
-/******************************************************************************
-* *
-* Paramètres : instr = instruction à mettre à jour. *
-* *
-* Description : Déverrouille les accès à la liste des opérandes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ result = (extra.flags & flag);
-void g_arch_instruction_unlock_operands(GArchInstruction *instr)
-{
- unlock_flat_array(&instr->operands);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* operand = instruction à venir associer. *
+* Paramètres : instr = instruction à venir consulter. *
* *
-* Description : Attache un opérande supplémentaire à une instruction. *
+* Description : Fournit les particularités de l'instruction. *
* *
-* Retour : - *
+* Retour : Somme de tous les fanions associés à l'opérande. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)
+ArchInstructionFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
- GSingletonFactory *factory; /* Unise à instances uniques */
- GArchOperand *singleton; /* Instance retenue */
-
- factory = get_operands_factory();
-
- singleton = G_ARCH_OPERAND(g_singleton_factory_get_instance(factory, G_SINGLETON_CANDIDATE(operand)));
-
- g_object_unref(G_OBJECT(operand));
- g_object_unref(G_OBJECT(factory));
-
- g_arch_instruction_lock_operands(instr);
-
- add_item_to_flat_array(&instr->operands, &singleton, sizeof(GArchOperand *));
-
- g_arch_instruction_unlock_operands(instr);
+ ArchInstructionFlag result; /* Fanions à retourner */
+ instruction_extra_data_t extra; /* Données insérées à modifier */
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance à consulter. *
-* *
-* Description : Indique la quantité d'opérandes présents dans l'instruction. *
-* *
-* Retour : Nombre d'opérandes attachés. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ extra = GET_ARCH_INSTR_EXTRA(instr);
-size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)
-{
- size_t result; /* Décompte à retourner */
-
- result = count_flat_array_items(instr->operands);
+ result = extra.flags;
return result;
}
-/******************************************************************************
-* *
-* Paramètres : instr = instance à consulter. *
-* index = indice de l'opérande concerné. *
-* *
-* Description : Fournit un opérande donné d'une instruction. *
-* *
-* Retour : Opérande trouvée. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)
-{
- GArchOperand *result; /* Opérande à retourner */
- GArchOperand **ptr; /* Adresse dans le tableau */
-
- ptr = get_flat_array_item(instr->operands, index, sizeof(GArchOperand *));
-
- result = *ptr;
-
- g_object_ref(G_OBJECT(result));
-
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* old = ancienne opérande à détacher. *
-* new = nouvelle opérande à attacher. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* dir = direction du lien recherché. *
+* type = type de lien à détecter. *
* *
-* Description : Remplace un opérande d'une instruction par un autre. *
+* Description : Détermine si un type de lien existe dans une instruction. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Bilan du statut courant de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
+static bool _g_arch_instruction_has_link(const GArchInstruction *instr, compact_ins_link_t dir, InstructionLinkType type)
{
bool result; /* Bilan à retourner */
- size_t count; /* Nombre d'opérandes en place */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à manipuler */
-
- result = false;
-
- count = _g_arch_instruction_count_operands(instr);
-
- for (i = 0; i < count && !result; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
+ uint16_t i; /* Boucle de parcours */
- result = (op == old);
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- if (result)
- {
- rpl_item_in_flat_array(instr->operands, i - 1, &new, sizeof(GArchOperand *));
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- g_object_unref(G_OBJECT(old));
+ result = false;
- }
+ for (i = 0; i < instr->link_count && !result; i++)
+ result = COMPACT_INS_LINK_DIR(instr->links[i]) == dir;
return result;
@@ -828,45 +600,22 @@ bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* target = instruction à venir dissocier. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* type = type de lien à détecter. *
* *
-* Description : Détache un opérande liée d'une instruction. *
+* Description : Détermine si un type de lien amène à une instruction. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Bilan du statut courant de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *target)
+bool g_arch_instruction_has_src_link(const GArchInstruction *instr, InstructionLinkType type)
{
bool result; /* Bilan à retourner */
- size_t count; /* Nombre d'opérandes en place */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à manipuler */
-
- result = false;
-
- count = _g_arch_instruction_count_operands(instr);
- for (i = 0; i < count && !result; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
-
- result = (op == target);
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- if (result)
- {
- rem_item_from_flat_array(&instr->operands, i - 1, sizeof(GArchOperand *));
-
- g_object_unref(G_OBJECT(target));
-
- }
+ result = _g_arch_instruction_has_link(instr, COMPACT_INS_LINK_FROM, type);
return result;
@@ -875,78 +624,22 @@ bool _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
/******************************************************************************
* *
-* Paramètres : instr = instance à consulter. *
-* target = instruction à venir retrouver. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* type = type de lien à détecter. *
* *
-* Description : Détermine le chemin conduisant à un opérande. *
+* Description : Détermine si un type de lien émerge d'une instruction. *
* *
-* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
+* Retour : Bilan du statut courant de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-char *g_arch_instruction_find_operand_path(GArchInstruction *instr, const GArchOperand *target)
+bool g_arch_instruction_has_dest_link(const GArchInstruction *instr, InstructionLinkType type)
{
- char *result; /* Chemin à retourner */
- size_t count; /* Nombre d'opérandes en place */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à manipuler */
- int ret; /* Bilan d'une construction */
- char *sub_path; /* Sous-chemin emprunté */
-
- result = NULL;
-
- g_arch_instruction_lock_operands(instr);
-
- count = _g_arch_instruction_count_operands(instr);
-
- /* Première passe : accès direct */
-
- for (i = 0; i < count && result == NULL; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
-
- if (op == target)
- {
- ret = asprintf(&result, "%zu", i);
- if (ret == -1)
- {
- LOG_ERROR_N("asprintf");
- result = NULL;
- }
- }
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- /* Seconde passe : accès profond */
-
- for (i = 0; i < count && result == NULL; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
-
- sub_path = g_arch_operand_find_inner_operand_path(op, target);
-
- if (sub_path != NULL)
- {
- ret = asprintf(&result, "%zu:%s", i, sub_path);
- if (ret == -1)
- {
- LOG_ERROR_N("asprintf");
- result = NULL;
- }
-
- free(sub_path);
-
- }
-
- g_object_unref(G_OBJECT(op));
-
- }
+ bool result; /* Bilan à retourner */
- g_arch_instruction_unlock_operands(instr);
+ result = _g_arch_instruction_has_link(instr, COMPACT_INS_LINK_TO, type);
return result;
@@ -955,104 +648,65 @@ char *g_arch_instruction_find_operand_path(GArchInstruction *instr, const GArchO
/******************************************************************************
* *
-* Paramètres : instr = instance à consulter. *
-* path = chemin d'accès à un opérande à retrouver. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* dir = direction du lien recherché. *
+* linked = seconde instruction à considérer. *
* *
-* Description : Obtient l'opérande correspondant à un chemin donné. *
+* Description : Détermine si un lien existe entre deux instructions. *
* *
-* Retour : Opérande trouvé ou NULL en cas d'échec. *
+* Retour : Bilan du statut courant de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *instr, const char *path)
+static bool _g_arch_instruction_has_link_with(const GArchInstruction *instr, compact_ins_link_t dir, const GArchInstruction *linked)
{
- GArchOperand *result; /* Opérande trouvée à renvoyer */
- size_t index; /* Indice de l'opérande visé */
- char *end; /* Poursuite du parcours ? */
- GArchOperand *found; /* Opérande trouvé */
-
- result = NULL;
-
- g_arch_instruction_lock_operands(instr);
-
- /* Recherche au premier niveau */
-
- index = strtoul(path, &end, 10);
-
- if ((index == ULONG_MAX && errno == ERANGE) || (index == 0 && errno == EINVAL))
- {
- LOG_ERROR_N("strtoul");
- goto done;
- }
-
- found = _g_arch_instruction_get_operand(instr, index);
- if (found == NULL) goto done;
-
- if (*end == '\0')
- {
- result = found;
- goto done;
- }
-
- /* Recherche en profondeur */
-
- assert(*end == ':');
-
- result = g_arch_operand_get_inner_operand_from_path(found, end + 1);
+ bool result; /* Bilan à retourner */
+ uint16_t i; /* Boucle de parcours */
- g_object_unref(G_OBJECT(found));
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- done:
+ result = false;
- g_arch_instruction_unlock_operands(instr);
+ for (i = 0; i < instr->link_count && !result; i++)
+ result = COMPACT_INS_LINK_PTR(instr->links[i]) == linked;
return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* DEFINITION DES LIAISONS ENTRE INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction à mettre à jour. *
-* src = sélection de l'extrémité à traiter. *
-* lock = indique le sens du verrouillage à mener. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* src = seconde instruction à considérer. *
* *
-* Description : Met à disposition un encadrement des accès aux liens. *
+* Description : Détermine si une instruction est source d'une autre. *
* *
-* Retour : - *
+* Retour : Bilan du statut courant de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool src, bool lock)
+bool g_arch_instruction_has_src_link_with(const GArchInstruction *instr, const GArchInstruction *src)
{
- flat_array_t **array; /* Choix du tableau ciblé */
+ bool result; /* Bilan à retourner */
- array = (src ? &instr->from : &instr->to);
+ result = _g_arch_instruction_has_link_with(instr, COMPACT_INS_LINK_FROM, src);
- if (lock)
- lock_flat_array(array);
- else
- unlock_flat_array(array);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* type = type de lien à détecter. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* dest = seconde instruction à considérer. *
* *
-* Description : Détermine si un type de lien existe dans une instruction. *
+* Description : Détermine si une instruction est destination d'une autre. *
* *
* Retour : Bilan du statut courant de l'instruction. *
* *
@@ -1060,30 +714,11 @@ void g_arch_instruction_lock_unlock_links(GArchInstruction *instr, bool src, boo
* *
******************************************************************************/
-bool g_arch_instruction_has_link(GArchInstruction *instr, InstructionLinkType type)
+bool g_arch_instruction_has_dest_link_with(const GArchInstruction *instr, const GArchInstruction *dest)
{
bool result; /* Bilan à retourner */
- size_t count; /* Nombre de liens à parcourir */
- size_t i; /* Boucle de parcours */
- const instr_link_t *dlink; /* Définition de destination */
-
- result = false;
-
- g_arch_instruction_lock_dest(instr);
- count = g_arch_instruction_count_destinations(instr);
-
- for (i = 0; i < count && !result; i++)
- {
- dlink = g_arch_instruction_get_destination(instr, i);
-
- result = (dlink->type == type);
-
- unref_instr_link(dlink);
-
- }
-
- g_arch_instruction_unlock_dest(instr);
+ result = _g_arch_instruction_has_link_with(instr, COMPACT_INS_LINK_TO, dest);
return result;
@@ -1092,54 +727,53 @@ bool g_arch_instruction_has_link(GArchInstruction *instr, InstructionLinkType ty
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les informations sont à manipuler. *
* dest = ligne visée par la liaison (côté destination). *
+* type = type de lien à construire. *
* *
-* Description : Détermine si un lien est déjà établi entre deux instructions.*
+* Description : Etablit un lien entre deux instructions. *
* *
-* Retour : Bilan de l'état actuel des liaisons. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruction *dest)
+void g_arch_instruction_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type)
{
- bool result; /* Bilan à retourner */
- size_t count; /* Nombre de liens à parcourir */
- size_t i; /* Boucle de parcours */
- const instr_link_t *dlink; /* Définition de destination */
+ compact_ins_link_t new_from; /* Nouvel enregistrement #1 */
+ compact_ins_link_t new_to; /* Nouvel enregistrement #2 */
- result = false;
+ new_from = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_FROM, instr, type);
+ ref_object(instr);
- g_arch_instruction_lock_dest(instr);
+ new_to = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_TO, dest, type);
+ ref_object(dest);
- count = g_arch_instruction_count_destinations(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+ g_thick_object_lock(G_THICK_OBJECT(dest));
- for (i = 0; i < count && !result; i++)
- {
- dlink = g_arch_instruction_get_destination(instr, i);
-
- result = (dlink->linked == dest);
+ dest->links = realloc(dest->links, ++dest->link_count * sizeof(compact_ins_link_t));
- unref_instr_link(dlink);
+ dest->links[dest->link_count - 1] = new_from;
- }
+ instr->links = realloc(instr->links, ++instr->link_count * sizeof(compact_ins_link_t));
- g_arch_instruction_unlock_dest(instr);
+ instr->links[instr->link_count - 1] = new_to;
- return result;
+ g_thick_object_unlock(G_THICK_OBJECT(dest));
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
}
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les informations sont à manipuler. *
* dest = ligne visée par la liaison (côté destination). *
* type = type de lien à construire. *
* *
-* Description : Etablit un lien entre deux instructions. *
+* Description : Supprime un lien entre deux instructions. *
* *
* Retour : - *
* *
@@ -1147,43 +781,59 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct
* *
******************************************************************************/
-void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type)
+void g_arch_instruction_unlink(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType type)
{
- instr_link_t new_src; /* Nouveau lien à définir #1 */
- instr_link_t new_dst; /* Nouveau lien à définir #2 */
+ compact_ins_link_t old_from; /* Ancien enregistrement #1 */
+ compact_ins_link_t old_to; /* Ancien enregistrement #2 */
+ uint16_t i_from; /* Boucle de parcours #1 */
+ uint16_t i_to; /* Boucle de parcours #2 */
+ bool status; /* Bilan des recherches */
+
+ old_from = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_FROM, instr, type);
+
+ old_to = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_TO, dest, type);
- /* Côté destination */
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+ g_thick_object_lock(G_THICK_OBJECT(dest));
- new_src.linked = instr;
- new_src.type = type;
+ for (i_from = 0; i_from < dest->link_count; i_from++)
+ if (dest->links[i_from] == old_from)
+ break;
- ref_instr_link((&new_src));
+ for (i_to = 0; i_to < instr->link_count; i_to++)
+ if (instr->links[i_to] == old_to)
+ break;
- /* Côté point de départ */
+ assert((i_from < dest->link_count && i_to < instr->link_count)
+ || (i_from == dest->link_count && i_to == instr->link_count));
- new_dst.linked = dest;
- new_dst.type = type;
+ status = (i_from < dest->link_count && i_to < instr->link_count);
- ref_instr_link((&new_dst));
+ if (status)
+ {
+ if ((i_from + 1) < dest->link_count)
+ memmove(&dest->links[i_from], &dest->links[i_from + 1],
+ (dest->link_count - i_from - 1) * sizeof(compact_ins_link_t));
- /* Ajout dans le respect d'une cohérence globale */
+ dest->links = realloc(dest->links, --dest->link_count * sizeof(compact_ins_link_t));
- g_arch_instruction_lock_src(dest);
- g_arch_instruction_lock_dest(instr);
+ if ((i_to + 1) < instr->link_count)
+ memmove(&instr->links[i_to], &instr->links[i_to + 1],
+ (instr->link_count - i_to - 1) * sizeof(compact_ins_link_t));
- add_item_to_flat_array(&dest->from, &new_src, sizeof(instr_link_t));
+ instr->links = realloc(instr->links, --instr->link_count * sizeof(compact_ins_link_t));
- add_item_to_flat_array(&instr->to, &new_dst, sizeof(instr_link_t));
+ }
- g_arch_instruction_unlock_dest(instr);
- g_arch_instruction_unlock_src(dest);
+ g_thick_object_unlock(G_THICK_OBJECT(dest));
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
}
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les informations sont à manipuler. *
* dest = ligne visée par la liaison (côté destination). *
* old = ancien type de lien construit. *
* new = nouveau type de lien à construire. *
@@ -1199,67 +849,43 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des
bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType old, InstructionLinkType new)
{
bool result; /* Bilan à retourner */
- size_t count; /* Raccourci pour la lecture */
- size_t i; /* Boucle de parcours */
- instr_link_t *slink; /* Définition de source */
- instr_link_t *dlink; /* Définition de destination */
-
- result = false;
+ compact_ins_link_t old_from; /* Ancien enregistrement #1 */
+ compact_ins_link_t new_from; /* Nouvel enregistrement #1 */
+ compact_ins_link_t old_to; /* Ancien enregistrement #2 */
+ compact_ins_link_t new_to; /* Nouvel enregistrement #2 */
+ uint16_t i_from; /* Boucle de parcours #1 */
+ uint16_t i_to; /* Boucle de parcours #2 */
- /**
- * Note : pour la récupération des liens de sources et de destinations,
- * on n'utilise pas les fonctions g_arch_instruction_get_(source|destination)(),
- * qui renvoient un pointeur non modifiable.
- *
- * On a en effet besoin de modifier le type de lien.
- */
+ old_from = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_FROM, instr, old);
+ new_from = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_FROM, instr, new);
+ old_to = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_TO, dest, old);
+ new_to = MAKE_COMPACT_INS_LINK(COMPACT_INS_LINK_TO, dest, new);
- g_arch_instruction_lock_src(dest);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+ g_thick_object_lock(G_THICK_OBJECT(dest));
- /* Côté destination */
-
- count = g_arch_instruction_count_sources(dest);
-
- for (i = 0; i < count; i++)
- {
- slink = get_flat_array_item(dest->from, i, sizeof(instr_link_t));
-
- if (slink->linked == instr && slink->type == old)
+ for (i_from = 0; i_from < dest->link_count; i_from++)
+ if (dest->links[i_from] == old_from)
break;
- }
-
- if (i == count)
- goto gaicl_exit;
+ for (i_to = 0; i_to < instr->link_count; i_to++)
+ if (instr->links[i_to] == old_to)
+ break;
- /* Côté point de départ */
+ assert((i_from < dest->link_count && i_to < instr->link_count)
+ || (i_from == dest->link_count && i_to == instr->link_count));
- count = g_arch_instruction_count_destinations(instr);
+ result = (i_from < dest->link_count && i_to < instr->link_count);
- for (i = 0; i < count; i++)
+ if (result)
{
- dlink = get_flat_array_item(instr->to, i, sizeof(instr_link_t));
-
- if (dlink->linked == dest && dlink->type == old)
- break;
-
+ dest->links[i_from] = new_from;
+ instr->links[i_to] = new_to;
}
- if (i == count)
- goto gaicl_exit;
-
- /* Si les deux extrémités sont raccord... */
-
- slink->type = new;
-
- dlink->type = new;
-
- result = true;
-
- gaicl_exit:
-
- g_arch_instruction_unlock_src(dest);
+ g_thick_object_unlock(G_THICK_OBJECT(dest));
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
return result;
@@ -1280,116 +906,92 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
void g_arch_instruction_delete_all_links(GArchInstruction *instr)
{
- instr_link_t *link_src; /* Lien à supprimer #2 */
- GArchInstruction *other; /* Instruction de l'autre bout */
- size_t count; /* Quantié de liens présents */
- size_t i; /* Boucle de parcours */
- instr_link_t *link_dst; /* Lien à supprimer #1 */
+ GArchInstruction *linked; /* Autre instruction liée */
+ InstructionLinkType type; /* Type de liaison */
- /* Coté sources */
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- g_arch_instruction_lock_src(instr);
-
- while (count_flat_array_items(instr->from) > 0)
+ while (g_arch_instruction_count_src_links(instr) > 0)
{
- link_src = get_flat_array_item(instr->from, 0, sizeof(instr_link_t));
-
- other = link_src->linked;
+ linked = g_arch_instruction_get_linked_source(instr, 0, &type);
- g_arch_instruction_lock_dest(other);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- count = count_flat_array_items(other->to);
+ g_arch_instruction_unlink(linked, instr, type);
- for (i = 0; i < count; i++)
- {
- link_dst = get_flat_array_item(other->to, i, sizeof(instr_link_t));
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- if (link_dst->linked == instr && link_dst->type == link_src->type)
- {
- unref_instr_link(link_dst);
-
- rem_item_from_flat_array(&other->to, i, sizeof(instr_link_t));
-
- break;
-
- }
-
- }
-
- assert(i < count);
-
- g_arch_instruction_unlock_dest(other);
-
- unref_instr_link(link_src);
-
- rem_item_from_flat_array(&instr->from, 0, sizeof(instr_link_t));
+ unref_object(linked);
}
- g_arch_instruction_unlock_src(instr);
-
- /* Coté destinations */
-
- g_arch_instruction_lock_dest(instr);
-
- while (count_flat_array_items(instr->to) > 0)
+ while (g_arch_instruction_count_dest_links(instr) > 0)
{
- link_dst = get_flat_array_item(instr->to, 0, sizeof(instr_link_t));
+ linked = g_arch_instruction_get_linked_destination(instr, 0, &type);
- other = link_dst->linked;
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- g_arch_instruction_lock_src(other);
+ g_arch_instruction_unlink(instr, linked, type);
- count = count_flat_array_items(other->from);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- for (i = 0; i < count; i++)
- {
- link_src = get_flat_array_item(other->from, i, sizeof(instr_link_t));
+ unref_object(linked);
- if (link_src->linked == instr && link_src->type == link_dst->type)
- {
- unref_instr_link(link_src);
-
- rem_item_from_flat_array(&other->from, i, sizeof(instr_link_t));
+ }
- break;
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- }
+}
- }
- assert(i < count);
+/******************************************************************************
+* *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* dir = direction des liens à considérer. *
+* *
+* Description : Fournit la quantité d'instructions pointant vers une autre. *
+* *
+* Retour : Nombre de ces liens. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- g_arch_instruction_unlock_src(other);
+static size_t _g_arch_instruction_count_links(const GArchInstruction *instr, compact_ins_link_t dir)
+{
+ size_t result; /* Nombre de liens à renvoyer */
+ uint16_t i; /* Boucle de parcours */
- unref_instr_link(link_dst);
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- rem_item_from_flat_array(&instr->to, 0, sizeof(instr_link_t));
+ result = 0;
- }
+ for (i = 0; i < instr->link_count; i++)
+ if (COMPACT_INS_LINK_DIR(instr->links[i]) == dir)
+ result++;
- g_arch_instruction_unlock_dest(instr);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
* *
-* Description : Fournit la quantité d'instructions pointant vers une autre. *
+* Description : Fournit la quantité d'instructions placées en source. *
* *
-* Retour : Nombre de ces origines. *
+* Retour : Nombre de ces liens. *
* *
* Remarques : - *
* *
******************************************************************************/
-size_t g_arch_instruction_count_sources(const GArchInstruction *instr)
+size_t g_arch_instruction_count_src_links(const GArchInstruction *instr)
{
size_t result; /* Nombre de liens à renvoyer */
- result = count_flat_array_items(instr->from);
+ result = _g_arch_instruction_count_links(instr, COMPACT_INS_LINK_FROM);
return result;
@@ -1398,24 +1000,21 @@ size_t g_arch_instruction_count_sources(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* index = indice de l'élément à retrouver. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
* *
-* Description : Fournit les détails d'une origine d'une instruction donnée. *
+* Description : Fournit la quantité d'instructions placées en destination. *
* *
-* Retour : Lien déterminé vers une instruction d'origine. *
+* Retour : Nombre de ces liens. *
* *
* Remarques : - *
* *
******************************************************************************/
-const instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index)
+size_t g_arch_instruction_count_dest_links(const GArchInstruction *instr)
{
- instr_link_t *result; /* Détails présents à renvoyer */
-
- result = get_flat_array_item(instr->from, index, sizeof(instr_link_t));
+ size_t result; /* Nombre de liens à renvoyer */
- ref_instr_link(result);
+ result = _g_arch_instruction_count_links(instr, COMPACT_INS_LINK_TO);
return result;
@@ -1424,43 +1023,47 @@ const instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* count = quantié de liens présents. [OUT] *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* index = indice de l'élément à retrouver. *
+* dir = direction des liens à considérer. *
+* type = type de lien enregistré. [OUT] *
* *
-* Description : Fournit tous les détails d'origine d'une instruction donnée. *
+* Description : Fournit les détails d'un lien donné avec une instruction. *
* *
-* Retour : Liens vers des instructions d'origine à libérer. *
+* Retour : Autre instruction pointée par l'instruction, voire NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-instr_link_t *g_arch_instruction_get_sources(GArchInstruction *instr, size_t *count)
+static GArchInstruction *_g_arch_instruction_get_linked_instruction(const GArchInstruction *instr, size_t index, compact_ins_link_t dir, InstructionLinkType *type)
{
- instr_link_t *result; /* Détails présents à renvoyer */
- size_t i; /* Boucle de parcours */
- const instr_link_t *link; /* Lien à fournir */
-
- g_arch_instruction_lock_src(instr);
+ GArchInstruction *result; /* Instance ciblée à renvoyer */
+ uint16_t i; /* Boucle de parcours */
- *count = g_arch_instruction_count_sources(instr);
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- if (*count == 0)
- result = NULL;
+ result = NULL;
+ *type = ILT_COUNT;
- else
+ for (i = 0; i < instr->link_count; i++)
{
- result = (instr_link_t *)malloc(*count * sizeof(instr_link_t));
+ if (COMPACT_INS_LINK_DIR(instr->links[i]) != dir)
+ continue;
- for (i = 0; i < *count; i++)
+ if (index == 0)
{
- link = g_arch_instruction_get_source(instr, i);
- memcpy(&result[i], link, sizeof(instr_link_t));
+ result = COMPACT_INS_LINK_PTR(instr->links[i]);
+ *type = COMPACT_INS_LINK_TYPE(instr->links[i]);
}
+ else
+ index--;
+
}
- g_arch_instruction_unlock_src(instr);
+ if (result != NULL)
+ ref_object(result);
return result;
@@ -1469,21 +1072,23 @@ instr_link_t *g_arch_instruction_get_sources(GArchInstruction *instr, size_t *co
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
+* index = indice de l'élément à retrouver. *
+* type = type de lien enregistré. [OUT] *
* *
-* Description : Donne le nombre d'instructions non naturellement suivantes. *
+* Description : Fournit les détails d'une source donnée d'une instruction. *
* *
-* Retour : Nombre de ces destinations. *
+* Retour : Autre instruction pointée par l'instruction, voire NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-size_t g_arch_instruction_count_destinations(const GArchInstruction *instr)
+GArchInstruction *g_arch_instruction_get_linked_source(const GArchInstruction *instr, size_t index, InstructionLinkType *type)
{
- size_t result; /* Nombre de liens à renvoyer */
+ GArchInstruction *result; /* Instance ciblée à renvoyer */
- result = count_flat_array_items(instr->to);
+ result = _g_arch_instruction_get_linked_instruction(instr, index, COMPACT_INS_LINK_FROM, type);
return result;
@@ -1492,71 +1097,54 @@ size_t g_arch_instruction_count_destinations(const GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
+* Paramètres : instr = instruction dont les liens sont à consulter. *
* index = indice de l'élément à retrouver. *
+* type = type de lien enregistré. [OUT] *
* *
-* Description : Fournit les détails d'une destination d'une instruction. *
+* Description : Fournit les détails d'une destination donnée d'une instruct. *
* *
-* Retour : Lien déterminé vers une instruction de destination. *
+* Retour : Autre instruction pointée par l'instruction, voire NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index)
+GArchInstruction *g_arch_instruction_get_linked_destination(const GArchInstruction *instr, size_t index, InstructionLinkType *type)
{
- instr_link_t *result; /* Détails présents à renvoyer */
-
- result = get_flat_array_item(instr->to, index, sizeof(instr_link_t));
+ GArchInstruction *result; /* Instance ciblée à renvoyer */
- ref_instr_link(result);
+ result = _g_arch_instruction_get_linked_instruction(instr, index, COMPACT_INS_LINK_TO, type);
return result;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION DES OPERANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* type = type de lien recherché. *
+* Paramètres : instr = instance à consulter. *
* *
-* Description : Fournit la destination d'une instruction et d'un type donné. *
+* Description : Indique la quantité d'opérandes présents dans l'instruction. *
* *
-* Retour : Instruction de destination trouvée ou NULL. *
+* Retour : Nombre d'opérandes attachés. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *instr, InstructionLinkType type)
+size_t g_arch_instruction_count_operands(const GArchInstruction *instr)
{
- GArchInstruction *result; /* Résultat à remonter */
- size_t count; /* Nombre de liens à parcourir */
- size_t i; /* Boucle de parcours */
- const instr_link_t *dest; /* Destination à étudier */
-
- result = NULL;
-
- g_arch_instruction_lock_dest(instr);
-
- count = g_arch_instruction_count_destinations(instr);
-
- for (i = 0; i < count && result == NULL; i++)
- {
- dest = g_arch_instruction_get_destination(instr, i);
-
- if (dest->type == type)
- {
- result = dest->linked;
- g_object_ref(G_OBJECT(result));
- }
+ size_t result; /* Décompte à retourner */
- unref_instr_link(dest);
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- }
-
- g_arch_instruction_unlock_dest(instr);
+ result = count_flat_array_items(instr->operands);
return result;
@@ -1565,56 +1153,45 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter. *
-* count = quantié de liens présents. [OUT] *
+* Paramètres : instr = instance à mettre à jour. *
+* operand = instruction à venir associer. *
* *
-* Description : Fournit tous les détails de destination d'une instruction. *
+* Description : Attache un opérande supplémentaire à une instruction. *
* *
-* Retour : Liens vers des instructions de destination à libérer. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_t *count)
+void g_arch_instruction_attach_operand(GArchInstruction *instr, GArchOperand *operand)
{
- instr_link_t *result; /* Détails présents à renvoyer */
- size_t i; /* Boucle de parcours */
- const instr_link_t *link; /* Lien à fournir */
-
- g_arch_instruction_lock_dest(instr);
-
- *count = g_arch_instruction_count_destinations(instr);
+ GSingletonFactory *factory; /* Unise à instances uniques */
+ GSingletonCandidate *singleton; /* Instance retenue */
+ GArchOperand *stored; /* Forme d'opérande conservée */
- if (*count == 0)
- result = NULL;
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- else
- {
- result = (instr_link_t *)malloc(*count * sizeof(instr_link_t));
+ factory = get_operands_factory();
- for (i = 0; i < *count; i++)
- {
- link = g_arch_instruction_get_destination(instr, i);
- memcpy(&result[i], link, sizeof(instr_link_t));
- }
+ singleton = g_singleton_factory_get_instance(factory, G_SINGLETON_CANDIDATE(operand));
- }
+ unref_object(factory);
- g_arch_instruction_unlock_dest(instr);
+ stored = G_ARCH_OPERAND(singleton);
- return result;
+ add_item_to_flat_array(&instr->operands, &stored, sizeof(GArchOperand *));
}
/******************************************************************************
* *
-* Paramètres : instr = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
+* Paramètres : instr = instance à mettre à jour. *
+* old = ancienne opérande à détacher. *
+* new = nouvelle opérande à attacher. *
* *
-* Description : Charge un contenu depuis une mémoire tampon. *
+* Description : Remplace un opérande d'une instruction par un autre. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -1622,40 +1199,47 @@ instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_
* *
******************************************************************************/
-static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+bool g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
{
bool result; /* Bilan à retourner */
- uleb128_t count; /* Nombre de liens à charger */
- uleb128_t i; /* Boucle de parcours */
- GArchInstruction *linked; /* Lien vers une instruction */
- uleb128_t type; /* Valeur ULEB128 à charger */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+ GSingletonFactory *factory; /* Unise à instances uniques */
+ GSingletonCandidate *singleton; /* Instance retenue */
+ GArchOperand *stored; /* Forme d'opérande conservée */
- g_arch_instruction_lock_dest(instr);
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- result = unpack_uleb128(&count, pbuf);
+ result = false;
- for (i = 0; i < count && result; i++)
+ count = g_arch_instruction_count_operands(instr);
+
+ for (i = 0; i < count && !result; i++)
{
- linked = G_ARCH_INSTRUCTION(g_object_storage_unpack_object(storage, "instructions", pbuf));
- if (linked == NULL)
- {
- result = false;
- break;
- }
+ op = g_arch_instruction_get_operand(instr, i);
- result = unpack_uleb128(&type, pbuf);
- if (!result)
- {
- g_object_unref(G_OBJECT(linked));
- break;
- }
+ result = (op == old);
- g_arch_instruction_link_with(instr, linked, type);
- g_object_unref(G_OBJECT(linked));
+ unref_object(op);
}
- g_arch_instruction_unlock_dest(instr);
+ if (result)
+ {
+ factory = get_operands_factory();
+
+ singleton = g_singleton_factory_get_instance(factory, G_SINGLETON_CANDIDATE(new));
+
+ unref_object(factory);
+
+ stored = G_ARCH_OPERAND(singleton);
+
+ rpl_item_in_flat_array(instr->operands, i - 1, &stored, sizeof(GArchOperand *));
+
+ unref_object(old);
+
+ }
return result;
@@ -1664,11 +1248,10 @@ static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjec
/******************************************************************************
* *
-* Paramètres : instr = instruction dont les informations sont à consulter.*
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instance à mettre à jour. *
+* target = instruction à venir dissocier. *
* *
-* Description : Sauvegarde toutes les destinations d'une instruction. *
+* Description : Détache un opérande liée d'une instruction. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -1676,87 +1259,67 @@ static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjec
* *
******************************************************************************/
-bool g_arch_instruction_store_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+bool g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *target)
{
bool result; /* Bilan à retourner */
- size_t count; /* Nombre d'éléments à traiter */
- size_t kept; /* Nombre de liens conservés */
+ size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
- const instr_link_t *link; /* Lien vers une instruction */
-
- g_arch_instruction_lock_dest(instr);
+ GArchOperand *op; /* Opérande à manipuler */
- count = g_arch_instruction_count_destinations(instr);
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- /**
- * Le type de lien ILT_REF n'est mis en place que lors de la création
- * d'opérandes de type G_TYPE_TARGET_OPERAND, et sera donc remis en place
- * dynamiquement lors de la restauration de ces derniers.
- */
+ result = false;
- kept = 0;
+ count = g_arch_instruction_count_operands(instr);
- for (i = 0; i < count; i++)
+ for (i = 0; i < count && !result; i++)
{
- link = g_arch_instruction_get_destination(instr, i);
+ op = g_arch_instruction_get_operand(instr, i);
- if (link->type != ILT_REF)
- kept++;
+ result = (op == target);
- unref_instr_link(link);
+ unref_object(op);
}
- result = pack_uleb128((uleb128_t []){ kept }, pbuf);
-
- for (i = 0; i < count && result; i++)
+ if (result)
{
- link = g_arch_instruction_get_destination(instr, i);
-
- if (link->type != ILT_REF)
- {
- result = g_object_storage_pack_object(storage, "instructions",
- G_SERIALIZABLE_OBJECT(link->linked), pbuf);
-
- if (result)
- result = pack_uleb128((uleb128_t []){ link->type }, pbuf);
-
- }
+ rem_item_from_flat_array(&instr->operands, i - 1, sizeof(GArchOperand *));
- unref_instr_link(link);
+ unref_object(target);
}
- g_arch_instruction_unlock_dest(instr);
-
return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* CONVERSIONS DU FORMAT DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
+* Paramètres : instr = instance à consulter. *
+* index = indice de l'opérande concerné. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Fournit un opérande donné d'une instruction. *
* *
-* Retour : Mot clef de bas niveau. *
+* Retour : Opérande trouvée. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
+GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)
{
- const char *result; /* Désignation à retourner */
+ GArchOperand *result; /* Opérande à retourner */
+ GArchOperand **ptr; /* Adresse dans le tableau */
+
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(instr)));
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);
+ ptr = get_flat_array_item(instr->operands, index, sizeof(GArchOperand *));
+
+ result = *ptr;
+
+ ref_object(result);
return result;
@@ -1765,450 +1328,396 @@ const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
+* Paramètres : instr = instance à consulter. *
+* target = instruction à venir retrouver. *
* *
-* Description : Construit un petit résumé concis de l'instruction. *
+* Description : Détermine le chemin conduisant à un opérande. *
* *
-* Retour : Chaîne de caractères à libérer après usage ou NULL. *
+* Retour : Chemin d'accès à l'opérande ou NULL en cas d'absence. *
* *
* Remarques : - *
* *
******************************************************************************/
-char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
+char *g_arch_instruction_find_operand_path(GArchInstruction *instr, const GArchOperand *target)
{
- char *result; /* Description à retourner */
- GArchInstructionClass *class; /* Classe des instructions */
+ char *result; /* Chemin à retourner */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+ int ret; /* Bilan d'une construction */
+ char *sub_path; /* Sous-chemin emprunté */
- class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+ result = NULL;
- if (class->build_tooltip != NULL)
- result = class->build_tooltip(instr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
- else
- result = NULL;
+ count = g_arch_instruction_count_operands(instr);
- return result;
+ /* Première passe : accès direct */
-}
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ op = g_arch_instruction_get_operand(instr, i);
+ if (op == target)
+ {
+ ret = asprintf(&result, "%zu", i);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
+ }
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Fournit une description pour l'instruction manipulée. *
-* *
-* Retour : Chaîne de caractères avec balises éventuelles. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ unref_object(op);
-const char *g_arch_instruction_get_description(const GArchInstruction *instr)
-{
- const char *result; /* Description à retourner */
+ }
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr);
+ /* Seconde passe : accès profond */
- return result;
-
-}
+ for (i = 0; i < count && result == NULL; i++)
+ {
+ op = g_arch_instruction_get_operand(instr, i);
+ sub_path = NULL;//g_arch_operand_find_inner_operand_path(op, target);
+ if (sub_path != NULL)
+ {
+ ret = asprintf(&result, "%zu:%s", i, sub_path);
+ if (ret == -1)
+ {
+ LOG_ERROR_N("asprintf");
+ result = NULL;
+ }
-/* ---------------------------------------------------------------------------------- */
-/* OFFRE DE CAPACITES DE GENERATION */
-/* ---------------------------------------------------------------------------------- */
+ free(sub_path);
+ }
-/******************************************************************************
-* *
-* Paramètres : instr = générateur à consulter. *
-* *
-* Description : Indique le nombre de ligne prêtes à être générées. *
-* *
-* Retour : Nombre de lignes devant apparaître au final. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ unref_object(op);
-static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
-{
- return 1;
+ }
-}
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
+ return result;
-#ifdef INCLUDE_GTK_SUPPORT
+}
/******************************************************************************
* *
-* Paramètres : instr = générateur à consulter. *
-* x = position géographique sur la ligne concernée. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* cursor = emplacement à constituer. [OUT] *
+* Paramètres : instr = instance à consulter. *
+* path = chemin d'accès à un opérande à retrouver. *
* *
-* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* Description : Obtient l'opérande correspondant à un chemin donné. *
* *
-* Retour : - *
+* Retour : Opérande trouvé ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_arch_instruction_compute_cursor(const GArchInstruction *instr, gint x, size_t index, size_t repeat, GLineCursor **cursor)
+GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *instr, const char *path)
{
- *cursor = g_binary_cursor_new();
+ GArchOperand *result; /* Opérande trouvée à renvoyer */
+ size_t index; /* Indice de l'opérande visé */
+ char *end; /* Poursuite du parcours ? */
+ GArchOperand *found; /* Opérande trouvé */
- g_binary_cursor_update(G_BINARY_CURSOR(*cursor), get_mrange_addr(&instr->range));
+ result = NULL;
-}
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+ /* Recherche au premier niveau */
-/******************************************************************************
-* *
-* Paramètres : instr = générateur à consulter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* cursor = emplacement à analyser. *
-* *
-* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
-* *
-* Retour : Bilan de la détermination, utilisable en comparaisons. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ index = strtoul(path, &end, 10);
-static int g_arch_instruction_contain_cursor(const GArchInstruction *instr, size_t index, size_t repeat, const GLineCursor *cursor)
-{
- int result; /* Conclusion à retourner */
- vmpa2t addr; /* Autre emplacement à comparer*/
+ if ((index == ULONG_MAX && errno == ERANGE) || (index == 0 && errno == EINVAL))
+ {
+ LOG_ERROR_N("strtoul");
+ goto done;
+ }
+
+ found = g_arch_instruction_get_operand(instr, index);
+ if (found == NULL) goto done;
+
+ if (*end == '\0')
+ {
+ result = found;
+ goto done;
+ }
+
+ /* Recherche en profondeur */
+
+ assert(*end == ':');
+
+ result = NULL;//g_arch_operand_get_inner_operand_from_path(found, end + 1);
- assert(G_IS_BINARY_CURSOR(cursor));
+ unref_object(found);
- g_binary_cursor_retrieve(G_BINARY_CURSOR(cursor), &addr);
+ done:
- result = cmp_mrange_with_vmpa(&instr->range, &addr);
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
return result;
}
-#endif
+
+/* ---------------------------------------------------------------------------------- */
+/* MECANISMES DE CONSERVATION ET RESTAURATION */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : instr = générateur à consulter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
+* Paramètres : object = élément GLib à constuire. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en lecture. *
* *
-* Description : Renseigne sur les propriétés liées à un générateur. *
+* Description : Charge un objet depuis un flux de données. *
* *
-* Retour : Propriétés particulières associées. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static BufferLineFlags g_arch_instruction_get_flags2(const GArchInstruction *instr, size_t index, size_t repeat)
+static bool g_arch_instruction_load(GSerializableObject *object, GObjectStorage *storage, int fd)
{
- return BLF_HAS_CODE;
+ bool result; /* Bilan à retourner */
+ uleb128_t extra; /* Données embarquées */
+
+ /* Propriétés internes */
+
+ result = load_uleb128(&extra, fd);
+
+ if (result)
+ g_thick_object_set_extra(G_THICK_OBJECT(object), extra);
+
+ /* Liaisons avec d'autres instructions */
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* line = ligne de rendu à compléter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
+* Paramètres : object = élément GLib à consulter. *
+* storage = conservateur de données à manipuler. *
+* fd = flux ouvert en écriture. *
* *
-* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* Description : Sauvegarde un objet dans un flux de données. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
+static bool g_arch_instruction_store(const GSerializableObject *object, GObjectStorage *storage, int fd)
{
- const char *key; /* Mot clef principal */
- size_t klen; /* Taille de ce mot clef */
- size_t count; /* Nombre d'opérandes en place */
+ bool result; /* Bilan à retourner */
+ GArchInstruction *instr; /* Version spécialisée */
+ size_t src_count; /* Quantité de sources */
+ size_t dest_count; /* Quantité de destinations */
+ off64_t *ins_offsets; /* Emplacements d'instructions */
size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à manipuler */
+ GArchInstruction *linked; /* Instruction liée */
+ size_t op_count; /* Quantité d'opérandes */
+ off64_t *op_offsets; /* Emplacements d'opérandes */
+ GArchOperand *op; /* Opérande à traiter */
+ guint extra; /* Données embarquées */
+ InstructionLinkType type; /* Type de lien */
- g_buffer_line_fill_phys(line, DLC_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&instr->range));
+ assert(g_thick_object_check_lock(G_THICK_OBJECT(object)));
- g_buffer_line_fill_virt(line, DLC_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&instr->range));
+ /* Préparation des références aux instructions liées */
- g_buffer_line_fill_content(line, DLC_BINARY, content, &instr->range, VMPA_NO_PHYSICAL);
+ instr = G_ARCH_INSTRUCTION(object);
- /* Instruction proprement dite */
+ src_count = g_arch_instruction_count_src_links(instr);
+ dest_count = g_arch_instruction_count_dest_links(instr);
- key = g_arch_instruction_get_keyword(instr);
- klen = strlen(key);
+ ins_offsets = malloc((src_count + dest_count) * sizeof(off64_t));
- g_buffer_line_append_text(line, DLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, G_OBJECT(instr));
+ for (i = 0; i < src_count && result; i++)
+ {
+ linked = g_arch_instruction_get_linked_source(instr, i, (InstructionLinkType []) { 0 });
- /* Liste des opérandes */
+ result = g_object_storage_store_object(storage, "instructions",
+ G_SERIALIZABLE_OBJECT(linked), &ins_offsets[i]);
- g_arch_instruction_lock_operands(instr);
+ unref_object(linked);
- count = _g_arch_instruction_count_operands(instr);
+ }
- if (count > 0)
+ for (i = 0; i < dest_count && result; i++)
{
- op = _g_arch_instruction_get_operand(instr, 0);
- g_arch_operand_print(op, line);
- g_object_unref(G_OBJECT(op));
+ linked = g_arch_instruction_get_linked_destination(instr, i, (InstructionLinkType []) { 0 });
- for (i = 1; i < count; i++)
- {
- g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+ result = g_object_storage_store_object(storage, "instructions",
+ G_SERIALIZABLE_OBJECT(linked), &ins_offsets[src_count + i]);
- op = _g_arch_instruction_get_operand(instr, i);
+ unref_object(linked);
- g_arch_operand_print(op, line);
+ }
- g_object_unref(G_OBJECT(op));
+ if (!result)
+ goto exit_with_ins_off;
- }
+ /* Préparation des références aux opérandes embarqués */
- }
+ op_count = g_arch_instruction_count_operands(instr);
- g_arch_instruction_unlock_operands(instr);
+ op_offsets = malloc(op_count * sizeof(off64_t));
-}
+ for (i = 0; i < op_count && result; i++)
+ {
+ op = g_arch_instruction_get_operand(instr, i);
+ result = g_object_storage_store_object(storage, "operandss",
+ G_SERIALIZABLE_OBJECT(op), &op_offsets[i]);
-/******************************************************************************
-* *
-* Paramètres : instr = générateur à utiliser pour l'impression. *
-* line = ligne de rendu à compléter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
-* *
-* Description : Imprime dans une ligne de rendu le contenu représenté. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ unref_object(op);
-static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
-{
- G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat, content);
+ }
-}
+ if (!result)
+ goto exit_with_op_off;
+ /* Propriétés internes */
+ extra = g_thick_object_get_extra(G_THICK_OBJECT(object));
-/* ---------------------------------------------------------------------------------- */
-/* CONSERVATION ET RECHARGEMENT DES DONNEES */
-/* ---------------------------------------------------------------------------------- */
+ result = store_uleb128((uleb128_t []) { extra }, fd);
+ if (!result) goto exit;
+ /* Liaisons avec d'autres instructions */
-/******************************************************************************
-* *
-* Paramètres : instr = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
-* *
-* Description : Charge un contenu depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ instr = G_ARCH_INSTRUCTION(object);
-static bool _g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- instr_extra_data_t *extra; /* Données insérées à consulter*/
- uleb128_t value; /* Valeur ULEB128 à charger */
- uleb128_t count; /* Nombre d'éléments à traiter */
- uleb128_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à traiter */
+ src_count = g_arch_instruction_count_src_links(instr);
+ dest_count = g_arch_instruction_count_dest_links(instr);
- extra = GET_ARCH_INSTR_EXTRA(instr);
+ result = store_uleb128((uleb128_t []) { src_count }, fd);
+ if (!result) goto exit;
- LOCK_GOBJECT_EXTRA(extra);
+ result = store_uleb128((uleb128_t []) { dest_count }, fd);
+ if (!result) goto exit;
- result = unpack_uleb128(&value, pbuf);
+ for (i = 0; i < src_count && result; i++)
+ {
+ linked = g_arch_instruction_get_linked_source(instr, i, &type);
- if (result)
- extra->uid = value;
+ result = store_uleb128((uleb128_t []) { type }, fd);
- if (result)
- {
- result = unpack_uleb128(&value, pbuf);
+ unref_object(linked);
if (result)
- extra->flags = value;
+ result = store_uleb128((uleb128_t []) { ins_offsets[i] }, fd);
}
- UNLOCK_GOBJECT_EXTRA(extra);
-
- if (result)
- result = unpack_mrange(&instr->range, pbuf);
-
- if (result)
+ for (i = 0; i < dest_count && result; i++)
{
- result = unpack_uleb128(&count, pbuf);
+ linked = g_arch_instruction_get_linked_destination(instr, i, &type);
- for (i = 0; i < count && result; i++)
- {
- op = G_ARCH_OPERAND(g_object_storage_unpack_object(storage, "operands", pbuf));
- result = (op != NULL);
+ result = store_uleb128((uleb128_t []) { type }, fd);
- if (result)
- g_arch_instruction_attach_extra_operand(instr, op);
+ unref_object(linked);
- }
+ if (result)
+ result = store_uleb128((uleb128_t []) { ins_offsets[src_count + i] }, fd);
}
- if (result)
- result = g_arch_instruction_load_destinations(instr, storage, pbuf);
-
- return result;
+ /* Opérandes embarqués */
-}
+ result = store_uleb128((uleb128_t []) { op_count }, fd);
+ if (!result) goto exit;
+ for (i = 0; i < op_count && result; i++)
+ result = store_uleb128((uleb128_t []) { op_offsets[i] }, fd);
-/******************************************************************************
-* *
-* Paramètres : instr = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
-* *
-* Description : Charge un contenu depuis une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ exit:
+ exit_with_op_off:
-static bool g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *class; /* Classe à activer */
+ free(op_offsets);
- class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+ exit_with_ins_off:
- result = class->load(instr, storage, pbuf);
+ free(ins_offsets);
return result;
}
-/******************************************************************************
-* *
-* Paramètres : instr = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-static bool _g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- instr_extra_data_t *extra; /* Données insérées à consulter*/
- size_t count; /* Nombre d'éléments à traiter */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à traiter */
-
- extra = GET_ARCH_INSTR_EXTRA(instr);
- LOCK_GOBJECT_EXTRA(extra);
- result = pack_uleb128((uleb128_t []){ extra->uid }, pbuf);
- if (result)
- result = pack_uleb128((uleb128_t []){ extra->flags }, pbuf);
- UNLOCK_GOBJECT_EXTRA(extra);
- if (result)
- result = pack_mrange(&instr->range, pbuf);
- if (result)
- {
- g_arch_instruction_lock_operands(instr);
- count = _g_arch_instruction_count_operands(instr);
- result = pack_uleb128((uleb128_t []){ count }, pbuf);
- for (i = 0; i < count && result; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
- result = g_object_storage_pack_object(storage, "operands", G_SERIALIZABLE_OBJECT(op), pbuf);
- g_object_unref(G_OBJECT(op));
- }
- g_arch_instruction_unlock_operands(instr);
- }
- if (result)
- result = g_arch_instruction_store_destinations(instr, storage, pbuf);
+#if 0
- return result;
-}
/******************************************************************************
* *
-* Paramètres : instr = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction quelconque à traiter. *
+* type = type de procédure à utiliser. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = accès aux données du binaire d'origine. *
* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* Description : Complète un désassemblage accompli pour une instruction. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_arch_instruction_store(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+void g_arch_instruction_call_hook(GArchInstruction *instr, InstrProcessHook type, GArchProcessor *proc, GProcContext *context, GExeFormat *format)
{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *class; /* Classe à activer */
+ GArchInstructionClass *class; /* Classe des instructions */
class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
- result = class->store(instr, storage, pbuf);
-
- return result;
+ if (class->call_hook != NULL)
+ class->call_hook(instr, type, proc, context, format);
}
+
+
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 3c9c149..98bc73e 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* instruction.h - prototypes pour la gestion générique des instructions
*
- * Copyright (C) 2008-2020 Cyrille Bagard
+ * Copyright (C) 2008-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,194 +25,118 @@
#define _ARCH_INSTRUCTION_H
-#include <sys/types.h>
+#include <stdbool.h>
+#include <stdint.h>
-#include "context.h"
#include "operand.h"
-#include "register.h"
#include "vmpa.h"
-#include "../analysis/type.h"
-#include "../common/packed.h"
-#include "../format/executable.h"
+#include "../glibext/helpers.h"
+#include "../glibext/portion.h"
-#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type()
-#define G_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction))
-#define G_IS_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type()))
-#define G_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
-#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION))
-#define G_ARCH_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass))
+/* ----------------------- DEFINITION GENERIQUE D'INSTRUCTION ----------------------- */
-/* Définition générique d'une instruction d'architecture (instance) */
-typedef struct _GArchInstruction GArchInstruction;
+#define G_TYPE_ARCH_INSTRUCTION (g_arch_instruction_get_type())
-/* Définition générique d'une instruction d'architecture (classe) */
-typedef struct _GArchInstructionClass GArchInstructionClass;
+DECLARE_GTYPE(GArchInstruction, g_arch_instruction, G, ARCH_INSTRUCTION);
-/* Drapeaux pour informations complémentaires */
-
-#define AIF_USER_BIT 4
-
-typedef enum _ArchInstrFlag
-{
- AIF_NONE = (0 << 0), /* Aucune information */
- AIF_ROUTINE_START = (1 << 0), /* Début de routine */
- AIF_RETURN_POINT = (1 << 1), /* Retour de fonction appelée */
- AIF_COND_RETURN_POINT = (1 << 2), /* Retour éventuel de fonction */
- AIF_CALL = (1 << 3), /* Instruction d'appel */
-
- AIF_LOW_USER = (1 << AIF_USER_BIT), /* Premier bit disponible */
- AIF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
-
-} ArchInstrFlag;
-
/* Type pour les types d'instructions */
typedef uint16_t itid_t;
-/* Types de crochet de traitement */
-typedef enum _InstrProcessHook
-{
- IPH_FETCH, /* Itinéraire de désassemblage */
- IPH_LINK, /* Edition des liens */
- IPH_POST, /* Résolution des symboles */
-
- IPH_COUNT
-
-} InstrProcessHook;
-
-
-/* Indique le type défini pour une instruction d'architecture. */
-GType g_arch_instruction_get_type(void);
+/* Fournit l'identifiant correspondant à un type d'instructions. */
+itid_t g_arch_instruction_get_type_id(const GArchInstruction *);
/* Indique l'encodage d'une instruction de façon détaillée. */
-const char *g_arch_instruction_get_encoding(const GArchInstruction *);
-
-/* Ajoute une information complémentaire à une instruction. */
-bool g_arch_instruction_set_flag(GArchInstruction *, ArchInstrFlag);
+char *g_arch_instruction_get_encoding(const GArchInstruction *);
-/* Retire une information complémentaire à une instruction. */
-bool g_arch_instruction_unset_flag(GArchInstruction *, ArchInstrFlag);
-
-/* Détermine si une instruction possède un fanion particulier. */
-bool g_arch_instruction_has_flag(const GArchInstruction *, ArchInstrFlag);
+/* Fournit le nom humain de l'instruction manipulée. */
+char *g_arch_instruction_get_keyword(const GArchInstruction *);
-/* Fournit les informations complémentaires d'une instruction. */
-ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *);
-/* Définit l'identifiant unique pour un ensemble d'instructions. */
-void g_arch_instruction_set_unique_id(GArchInstruction *, itid_t);
+ /* Type de masques pour les encodages d'instructions */
+typedef enum _InstructionBytesMask
+{
+ /**
+ * Correspond aux bits fixes : pas de valeurs de registre ni de valeur entière.
+ */
+ IBM_LOOSE,
-/* Fournit l'identifiant unique pour un ensemble d'instructions. */
-itid_t g_arch_instruction_get_unique_id(const GArchInstruction *);
+ /**
+ * Dissimulation des références à des éléments externes pouvant varier avec
+ * entre compilations : adresses de saut ou d'appel, références vers des tables,
+ * etc.
+ */
+ IBM_LOCAL,
+ /**
+ * Dissimulation des déplacements à partir d'une base.
+ */
+ IBM_STRICT,
-/**
- * La définition de "GArchProcessor", utile aux traitements complémentaires, ne peut
- * se faire en incluant le fichier d'en-tête "processor.h", pour cause de références
- * circulaires.
- *
- * On procède donc à une seconde déclaration, en attendant éventuellement mieux.
- */
+ /**
+ * Conservation de toutes les valeurs immédiates et dissimulation des registres.
+ */
+ IBM_LARGE,
-/* Depuis "processeur.h" : définition générique d'un processeur d'architecture (instance) */
-typedef struct _GArchProcessor GArchProcessor;
+ IBM_COUNT
+} InstructionBytesMask;
-/* Complète un désassemblage accompli pour une instruction. */
-typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GExeFormat *);
-
-/* Complète un désassemblage accompli pour une instruction. */
-void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GExeFormat *);
-/* Définit la localisation d'une instruction. */
-void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *);
+/* Calcule la localisation d'une instruction. */
+void g_arch_instruction_compute_range(GArchInstruction *, GBinaryPortion *, const vmpa2t *, phys_t);
/* Fournit la place mémoire d'une instruction. */
-const mrange_t *g_arch_instruction_get_range(const GArchInstruction *);
-
-
-
-/* Fournit la localisation d'une instruction. */
-void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, vmpa_t *) __attribute__ ((deprecated));
+bool g_arch_instruction_get_range(const GArchInstruction *, mrange_t *);
+#define AIF_USER_BIT 4
-/* Liste les registres lus et écrits par l'instruction. */
-void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated));
+typedef enum _ArchInstructionFlag
+{
+ AIF_NONE = (0 << 0), /* Aucune information */
+ AIF_ROUTINE_START = (1 << 0), /* Début de routine */
+ AIF_RETURN_POINT = (1 << 1), /* Retour de fonction appelée */
+ AIF_COND_RETURN_POINT = (1 << 2), /* Retour éventuel de fonction */
+ AIF_CALL = (1 << 3), /* Instruction d'appel */
+ AIF_LOW_USER = (1 << AIF_USER_BIT), /* Premier bit disponible */
+ AIF_HIGH_USER = (1 << 7), /* Dernier bit disponible */
+} ArchInstructionFlag;
-/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */
+#define AIF_USER_FLAG(n) (1 << (AIF_USER_BIT + n))
-/* Verrouille les accès à la liste des opérandes. */
-void g_arch_instruction_lock_operands(GArchInstruction *);
+/* Ajoute une information complémentaire à une instruction. */
+bool g_arch_instruction_set_flag(GArchInstruction *, ArchInstructionFlag);
-/* Déverrouille les accès à la liste des opérandes. */
-void g_arch_instruction_unlock_operands(GArchInstruction *);
+/* Retire une information complémentaire à une instruction. */
+bool g_arch_instruction_unset_flag(GArchInstruction *, ArchInstructionFlag);
-/* Attache un opérande supplémentaire à une instruction. */
-void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);
+/* Détermine si une instruction possède un fanion particulier. */
+bool g_arch_instruction_has_flag(const GArchInstruction *, ArchInstructionFlag);
-/* Indique la quantité d'opérandes présents dans l'instruction. */
-size_t _g_arch_instruction_count_operands(const GArchInstruction *);
+/* Fournit les particularités de l'instruction. */
+ArchInstructionFlag g_arch_instruction_get_flags(const GArchInstruction *);
-/* Fournit un opérande donné d'une instruction. */
-GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *, size_t);
-/* Remplace un opérande d'une instruction par un autre. */
-bool _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *);
+/* Types de crochet de traitement */
+typedef enum _InstrProcessHook
+{
+ IPH_FETCH, /* Itinéraire de désassemblage */
+ IPH_LINK, /* Edition des liens */
+ IPH_POST, /* Résolution des symboles */
-/* Détache un opérande liée d'une instruction. */
-bool _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
-
-
-#define g_arch_instruction_count_operands(ins) \
- ({ \
- size_t __result; \
- g_arch_instruction_lock_operands(ins); \
- __result = _g_arch_instruction_count_operands(ins); \
- g_arch_instruction_unlock_operands(ins); \
- __result; \
- })
-
-#define g_arch_instruction_get_operand(ins, idx) \
- ({ \
- GArchOperand *__result; \
- g_arch_instruction_lock_operands(ins); \
- __result = _g_arch_instruction_get_operand(ins, idx); \
- g_arch_instruction_unlock_operands(ins); \
- __result; \
- })
-
-#define g_arch_instruction_replace_operand(ins, o, n) \
- ({ \
- bool __result; \
- g_arch_instruction_lock_operands(ins); \
- __result = _g_arch_instruction_replace_operand(ins, o, n); \
- g_arch_instruction_unlock_operands(ins); \
- __result; \
- })
-
-#define g_arch_instruction_detach_operand(ins, o) \
- ({ \
- bool __result; \
- g_arch_instruction_lock_operands(ins); \
- __result = _g_arch_instruction_detach_operand(ins, o); \
- g_arch_instruction_unlock_operands(ins); \
- __result; \
- })
+ IPH_COUNT
+} InstrProcessHook;
-/* Détermine le chemin conduisant à un opérande. */
-char *g_arch_instruction_find_operand_path(GArchInstruction *, const GArchOperand *);
-/* Obtient l'opérande correspondant à un chemin donné. */
-GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *, const char *);
@@ -236,30 +160,24 @@ typedef enum _InstructionLinkType
} InstructionLinkType;
-/* Déscription d'une liaison entre deux instructions */
-typedef struct _instr_link_t
-{
- GArchInstruction *linked; /* Autre instruction liée */
- InstructionLinkType type; /* Type de liaison */
-
-} instr_link_t;
-
-#define ref_instr_link(l) g_object_ref(G_OBJECT(l->linked));
-#define unref_instr_link(l) g_object_unref(G_OBJECT(l->linked));
+/* Détermine si un type de lien amène à une instruction. */
+bool g_arch_instruction_has_src_link(const GArchInstruction *, InstructionLinkType);
+/* Détermine si un type de lien émerge d'une instruction. */
+bool g_arch_instruction_has_dest_link(const GArchInstruction *, InstructionLinkType);
-/* Met à disposition un encadrement des accès aux liens. */
-void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool);
+/* Détermine si une instruction est source d'une autre. */
+bool g_arch_instruction_has_src_link_with(const GArchInstruction *, const GArchInstruction *);
-/* Détermine si un type de lien existe dans une instruction. */
-bool g_arch_instruction_has_link(GArchInstruction *, InstructionLinkType);
-
-/* Détermine si un lien est déjà établi entre deux instructions. */
-bool g_arch_instruction_has_link_to(GArchInstruction *, const GArchInstruction *);
+/* Détermine si une instruction est destination d'une autre. */
+bool g_arch_instruction_has_dest_link_with(const GArchInstruction *, const GArchInstruction *);
/* Etablit un lien entre deux instructions. */
-void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType);
+void g_arch_instruction_link(GArchInstruction *, GArchInstruction *, InstructionLinkType);
+
+/* Supprime un lien entre deux instructions. */
+void g_arch_instruction_unlink(GArchInstruction *, GArchInstruction *, InstructionLinkType);
/* Change la nature d'un lien entre deux instructions. */
bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType);
@@ -267,46 +185,72 @@ bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, Inst
/* Supprime tous les liens établis avec d'autres instructions. */
void g_arch_instruction_delete_all_links(GArchInstruction *);
-#define g_arch_instruction_lock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true)
-#define g_arch_instruction_unlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false)
+/* Fournit la quantité d'instructions placées en source. */
+size_t g_arch_instruction_count_src_links(const GArchInstruction *);
-/* Fournit la quantité d'instructions pointant vers une autre. */
-size_t g_arch_instruction_count_sources(const GArchInstruction *);
+/* Fournit la quantité d'instructions placées en destination. */
+size_t g_arch_instruction_count_dest_links(const GArchInstruction *);
-/* Fournit les détails d'une origine d'une instruction donnée. */
-const instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t);
+/* Fournit les détails d'une source donnée d'une instruction. */
+GArchInstruction *g_arch_instruction_get_linked_source(const GArchInstruction *, size_t, InstructionLinkType *);
-/* Fournit tous les détails d'origine d'une instruction donnée. */
-instr_link_t *g_arch_instruction_get_sources(GArchInstruction *, size_t *);
+/* Fournit les détails d'une destination donnée d'une instruction. */
+GArchInstruction *g_arch_instruction_get_linked_destination(const GArchInstruction *, size_t, InstructionLinkType *);
-#define g_arch_instruction_lock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true)
-#define g_arch_instruction_unlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false)
-/* Donne le nombre d'instructions non naturellement suivantes. */
-size_t g_arch_instruction_count_destinations(const GArchInstruction *);
-/* Fournit les détails d'une destination d'une instruction. */
-const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t);
+/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */
-/* Fournit la destination d'une instruction et d'un type donné. */
-GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *, InstructionLinkType);
-/* Fournit tous les détails de destination d'une instruction. */
-instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *, size_t *);
+/* Indique la quantité d'opérandes présents dans l'instruction. */
+size_t g_arch_instruction_count_operands(const GArchInstruction *);
+/* Attache un opérande supplémentaire à une instruction. */
+void g_arch_instruction_attach_operand(GArchInstruction *, GArchOperand *);
+/* Remplace un opérande d'une instruction par un autre. */
+bool g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, GArchOperand *);
-/* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */
+/* Détache un opérande liée d'une instruction. */
+bool g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
+/* Fournit un opérande donné d'une instruction. */
+GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *, size_t);
+
+/* Détermine le chemin conduisant à un opérande. */
+char *g_arch_instruction_find_operand_path(GArchInstruction *, const GArchOperand *);
+
+/* Obtient l'opérande correspondant à un chemin donné. */
+GArchOperand *g_arch_instruction_get_operand_from_path(GArchInstruction *, const char *);
+
+
+
+
+#if 0
+
+
+
+/**
+ * La définition de "GArchProcessor", utile aux traitements complémentaires, ne peut
+ * se faire en incluant le fichier d'en-tête "processor.h", pour cause de références
+ * circulaires.
+ *
+ * On procède donc à une seconde déclaration, en attendant éventuellement mieux.
+ */
+
+/* Depuis "processeur.h" : définition générique d'un processeur d'architecture (instance) */
+typedef struct _GArchProcessor GArchProcessor;
+
+
+/* Complète un désassemblage accompli pour une instruction. */
+typedef void (* instr_hook_fc) (GArchInstruction *, GArchProcessor *, GProcContext *, GExeFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void g_arch_instruction_call_hook(GArchInstruction *, InstrProcessHook, GArchProcessor *, GProcContext *, GExeFormat *);
-/* Fournit le nom humain de l'instruction manipulée. */
-const char *g_arch_instruction_get_keyword(GArchInstruction *);
-/* Construit un petit résumé concis de l'instruction. */
-char *g_arch_instruction_build_tooltip(const GArchInstruction *);
-/* Fournit une description pour l'instruction manipulée. */
-const char *g_arch_instruction_get_description(const GArchInstruction *);
+#endif
diff --git a/src/arch/instructions/Makefile.am b/src/arch/instructions/Makefile.am
index 28cf90f..d6fc4bd 100644
--- a/src/arch/instructions/Makefile.am
+++ b/src/arch/instructions/Makefile.am
@@ -1,12 +1,19 @@
-noinst_LTLIBRARIES = libarchinstructions.la
+noinst_LTLIBRARIES = libarchinstructions.la libarchinstructionsui.la
libarchinstructions_la_SOURCES = \
+ raw-int.h \
raw.h raw.c \
undefined-int.h \
undefined.h undefined.c
-libarchinstructions_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
+libarchinstructions_la_CFLAGS = $(LIBGOBJ_CFLAGS)
+
+libarchinstructionsui_la_SOURCES = \
+ raw-ui.h raw-ui.c \
+ undefined-ui.h undefined-ui.c
+
+libarchinstructionsui_la_CFLAGS = $(LIBGTK4_CFLAGS)
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
diff --git a/src/arch/instructions/raw-int.h b/src/arch/instructions/raw-int.h
new file mode 100644
index 0000000..4a5e64b
--- /dev/null
+++ b/src/arch/instructions/raw-int.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * raw-int.h - prototypes pour la définition interne des instructions de données brutes
+ *
+ * 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_INSTRUCTIONS_RAW_INT_H
+#define _ARCH_INSTRUCTIONS_RAW_INT_H
+
+
+#include "raw.h"
+#include "../instruction-int.h"
+
+
+
+/* Définition générique d'une instruction brute d'architecture (instance) */
+struct _GRawInstruction
+{
+ GArchInstruction parent; /* A laisser en premier */
+
+};
+
+/* Définition générique d'une instruction brute d'architecture (instance) */
+struct _GRawInstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une instruction de type 'db/dw/etc' simple. */
+bool g_raw_instruction_create_value(GRawInstruction *, GBinaryPortion *, const vmpa2t *, MemoryDataSize, uint64_t);
+
+/* Met en place une instruction de type 'db/dw/etc' étendue. */
+bool g_raw_instruction_create_array(GRawInstruction *, GBinaryPortion *, vmpa2t *, MemoryDataSize, const GBinContent *, size_t, SourceEndian);
+
+
+
+#endif /* _ARCH_INSTRUCTIONS_RAW_INT_H */
diff --git a/src/arch/instructions/raw-ui.c b/src/arch/instructions/raw-ui.c
new file mode 100644
index 0000000..1026dfb
--- /dev/null
+++ b/src/arch/instructions/raw-ui.c
@@ -0,0 +1,261 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * raw-ui.c - opérandes représentant des instructions de données brutes 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 "raw-ui.h"
+
+
+#include <assert.h>
+#include <ctype.h>
+#include <malloc.h>
+
+
+#include "raw.h"
+#include "../operand-ui.h"
+#include "../operands/immediate.h"
+#include "../../glibext/objhole.h"
+#include "../../glibext/options/asm.h"
+
+
+
+/* Etablit dans une ligne de rendu le contenu représenté. */
+static void g_raw_instruction_ui_populate_line(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_raw_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *iface)
+{
+ iface->populate = g_raw_instruction_ui_populate_line;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* line = ligne de rendu à compléter. *
+* data = éventuelle donnée complémentaire fournie. *
+* *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_raw_instruction_ui_populate_line(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)
+{
+ GArchInstruction *instr; /* Version spécialisée #1 */
+ GRawInstruction *raw; /* Version spécialisée #2 */
+ GBinContent *content; /* Contenu brut d'origine */
+ mrange_t range; /* Emplacement couvert */
+ phys_t max_displayed_len; /* Quantité de code affichée */
+ char *key; /* Mot clef principal */
+ char *string; /* Chaîne reconstituée */
+ size_t iter; /* Tête d'écriture */
+ bool first; /* Mémorise une énumération */
+ size_t count; /* Nombre d'opérandes en place */
+ size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+ GImmediateOperand *imm; /* Version opérande de valeur */
+ char byte; /* Octet à afficher (ou pas) */
+#ifndef NDEBUG
+ bool status; /* Bilan d'une récupération */
+#endif
+
+ instr = G_ARCH_INSTRUCTION(generator);
+ raw = G_RAW_INSTRUCTION(instr);
+ content = G_BIN_CONTENT(data);
+
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ /* Prologue */
+
+ if (g_arch_instruction_get_range(instr, &range))
+ {
+ /* Localisation */
+
+ g_buffer_line_fill_physical(line, ACO_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ g_buffer_line_fill_virtual(line, ACO_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ /* Contenu */
+
+ if (g_raw_instruction_is_padding(raw))
+ max_displayed_len = 0;
+
+ else if (g_raw_instruction_is_string(raw))
+ max_displayed_len = 1;
+
+ else
+ {
+ max_displayed_len = get_mrange_length(&range);
+ max_displayed_len /= g_arch_instruction_count_operands(instr);
+ }
+
+ g_buffer_line_fill_content(line, ACO_BINARY, content, &range, max_displayed_len);
+
+ }
+
+ /* Instruction proprement dite */
+
+ key = g_arch_instruction_get_keyword(instr);
+
+ g_buffer_line_append_text(line, ACO_ASSEMBLY_HEAD, TRT_INSTRUCTION, SL(key), NULL, G_OBJECT(instr));
+
+ free(key);
+
+ /* Contenu sous forme d'opérandes */
+
+ if (g_raw_instruction_is_padding(raw))
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_CHR_PRINTABLE, STCSL("..."), NULL, NULL);
+
+ else
+ {
+ string = NULL;
+ iter = 0;
+
+ first = true;
+
+ count = g_arch_instruction_count_operands(instr);
+
+ for (i = 0; i < count; i++)
+ {
+ op = g_arch_instruction_get_operand(instr, i);
+
+ if (!G_IS_IMMEDIATE_OPERAND(op))
+ goto fallback;
+
+ imm = G_IMMEDIATE_OPERAND(op);
+
+ if (g_immediate_operand_get_size(imm) != MDS_8_BITS)
+ goto fallback;
+
+ if (!g_raw_instruction_is_string(raw) && g_immediate_operand_get_display(imm) != IOD_CHAR)
+ goto fallback;
+
+#ifndef NDEBUG
+ status = g_immediate_operand_get_value(imm, MDS_8_BITS, &byte);
+ assert(status);
+#else
+ g_immediate_operand_get_value(imm, MDS_8_BITS, &byte);
+#endif
+
+ /* Si le caractère doit apparaître en hexadécimal... */
+
+ if (!isprint(byte))
+ goto fallback;
+
+ /* Impression de l'octet */
+
+ if (string == NULL)
+ {
+ string = calloc(count + 3, sizeof(char));
+
+ strcpy(string, "\"");
+ iter = 1;
+
+ }
+
+ string[iter++] = byte;
+
+ unref_object(op);
+
+ continue;
+
+ fallback:
+
+ /* Si une chaîne précède */
+
+ if (string != NULL && iter > 1)
+ {
+ if (!first)
+ {
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_PUNCT, STCSL(","), NULL, NULL);
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_CHR_PRINTABLE, STCSL(" "), NULL, NULL);
+ }
+ else
+ first = false;
+
+ string[iter++] = '"';
+
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_STRING, string, iter, NULL, NULL);
+
+ iter = 1;
+
+ }
+
+ /* Intégration en tant qu'opérande classique */
+
+ if (!first)
+ {
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_PUNCT, STCSL(","), NULL, NULL);
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_CHR_PRINTABLE, STCSL(" "), NULL, NULL);
+ }
+ else
+ first = false;
+
+ g_arch_operand_ui_print(G_ARCH_OPERAND_UI(op), line);
+
+ unref_object(op);
+
+ }
+
+ /* Si au final une chaîne traine encore */
+
+ if (string != NULL && iter > 1)
+ {
+ if (!first)
+ {
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_PUNCT, STCSL(","), NULL, NULL);
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_CHR_PRINTABLE, STCSL(" "), NULL, NULL);
+ }
+
+ string[iter++] = '"';
+
+ g_buffer_line_append_text(line, ACO_ASSEMBLY, TRT_STRING, string, iter, NULL, NULL);
+
+ }
+
+ if (string != NULL)
+ free(string);
+
+ }
+
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
+
+}
diff --git a/src/arch/instructions/raw-ui.h b/src/arch/instructions/raw-ui.h
new file mode 100644
index 0000000..cd604e6
--- /dev/null
+++ b/src/arch/instructions/raw-ui.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * raw-ui.h - prototypes pour les opérandes représentant des instructions de données brutes 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_RAW_UI_H
+#define _ARCH_OPERANDS_RAW_UI_H
+
+
+#include "../../glibext/generator-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+void g_raw_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *);
+
+
+
+#endif /* _ARCH_OPERANDS_RAW_UI_H */
diff --git a/src/arch/instructions/raw.c b/src/arch/instructions/raw.c
index 26282fa..87297f1 100644
--- a/src/arch/instructions/raw.c
+++ b/src/arch/instructions/raw.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* raw.c - instructions pures vues de l'esprit
*
- * Copyright (C) 2014-2020 Cyrille Bagard
+ * Copyright (C) 2014-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,36 +25,19 @@
#include <assert.h>
-#include <ctype.h>
#include <string.h>
#include <i18n.h>
-#include "../instruction-int.h"
+#include "raw-int.h"
#include "../operands/immediate.h"
-#include "../operands/target.h"
-#include "../../core/columns.h"
+//#include "../operands/target.h" // FIXME
-/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
-
-
-/* Définition générique d'une instruction brute d'architecture (instance) */
-struct _GRawInstruction
-{
- GArchInstruction parent; /* A laisser en premier */
-
-};
-
-/* Définition générique d'une instruction brute d'architecture (classe) */
-struct _GRawInstructionClass
-{
- GArchInstructionClass parent; /* A laisser en premier */
-
-};
+/* --------------------- INSTRUCTION AVEC JEU DE DONNEES BRUTES --------------------- */
/* Initialise la classe des instructions brutes d'architecture. */
@@ -64,40 +47,26 @@ static void g_raw_instruction_class_init(GRawInstructionClass *);
static void g_raw_instruction_init(GRawInstruction *);
/* Supprime toutes les références externes. */
-static void g_raw_instruction_dispose(GRawInstruction *);
+static void g_raw_instruction_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_raw_instruction_finalize(GRawInstruction *);
-
-/* Indique l'encodage d'une instruction de façon détaillée. */
-static const char *g_raw_instruction_get_encoding(const GRawInstruction *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static const char *g_raw_instruction_get_keyword(const GRawInstruction *);
+static void g_raw_instruction_finalize(GObject *);
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* Charge une instruction depuis une mémoire tampon. */
-static bool g_raw_instruction_unserialize(GRawInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde une instruction dans une mémoire tampon. */
-static bool g_raw_instruction_serialize(GRawInstruction *, GAsmStorage *, packed_buffer_t *);
-
-
-
-/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
-
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static char *g_raw_instruction_get_encoding(const GArchInstruction *);
-/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static void g_raw_instruction_print(GRawInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* Fournit le nom humain de l'instruction manipulée. */
+static char *g_raw_instruction_get_keyword(const GArchInstruction *);
/* ---------------------------------------------------------------------------------- */
-/* INSTRUCTION INCONNUE / DONNEES */
+/* INSTRUCTION AVEC JEU DE DONNEES BRUTES */
/* ---------------------------------------------------------------------------------- */
@@ -124,18 +93,13 @@ static void g_raw_instruction_class_init(GRawInstructionClass *klass)
object = G_OBJECT_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_raw_instruction_dispose;
- object->finalize = (GObjectFinalizeFunc)g_raw_instruction_finalize;
+ object->dispose = g_raw_instruction_dispose;
+ object->finalize = g_raw_instruction_finalize;
instr = G_ARCH_INSTRUCTION_CLASS(klass);
- instr->get_encoding = (get_instruction_encoding_fc)g_raw_instruction_get_encoding;
- instr->get_keyword = (get_instruction_keyword_fc)g_raw_instruction_get_keyword;
-
- instr->unserialize = (unserialize_instruction_fc)g_raw_instruction_unserialize;
- instr->serialize = (serialize_instruction_fc)g_raw_instruction_serialize;
-
- instr->print = (print_instruction_fc)g_raw_instruction_print;
+ instr->get_encoding = g_raw_instruction_get_encoding;
+ instr->get_keyword = g_raw_instruction_get_keyword;
}
@@ -160,7 +124,7 @@ static void g_raw_instruction_init(GRawInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -170,16 +134,16 @@ static void g_raw_instruction_init(GRawInstruction *instr)
* *
******************************************************************************/
-static void g_raw_instruction_dispose(GRawInstruction *instr)
+static void g_raw_instruction_dispose(GObject *object)
{
- G_OBJECT_CLASS(g_raw_instruction_parent_class)->dispose(G_OBJECT(instr));
+ G_OBJECT_CLASS(g_raw_instruction_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -189,16 +153,17 @@ static void g_raw_instruction_dispose(GRawInstruction *instr)
* *
******************************************************************************/
-static void g_raw_instruction_finalize(GRawInstruction *instr)
+static void g_raw_instruction_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_raw_instruction_parent_class)->finalize(G_OBJECT(instr));
+ G_OBJECT_CLASS(g_raw_instruction_parent_class)->finalize(object);
}
/******************************************************************************
* *
-* Paramètres : addr = position à associer à l'instruction. *
+* Paramètres : area = portion de binaire incluant l'instruction. *
+* addr = adresse virtuelle et/ou position physique. *
* size = taille de l'opérande souhaitée. *
* value = valeur sur x bits à venir récupérer. *
* *
@@ -210,127 +175,106 @@ static void g_raw_instruction_finalize(GRawInstruction *instr)
* *
******************************************************************************/
-GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDataSize size, uint64_t value)
+GArchInstruction *g_raw_instruction_new_from_value(GBinaryPortion *area, const vmpa2t *addr, MemoryDataSize size, uint64_t value)
{
GArchInstruction *result; /* Instruction à retourner */
- GArchOperand *operand; /* Octet non décodé à afficher */
- mrange_t range; /* Couverture de l'instruction */
result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
- operand = g_imm_operand_new_from_value(size, value);
- if (operand == NULL) goto error;
+ if (!g_raw_instruction_create_value(G_RAW_INSTRUCTION(result), area, addr, size, value))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à initialiser pleinement. *
+* area = portion de binaire incluant l'instruction. *
+* addr = adresse virtuelle et/ou position physique. *
+* size = taille de chacun des éléments à représenter. *
+* value = valeur sur x bits à venir récupérer. *
+* *
+* Description : Met en place une instruction de type 'db/dw/etc' simple. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_raw_instruction_create_value(GRawInstruction *instr, GBinaryPortion *area, const vmpa2t *addr, MemoryDataSize size, uint64_t value)
+{
+ bool result; /* Bilan à retourner */
+ GArchOperand *operand; /* Octet non décodé à afficher */
+ uint16_t length; /* Taille de l'instruction */
+
+ result = false;
+
+ operand = g_immediate_operand_new_from_value(size, value);
+ if (operand == NULL) goto exit;
g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, operand);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
+
+ g_arch_instruction_attach_operand(G_ARCH_INSTRUCTION(instr), operand);
+ unref_object(operand);
+
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
switch (size)
{
case MDS_8_BITS_UNSIGNED:
case MDS_8_BITS_SIGNED:
- init_mrange(&range, addr, 1);
+ length = 1;
break;
case MDS_16_BITS_UNSIGNED:
case MDS_16_BITS_SIGNED:
- init_mrange(&range, addr, 2);
+ length = 2;
break;
case MDS_32_BITS_UNSIGNED:
case MDS_32_BITS_SIGNED:
- init_mrange(&range, addr, 4);
+ length = 4;
break;
case MDS_64_BITS_UNSIGNED:
case MDS_64_BITS_SIGNED:
- init_mrange(&range, addr, 8);
+ length = 8;
break;
default:
assert(false);
- goto error;
+ goto exit;
break;
}
- g_arch_instruction_set_range(result, &range);
+ g_arch_instruction_compute_range(G_ARCH_INSTRUCTION(instr), area, addr, length);
- return result;
-
- error:
-
- g_object_unref(G_OBJECT(result));
-
- return NULL;
-
-}
+ result = true;
-
-/******************************************************************************
-* *
-* Paramètres : content = flux de données à analyser. *
-* addr = position courante dans ce flux. [OUT] *
-* *
-* Description : Crée une instruction de type 'db/dw/etc' pour un uleb128. *
-* *
-* Retour : Instruction mise en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa2t *addr)
-{
- GArchInstruction *result; /* Instruction à retourner */
- vmpa2t start; /* Départ original de lecture */
- uleb128_t value; /* Valeur uleb128 à représenter*/
- phys_t diff; /* Couverture de la lecture */
- MemoryDataSize leb_size; /* Taille de la valeur */
- GArchOperand *operand; /* Octet non décodé à afficher */
- mrange_t range; /* Couverture de l'instruction */
-
- result = NULL;
-
- copy_vmpa(&start, addr);
-
- if (!g_binary_content_read_uleb128(content, addr, &value))
- goto error;
-
- diff = compute_vmpa_diff(&start, addr);
-
- leb_size = MDS_FROM_BYTES(diff);
- assert(leb_size != MDS_UNDEFINED);
-
- result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
-
- init_mrange(&range, &start, diff);
- g_arch_instruction_set_range(result, &range);
-
- operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
- if (operand == NULL) goto error;
-
- g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
-
- g_arch_instruction_attach_extra_operand(result, operand);
+ exit:
return result;
- error:
-
- g_clear_object(&result);
-
- return NULL;
-
}
/******************************************************************************
* *
-* Paramètres : content = flux de données à analyser. *
-* addr = position courante dans ce flux. [OUT] *
+* Paramètres : area = portion de binaire incluant l'instruction. *
+* addr = adresse virtuelle et/ou position physique. *
+* size = taille de chacun des éléments à représenter. *
+* content = flux de données à analyser. *
+* count = nombre de ces éléments. *
+* endian = ordre des bits dans la source. *
* *
-* Description : Crée une instruction de type 'db/dw/etc' pour un sleb128. *
+* Description : Crée une instruction de type 'db/dw/etc' étendue. *
* *
* Retour : Instruction mise en place. *
* *
@@ -338,256 +282,174 @@ GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa
* *
******************************************************************************/
-GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa2t *addr)
+GArchInstruction *g_raw_instruction_new_array(GBinaryPortion *area, vmpa2t *addr, MemoryDataSize size, const GBinContent *content, size_t count, SourceEndian endian)
{
GArchInstruction *result; /* Instruction à retourner */
- vmpa2t start; /* Départ original de lecture */
- uleb128_t value; /* Valeur uleb128 à représenter*/
- phys_t diff; /* Couverture de la lecture */
- MemoryDataSize leb_size; /* Taille de la valeur */
- GArchOperand *operand; /* Octet non décodé à afficher */
- mrange_t range; /* Couverture de l'instruction */
-
- result = NULL;
-
- copy_vmpa(&start, addr);
-
- if (!g_binary_content_read_uleb128(content, addr, &value))
- goto error;
-
- diff = compute_vmpa_diff(&start, addr);
-
- leb_size = MDS_FROM_BYTES(diff) | MDS_SIGN;
- assert(leb_size != MDS_SIGN);
result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
- init_mrange(&range, &start, diff);
- g_arch_instruction_set_range(result, &range);
-
- operand = g_imm_operand_new_from_value(leb_size, (uint64_t)value);
- if (operand == NULL) goto error;
-
- g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
-
- g_arch_instruction_attach_extra_operand(result, operand);
+ if (!g_raw_instruction_create_array(G_RAW_INSTRUCTION(result), area, addr, size, content, count, endian))
+ g_clear_object(&result);
return result;
- error:
-
- g_clear_object(&result);
-
- return NULL;
-
}
/******************************************************************************
* *
-* Paramètres : content = flux de données à analyser. *
+* Paramètres : instr = instance à initialiser pleinement. *
+* area = portion de binaire incluant l'instruction. *
+* addr = adresse virtuelle et/ou position physique. *
* size = taille de chacun des éléments à représenter. *
+* content = flux de données à analyser. *
* count = nombre de ces éléments. *
-* addr = position courante dans ce flux. [OUT] *
* endian = ordre des bits dans la source. *
* *
-* Description : Crée une instruction de type 'db/dw/etc' étendue. *
+* Description : Met en place une instruction de type 'db/dw/etc' étendue. *
* *
-* Retour : Instruction mise en place. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_raw_instruction_new_array(const GBinContent *content, MemoryDataSize size, size_t count, vmpa2t *addr, SourceEndian endian)
+bool g_raw_instruction_create_array(GRawInstruction *instr, GBinaryPortion *area, vmpa2t *addr, MemoryDataSize size, const GBinContent *content, size_t count, SourceEndian endian)
{
- GArchInstruction *result; /* Instruction à retourner */
- vmpa2t old; /* Sauvegarde de la position */
+ bool result; /* Bilan à retourner */
+ vmpa2t start; /* Sauvegarde de la position */
size_t i; /* Boucle de parcours */
GArchOperand *operand; /* Octet non décodé à afficher */
- mrange_t range; /* Couverture de l'instruction */
+ phys_t diff; /* Décalage à appliquer */
+
+ result = false;
/* Par soucis de cohérence */
- if (count == 0) return NULL;
+ if (count == 0)
+ goto exit;
- result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL);
+ copy_vmpa(&start, addr);
- copy_vmpa(&old, addr);
+ g_thick_object_lock(G_THICK_OBJECT(instr));
for (i = 0; i < count; i++)
{
- operand = g_imm_operand_new_from_data(size, content, addr, endian);
- if (operand == NULL) goto error;
+ operand = g_immediate_operand_new_from_data(size, content, addr, (bool []){ false /* unused */ }, endian);
+ if (operand == NULL) break;
g_arch_operand_set_flag(operand, IOF_ZERO_PADDING_BY_DEFAULT | IOF_ZERO_PADDING);
- g_arch_instruction_attach_extra_operand(result, operand);
+ g_arch_instruction_attach_operand(G_ARCH_INSTRUCTION(instr), operand);
+ unref_object(operand);
}
- init_mrange(&range, &old, compute_vmpa_diff(addr, &old));
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- g_arch_instruction_set_range(result, &range);
+ if (i < count)
+ goto exit;
- return result;
+ diff = compute_vmpa_diff(addr, &start);
+
+ g_arch_instruction_compute_range(G_ARCH_INSTRUCTION(instr), area, &start, diff);
- error:
+ result = true;
- g_object_unref(G_OBJECT(result));
+ exit:
- return NULL;
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à consulter. *
+* Paramètres : instr = instruction à traiter. *
+* is_padding = nouveau statut à associer au contenu. *
* *
-* Description : Indique l'encodage d'une instruction de façon détaillée. *
+* Description : Marque l'instruction comme ne contenant que du bourrage. *
* *
-* Retour : Description humaine de l'encodage utilisé. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static const char *g_raw_instruction_get_encoding(const GRawInstruction *instr)
+void g_raw_instruction_mark_as_padding(GRawInstruction *instr, bool is_padding)
{
- const char *result; /* Description à retourner */
-
- if (g_raw_instruction_is_string(instr))
- result = _("String");
+ if (is_padding)
+ g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
else
- result = _("Raw");
-
- return result;
+ g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
}
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
+* Paramètres : instr = instruction à traiter. *
+* is_padding = nouveau statut à associer au contenu. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Indique si le contenu de l'instruction est du bourrage. *
* *
-* Retour : Mot clef de bas niveau. *
+* Retour : Statut du contenu de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr)
+bool g_raw_instruction_is_padding(const GRawInstruction *instr)
{
- GArchOperand *operand; /* Octet décodé à afficher */
- MemoryDataSize size; /* Taille de valeur associée */
-
- static char *defines[] = { "dn", "db", "dw", "dd", "dq" };
-
- operand = g_arch_instruction_get_operand(G_ARCH_INSTRUCTION(instr), 0);
-
- if (G_IS_TARGET_OPERAND(operand))
- size = g_target_operand_get_size(G_TARGET_OPERAND(operand));
- else
- size = g_imm_operand_get_size(G_IMM_OPERAND(operand));
+ bool result; /* Indication à retourner */
- g_object_unref(G_OBJECT(operand));
+ result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
- return defines[MDS_RANGE(size)];
+ return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction à traiter. *
+* is_string = nouveau statut à associer au contenu. *
* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Marque l'instruction comme contenant une chaîne de texte. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_raw_instruction_unserialize(GRawInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+void g_raw_instruction_mark_as_string(GRawInstruction *instr, bool is_string)
{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class);
-
- result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf);
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- g_raw_instruction_mark_as_padding(instr, (boolean == 1));
-
- }
-
- if (result)
- {
- result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
-
- if (result)
- g_raw_instruction_mark_as_string(instr, (boolean == 1));
-
- }
-
- return result;
+ if (is_string)
+ g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
+ else
+ g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
}
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction à traiter. *
+* is_string = nouveau statut à associer au contenu. *
* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
+* Description : Indique si le contenu de l'instruction est un texte. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Statut du contenu de l'instruction. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_raw_instruction_serialize(GRawInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
+bool g_raw_instruction_is_string(const GRawInstruction *instr)
{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- uint8_t boolean; /* Valeur booléenne */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_raw_instruction_parent_class);
-
- result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf);
-
- if (result)
- {
- boolean = (g_raw_instruction_is_padding(instr) ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ bool result; /* Indication à retourner */
- if (result)
- {
- boolean = (g_raw_instruction_is_string(instr) ? 1 : 0);
- result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false);
- }
+ result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
return result;
@@ -596,285 +458,73 @@ static bool g_raw_instruction_serialize(GRawInstruction *instr, GAsmStorage *sto
/* ---------------------------------------------------------------------------------- */
-/* OFFRE DE CAPACITES DE GENERATION */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* line = ligne de rendu à compléter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
+* Paramètres : instr = instruction quelconque à consulter. *
* *
-* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : - *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
+static char *g_raw_instruction_get_encoding(const GArchInstruction *instr)
{
- GArchInstruction *base; /* Autre version de l'instance */
- phys_t max_displayed_len; /* Quantité de code affichée */
- const char *key; /* Mot clef principal */
- size_t klen; /* Taille de ce mot clef */
- char *string; /* Chaîne reconstituée */
- size_t iter; /* Tête d'écriture */
- bool first; /* Mémorise une énumération */
- size_t count; /* Nombre d'opérandes en place */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à manipuler */
- GImmOperand *imm; /* Version opérande de valeur */
- char byte; /* Octet à afficher (ou pas) */
-#ifndef NDEBUG
- bool status; /* Bilan d'une récupération */
-#endif
-
- base = G_ARCH_INSTRUCTION(instr);
-
- /* Localisation */
-
- g_buffer_line_fill_phys(line, DLC_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&base->range));
-
- g_buffer_line_fill_virt(line, DLC_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&base->range));
-
- /* Contenu */
-
- if (g_raw_instruction_is_padding(instr))
- max_displayed_len = 0;
-
- else if (g_raw_instruction_is_string(instr))
- max_displayed_len = 1;
-
- else
- {
- max_displayed_len = get_mrange_length(&base->range);
- max_displayed_len /= g_arch_instruction_count_operands(base);
- }
-
- g_buffer_line_fill_content(line, DLC_BINARY, content, &base->range, max_displayed_len);
-
- /* Zone du code d'assemblage */
+ char *result; /* Description à retourner */
+ GRawInstruction *raw; /* Version spécialisée */
- key = g_arch_instruction_get_keyword(base);
- klen = strlen(key);
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
-
- if (g_raw_instruction_is_padding(instr))
- g_buffer_line_append_text(line, DLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
+ raw = G_RAW_INSTRUCTION(instr);
+ if (g_raw_instruction_is_string(raw))
+ result = strdup(_("String"));
else
- {
- string = NULL;
- iter = 0;
-
- first = true;
-
- g_arch_instruction_lock_operands(base);
-
- count = _g_arch_instruction_count_operands(base);
-
- for (i = 0; i < count; i++)
- {
- op = _g_arch_instruction_get_operand(base, i);
-
- if (!G_IS_IMM_OPERAND(op))
- goto grip_fallback;
-
- imm = G_IMM_OPERAND(op);
-
- if (g_imm_operand_get_size(imm) != MDS_8_BITS)
- goto grip_fallback;
-
- if (!g_raw_instruction_is_string(instr) && g_imm_operand_get_display(imm) != IOD_CHAR)
- goto grip_fallback;
-
-#ifndef NDEBUG
- status = g_imm_operand_get_value(imm, MDS_8_BITS, &byte);
- assert(status);
-#else
- g_imm_operand_get_value(imm, MDS_8_BITS, &byte);
-#endif
-
- /* Si le caractère doit apparaître en hexadécimal... */
-
- if (!isprint(byte))
- goto grip_fallback;
-
- /* Impression de l'octet */
-
- if (string == NULL)
- {
- string = (char *)calloc(count + 3, sizeof(char));
-
- strcpy(string, "\"");
- iter = 1;
-
- }
-
- string[iter++] = byte;
-
- g_object_unref(G_OBJECT(op));
-
- continue;
-
- grip_fallback:
-
- /* Si une chaîne précède */
-
- if (string != NULL && iter > 1)
- {
- if (!first)
- {
- g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
- }
- else
- first = false;
-
- string[iter++] = '"';
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
-
- iter = 1;
-
- }
-
- /* Intégration en tant qu'opérande classique */
-
- if (!first)
- {
- g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
- }
- else
- first = false;
-
- g_arch_operand_print(op, line);
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- /* Si au final une chaîne traine encore */
-
- if (string != NULL && iter > 1)
- {
- if (!first)
- {
- g_buffer_line_append_text(line, DLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
- g_buffer_line_append_text(line, DLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
- }
-
- string[iter++] = '"';
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
-
- }
+ result = strdup(_("Raw"));
- g_arch_instruction_unlock_operands(base);
-
- if (string != NULL)
- free(string);
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction à traiter. *
-* is_padding = nouveau statut à associer au contenu. *
-* *
-* Description : Marque l'instruction comme ne contenant que du bourrage. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_raw_instruction_mark_as_padding(GRawInstruction *instr, bool is_padding)
-{
- if (is_padding)
- g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
- else
- g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : instr = instruction à traiter. *
-* is_padding = nouveau statut à associer au contenu. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Indique si le contenu de l'instruction est du bourrage. *
+* Description : Fournit le nom humain de l'instruction manipulée. *
* *
-* Retour : Statut du contenu de l'instruction. *
+* Retour : Mot clef de bas niveau. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_raw_instruction_is_padding(const GRawInstruction *instr)
+static char *g_raw_instruction_get_keyword(const GArchInstruction *instr)
{
- bool result; /* Indication à retourner */
-
- result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_PADDING);
-
- return result;
-
-}
+ char *result; /* Désignation à retourner */
+ GArchOperand *operand; /* Octet décodé à afficher */
+ MemoryDataSize size; /* Taille de valeur associée */
+ static char *defines[] = { "dn", "db", "dw", "dd", "dq" };
-/******************************************************************************
-* *
-* Paramètres : instr = instruction à traiter. *
-* is_string = nouveau statut à associer au contenu. *
-* *
-* Description : Marque l'instruction comme contenant une chaîne de texte. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ g_thick_object_lock(G_THICK_OBJECT(instr));
-void g_raw_instruction_mark_as_string(GRawInstruction *instr, bool is_string)
-{
- if (is_string)
- g_arch_instruction_set_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
- else
- g_arch_instruction_unset_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
-
-}
+ operand = g_arch_instruction_get_operand(instr, 0);
+ /*if (G_IS_TARGET_OPERAND(operand)) FIXME
+ size = g_target_operand_get_size(G_TARGET_OPERAND(operand));
+ else*/
+ size = g_immediate_operand_get_size(G_IMMEDIATE_OPERAND(operand));
-/******************************************************************************
-* *
-* Paramètres : instr = instruction à traiter. *
-* is_string = nouveau statut à associer au contenu. *
-* *
-* Description : Indique si le contenu de l'instruction est un texte. *
-* *
-* Retour : Statut du contenu de l'instruction. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ unref_object(operand);
-bool g_raw_instruction_is_string(const GRawInstruction *instr)
-{
- bool result; /* Indication à retourner */
+ g_thick_object_unlock(G_THICK_OBJECT(instr));
- result = g_arch_instruction_has_flag(G_ARCH_INSTRUCTION(instr), RIF_STRING);
+ result = strdup(defines[MDS_RANGE(size)]);
return result;
diff --git a/src/arch/instructions/raw.h b/src/arch/instructions/raw.h
index 4e92cd4..712f877 100644
--- a/src/arch/instructions/raw.h
+++ b/src/arch/instructions/raw.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * raw.h - prototypes pour les instructions pures vues de l'esprit
+ * raw.h - prototypes pour les instructions de données brutes
*
- * Copyright (C) 2014-2020 Cyrille Bagard
+ * Copyright (C) 2014-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,46 +25,24 @@
#define _ARCH_INSTRUCTIONS_RAW_H
-#include <glib-object.h>
-
-
#include "../instruction.h"
#include "../vmpa.h"
+#include "../../analysis/content.h"
+#include "../../glibext/helpers.h"
-/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
-
-
-#define G_TYPE_RAW_INSTRUCTION g_raw_instruction_get_type()
-#define G_RAW_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_RAW_INSTRUCTION, GRawInstruction))
-#define G_IS_RAW_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_RAW_INSTRUCTION))
-#define G_RAW_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_RAW_INSTRUCTION, GRawInstructionClass))
-#define G_IS_RAW_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_RAW_INSTRUCTION))
-#define G_RAW_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_RAW_INSTRUCTION, GRawInstructionClass))
-
+#define G_TYPE_RAW_INSTRUCTION (g_raw_instruction_get_type())
-/* Définition générique d'une instruction brute d'architecture (instance) */
-typedef struct _GRawInstruction GRawInstruction;
+DECLARE_GTYPE(GRawInstruction, g_raw_instruction, G, RAW_INSTRUCTION);
-/* Définition générique d'une instruction brute d'architecture (classe) */
-typedef struct _GRawInstructionClass GRawInstructionClass;
-
-
-/* Indique le type défini pour une instruction inconnue d'architecture. */
-GType g_raw_instruction_get_type(void);
/* Crée une instruction de type 'db/dw/etc' simple. */
-GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t);
+GArchInstruction *g_raw_instruction_new_from_value(GBinaryPortion *, const vmpa2t *, MemoryDataSize, uint64_t);
-/* Crée une instruction de type 'db/dw/etc' pour un uleb128. */
-GArchInstruction *g_raw_instruction_new_uleb128(const GBinContent *content, vmpa2t *);
+/* Crée une instruction de type 'db/dw/etc' étendue. */
+GArchInstruction *g_raw_instruction_new_array(GBinaryPortion *, vmpa2t *, MemoryDataSize, const GBinContent *, size_t, SourceEndian);
-/* Crée une instruction de type 'db/dw/etc' pour un sleb128. */
-GArchInstruction *g_raw_instruction_new_sleb128(const GBinContent *content, vmpa2t *);
-
-/* Crée une instruction de type 'db/dw/etc' étendue. */
-GArchInstruction *g_raw_instruction_new_array(const GBinContent *, MemoryDataSize, size_t, vmpa2t *, SourceEndian);
/* Drapeaux pour informations complémentaires */
typedef enum _RawInstrFlag
@@ -74,6 +52,7 @@ typedef enum _RawInstrFlag
} RawInstrFlag;
+
/* Marque l'instruction comme ne contenant que du bourrage. */
void g_raw_instruction_mark_as_padding(GRawInstruction *, bool);
diff --git a/src/arch/instructions/undefined-int.h b/src/arch/instructions/undefined-int.h
index a9b7627..faf0b4b 100644
--- a/src/arch/instructions/undefined-int.h
+++ b/src/arch/instructions/undefined-int.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * undefined-int.h - prototypes pour la définition générique interne des instructions au comportement non défini
+ * undefined-int.h - prototypes pour la définition interne des instructions au comportement non défini
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2019-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -27,42 +27,18 @@
#include "undefined.h"
#include "../instruction-int.h"
-#include "../../glibext/objhole.h"
-/* Informations glissées dans la structure GObject de GArchInstruction */
-typedef struct _undef_extra_data_t
-{
- /**
- * Le champ uid de la structure parente attendue conduit à une taille
- * alignée sur 2 octets, donc à une taille totale de 4 octets ce qui
- * représente la limite maximale de taille supportée.
- *
- * Pour 3 octets à la base, qui devraient laisser 8 - 1 octets disponbibles
- * en incluant le bit de verrouillage.
- *
- * On reproduit donc la structure instr_extra_data_t ici, en basculant
- * l'énumération InstrExpectedBehavior en champ de bits.
- */
-
- itid_t uid; /* Identifiant unique du type */
- ArchInstrFlag flags; /* Informations complémentaires*/
-
- unsigned int behavior : 2; /* Conséquences réelles */
-
-} undef_extra_data_t;
-
-
/* Définition générique d'une instruction au comportement non défini (instance) */
-struct _GUndefInstruction
+struct _GUndefinedInstruction
{
GArchInstruction parent; /* A laisser en premier */
};
/* Définition générique d'une instruction au comportement non défini (classe) */
-struct _GUndefInstructionClass
+struct _GUndefinedInstructionClass
{
GArchInstructionClass parent; /* A laisser en premier */
@@ -73,15 +49,25 @@ struct _GUndefInstructionClass
* Accès aux informations éventuellement déportées.
*/
-#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+/* Informations glissées dans la structure GObject de GArchInstruction */
+typedef struct _undef_extra_data_t
+{
+ ARCH_INSTRUCTION_EXTRA_DATA
+
+ unsigned int behavior : 2; /* Conséquences réelles */
+
+} undef_extra_data_t;
+
-# define GET_UNDEF_INSTR_EXTRA(ins) ((undef_extra_data_t *)&((GArchInstruction *)ins)->extra)
+#define GET_UNDEF_INSTR_EXTRA(op) \
+ GET_GOBJECT_EXTRA(op, undef_extra_data_t)
-#else
+#define SET_UNDEF_INSTR_EXTRA(op, data) \
+ SET_GOBJECT_EXTRA(op, undef_extra_data_t, data)
-# define GET_UNDEF_INSTR_EXTRA(ins) GET_GOBJECT_EXTRA(G_OBJECT(ins), undef_extra_data_t)
-#endif
+/* Met en place une instruction au comportement indéfini. */
+bool g_undefined_instruction_create(GUndefinedInstruction *, InstrExpectedBehavior);
diff --git a/src/arch/instructions/undefined-ui.c b/src/arch/instructions/undefined-ui.c
new file mode 100644
index 0000000..fbc0452
--- /dev/null
+++ b/src/arch/instructions/undefined-ui.c
@@ -0,0 +1,102 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * undefined-ui.c - opérandes représentant des instructions indéfinies 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 "undefined-ui.h"
+
+
+#include "../instruction.h"
+#include "../../glibext/options/asm.h"
+
+
+
+/* Etablit dans une ligne de rendu le contenu représenté. */
+static void g_undefined_instruction_ui_populate_line(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de génération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_undefined_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *iface)
+{
+ iface->populate = g_undefined_instruction_ui_populate_line;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* index = indice de cette même ligne dans le tampon global.*
+* repeat = indice d'utilisations successives du générateur. *
+* line = ligne de rendu à compléter. *
+* data = éventuelle donnée complémentaire fournie. *
+* *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_undefined_instruction_ui_populate_line(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)
+{
+ GArchInstruction *instr; /* Version spécialisée */
+ GBinContent *content; /* Contenu brut d'origine */
+ mrange_t range; /* Emplacement couvert */
+ char *key; /* Mot clef principal */
+
+ instr = G_ARCH_INSTRUCTION(generator);
+ content = G_BIN_CONTENT(data);
+
+ /* Prologue */
+
+ if (g_arch_instruction_get_range(instr, &range))
+ {
+ g_buffer_line_fill_physical(line, ACO_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ g_buffer_line_fill_virtual(line, ACO_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&range));
+
+ g_buffer_line_fill_content(line, ACO_BINARY, content, &range, VMPA_NO_PHYSICAL);
+
+ }
+
+ /* Instruction proprement dite */
+
+ key = g_arch_instruction_get_keyword(instr);
+
+ g_buffer_line_append_text(line, ACO_ASSEMBLY_HEAD, TRT_ERROR, SL(key), NULL, G_OBJECT(instr));
+
+ free(key);
+
+}
diff --git a/src/arch/instructions/undefined-ui.h b/src/arch/instructions/undefined-ui.h
new file mode 100644
index 0000000..8bc2d67
--- /dev/null
+++ b/src/arch/instructions/undefined-ui.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * undefined-ui.h - prototypes pour les opérandes représentant des instructions indéfinies 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_UNDEFINED_UI_H
+#define _ARCH_OPERANDS_UNDEFINED_UI_H
+
+
+#include "../../glibext/generator-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+void g_undefined_instruction_ui_token_generator_iface_init(GTokenGeneratorInterface *);
+
+
+
+#endif /* _ARCH_OPERANDS_UNDEFINED_UI_H */
diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c
index 15c63e7..75df493 100644
--- a/src/arch/instructions/undefined.c
+++ b/src/arch/instructions/undefined.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.c - instructions au comportement non défini
*
- * Copyright (C) 2016-2019 Cyrille Bagard
+ * Copyright (C) 2016-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,63 +25,42 @@
#include <assert.h>
+#include <string.h>
#include <i18n.h>
#include "undefined-int.h"
-#include "../../core/columns.h"
+#include "../../glibext/serialize-int.h"
+/* ------------------------- INSTRUCTION INCONNUE / DONNEES ------------------------- */
+
+
/* Initialise la classe des instructions non définies. */
-static void g_undef_instruction_class_init(GUndefInstructionClass *);
+static void g_undefined_instruction_class_init(GUndefinedInstructionClass *);
/* Initialise une instance d'instruction non définie. */
-static void g_undef_instruction_init(GUndefInstruction *);
+static void g_undefined_instruction_init(GUndefinedInstruction *);
/* Supprime toutes les références externes. */
-static void g_undef_instruction_dispose(GUndefInstruction *);
+static void g_undefined_instruction_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void g_undef_instruction_finalize(GUndefInstruction *);
-
-/* Indique l'encodage d'une instruction de façon détaillée. */
-static const char *g_undef_instruction_get_encoding(const GUndefInstruction *);
-
-/* Fournit le nom humain de l'instruction manipulée. */
-static const char *g_undef_instruction_get_keyword(const GUndefInstruction *);
-
-
-
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
-
-
-/* Charge une instruction depuis une mémoire tampon. */
-static bool g_undef_instruction_unserialize(GUndefInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
-
-/* Sauvegarde une instruction dans une mémoire tampon. */
-static bool g_undef_instruction_serialize(GUndefInstruction *, GAsmStorage *, packed_buffer_t *);
-
-
-
-/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
-
-
-/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
-static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
+static void g_undefined_instruction_finalize(GObject *);
/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
-/* Charge un contenu depuis une mémoire tampon. */
-static bool g_undef_instruction_load(GUndefInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Indique l'encodage d'une instruction de façon détaillée. */
+static char *g_undefined_instruction_get_encoding(const GArchInstruction *);
-/* Sauvegarde un contenu dans une mémoire tampon. */
-static bool g_undef_instruction_store(GUndefInstruction *, GObjectStorage *, packed_buffer_t *);
+/* Fournit le nom humain de l'instruction manipulée. */
+static char *g_undefined_instruction_get_keyword(const GArchInstruction *);
@@ -91,7 +70,9 @@ static bool g_undef_instruction_store(GUndefInstruction *, GObjectStorage *, pac
/* Indique le type défini pour une instruction au comportement non défini. */
-G_DEFINE_TYPE(GUndefInstruction, g_undef_instruction, G_TYPE_ARCH_INSTRUCTION);
+G_DEFINE_TYPE_WITH_CODE(GUndefinedInstruction, g_undefined_instruction, G_TYPE_ARCH_INSTRUCTION,
+ G_IMPLEMENT_INTERFACE_IF_SYM(g_token_generator_get_type, g_undefined_instruction_ui_token_generator_iface_init));
+
/******************************************************************************
@@ -106,28 +87,20 @@ G_DEFINE_TYPE(GUndefInstruction, g_undef_instruction, G_TYPE_ARCH_INSTRUCTION);
* *
******************************************************************************/
-static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
+static void g_undefined_instruction_class_init(GUndefinedInstructionClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
GArchInstructionClass *instr; /* Encore une autre vision... */
object = G_OBJECT_CLASS(klass);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_undef_instruction_dispose;
- object->finalize = (GObjectFinalizeFunc)g_undef_instruction_finalize;
+ object->dispose = g_undefined_instruction_dispose;
+ object->finalize = g_undefined_instruction_finalize;
instr = G_ARCH_INSTRUCTION_CLASS(klass);
- instr->get_encoding = (get_instruction_encoding_fc)g_undef_instruction_get_encoding;
- instr->get_keyword = (get_instruction_keyword_fc)g_undef_instruction_get_keyword;
-
- instr->unserialize = (unserialize_instruction_fc)g_undef_instruction_unserialize;
- instr->serialize = (serialize_instruction_fc)g_undef_instruction_serialize;
-
- instr->print = (print_instruction_fc)g_undef_instruction_print;
-
- instr->load = (load_instruction_fc)g_undef_instruction_load;
- instr->store = (store_instruction_fc)g_undef_instruction_store;
+ instr->get_encoding = g_undefined_instruction_get_encoding;
+ instr->get_keyword = g_undefined_instruction_get_keyword;
}
@@ -144,16 +117,22 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)
* *
******************************************************************************/
-static void g_undef_instruction_init(GUndefInstruction *instr)
+static void g_undefined_instruction_init(GUndefinedInstruction *instr)
{
- GET_UNDEF_INSTR_EXTRA(instr)->behavior = IEB_UNDEFINED;
+ undef_extra_data_t extra; /* Données insérées à consulter*/
+
+ extra = GET_UNDEF_INSTR_EXTRA(instr);
+
+ extra.behavior = IEB_UNDEFINED;
+
+ SET_UNDEF_INSTR_EXTRA(instr, &extra);
}
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -163,16 +142,16 @@ static void g_undef_instruction_init(GUndefInstruction *instr)
* *
******************************************************************************/
-static void g_undef_instruction_dispose(GUndefInstruction *instr)
+static void g_undefined_instruction_dispose(GObject *object)
{
- G_OBJECT_CLASS(g_undef_instruction_parent_class)->dispose(G_OBJECT(instr));
+ G_OBJECT_CLASS(g_undefined_instruction_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : instr = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -182,9 +161,9 @@ static void g_undef_instruction_dispose(GUndefInstruction *instr)
* *
******************************************************************************/
-static void g_undef_instruction_finalize(GUndefInstruction *instr)
+static void g_undefined_instruction_finalize(GObject *object)
{
- G_OBJECT_CLASS(g_undef_instruction_parent_class)->finalize(G_OBJECT(instr));
+ G_OBJECT_CLASS(g_undefined_instruction_parent_class)->finalize(object);
}
@@ -201,16 +180,14 @@ static void g_undef_instruction_finalize(GUndefInstruction *instr)
* *
******************************************************************************/
-GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior)
+GArchInstruction *g_undefined_instruction_new(InstrExpectedBehavior behavior)
{
GArchInstruction *result; /* Instruction à retourner */
- undef_extra_data_t *extra; /* Données insérées à modifier */
- result = g_object_new(G_TYPE_UNDEF_INSTRUCTION, NULL);
+ result = g_object_new(G_TYPE_UNDEFINED_INSTRUCTION, NULL);
- extra = GET_UNDEF_INSTR_EXTRA(result);
-
- extra->behavior = behavior;
+ if (!g_undefined_instruction_create(G_UNDEFINED_INSTRUCTION(result), behavior))
+ g_clear_object(&result);
return result;
@@ -219,90 +196,10 @@ GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior behavior)
/******************************************************************************
* *
-* Paramètres : instr = instruction quelconque à consulter. *
-* *
-* Description : Indique l'encodage d'une instruction de façon détaillée. *
-* *
-* Retour : Description humaine de l'encodage utilisé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static const char *g_undef_instruction_get_encoding(const GUndefInstruction *instr)
-{
- const char *result; /* Description à retourner */
-
- result = _("Undefined");
-
- return result;
-
-}
-
-
-/******************************************************************************
+* Paramètres : instr = instance à initialiser pleinement. *
+* behavior = état réel du CPU après une passe de l'instruction.*
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
-* *
-* Retour : Mot clef de bas niveau. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr)
-{
- const char *result; /* Désignation à retourner */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
-
- extra = GET_UNDEF_INSTR_EXTRA(instr);
-
- switch (extra->behavior)
- {
- case IEB_NOP:
- result = "nop";
- break;
-
- case IEB_UNDEFINED:
- result = "undefined";
- break;
-
- case IEB_UNPREDICTABLE:
- result = "unpredictable";
- break;
-
- case IEB_RESERVED:
- result = "reserved";
- break;
-
- default:
- assert(false);
- result = NULL;
- break;
-
- }
-
- return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* CONSERVATION SUR DISQUE DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Met en place une instruction au comportement indéfini. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -310,122 +207,24 @@ const char *g_undef_instruction_get_keyword(const GUndefInstruction *instr)
* *
******************************************************************************/
-static bool g_undef_instruction_unserialize(GUndefInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+bool g_undefined_instruction_create(GUndefinedInstruction *instr, InstrExpectedBehavior behavior)
{
bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
- uint8_t val; /* Champ de bits manipulé */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
+ undef_extra_data_t extra; /* Données insérées à modifier */
- result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf);
+ result = true;
- if (result)
- {
- extra = GET_UNDEF_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
-
- result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
- extra->behavior = val;
-
- UNLOCK_GOBJECT_EXTRA(extra);
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
-* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static bool g_undef_instruction_serialize(GUndefInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
-{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
-
- result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf);
-
- if (result)
- {
- extra = GET_UNDEF_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
-
- result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false);
+ extra = GET_UNDEF_INSTR_EXTRA(instr);
- UNLOCK_GOBJECT_EXTRA(extra);
+ extra.behavior = behavior;
- }
+ SET_UNDEF_INSTR_EXTRA(instr, &extra);
return result;
}
-
-/* ---------------------------------------------------------------------------------- */
-/* OFFRE DE CAPACITES DE GENERATION */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à représenter. *
-* line = ligne de rendu à compléter. *
-* index = indice de cette même ligne dans le tampon global. *
-* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
-* *
-* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
-{
- GArchInstruction *base; /* Version de base */
- const char *key; /* Mot clef principal */
- size_t klen; /* Taille de ce mot clef */
-
- base = G_ARCH_INSTRUCTION(instr);
-
- g_buffer_line_fill_phys(line, DLC_PHYSICAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&base->range));
-
- g_buffer_line_fill_virt(line, DLC_VIRTUAL, MDS_32_BITS_UNSIGNED, get_mrange_addr(&base->range));
-
- g_buffer_line_fill_content(line, DLC_BINARY, content, &base->range, VMPA_NO_PHYSICAL);
-
- /* Instruction proprement dite */
-
- key = g_arch_instruction_get_keyword(base);
- klen = strlen(key);
-
- g_buffer_line_append_text(line, DLC_ASSEMBLY_HEAD, key, klen, RTT_ERROR, NULL);
-
-}
-
-
/******************************************************************************
* *
* Paramètres : instr = instruction à consulter. *
@@ -438,18 +237,14 @@ static void g_undef_instruction_print(GUndefInstruction *instr, GBufferLine *lin
* *
******************************************************************************/
-InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *instr)
+InstrExpectedBehavior g_undefined_instruction_get_behavior(const GUndefinedInstruction *instr)
{
InstrExpectedBehavior result; /* Comportement à retourner */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
+ undef_extra_data_t extra; /* Données insérées à consulter*/
extra = GET_UNDEF_INSTR_EXTRA(instr);
- LOCK_GOBJECT_EXTRA(extra);
-
- result = extra->behavior;
-
- UNLOCK_GOBJECT_EXTRA(extra);
+ result = extra.behavior;
return result;
@@ -464,41 +259,21 @@ InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *
/******************************************************************************
* *
-* Paramètres : instr = élément GLib à constuire. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à lire. *
+* Paramètres : instr = instruction quelconque à consulter. *
* *
-* Description : Charge un contenu depuis une mémoire tampon. *
+* Description : Indique l'encodage d'une instruction de façon détaillée. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Description humaine de l'encodage utilisé. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_undef_instruction_load(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+static char *g_undefined_instruction_get_encoding(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
- uint8_t val; /* Champ de bits manipulé */
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
-
- result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf);
-
- if (result)
- {
- extra = GET_UNDEF_INSTR_EXTRA(instr);
-
- LOCK_GOBJECT_EXTRA(extra);
+ char *result; /* Description à retourner */
- result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false);
- extra->behavior = val;
-
- UNLOCK_GOBJECT_EXTRA(extra);
-
- }
+ result = strdup(_("Undefined"));
return result;
@@ -507,37 +282,45 @@ static bool g_undef_instruction_load(GUndefInstruction *instr, GObjectStorage *s
/******************************************************************************
* *
-* Paramètres : instr = élément GLib à consulter. *
-* storage = conservateur de données à manipuler ou NULL. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Sauvegarde un contenu dans une mémoire tampon. *
+* Description : Fournit le nom humain de l'instruction manipulée. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Mot clef de bas niveau. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_undef_instruction_store(GUndefInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+static char *g_undefined_instruction_get_keyword(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- GArchInstructionClass *parent; /* Classe parente à consulter */
- undef_extra_data_t *extra; /* Données insérées à consulter*/
-
- parent = G_ARCH_INSTRUCTION_CLASS(g_undef_instruction_parent_class);
+ char *result; /* Désignation à retourner */
+ undef_extra_data_t extra; /* Données insérées à consulter*/
- result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf);
+ extra = GET_UNDEF_INSTR_EXTRA(instr);
- if (result)
+ switch (extra.behavior)
{
- extra = GET_UNDEF_INSTR_EXTRA(instr);
+ case IEB_NOP:
+ result = strdup("nop");
+ break;
- LOCK_GOBJECT_EXTRA(extra);
+ case IEB_UNDEFINED:
+ result = strdup("undefined");
+ break;
- result = extend_packed_buffer(pbuf, (uint8_t []){ extra->behavior }, sizeof(uint8_t), false);
+ case IEB_UNPREDICTABLE:
+ result = strdup("unpredictable");
+ break;
- UNLOCK_GOBJECT_EXTRA(extra);
+ case IEB_RESERVED:
+ result = strdup("reserved");
+ break;
+
+ default:
+ assert(false);
+ result = NULL;
+ break;
}
diff --git a/src/arch/instructions/undefined.h b/src/arch/instructions/undefined.h
index 8f35f35..d4b35f4 100644
--- a/src/arch/instructions/undefined.h
+++ b/src/arch/instructions/undefined.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* undefined.h - prototypes pour les instructions au comportement non défini
*
- * Copyright (C) 2016-2019 Cyrille Bagard
+ * Copyright (C) 2016-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,27 +25,14 @@
#define _ARCH_INSTRUCTIONS_UNDEFINED_H
-#include <glib-object.h>
-
-
#include "../instruction.h"
-#include "../vmpa.h"
-
+#include "../../glibext/helpers.h"
-#define G_TYPE_UNDEF_INSTRUCTION g_undef_instruction_get_type()
-#define G_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstruction))
-#define G_IS_UNDEF_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_UNDEF_INSTRUCTION))
-#define G_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass))
-#define G_IS_UNDEF_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_UNDEF_INSTRUCTION))
-#define G_UNDEF_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_UNDEF_INSTRUCTION, GUndefInstructionClass))
+#define G_TYPE_UNDEFINED_INSTRUCTION (g_undefined_instruction_get_type())
-/* Définition générique d'une instruction au comportement non défini (instance) */
-typedef struct _GUndefInstruction GUndefInstruction;
-
-/* Définition générique d'une instruction au comportement non défini (classe) */
-typedef struct _GUndefInstructionClass GUndefInstructionClass;
+DECLARE_GTYPE(GUndefinedInstruction, g_undefined_instruction, G, UNDEFINED_INSTRUCTION);
/* Etat précis de l'instruction */
@@ -59,14 +46,11 @@ typedef enum _InstrExpectedBehavior
} InstrExpectedBehavior;
-/* Indique le type défini pour une instruction au comportement non défini. */
-GType g_undef_instruction_get_type(void);
-
/* Crée une instruction au comportement nominalement indéfini. */
-GArchInstruction *g_undef_instruction_new(InstrExpectedBehavior);
+GArchInstruction *g_undefined_instruction_new(InstrExpectedBehavior);
/* Indique le type de conséquences réél de l'instruction. */
-InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *);
+InstrExpectedBehavior g_undefined_instruction_get_behavior(const GUndefinedInstruction *);
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 8a9b961..7a11deb 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -296,4 +296,33 @@ char *mrange_length_to_string(const mrange_t *, MemoryDataSize, char [VMPA_MAX_L
+/* ------------------- DEFINITION D'UN ESPACE RELATIVE EN MEMOIRE ------------------- */
+
+
+/* Couverture mémoire */
+typedef struct _rel_mrange_t
+{
+ uint32_t offset; /* Décalage depuis une ref. */
+ uint16_t length; /* Taille de la couverture */
+
+} rel_mrange_t;
+
+
+#define init_rel_mrange(rr, o, l) \
+ do \
+ { \
+ (rr)->offset = o; \
+ (rr)->length = l; \
+ } \
+ while (0);
+
+
+#define get_rel_mrange_offset(rr) \
+ (rr)->offset
+
+#define get_rel_mrange_length(rr) \
+ (rr)->length
+
+
+
#endif /* _ARCH_VMPA_H */
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index d09b661..1056cb2 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -47,6 +47,7 @@ endif
libcommon4_la_SOURCES = \
+ array.h array.c \
asm.h asm.c \
bits.h bits.c \
compiler.h \
diff --git a/src/common/cpp.h b/src/common/cpp.h
index 9616db3..4ebad82 100644
--- a/src/common/cpp.h
+++ b/src/common/cpp.h
@@ -48,6 +48,8 @@
*/
#define SL(str) str, strlen(str)
+#define STCSL(str) str, STATIC_STR_SIZE(str)
+
/**
* Détermine la taille de la plus longue chaîne de caractères
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 17fd2bf..15ed866 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -20,7 +20,8 @@ libcore4_la_SOURCES = \
logs.h logs.c \
nox.h nox.c \
nproc.h nproc.c \
- paths.h paths.c
+ paths.h paths.c \
+ processors.h processors.c
libcore4_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBSSL_CFLAGS)
diff --git a/src/core/core.c b/src/core/core.c
index 8fe12f5..c730fad 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -25,6 +25,7 @@
#include "global.h"
+#include "processors.h"
@@ -61,6 +62,14 @@ bool load_core_components(AvailableCoreComponent flags)
}
+ if ((flags & ACC_CODE_ANALYSIS) != 0 && (__loaded & ACC_CODE_ANALYSIS) == 0)
+ {
+ register_arch_gtypes();
+
+ init_operands_factory();
+
+ }
+
return result;
}
@@ -80,6 +89,12 @@ bool load_core_components(AvailableCoreComponent flags)
void unload_core_components(AvailableCoreComponent flags)
{
+ if ((flags & ACC_CODE_ANALYSIS) != 0 && (__loaded & ACC_CODE_ANALYSIS) == 0)
+ {
+ exit_operands_factory();
+
+ }
+
if ((flags & ACC_GLOBAL_VARS) != 0 && (__loaded & ACC_GLOBAL_VARS) == 0)
{
set_work_queue(NULL);
@@ -111,7 +126,6 @@ void unload_core_components(AvailableCoreComponent flags)
#include "demanglers.h"
#include "global.h"
#include "params.h"
-#include "processors.h"
#include "queue.h"
#include "../analysis/scan/core.h"
#ifdef INCLUDE_MAGIC_SUPPORT
@@ -195,9 +209,6 @@ bool load_all_core_components(bool cs)
if (result) result = init_segment_content_hash_table();
- register_arch_gtypes();
- init_operands_factory();
-
}
}
@@ -223,8 +234,6 @@ void unload_all_core_components(bool cs)
{
if (cs)
{
- exit_operands_factory();
-
exit_segment_content_hash_table();
unload_demanglers_definitions();
diff --git a/src/core/core.h b/src/core/core.h
index e5f0a60..640476a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -34,9 +34,10 @@ typedef enum _AvailableCoreComponent
{
ACC_NONE = (0 << 0), /* Statut initial */
ACC_GLOBAL_VARS = (1 << 0), /* Singletons globaux */
- ACC_SCAN_FEATURES = (1 << 1), /* Espace de noms pour scan */
+ ACC_CODE_ANALYSIS = (1 << 1), /* Désassemblage de code */
+ ACC_SCAN_FEATURES = (1 << 2), /* Espace de noms pour scan */
- ACC_ALL_COMPONENTS = (1 << 2) - 1
+ ACC_ALL_COMPONENTS = (1 << 3) - 1
} AvailableCoreComponent;
diff --git a/src/core/processors.c b/src/core/processors.c
index e4a558f..056fc23 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* processors.c - enregistrement et fourniture des architectures supportées
*
- * Copyright (C) 2015-2020 Cyrille Bagard
+ * Copyright (C) 2015-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -29,13 +29,13 @@
#include <pthread.h>
#include <string.h>
-
+#if 0
#include "../arch/instructions/raw.h"
#include "../arch/instructions/undefined.h"
#include "../arch/operands/immediate.h"
#include "../arch/operands/register.h"
#include "../arch/operands/target.h"
-
+#endif
/* Cache des singletons d'opérandes */
@@ -77,12 +77,12 @@ static proc_t *find_processor_by_key(const char *);
void register_arch_gtypes(void)
{
- g_type_ensure(G_TYPE_RAW_INSTRUCTION);
- g_type_ensure(G_TYPE_UNDEF_INSTRUCTION);
+ //g_type_ensure(G_TYPE_RAW_INSTRUCTION);
+ //g_type_ensure(G_TYPE_UNDEF_INSTRUCTION);
- g_type_ensure(G_TYPE_IMM_OPERAND);
- g_type_ensure(G_TYPE_REGISTER_OPERAND);
- g_type_ensure(G_TYPE_TARGET_OPERAND);
+ //g_type_ensure(G_TYPE_IMM_OPERAND);
+ //g_type_ensure(G_TYPE_REGISTER_OPERAND);
+ //g_type_ensure(G_TYPE_TARGET_OPERAND);
}
@@ -126,7 +126,7 @@ GSingletonFactory *get_operands_factory(void)
result = __operands_factory;
- g_object_ref(G_OBJECT(result));
+ ref_object(result);
return result;
@@ -154,7 +154,7 @@ void exit_operands_factory(void)
}
-
+#if 0
/******************************************************************************
* *
* Paramètres : type = type GLib représentant le type à instancier. *
@@ -206,7 +206,7 @@ bool register_processor_type(GType type)
done:
- g_object_unref(G_OBJECT(proc));
+ unref_object(proc);
return result;
@@ -341,3 +341,4 @@ GArchProcessor *get_arch_processor_for_key(const char *key)
return result;
}
+#endif
diff --git a/src/core/processors.h b/src/core/processors.h
index 6aa2d1e..b622305 100644
--- a/src/core/processors.h
+++ b/src/core/processors.h
@@ -29,7 +29,7 @@
#include <stdbool.h>
-#include "../arch/processor.h"
+//#include "../arch/processor.h"
#include "../glibext/singleton.h"
@@ -45,7 +45,7 @@ GSingletonFactory *get_operands_factory(void);
/* Supprime le fournisseur d'instances uniques d'opérandes. */
void exit_operands_factory(void);
-
+#if 0
/* Enregistre un processeur pour une architecture donnée. */
bool register_processor_type(GType);
@@ -57,7 +57,7 @@ char **get_all_processor_keys(size_t *);
/* Fournit le processeur d'architecture correspondant à un nom. */
GArchProcessor *get_arch_processor_for_key(const char *);
-
+#endif
#endif /* _CORE_PROCESSORS_H */
diff --git a/src/glibext/bufferline.c b/src/glibext/bufferline.c
index 4862e9f..e3fb27b 100644
--- a/src/glibext/bufferline.c
+++ b/src/glibext/bufferline.c
@@ -24,14 +24,16 @@
#include "bufferline.h"
+#include <assert.h>
+#include <malloc.h>
+
+
#include "bufferline-int.h"
#if 0
-#include <assert.h>
-#include <malloc.h>
#include <string.h>
@@ -273,158 +275,12 @@ bool g_buffer_line_create(GBufferLine *line, size_t col_count)
}
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* column = colonne de la ligne visée par l'insertion. *
-* tag = type de décorateur à utiliser. *
-* text = texte à insérer dans l'existant. *
-* length = taille du texte à traiter. *
-* style = gestionnaire de paramètres de rendu à consulter. *
-* creator = instance GLib quelconque à associer. *
-* *
-* Description : Ajoute du texte à formater dans une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_append_text(GBufferLine *line, size_t column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style, GObject *creator)
-{
- size_t index; /* Indice d'insertion */
- //content_origin *origin; /* Définition d'une origine */
-
- assert(column < line->col_count);
- assert(length > 0);
-
- index = append_text_to_line_column(&line->columns[column], tag, text, length, style);
-
- /*
- if (creator != NULL)
- {
- line->origins = realloc(line->origins, ++line->ocount * sizeof(content_origin));
-
- origin = &line->origins[line->ocount - 1];
-
- origin->coord.column = column;
- origin->coord.index = index;
-
- origin->creator = creator;
- g_object_ref(G_OBJECT(creator));
-
- }
- */
-
-}
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne de texte à manipuler. *
-* cr = contexte graphique dédié à la procédure. *
-* column = (première) colonne à traiter. *
-* y = ordonnée du point d'impression. *
-* style = style de rendu pour les bribes de texte. *
-* *
-* Description : Imprime la ligne de texte représentée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_draw(const GBufferLine *line, cairo_t *cr, size_t column, int y, const GTokenStyle *style)
-{
-#if 0
- GBufferLineClass *class; /* Stockage de briques de base */
- bool has_src_surface; /* Note une présence définie */
-#endif
- size_t max_column; /* Borne de fin des colonnes */
- int x; /* Point de départ d'impression*/
- size_t i; /* Boucle de parcours */
-
- /*
- if (line->flags != BLF_NONE)
- {
- class = G_BUFFER_LINE_GET_CLASS(line);
-
- if (line->flags & BLF_ENTRYPOINT)
- {
- cairo_set_source_surface(cairo, class->entrypoint_img, 5, y);
- has_src_surface = true;
- }
- else if (line->flags & BLF_BOOKMARK)
- {
- cairo_set_source_surface(cairo, class->bookmark_img, 5, y);
- has_src_surface = true;
- }
- else
- has_src_surface = false;
-
- if (has_src_surface)
- cairo_paint(cairo);
-
- }
- */
-
-
- /* Détermination de l'éventail des colonnes à traiter */
-
- if (column == line->merge_start)
- max_column = line->col_count;
-
- else if (column > line->merge_start)
- max_column = 0;
-
- else
- max_column = column + 1;
-
- /* Dessin du contenu de ces colonnes */
-
- x = 0;
-
- for (i = column; i < max_column; i++)
- draw_line_column(&line->columns[i], cr, &x, y, style);
-
-}
-
-
-
-
-
-
-
-
-
-
-#if 0
-
-
/******************************************************************************
* *
-* Paramètres : line = ligne à venir compléter. *
-* col = indice de la colonne à constituer. *
-* size = taille souhaitée de l'impression des positions. *
-* addr = localisation physique à venir représenter. *
+* Paramètres : line = ligne à venir compléter. *
+* column = indice de la colonne visée par l'insertion. *
+* size = taille souhaitée de l'impression des positions. *
+* addr = localisation physique à venir représenter. *
* *
* Description : Construit le tronc commun d'une ligne autour de sa position. *
* *
@@ -434,7 +290,7 @@ void g_buffer_line_draw(const GBufferLine *line, cairo_t *cr, size_t column, int
* *
******************************************************************************/
-void g_buffer_line_fill_phys(GBufferLine *line, size_t col, MemoryDataSize size, const vmpa2t *addr)
+void g_buffer_line_fill_physical(GBufferLine *line, size_t column, MemoryDataSize size, const vmpa2t *addr)
{
VMPA_BUFFER(position); /* Emplacement au format texte */
size_t len; /* Taille de l'élément inséré */
@@ -448,20 +304,22 @@ void g_buffer_line_fill_phys(GBufferLine *line, size_t col, MemoryDataSize size,
if (i == len)
i = len - 1;
+ assert(column < line->col_count);
+
if (i > 0)
- g_buffer_line_append_text(line, col, position, i, RTT_PHYS_ADDR_PAD, NULL);
+ g_buffer_line_append_text(line, column, TRT_PHYS_ADDR_PAD, position, i, NULL, NULL);
- g_buffer_line_append_text(line, col, &position[i], len - i, RTT_PHYS_ADDR, NULL);
+ g_buffer_line_append_text(line, column, TRT_PHYS_ADDR, &position[i], len - i, NULL, NULL);
}
/******************************************************************************
* *
-* Paramètres : line = ligne à venir compléter. *
-* col = indice de la colonne à constituer. *
-* size = taille souhaitée de l'impression des positions. *
-* addr = localisation virtuelle à venir représenter. *
+* Paramètres : line = ligne à venir compléter. *
+* column = indice de la colonne visée par l'insertion. *
+* size = taille souhaitée de l'impression des positions. *
+* addr = localisation virtuelle à venir représenter. *
* *
* Description : Construit le tronc commun d'une ligne autour de sa position. *
* *
@@ -471,7 +329,7 @@ void g_buffer_line_fill_phys(GBufferLine *line, size_t col, MemoryDataSize size,
* *
******************************************************************************/
-void g_buffer_line_fill_virt(GBufferLine *line, size_t col, MemoryDataSize size, const vmpa2t *addr)
+void g_buffer_line_fill_virtual(GBufferLine *line, size_t column, MemoryDataSize size, const vmpa2t *addr)
{
VMPA_BUFFER(position); /* Emplacement au format texte */
size_t len; /* Taille de l'élément inséré */
@@ -479,6 +337,8 @@ void g_buffer_line_fill_virt(GBufferLine *line, size_t col, MemoryDataSize size,
vmpa2_virt_to_string(addr, size, position, &len);
+ assert(column < line->col_count);
+
if (has_virt_addr(addr))
{
for (i = 2; i < len; i++)
@@ -488,14 +348,14 @@ void g_buffer_line_fill_virt(GBufferLine *line, size_t col, MemoryDataSize size,
i = len - 1;
if (i > 0)
- g_buffer_line_append_text(line, col, position, i, RTT_VIRT_ADDR_PAD, NULL);
+ g_buffer_line_append_text(line, column, TRT_VIRT_ADDR_PAD, position, i, NULL, NULL);
- g_buffer_line_append_text(line, col, &position[i], len - i, RTT_VIRT_ADDR, NULL);
+ g_buffer_line_append_text(line, column, TRT_VIRT_ADDR, &position[i], len - i, NULL, NULL);
}
else
- g_buffer_line_append_text(line, col, position, len, RTT_VIRT_ADDR_PAD, NULL);
+ g_buffer_line_append_text(line, column, TRT_VIRT_ADDR_PAD, position, len, NULL, NULL);
}
@@ -503,7 +363,7 @@ void g_buffer_line_fill_virt(GBufferLine *line, size_t col, MemoryDataSize size,
/******************************************************************************
* *
* Paramètres : line = ligne à venir compléter. *
-* col = indice de la colonne à constituer. *
+* column = indice de la colonne visée par l'insertion. *
* content = contenu binaire global à venir lire. *
* range = localisation des données à venir lire et présenter.*
* max = taille maximale de la portion binaire en octets. *
@@ -516,7 +376,7 @@ void g_buffer_line_fill_virt(GBufferLine *line, size_t col, MemoryDataSize size,
* *
******************************************************************************/
-void g_buffer_line_fill_content(GBufferLine *line, size_t col, const GBinContent *content, const mrange_t *range, phys_t max)
+void g_buffer_line_fill_content(GBufferLine *line, size_t column, const GBinContent *content, const mrange_t *range, phys_t max)
{
phys_t length; /* Taille de la couverture */
bool truncated; /* Indique si le code est coupé*/
@@ -548,7 +408,7 @@ void g_buffer_line_fill_content(GBufferLine *line, size_t col, const GBinContent
if (required <= sizeof(static_buffer))
bin_code = static_buffer;
else
- bin_code = (char *)calloc(required, sizeof(char));
+ bin_code = calloc(required, sizeof(char));
/* Code brut */
@@ -589,7 +449,7 @@ void g_buffer_line_fill_content(GBufferLine *line, size_t col, const GBinContent
/* Conclusion */
- g_buffer_line_append_text(line, col, bin_code, iter - bin_code, RTT_RAW_CODE, NULL);
+ g_buffer_line_append_text(line, column, TRT_RAW_CODE, bin_code, iter - bin_code, NULL, NULL);
if (bin_code != static_buffer)
free(bin_code);
@@ -599,6 +459,146 @@ void g_buffer_line_fill_content(GBufferLine *line, size_t col, const GBinContent
/******************************************************************************
* *
+* Paramètres : line = ligne à venir compléter. *
+* column = colonne de la ligne visée par l'insertion. *
+* tag = type de décorateur à utiliser. *
+* text = texte à insérer dans l'existant. *
+* length = taille du texte à traiter. *
+* style = gestionnaire de paramètres de rendu à consulter. *
+* creator = instance GLib quelconque à associer. *
+* *
+* Description : Ajoute du texte à formater dans une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_append_text(GBufferLine *line, size_t column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style, GObject *creator)
+{
+ size_t index; /* Indice d'insertion */
+ //content_origin *origin; /* Définition d'une origine */
+
+ assert(column < line->col_count);
+ assert(length > 0);
+
+ index = append_text_to_line_column(&line->columns[column], tag, text, length, style);
+
+ /*
+ if (creator != NULL)
+ {
+ line->origins = realloc(line->origins, ++line->ocount * sizeof(content_origin));
+
+ origin = &line->origins[line->ocount - 1];
+
+ origin->coord.column = column;
+ origin->coord.index = index;
+
+ origin->creator = creator;
+ g_object_ref(G_OBJECT(creator));
+
+ }
+ */
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne de texte à manipuler. *
+* cr = contexte graphique dédié à la procédure. *
+* column = (première) colonne à traiter. *
+* y = ordonnée du point d'impression. *
+* style = style de rendu pour les bribes de texte. *
+* *
+* Description : Imprime la ligne de texte représentée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_draw(const GBufferLine *line, cairo_t *cr, size_t column, int y, const GTokenStyle *style)
+{
+#if 0
+ GBufferLineClass *class; /* Stockage de briques de base */
+ bool has_src_surface; /* Note une présence définie */
+#endif
+ size_t max_column; /* Borne de fin des colonnes */
+ int x; /* Point de départ d'impression*/
+ size_t i; /* Boucle de parcours */
+
+ /*
+ if (line->flags != BLF_NONE)
+ {
+ class = G_BUFFER_LINE_GET_CLASS(line);
+
+ if (line->flags & BLF_ENTRYPOINT)
+ {
+ cairo_set_source_surface(cairo, class->entrypoint_img, 5, y);
+ has_src_surface = true;
+ }
+ else if (line->flags & BLF_BOOKMARK)
+ {
+ cairo_set_source_surface(cairo, class->bookmark_img, 5, y);
+ has_src_surface = true;
+ }
+ else
+ has_src_surface = false;
+
+ if (has_src_surface)
+ cairo_paint(cairo);
+
+ }
+ */
+
+
+ /* Détermination de l'éventail des colonnes à traiter */
+
+ if (column == line->merge_start)
+ max_column = line->col_count;
+
+ else if (column > line->merge_start)
+ max_column = 0;
+
+ else
+ max_column = column + 1;
+
+ /* Dessin du contenu de ces colonnes */
+
+ x = 0;
+
+ for (i = column; i < max_column; i++)
+ draw_line_column(&line->columns[i], cr, &x, y, style);
+
+}
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir consulter. *
* column = indice de la colonne visée par les recherches. *
* *
diff --git a/src/glibext/bufferline.h b/src/glibext/bufferline.h
index d6a2e2d..e95ee2b 100644
--- a/src/glibext/bufferline.h
+++ b/src/glibext/bufferline.h
@@ -30,6 +30,8 @@
#include "helpers.h"
#include "tokenstyle.h"
+#include "../arch/vmpa.h"
+#include "../analysis/content.h"
@@ -45,8 +47,6 @@
#ifdef INCLUDE_GTK_SUPPORT
# include "widthtracker.h"
#endif
-#include "../analysis/content.h"
-#include "../arch/vmpa.h"
@@ -75,6 +75,9 @@ typedef struct _GBufferLineClass GBufferLineClass;
+
+
+
#define G_TYPE_BUFFER_LINE (g_buffer_line_get_type())
DECLARE_GTYPE(GBufferLine, g_buffer_line, G, BUFFER_LINE);
@@ -98,7 +101,14 @@ typedef enum _BufferLineFlags
/* Crée une nouvelle représentation de fragments de texte. */
GBufferLine *g_buffer_line_new(size_t);
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_physical(GBufferLine *, size_t, MemoryDataSize, const vmpa2t *);
+
+/* Construit le tronc commun d'une ligne autour de sa position. */
+void g_buffer_line_fill_virtual(GBufferLine *, size_t, MemoryDataSize, const vmpa2t *);
+/* Construit le tronc commun d'une ligne autour de son contenu. */
+void g_buffer_line_fill_content(GBufferLine *, size_t, const GBinContent *, const mrange_t *, phys_t);
/* Ajoute du texte à formater dans une ligne donnée. */
void g_buffer_line_append_text(GBufferLine *, size_t, TokenRenderingTag, const char *, size_t, const GTokenStyle *, GObject *);
diff --git a/src/glibext/options/asm.h b/src/glibext/options/asm.h
index e916083..d7a2c86 100644
--- a/src/glibext/options/asm.h
+++ b/src/glibext/options/asm.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * disass.h - prototypes pour les options de rendus de code désassemblé
+ * asm.h - prototypes pour les options de rendus de code désassemblé
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -21,8 +21,8 @@
*/
-#ifndef _GLIBEXT_OPTIONS_DISASS_H
-#define _GLIBEXT_OPTIONS_DISASS_H
+#ifndef _GLIBEXT_OPTIONS_ASM_H
+#define _GLIBEXT_OPTIONS_ASM_H
#include "../helpers.h"
@@ -32,14 +32,23 @@
/* Liste des colonnes en options */
typedef enum _DisassColumnOptions
{
- ACO_OFFSET, /* Position */
+ ACO_PHYSICAL, /* Position physique */
+ ACO_VIRTUAL, /* Adresse virtuelle */
+ ACO_BINARY, /* Contenu sous forme binaire */
ACO_COUNT
} DisassColumnOptions;
-#define ACO_ASSEMBLY (ACO_COUNT + 0) /* Code pour assembleur */
+#define ACO_ASSEMBLY_LABEL (ACO_COUNT + 0) /* Etiquette dans les données */
+#define ACO_ASSEMBLY_HEAD (ACO_COUNT + 1) /* Instruction pour assembleur */
+#define ACO_ASSEMBLY (ACO_COUNT + 2) /* Code pour assembleur */
+#define ACO_COMMENTS (ACO_COUNT + 3) /* Commentaires éventuels */
+
+
+
+
#if 0