From 009f00f18ef49295a55e6389c0687d0d767f45b0 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 8 Mar 2017 22:18:11 +0100
Subject: Reduced the number of produced reference links.

---
 ChangeLog                   |  9 +++++++++
 src/analysis/disass/links.c |  5 ++++-
 src/arch/instruction.c      | 37 ++++++++++++++++++++++++++++++++++++-
 src/arch/instruction.h      |  3 +++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8a60475..a72f452 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,15 @@
 17-03-08  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/links.c:
+	Reduce the number of produced reference links.
+
+	* src/arch/instruction.c:
+	* src/arch/instruction.h:
+	Determine if a link exists between two instructions.
+
+17-03-08  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/links.c:
 	Fix conditions for adding missing natural execution flow links.
 
 17-03-08  Cyrille Bagard <nocbos@gmail.com>
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index cf33677..d67040b 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -273,8 +273,11 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
 
         if (target != NULL)
         {
-            g_arch_instruction_link_with(instr, target, ILT_REF);
+            if (!g_arch_instruction_has_link_to(instr, target))
+                g_arch_instruction_link_with(instr, target, ILT_REF);
+
             g_object_unref(G_OBJECT(target));
+
         }
 
     }
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index a86509c..4bb2e2d 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -750,8 +750,43 @@ static size_t g_arch_instruction_inc_link_counter(GArchInstruction *instr, bool
 *                                                                             *
 *  Paramètres  : instr = instruction dont les informations sont à consulter.  *
 *                dest  = ligne visée par la liaison (côté destination).       *
+*                                                                             *
+*  Description : Détermine si un lien est déjà établi entre deux instructions.*
+*                                                                             *
+*  Retour      : Bilan de l'état actuel des liaisons.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruction *dest)
+{
+    bool result;                            /* Bilan à retourner           */
+    size_t count;                           /* Nombre de liens à parcourir */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = false;
+
+    g_arch_instruction_rlock_dest(instr);
+
+    count = g_arch_instruction_get_destination_counter(instr);
+
+    for (i = 0; i < count && !result; i++)
+        if (instr->to[i].linked == dest)
+            result = true;
+
+    g_arch_instruction_runlock_dest(instr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instruction dont les informations sont à consulter.  *
+*                dest  = ligne visée par la liaison (côté destination).       *
 *                type  = type de lien à construire.                           *
-*                ...   = éventuelles informations complémentaires.            *
 *                                                                             *
 *  Description : Etablit un lien entre deux instructions.                     *
 *                                                                             *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 4f5a042..d38bb62 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -217,6 +217,9 @@ typedef struct _instr_link_t
 /* Met à disposition un encadrement des accès aux liens. */
 void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool, bool);
 
+/* Détermine si un lien est déjà établi entre deux instructions. */
+bool g_arch_instruction_has_link_to(GArchInstruction *, const GArchInstruction *);
+
 /* Etablit un lien entre deux instructions. */
 void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType);
 
-- 
cgit v0.11.2-87-g4458