summaryrefslogtreecommitdiff
path: root/plugins/arm/instruction.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-14 19:40:07 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-14 19:40:07 (GMT)
commit0286b53bad21abf91cbe17c4772ca9cde6a89cbc (patch)
tree3bec9dc7e118c00ce9c748576b01606a71880ad7 /plugins/arm/instruction.c
parent267b1ae8608ed4bf52de743798e8647c903ee1b4 (diff)
Created an instruction database for Chrysalide.
Diffstat (limited to 'plugins/arm/instruction.c')
-rw-r--r--plugins/arm/instruction.c139
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;
+
+}