summaryrefslogtreecommitdiff
path: root/src/arch/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 /src/arch/instruction.c
parent267b1ae8608ed4bf52de743798e8647c903ee1b4 (diff)
Created an instruction database for Chrysalide.
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r--src/arch/instruction.c335
1 files changed, 334 insertions, 1 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index be7ff37..e2d8d2a 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -30,6 +30,7 @@
#include "instruction-int.h"
+#include "storage.h"
#include "../glibext/linegen-int.h"
@@ -51,6 +52,17 @@ 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 *);
+
+/* Sauvegarde une instruction dans une mémoire tampon. */
+static bool g_arch_instruction_serialize(GArchInstruction *, GAsmStorage *, packed_buffer *);
+
+
+
/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */
@@ -103,6 +115,9 @@ 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;
}
@@ -1055,7 +1070,7 @@ char *g_arch_instruction_build_tooltip(const GArchInstruction *instr)
* Remarques : - *
* *
******************************************************************************/
-
+
const char *g_arch_instruction_get_description(const GArchInstruction *instr)
{
const char *result; /* Description à retourner */
@@ -1069,6 +1084,324 @@ const char *g_arch_instruction_get_description(const GArchInstruction *instr)
/* ---------------------------------------------------------------------------------- */
+/* 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_arch_instruction_unserialize(GArchInstruction *instr, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ packed_buffer op_pbuf; /* Tampon des données à écrire */
+ size_t count; /* Nombre d'éléments à traiter */
+ 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 ins_pbuf; /* Tampon des données à écrire */
+
+ 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);
+ }
+
+ if (result)
+ g_arch_instruction_attach_extra_operand(instr, op);
+
+ }
+
+ exit_packed_buffer(&op_pbuf);
+
+ }
+
+ bool unserialize_link(instr_link_t *lk)
+ {
+ 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);
+
+ if (!status)
+ g_object_unref(G_OBJECT(lk->linked));
+
+ }
+
+ return status;
+
+ }
+
+ if (result)
+ {
+ init_packed_buffer(&ins_pbuf);
+
+ result = extract_packed_buffer(pbuf, &count, sizeof(size_t), true);
+
+ for (i = 0; i < count && result; i++)
+ {
+ result = unserialize_link(&link);
+
+ if (result)
+ {
+ g_arch_instruction_link_with(instr, link.linked, link.type);
+ g_object_unref(G_OBJECT(link.linked));
+ }
+
+ }
+
+ exit_packed_buffer(&ins_pbuf);
+
+ }
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : 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 : Instruction d'assemblage constitué ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_arch_instruction_load(GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf)
+{
+ 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;
+ }
+
+ }
+
+ 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_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ packed_buffer 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 */
+ instr_link_t *link; /* Lien vers une instruction */
+
+ 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++;
+
+ }
+
+ 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);
+ }
+
+ g_arch_instruction_unlock_dest(instr);
+
+ }
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &instr->uid, sizeof(itid_t), true);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &instr->flags, sizeof(ArchInstrFlag), 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 : - *
+* *
+******************************************************************************/
+
+bool g_arch_instruction_store(GArchInstruction *instr, GAsmStorage *storage, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_asm_storage_store_object_gtype(storage, G_OBJECT(instr), pbuf);
+
+ if (result)
+ result = G_ARCH_INSTRUCTION_GET_CLASS(instr)->serialize(instr, storage, pbuf);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* OFFRE DE CAPACITES DE GENERATION */
/* ---------------------------------------------------------------------------------- */