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; + +} |