diff options
Diffstat (limited to 'plugins/arm/instruction.c')
| -rw-r--r-- | plugins/arm/instruction.c | 139 | 
1 files changed, 139 insertions, 0 deletions
| diff --git a/plugins/arm/instruction.c b/plugins/arm/instruction.c index 9af8045..a717055 100644 --- a/plugins/arm/instruction.c +++ b/plugins/arm/instruction.c @@ -30,6 +30,7 @@  #include <common/extstr.h> +#include <core/logs.h>  #include "instruction-int.h" @@ -50,6 +51,17 @@ static void g_arm_instruction_finalize(GArmInstruction *); +/* -------------------- CONSERVATION SUR DISQUE DES INSTRUCTIONS -------------------- */ + + +/* Charge une instruction depuis une mémoire tampon. */ +static bool g_arm_instruction_unserialize(GArmInstruction *, GAsmStorage *, GBinFormat *, packed_buffer *); + +/* Sauvegarde une instruction dans une mémoire tampon. */ +static bool g_arm_instruction_serialize(GArmInstruction *, GAsmStorage *, packed_buffer *); + + +  /* Indique le type défini pour une représentation d'une instruction ARM. */  G_DEFINE_TYPE(GArmInstruction, g_arm_instruction, G_TYPE_ARCH_INSTRUCTION); @@ -69,12 +81,18 @@ G_DEFINE_TYPE(GArmInstruction, g_arm_instruction, G_TYPE_ARCH_INSTRUCTION);  static void g_arm_instruction_class_init(GArmInstructionClass *klass)  {      GObjectClass *object_class;             /* Autre version de la classe  */ +    GArchInstructionClass *instr;           /* Encore une autre vision...  */      object_class = G_OBJECT_CLASS(klass);      object_class->dispose = (GObjectFinalizeFunc/* ! */)g_arm_instruction_dispose;      object_class->finalize = (GObjectFinalizeFunc)g_arm_instruction_finalize; +    instr = G_ARCH_INSTRUCTION_CLASS(klass); + +    instr->unserialize = (unserialize_instruction_fc)g_arm_instruction_unserialize; +    instr->serialize = (serialize_instruction_fc)g_arm_instruction_serialize; +  } @@ -92,6 +110,9 @@ static void g_arm_instruction_class_init(GArmInstructionClass *klass)  static void g_arm_instruction_init(GArmInstruction *instr)  { +    instr->suffix = NULL; +    instr->cached_keyword = NULL; +      instr->cond = ACC_AL;  } @@ -243,3 +264,121 @@ ArmCondCode g_arm_instruction_get_cond(const GArmInstruction *instr)      return instr->cond;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                      CONSERVATION SUR DISQUE DES INSTRUCTIONS                      */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction d'assemblage à consulter.              * +*                storage = mécanisme de sauvegarde à manipuler.               * +*                format  = format binaire chargé associé à l'architecture.    * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Charge une instruction depuis une mémoire tampon.            * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arm_instruction_unserialize(GArmInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    unsigned char len;                      /* Taille de textes            */ +    char *text;                             /* Texte reconstitué           */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + +    result = parent->unserialize(G_ARCH_INSTRUCTION(instr), storage, format, pbuf); + +    if (result) +    { +        result = extract_packed_buffer(pbuf, &len, sizeof(unsigned char), false); + +        if (result && len > 0) +        { +            text = (char *)malloc(len); + +            if (result) +                result = extract_packed_buffer(pbuf, text, len, false); + +            if (result) +                result = g_arm_instruction_extend_keyword(instr, text); + +            free(text); + +        } + +    } + +    if (result) +        result = extract_packed_buffer(pbuf, &instr->cond, sizeof(ArmCondCode), true); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr   = instruction d'assemblage à consulter.              * +*                storage = mécanisme de sauvegarde à manipuler.               * +*                pbuf    = zone tampon à remplir.                             * +*                                                                             * +*  Description : Sauvegarde une instruction dans une mémoire tampon.          * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_arm_instruction_serialize(GArmInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf) +{ +    bool result;                            /* Bilan à retourner           */ +    GArchInstructionClass *parent;          /* Classe parente à consulter  */ +    size_t len;                             /* Taille de textes            */ + +    parent = G_ARCH_INSTRUCTION_CLASS(g_arm_instruction_parent_class); + +    result = parent->serialize(G_ARCH_INSTRUCTION(instr), storage, pbuf); + +    if (result) +    { +        if (instr->suffix == NULL) +            result = extend_packed_buffer(pbuf, (unsigned char []) { 0 }, sizeof(unsigned char), false); + +        else +        { +            len = strlen(instr->suffix) + 1; +            assert(len > 1); + +            if (len > (2 << (sizeof(unsigned char) * 8 - 1))) +            { +                log_variadic_message(LMT_ERROR, "ARM suffix too long: '%s' (%zu bytes)", instr->suffix, len); +                result = false; +            } + +            else +                result = extend_packed_buffer(pbuf, (unsigned char []) { len }, sizeof(unsigned char), false); + +            if (result) +                result = extend_packed_buffer(pbuf, instr->suffix, len, false); + +        } + +    } + +    if (result) +        result = extend_packed_buffer(pbuf, &instr->cond, sizeof(ArmCondCode), true); + +    return result; + +} | 
