summaryrefslogtreecommitdiff
path: root/src/arch/instruction.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r--src/arch/instruction.c744
1 files changed, 392 insertions, 352 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 4079e82..cd1e9c7 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -34,10 +34,12 @@
#include "instruction-int.h"
#include "storage.h"
+#include "../analysis/storage/serialize-int.h"
+#include "../core/columns.h"
#include "../core/logs.h"
+#include "../core/processors.h"
#include "../glibext/gbinarycursor.h"
#include "../glibext/linegen-int.h"
-#include "../gtkext/gtkblockdisplay.h"
@@ -48,7 +50,10 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
static void g_arch_instruction_init(GArchInstruction *);
/* Procède à l'initialisation de l'interface de génération. */
-static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *);
+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 *);
@@ -58,14 +63,15 @@ static void g_arch_instruction_finalize(GArchInstruction *);
-/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */
-/* Charge une instruction depuis une mémoire tampon. */
-static bool g_arch_instruction_unserialize(GArchInstruction *, GAsmStorage *, GBinFormat *, packed_buffer_t *);
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_instruction_load_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde toutes les destinations d'une instruction. */
+bool g_arch_instruction_store_destinations(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
-/* Sauvegarde une instruction dans une mémoire tampon. */
-static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, packed_buffer_t *);
@@ -75,12 +81,16 @@ static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, pack
/* Indique le nombre de ligne prêtes à être générées. */
static size_t g_arch_instruction_count_lines(const GArchInstruction *);
+#ifdef INCLUDE_GTK_SUPPORT
+
/* Retrouve l'emplacement correspondant à une position donnée. */
static void g_arch_instruction_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_contain_cursor(const GArchInstruction *, size_t, size_t, const GLineCursor *);
+#endif
+
/* 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);
@@ -91,10 +101,27 @@ static void _g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t,
static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* -------------------- CONSERVATION ET RECHARGEMENT DES DONNEES -------------------- */
+
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool _g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* Charge un contenu depuis une mémoire tampon. */
+static bool g_arch_instruction_load(GArchInstruction *, GObjectStorage *, packed_buffer_t *);
+
+/* 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 *);
+
+
/* 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_interface_init));
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_SERIALIZABLE_OBJECT, g_arch_instruction_serializable_init));
/******************************************************************************
@@ -121,11 +148,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
instr = G_ARCH_INSTRUCTION_CLASS(klass);
- instr->unserialize = (unserialize_instruction_fc)g_arch_instruction_unserialize;
- instr->serialize = (serialize_instruction_fc)g_arch_instruction_serialize;
-
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;
+
}
@@ -143,7 +170,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
- INIT_ARCH_INSTR_EXTRA(instr);
+ 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;
@@ -165,11 +196,13 @@ static void g_arch_instruction_init(GArchInstruction *instr)
* *
******************************************************************************/
-static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface)
+static void g_arch_instruction_generator_init(GLineGeneratorInterface *iface)
{
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;
@@ -178,6 +211,26 @@ static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface
/******************************************************************************
* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
+* Description : Procède à l'initialisation de l'interface de sérialisation. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+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;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
@@ -285,19 +338,19 @@ const char *g_arch_instruction_get_encoding(const GArchInstruction *instr)
bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags |= flag;
+ result = !(extra->flags & flag);
- result = true;
+ extra->flags |= flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -320,19 +373,19 @@ bool g_arch_instruction_set_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
- extra->flags &= ~flag;
+ result = (extra->flags & flag);
- result = true;
+ extra->flags &= ~flag;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -355,17 +408,17 @@ bool g_arch_instruction_unset_flag(GArchInstruction *instr, ArchInstrFlag flag)
bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag flag)
{
bool result; /* Bilan à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
assert(flag <= AIF_HIGH_USER);
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = (extra->flags & flag);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -387,27 +440,15 @@ bool g_arch_instruction_has_flag(const GArchInstruction *instr, ArchInstrFlag fl
ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
{
ArchInstrFlag result; /* Fanions à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->flags;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
-
- /**
- * La pose du verrou a entraîné la mise à 1 du bit de poids fort de la zone
- * couverte par le champ "extra".
- *
- * Même si les fanions ne couvrent pas cet emplacement, leur stockage s'étend
- * sur 16 bits, et contient donc le fameux bit de verrouillage.
- *
- * On efface ce marqueur après-coup ici.
- */
-
- result &= ((AIF_HIGH_USER << 1) - 1);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -429,15 +470,15 @@ ArchInstrFlag g_arch_instruction_get_flags(const GArchInstruction *instr)
void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
{
- instr_obj_extra *extra; /* Données insérées à modifier */
+ instr_extra_data_t *extra; /* Données insérées à modifier */
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
extra->uid = uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
}
@@ -457,15 +498,15 @@ void g_arch_instruction_set_unique_id(GArchInstruction *instr, itid_t uid)
itid_t g_arch_instruction_get_unique_id(const GArchInstruction *instr)
{
itid_t result; /* Numéro à retourner */
- instr_obj_extra *extra; /* Données insérées à consulter*/
+ instr_extra_data_t *extra; /* Données insérées à consulter*/
extra = GET_ARCH_INSTR_EXTRA(instr);
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
+ LOCK_GOBJECT_EXTRA(extra);
result = extra->uid;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ UNLOCK_GOBJECT_EXTRA(extra);
return result;
@@ -666,9 +707,19 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr)
void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)
{
+ 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, &operand, sizeof(GArchOperand *));
+ add_item_to_flat_array(&instr->operands, &singleton, sizeof(GArchOperand *));
g_arch_instruction_unlock_operands(instr);
@@ -1557,59 +1608,54 @@ instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_
}
-
-/* ---------------------------------------------------------------------------------- */
-/* CONVERSIONS DU FORMAT DES INSTRUCTIONS */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
* *
-* Description : Fournit le nom humain de l'instruction manipulée. *
+* Description : Charge un contenu depuis une mémoire tampon. *
* *
-* Retour : Mot clef de bas niveau. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
+static bool g_arch_instruction_load_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
{
- const char *result; /* Désignation à retourner */
-
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);
-
- return result;
+ 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 */
-}
+ g_arch_instruction_lock_dest(instr);
+ result = unpack_uleb128(&count, pbuf);
-/******************************************************************************
-* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* *
-* Description : Construit un petit résumé concis de l'instruction. *
-* *
-* Retour : Chaîne de caractères à libérer après usage ou NULL. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ 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;
+ }
-char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
-{
- char *result; /* Description à retourner */
- GArchInstructionClass *class; /* Classe des instructions */
+ result = unpack_uleb128(&type, pbuf);
+ if (!result)
+ {
+ g_object_unref(G_OBJECT(linked));
+ break;
+ }
- class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+ g_arch_instruction_link_with(instr, linked, type);
+ g_object_unref(G_OBJECT(linked));
- if (class->build_tooltip != NULL)
- result = class->build_tooltip(instr);
+ }
- else
- result = NULL;
+ g_arch_instruction_unlock_dest(instr);
return result;
@@ -1618,41 +1664,11 @@ char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
/******************************************************************************
* *
-* 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 : - *
-* *
-******************************************************************************/
-
-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);
-
- 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. *
+* Paramètres : instr = instruction dont les informations sont à consulter.*
+* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à remplir. *
* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Sauvegarde toutes les destinations d'une instruction. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -1660,148 +1676,87 @@ const char *g_arch_instruction_get_description(const GArchInstruction *instr)
* *
******************************************************************************/
-static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+bool g_arch_instruction_store_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
{
bool result; /* Bilan à retourner */
- packed_buffer_t op_pbuf; /* Tampon des données à écrire */
size_t count; /* Nombre d'éléments à traiter */
+ size_t kept; /* Nombre de liens conservés */
size_t i; /* Boucle de parcours */
- off64_t pos; /* Position dans le flux */
- GArchOperand *op; /* Opérande à traiter */
- instr_link_t link; /* Lien vers une instruction */
- packed_buffer_t ins_pbuf; /* Tampon des données à écrire */
- instr_obj_extra *extra; /* Données insérées à consulter*/
-
- result = unpack_mrange(&instr->range, pbuf);
-
- if (result)
- {
- init_packed_buffer(&op_pbuf);
-
- result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- result = extract_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
-
- if (result)
- result = g_asm_storage_load_operand_data(storage, &op_pbuf, pos);
-
- if (result)
- {
- op = g_arch_operand_load(storage, format, &op_pbuf);
- result = (op != NULL);
- }
+ const instr_link_t *link; /* Lien vers une instruction */
- if (result)
- g_arch_instruction_attach_extra_operand(instr, op);
+ g_arch_instruction_lock_dest(instr);
- }
+ count = g_arch_instruction_count_destinations(instr);
- exit_packed_buffer(&op_pbuf);
+ /**
+ * 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.
+ */
- }
+ kept = 0;
- bool unserialize_link(instr_link_t *lk)
+ for (i = 0; i < count; i++)
{
- bool status; /* Bilan d'une conservation */
- phys_t lk_phys; /* Position physique courante */
-
- status = extract_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true);
-
- if (status)
- {
- lk->linked = g_asm_storage_get_instruction_at(storage, format, lk_phys, &ins_pbuf);
- status = (lk->linked != NULL);
- }
-
- if (status)
- {
- status = extract_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true);
+ link = g_arch_instruction_get_destination(instr, i);
- if (!status)
- g_object_unref(G_OBJECT(lk->linked));
+ if (link->type != ILT_REF)
+ kept++;
- }
-
- return status;
+ unref_instr_link(link);
}
- if (result)
- {
- init_packed_buffer(&ins_pbuf);
+ result = pack_uleb128((uleb128_t []){ kept }, pbuf);
- result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
+ for (i = 0; i < count && result; i++)
+ {
+ link = g_arch_instruction_get_destination(instr, i);
- for (i = 0; i < count && result; i++)
+ if (link->type != ILT_REF)
{
- result = unserialize_link(&link);
+ result = g_object_storage_pack_object(storage, "instructions",
+ G_SERIALIZABLE_OBJECT(link->linked), pbuf);
if (result)
- {
- g_arch_instruction_link_with(instr, link.linked, link.type);
- g_object_unref(G_OBJECT(link.linked));
- }
+ result = pack_uleb128((uleb128_t []){ link->type }, pbuf);
}
- exit_packed_buffer(&ins_pbuf);
+ unref_instr_link(link);
}
- if (result)
- {
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extract_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+ g_arch_instruction_unlock_dest(instr);
- if (result)
- result = extract_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+ return result;
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+}
- }
- return result;
-}
+/* ---------------------------------------------------------------------------------- */
+/* CONVERSIONS DU FORMAT DES INSTRUCTIONS */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : storage = mécanisme de sauvegarde à manipuler. *
-* format = format binaire chargé associé à l'architecture. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Charge une instruction depuis une mémoire tampon. *
+* Description : Fournit le nom humain de l'instruction manipulée. *
* *
-* Retour : Instruction d'assemblage constitué ou NULL en cas d'échec. *
+* Retour : Mot clef de bas niveau. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)
+const char *g_arch_instruction_get_keyword(GArchInstruction *instr)
{
- GArchInstruction *result; /* Instance à retourner */
- bool status; /* Bilan du chargement */
-
- result = G_ARCH_INSTRUCTION(g_asm_storage_create_object(storage, pbuf));
-
- if (result != NULL)
- {
- status = G_ARCH_INSTRUCTION_GET_CLASS(result)->unserialize(result, storage, format, pbuf);
-
- if (!status)
- {
- g_object_unref(G_OBJECT(result));
- result = NULL;
- }
+ const char *result; /* Désignation à retourner */
- }
+ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_keyword(instr);
return result;
@@ -1810,142 +1765,28 @@ GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *form
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
+* Description : Construit un petit résumé concis de l'instruction. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Chaîne de caractères à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
+char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
- packed_buffer_t op_pbuf; /* Tampon des données à écrire */
- size_t count; /* Nombre d'éléments à traiter */
- size_t i; /* Boucle de parcours */
- GArchOperand *op; /* Opérande à traiter */
- off64_t pos; /* Position dans le flux */
- size_t kept; /* Nombre de liens conservés */
- const instr_link_t *link; /* Lien vers une instruction */
- instr_obj_extra *extra; /* Données insérées à consulter*/
-
- result = pack_mrange(&instr->range, pbuf);
-
- if (result)
- {
- init_packed_buffer(&op_pbuf);
-
- g_arch_instruction_lock_operands(instr);
-
- count = _g_arch_instruction_count_operands(instr);
-
- result = extend_packed_buffer(pbuf, &count, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- op = _g_arch_instruction_get_operand(instr, i);
-
- result = g_arch_operand_store(op, storage, &op_pbuf);
-
- if (result)
- result = g_asm_storage_store_operand_data(storage, &op_pbuf, &pos);
-
- if (result)
- result = extend_packed_buffer(pbuf, &pos, sizeof(off64_t), true);
-
- g_object_unref(G_OBJECT(op));
-
- }
-
- g_arch_instruction_unlock_operands(instr);
-
- exit_packed_buffer(&op_pbuf);
-
- }
-
- bool serialize_link(const instr_link_t *lk)
- {
- bool status; /* Bilan d'une conservation */
- const mrange_t *range; /* Emplacement d'une instruct° */
- phys_t lk_phys; /* Position physique courante */
-
- if (lk->type == ILT_REF)
- status = true;
-
- else
- {
- range = g_arch_instruction_get_range(lk->linked);
-
- lk_phys = get_phy_addr(get_mrange_addr(range));
-
- status = extend_packed_buffer(pbuf, &lk_phys, sizeof(phys_t), true);
-
- if (status)
- status = extend_packed_buffer(pbuf, &lk->type, sizeof(InstructionLinkType), true);
-
- }
-
- return status;
-
- }
-
- if (result)
- {
- g_arch_instruction_lock_dest(instr);
-
- count = g_arch_instruction_count_destinations(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.
- */
-
- kept = 0;
-
- for (i = 0; i < count && result; i++)
- {
- link = g_arch_instruction_get_destination(instr, i);
-
- if (link->type != ILT_REF)
- kept++;
-
- unref_instr_link(link);
-
- }
-
- result = extend_packed_buffer(pbuf, &kept, sizeof(size_t), true);
-
- for (i = 0; i < count && result; i++)
- {
- link = g_arch_instruction_get_destination(instr, i);
- result = serialize_link(link);
- unref_instr_link(link);
- }
-
- g_arch_instruction_unlock_dest(instr);
-
- }
-
- if (result)
- {
- extra = GET_ARCH_INSTR_EXTRA(instr);
-
- g_bit_lock(&extra->lock, HOLE_LOCK_BIT);
-
- result = extend_packed_buffer(pbuf, &extra->uid, sizeof(itid_t), true);
+ char *result; /* Description à retourner */
+ GArchInstructionClass *class; /* Classe des instructions */
- if (result)
- result = extend_packed_buffer(pbuf, &extra->flags, sizeof(ArchInstrFlag), true);
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
- g_bit_unlock(&extra->lock, HOLE_LOCK_BIT);
+ if (class->build_tooltip != NULL)
+ result = class->build_tooltip(instr);
- }
+ else
+ result = NULL;
return result;
@@ -1954,29 +1795,24 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
/******************************************************************************
* *
-* Paramètres : instr = instruction d'assemblage à consulter. *
-* storage = mécanisme de sauvegarde à manipuler. *
-* pbuf = zone tampon à remplir. *
+* Paramètres : instr = instruction d'assemblage à consulter. *
* *
-* Description : Sauvegarde une instruction dans une mémoire tampon. *
+* Description : Fournit une description pour l'instruction manipulée. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Chaîne de caractères avec balises éventuelles. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool g_arch_instruction_store(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)
+const char *g_arch_instruction_get_description(const GArchInstruction *instr)
{
- bool result; /* Bilan à retourner */
-
- result = g_asm_storage_store_object_gtype(storage, G_OBJECT(instr), pbuf);
+ const char *result; /* Description à retourner */
- if (result)
- result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->serialize(instr, storage, pbuf);
+ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_desc(instr);
return result;
-
+
}
@@ -2005,6 +1841,9 @@ static size_t g_arch_instruction_count_lines(const GArchInstruction *instr)
}
+#ifdef INCLUDE_GTK_SUPPORT
+
+
/******************************************************************************
* *
* Paramètres : instr = générateur à consulter. *
@@ -2061,6 +1900,9 @@ static int g_arch_instruction_contain_cursor(const GArchInstruction *instr, size
}
+#endif
+
+
/******************************************************************************
* *
* Paramètres : instr = générateur à consulter. *
@@ -2172,3 +2014,201 @@ static void g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line,
G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, line, index, repeat, content);
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONSERVATION ET RECHARGEMENT DES DONNEES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool _g_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 */
+
+ extra = GET_ARCH_INSTR_EXTRA(instr);
+
+ LOCK_GOBJECT_EXTRA(extra);
+
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->uid = value;
+
+ if (result)
+ {
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->flags = value;
+
+ }
+
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ if (result)
+ result = unpack_mrange(&instr->range, pbuf);
+
+ if (result)
+ {
+ result = unpack_uleb128(&count, pbuf);
+
+ for (i = 0; i < count && result; i++)
+ {
+ op = G_ARCH_OPERAND(g_object_storage_unpack_object(storage, "operands", pbuf));
+ result = (op != NULL);
+
+ if (result)
+ g_arch_instruction_attach_extra_operand(instr, op);
+
+ }
+
+ }
+
+ if (result)
+ result = g_arch_instruction_load_destinations(instr, storage, pbuf);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = élément GLib à constuire. *
+* storage = conservateur de données à manipuler ou NULL. *
+* pbuf = zone tampon à lire. *
+* *
+* Description : Charge un contenu depuis une mémoire tampon. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_arch_instruction_load(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ GArchInstructionClass *class; /* Classe à activer */
+
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+
+ result = class->load(instr, storage, pbuf);
+
+ 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);
+
+ 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 */
+ GArchInstructionClass *class; /* Classe à activer */
+
+ class = G_ARCH_INSTRUCTION_GET_CLASS(instr);
+
+ result = class->store(instr, storage, pbuf);
+
+ return result;
+
+}