summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-08-06 17:08:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-08-06 17:08:01 (GMT)
commitebfc6a8ebcef2b42beb6ef12e4946bb2f73f2723 (patch)
tree2a1eeb714ea15ff0ca0da9cada3c5aeb38a7e1cc
parentcdfe7b0efbb358fdb3fff8f6d5a8d34d89b220e5 (diff)
Secured the links between instructions.
-rw-r--r--src/arch/instruction.c123
-rw-r--r--src/arch/instruction.h3
2 files changed, 126 insertions, 0 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 1bf3c9b..5ce0c12 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -208,6 +208,18 @@ static void g_arch_instruction_dispose(GArchInstruction *instr)
g_arch_instruction_unlock_operands(instr);
+#ifndef NDEBUG
+ g_arch_instruction_lock_src(instr);
+ assert(count_flat_array_items(instr->from) == 0);
+ g_arch_instruction_unlock_src(instr);
+#endif
+
+#ifndef NDEBUG
+ g_arch_instruction_lock_dest(instr);
+ assert(count_flat_array_items(instr->to) == 0);
+ g_arch_instruction_unlock_dest(instr);
+#endif
+
G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr));
}
@@ -791,11 +803,15 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des
new_src.linked = instr;
new_src.type = type;
+ ref_instr_link((&new_src));
+
/* Côté point de départ */
new_dst.linked = dest;
new_dst.type = type;
+ ref_instr_link((&new_dst));
+
/* Ajout dans le respect d'une cohérence globale */
g_arch_instruction_lock_src(dest);
@@ -898,6 +914,113 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
/******************************************************************************
* *
+* Paramètres : instr = instruction dont les informations sont à traiter. *
+* *
+* Description : Supprime tous les liens établis avec d'autres instructions. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_arch_instruction_delete_all_links(GArchInstruction *instr)
+{
+ instr_link_t *link_src; /* Lien à supprimer #2 */
+ GArchInstruction *other; /* Instruction de l'autre bout */
+ size_t count; /* Quantié de liens présents */
+ size_t i; /* Boucle de parcours */
+ instr_link_t *link_dst; /* Lien à supprimer #1 */
+
+ /* Coté sources */
+
+ g_arch_instruction_lock_src(instr);
+
+ while (count_flat_array_items(instr->from) > 0)
+ {
+ link_src = get_flat_array_item(instr->from, 0, sizeof(instr_link_t));
+
+ other = link_src->linked;
+
+ g_arch_instruction_lock_dest(other);
+
+ count = count_flat_array_items(other->to);
+
+ for (i = 0; i < count; i++)
+ {
+ link_dst = get_flat_array_item(other->to, i, sizeof(instr_link_t));
+
+ if (link_dst->linked == instr && link_dst->type == link_src->type)
+ {
+ unref_instr_link(link_dst);
+
+ rem_item_from_flat_array(&other->to, i, sizeof(instr_link_t));
+
+ break;
+
+ }
+
+ }
+
+ assert(i < count);
+
+ g_arch_instruction_unlock_dest(other);
+
+ unref_instr_link(link_src);
+
+ rem_item_from_flat_array(&instr->from, 0, sizeof(instr_link_t));
+
+ }
+
+ g_arch_instruction_unlock_src(instr);
+
+ /* Coté destinations */
+
+ g_arch_instruction_lock_dest(instr);
+
+ while (count_flat_array_items(instr->to) > 0)
+ {
+ link_dst = get_flat_array_item(instr->to, 0, sizeof(instr_link_t));
+
+ other = link_dst->linked;
+
+ g_arch_instruction_lock_src(other);
+
+ count = count_flat_array_items(other->from);
+
+ for (i = 0; i < count; i++)
+ {
+ link_src = get_flat_array_item(other->from, i, sizeof(instr_link_t));
+
+ if (link_src->linked == instr && link_src->type == link_dst->type)
+ {
+ unref_instr_link(link_src);
+
+ rem_item_from_flat_array(&other->from, i, sizeof(instr_link_t));
+
+ break;
+
+ }
+
+ }
+
+ assert(i < count);
+
+ g_arch_instruction_unlock_src(other);
+
+ unref_instr_link(link_dst);
+
+ rem_item_from_flat_array(&instr->to, 0, sizeof(instr_link_t));
+
+ }
+
+ g_arch_instruction_unlock_dest(instr);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : instr = instruction dont les informations sont à consulter. *
* *
* Description : Fournit la quantité d'instructions pointant vers une autre. *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 0c8510a..8289a43 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -227,6 +227,9 @@ void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, Instru
/* Change la nature d'un lien entre deux instructions. */
bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType);
+/* Supprime tous les liens établis avec d'autres instructions. */
+void g_arch_instruction_delete_all_links(GArchInstruction *);
+
#define g_arch_instruction_lock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, true)
#define g_arch_instruction_unlock_src(ins) g_arch_instruction_lock_unlock_links(ins, true, false)