diff options
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r-- | src/arch/instruction.c | 744 |
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; + +} |