diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2021-08-21 15:07:38 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2021-08-21 15:07:38 (GMT) | 
| commit | bae8c01323703d467ed2cce07c8bf8fd70f7816a (patch) | |
| tree | a4e180f9d82ed3f7312dcf52b4517cb7580b83e5 | |
| parent | 9ed9405f37244832570f48b42dced1c92704ba3d (diff) | |
Define all architecture instructions as serializable.
| -rw-r--r-- | plugins/arm/instruction.c | 121 | ||||
| -rw-r--r-- | plugins/arm/v7/instruction.c | 109 | ||||
| -rw-r--r-- | src/arch/instruction-int.h | 11 | ||||
| -rw-r--r-- | src/arch/instruction.c | 387 | ||||
| -rw-r--r-- | src/arch/instruction.h | 4 | ||||
| -rw-r--r-- | src/arch/instructions/undefined.c | 104 | ||||
| -rw-r--r-- | src/arch/processor.c | 4 | ||||
| -rw-r--r-- | src/arch/storage.c | 4 | 
8 files changed, 733 insertions, 11 deletions
| diff --git a/plugins/arm/instruction.c b/plugins/arm/instruction.c index 4872aba..c42250f 100644 --- a/plugins/arm/instruction.c +++ b/plugins/arm/instruction.c @@ -29,6 +29,7 @@  #include <string.h> +#include <analysis/db/misc/rlestr.h>  #include <common/extstr.h>  #include <core/logs.h> @@ -62,6 +63,17 @@ static bool g_arm_instruction_serialize(GArmInstruction *, GAsmStorage *, packed +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_arm_instruction_load(GArmInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_arm_instruction_store(GArmInstruction *, GObjectStorage *, packed_buffer_t *); + + +  /* Indique le type défini pour une représentation d'une instruction ARM. */  G_DEFINE_TYPE(GArmInstruction, g_arm_instruction, G_TYPE_ARCH_INSTRUCTION); @@ -93,6 +105,9 @@ static void g_arm_instruction_class_init(GArmInstructionClass *klass)      instr->unserialize = (unserialize_instruction_fc)g_arm_instruction_unserialize;      instr->serialize = (serialize_instruction_fc)g_arm_instruction_serialize; +    instr->load = (load_instruction_fc)g_arm_instruction_load; +    instr->store = (store_instruction_fc)g_arm_instruction_store; +  } @@ -382,3 +397,109 @@ static bool g_arm_instruction_serialize(GArmInstruction *instr, GAsmStorage *sto      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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_arm_instruction_load(GArmInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    rle_string str;                         /* Chaîne à charger            */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + +    result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +    { +        setup_empty_rle_string(&str); + +        result = unpack_rle_string(&str, pbuf); + +        if (result) +        { +            result = (get_rle_string(&str) != NULL); + +            if (result) +                result = g_arm_instruction_extend_keyword(instr, get_rle_string(&str)); + +            exit_rle_string(&str); + +        } + +    } + +    if (result) +    { +        result = unpack_uleb128(&value, pbuf); + +        if (result) +            instr->cond = value; + +    } + +    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_arm_instruction_store(GArmInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    rle_string str;                         /* Chaîne à conserver          */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + +    result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +    { +        init_static_rle_string(&str, instr->suffix); + +        result = pack_rle_string(&str, pbuf); + +        exit_rle_string(&str); + +    } + +    if (result) +        result = pack_uleb128((uleb128_t []){ instr->cond }, pbuf); + +    return result; + +} diff --git a/plugins/arm/v7/instruction.c b/plugins/arm/v7/instruction.c index 30a5bd8..eb4a082 100644 --- a/plugins/arm/v7/instruction.c +++ b/plugins/arm/v7/instruction.c @@ -97,6 +97,17 @@ static bool g_armv7_instruction_serialize(GArmV7Instruction *, GAsmStorage *, pa +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_armv7_instruction_load(GArmV7Instruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_armv7_instruction_store(GArmV7Instruction *, GObjectStorage *, packed_buffer_t *); + + +  /* Indique le type défini pour une représentation d'une instruction ARMv7. */  G_DEFINE_TYPE(GArmV7Instruction, g_armv7_instruction, G_TYPE_ARM_INSTRUCTION); @@ -132,6 +143,9 @@ static void g_armv7_instruction_class_init(GArmV7InstructionClass *klass)      instr->unserialize = (unserialize_instruction_fc)g_armv7_instruction_unserialize;      instr->serialize = (serialize_instruction_fc)g_armv7_instruction_serialize; +    instr->load = (load_instruction_fc)g_armv7_instruction_load; +    instr->store = (store_instruction_fc)g_armv7_instruction_store; +  } @@ -506,3 +520,98 @@ static bool g_armv7_instruction_serialize(GArmV7Instruction *instr, GAsmStorage      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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_armv7_instruction_load(GArmV7Instruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    uleb128_t value;                        /* Valeur ULEB128 à charger    */ +    uint8_t boolean;                        /* Valeur booléenne            */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + +    result = parent->load(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +        result = unpack_uleb128(&value, pbuf); + +    if (result) +        instr->sid = value; + +    if (result) +        result = extract_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + +    if (result) +    { +        result = extract_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); + +        if (result) +            instr->setflags = (boolean == 1 ? true : false); + +    } + +    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_armv7_instruction_store(GArmV7Instruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    uint8_t boolean;                        /* Valeur booléenne            */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_armv7_instruction_parent_class); + +    result = parent->store(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +        result = pack_uleb128((uleb128_t []){ instr->sid }, pbuf); + +    if (result) +        result = extend_packed_buffer(pbuf, &instr->encoding, sizeof(char), false); + +    if (result) +    { +        boolean = (instr->setflags ? 1 : 0); +        result = extend_packed_buffer(pbuf, &boolean, sizeof(uint8_t), false); +    } + +    return result; + +} diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 9a23bf2..f8998a1 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -26,6 +26,7 @@  #include "instruction.h" +#include "../analysis/storage/storage.h"  #include "../common/array.h"  #include "../glibext/objhole.h" @@ -58,6 +59,13 @@ typedef GBufferLine * (* print_instruction_fc) (const GArchInstruction *, GBuffe  /* Liste les registres lus et écrits par l'instruction. */  typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); +/* Charge un contenu depuis une mémoire tampon. */ +typedef bool (* load_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +typedef bool (* store_instruction_fc) (GArchInstruction *, GObjectStorage *, packed_buffer_t *); + +  /* Informations glissées dans la structure GObject de GArchOperand */  typedef struct _instr_extra_data_t @@ -142,6 +150,9 @@ struct _GArchInstructionClass      print_instruction_fc print;             /* Imprime l'ensemble          */ +    load_instruction_fc load;               /* Chargement depuis un tampon */ +    store_instruction_fc store;             /* Conservation dans un tampon */ +      //get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés    */  }; diff --git a/src/arch/instruction.c b/src/arch/instruction.c index e0d1091..c4354d4 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -34,6 +34,7 @@  #include "instruction-int.h"  #include "storage.h" +#include "../analysis/storage/serialize-int.h"  #include "../core/logs.h"  #include "../core/processors.h"  #include "../glibext/gbinarycursor.h" @@ -49,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 *); @@ -59,6 +63,18 @@ static void g_arch_instruction_finalize(GArchInstruction *); + + +/* 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 *); + + + + +  /* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ @@ -92,10 +108,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));  /****************************************************************************** @@ -127,6 +160,9 @@ static void g_arch_instruction_class_init(GArchInstructionClass *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; +  } @@ -170,7 +206,7 @@ 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;      iface->compute = (linegen_compute_fc)g_arch_instruction_compute_cursor; @@ -183,6 +219,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.                     * @@ -1560,6 +1616,132 @@ instr_link_t *g_arch_instruction_get_destinations(GArchInstruction *instr, size_  } +/****************************************************************************** +*                                                                             * +*  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_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    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); + +    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; +        } + +        result = unpack_uleb128(&type, pbuf); +        if (!result) +        { +            g_object_unref(G_OBJECT(linked)); +            break; +        } + +        g_arch_instruction_link_with(instr, linked, type); +        g_object_unref(G_OBJECT(linked)); + +    } + +    g_arch_instruction_unlock_dest(instr); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction dont les informations sont à consulter.* +*                storage = conservateur de données à manipuler ou NULL.       * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde toutes les destinations d'une instruction.        * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_arch_instruction_store_destinations(GArchInstruction *instr, GObjectStorage *storage, packed_buffer_t *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    size_t count;                           /* Nombre d'éléments à traiter */ +    size_t kept;                            /* Nombre de liens conservés   */ +    size_t i;                               /* Boucle de parcours          */ +    const instr_link_t *link;               /* Lien vers une instruction   */ + +    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; i++) +    { +        link = g_arch_instruction_get_destination(instr, i); + +        if (link->type != ILT_REF) +            kept++; + +        unref_instr_link(link); + +    } + +    result = pack_uleb128((uleb128_t []){ kept }, pbuf); + +    for (i = 0; i < count && result; i++) +    { +        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); + +        } + +        unref_instr_link(link); + +    } + +    g_arch_instruction_unlock_dest(instr); + +    return result; + +} + +  /* ---------------------------------------------------------------------------------- */  /*                       CONVERSIONS DU FORMAT DES INSTRUCTIONS                       */ @@ -1787,7 +1969,7 @@ static bool g_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage  *                                                                             *  ******************************************************************************/ -GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf) +GArchInstruction *g_arch_instruction_load__old(GAsmStorage *storage, GBinFormat *format, packed_buffer_t *pbuf)  {      GArchInstruction *result;               /* Instance à retourner        */      bool status;                            /* Bilan du chargement         */ @@ -1969,7 +2151,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s  *                                                                             *  ******************************************************************************/ -bool g_arch_instruction_store(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf) +bool g_arch_instruction_store__old(GArchInstruction *instr, GAsmStorage *storage, packed_buffer_t *pbuf)  {      bool result;                            /* Bilan à retourner           */ @@ -2175,3 +2357,198 @@ 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) goto exit; + +    extra->uid = value; + +    result = unpack_uleb128(&value, pbuf); +    if (!result) goto exit; + +    extra->flags = value; + +    UNLOCK_GOBJECT_EXTRA(extra); + +    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); + + exit: + +    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; + +} diff --git a/src/arch/instruction.h b/src/arch/instruction.h index a9d66be..683adfb 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -318,10 +318,10 @@ typedef struct _GAsmStorage GAsmStorage;  /* Charge une instruction depuis une mémoire tampon. */ -GArchInstruction *g_arch_instruction_load(GAsmStorage *, GBinFormat *, packed_buffer_t *); +GArchInstruction *g_arch_instruction_load__old(GAsmStorage *, GBinFormat *, packed_buffer_t *);  /* Sauvegarde une instruction dans une mémoire tampon. */ -bool g_arch_instruction_store(GArchInstruction *, GAsmStorage *, packed_buffer_t *); +bool g_arch_instruction_store__old(GArchInstruction *, GAsmStorage *, packed_buffer_t *); diff --git a/src/arch/instructions/undefined.c b/src/arch/instructions/undefined.c index 663a9eb..7ed5db9 100644 --- a/src/arch/instructions/undefined.c +++ b/src/arch/instructions/undefined.c @@ -74,6 +74,17 @@ static void g_undef_instruction_print(GUndefInstruction *, GBufferLine *, size_t +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Charge un contenu depuis une mémoire tampon. */ +static bool g_undef_instruction_load(GUndefInstruction *, GObjectStorage *, packed_buffer_t *); + +/* Sauvegarde un contenu dans une mémoire tampon. */ +static bool g_undef_instruction_store(GUndefInstruction *, GObjectStorage *, packed_buffer_t *); + + +  /* ---------------------------------------------------------------------------------- */  /*                           INSTRUCTION INCONNUE / DONNEES                           */  /* ---------------------------------------------------------------------------------- */ @@ -115,6 +126,9 @@ static void g_undef_instruction_class_init(GUndefInstructionClass *klass)      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; +  } @@ -440,3 +454,93 @@ InstrExpectedBehavior g_undef_instruction_get_behavior(const GUndefInstruction *      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  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_undef_instruction_load(GUndefInstruction *instr, GObjectStorage *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*/ +    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); + +        result = extract_packed_buffer(pbuf, &val, sizeof(uint8_t), false); +        extra->behavior = val; + +        UNLOCK_GOBJECT_EXTRA(extra); + +    } + +    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_undef_instruction_store(GUndefInstruction *instr, GObjectStorage *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->store(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); + +        UNLOCK_GOBJECT_EXTRA(extra); + +    } + +    return result; + +} diff --git a/src/arch/processor.c b/src/arch/processor.c index 1fbc14b..56a45a4 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -1898,7 +1898,7 @@ instr_iter_t *_g_arch_processor_get_covered_iter_from_address(GArchProcessor *pr  /******************************************************************************  *                                                                             * -*  Paramètres  : content = élément GLib à constuire.                          * +*  Paramètres  : proc    = élément GLib à constuire.                          *  *                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à lire.                                *  *                                                                             * @@ -1940,7 +1940,7 @@ static bool g_arch_processor_load(GArchProcessor *proc, GObjectStorage *storage,  /******************************************************************************  *                                                                             * -*  Paramètres  : content = élément GLib à consulter.                          * +*  Paramètres  : proc    = élément GLib à consulter.                          *  *                storage = conservateur de données à manipuler ou NULL.       *  *                pbuf    = zone tampon à remplir.                             *  *                                                                             * diff --git a/src/arch/storage.c b/src/arch/storage.c index 41fa602..d552ae3 100644 --- a/src/arch/storage.c +++ b/src/arch/storage.c @@ -486,7 +486,7 @@ static void g_ins_caching_process_store(GInsCaching *caching, GtkStatusStack *st          instr = g_arch_processor_get_instruction(proc, i); -        caching->status = g_arch_instruction_store(instr, storage, &pbuf); +        caching->status = g_arch_instruction_store__old(instr, storage, &pbuf);          if (caching->status)              caching->status = g_asm_storage_store_instruction_data(storage, &pbuf, &pos); @@ -1544,7 +1544,7 @@ GArchInstruction *g_asm_storage_get_instruction_at(GAsmStorage *storage, GBinFor                  status = g_asm_storage_load_instruction_data(storage, pbuf, target);              if (status) -                storage->collected[index] = g_arch_instruction_load(storage, format, pbuf); +                storage->collected[index] = g_arch_instruction_load__old(storage, format, pbuf);              if (storage->collected[index] != NULL)              { | 
