From 4d179bc994cf85832d08f468c7e4122ad23e9244 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 3 Aug 2018 13:24:26 +0200
Subject: Updated the reference counters when providing instruction links.

---
 plugins/libcsem/exit.c                  |  7 ++++---
 plugins/lnxsyscalls/collect.c           |  4 +++-
 plugins/pychrysalide/arch/instruction.c |  8 ++++++--
 src/analysis/db/items/comment.c         |  4 +++-
 src/analysis/decomp/il.c                |  4 +++-
 src/analysis/disass/dragon.c            | 20 +++++++++++++------
 src/analysis/disass/links.c             |  8 +++++++-
 src/analysis/disass/loop.c              |  4 +++-
 src/analysis/disass/rank.c              | 14 ++++++++++----
 src/analysis/routine.c                  | 18 ++++++++++-------
 src/arch/instruction.c                  | 34 ++++++++++++++++++++++++++-------
 src/arch/instruction.h                  |  8 ++++++--
 src/debug/debugger.c                    |  6 ++++--
 src/gtkext/graph/cluster.c              |  8 ++++++--
 src/gui/dialogs/gotox.c                 |  6 +++++-
 15 files changed, 112 insertions(+), 41 deletions(-)

diff --git a/plugins/libcsem/exit.c b/plugins/libcsem/exit.c
index ee536b5..794369e 100644
--- a/plugins/libcsem/exit.c
+++ b/plugins/libcsem/exit.c
@@ -54,7 +54,7 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
     GArchInstruction *instr;                /* Instruction de sortie       */
     size_t count;                           /* Nbre de sources affichées   */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *source;                   /* Instruction diverse liée    */
+    const instr_link_t *source;             /* Instruction diverse liée    */
 
     format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
 
@@ -81,9 +81,10 @@ static void mark_one_kind_of_exit_as_return(const GLoadedBinary *binary, const c
     {
         source = g_arch_instruction_get_source(instr, i);
 
-        if (source->type != ILT_CALL) continue;
+        if (source->type == ILT_CALL)
+            g_arch_instruction_set_flag(source->linked, AIF_RETURN_POINT);
 
-        g_arch_instruction_set_flag(source->linked, AIF_RETURN_POINT);
+        unref_instr_link(source);
 
     }
 
diff --git a/plugins/lnxsyscalls/collect.c b/plugins/lnxsyscalls/collect.c
index 87f5fa2..e73b444 100644
--- a/plugins/lnxsyscalls/collect.c
+++ b/plugins/lnxsyscalls/collect.c
@@ -488,7 +488,7 @@ bool look_for_registers(tracked_path *path, size_t sid, GArchProcessor *proc, co
     size_t count;                           /* Nombre de sources présentes */
     bool first;                             /* Premier aiguillage ?        */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *link;                     /* Détails d'un lien           */
+    const instr_link_t *link;               /* Détails d'un lien           */
     size_t next;                            /* Indice de la pile suivante  */
 
     stack = &path->stacks[sid];
@@ -589,6 +589,8 @@ bool look_for_registers(tracked_path *path, size_t sid, GArchProcessor *proc, co
 
             }
 
+            unref_instr_link(link);
+
         }
 
         g_arch_instruction_unlock_src(instr);
diff --git a/plugins/pychrysalide/arch/instruction.c b/plugins/pychrysalide/arch/instruction.c
index e9a2e04..8c3d78d 100644
--- a/plugins/pychrysalide/arch/instruction.c
+++ b/plugins/pychrysalide/arch/instruction.c
@@ -110,7 +110,7 @@ static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
 {
     PyObject *result;                       /* Instance à retourner        */
     GArchInstruction *instr;                /* Version native              */
-    instr_link_t *source;                   /* Origine des liens           */
+    const instr_link_t *source;             /* Origine des liens           */
     size_t count;                           /* Nombre de liens présents    */
     size_t i;                               /* Boucle de parcours          */
     PyObject *linked;                       /* Source de lien Python       */
@@ -135,6 +135,8 @@ static PyObject *py_arch_instruction_get_sources(PyObject *self, void *unused)
         ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
         assert(ret == 0);
 
+        unref_instr_link(source);
+
     }
 
     g_arch_instruction_unlock_src(instr);
@@ -161,7 +163,7 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unus
 {
     PyObject *result;                       /* Instance à retourner        */
     GArchInstruction *instr;                /* Version native              */
-    instr_link_t *dest;                     /* Destination des liens       */
+    const instr_link_t *dest;               /* Destination des liens       */
     size_t count;                           /* Nombre de liens présents    */
     size_t i;                               /* Boucle de parcours          */
     PyObject *linked;                       /* Destination de lien Python  */
@@ -186,6 +188,8 @@ static PyObject *py_arch_instruction_get_destinations(PyObject *self, void *unus
         ret = PyTuple_SetItem(result, i, Py_BuildValue("(OO)", linked, type));
         assert(ret == 0);
 
+        unref_instr_link(dest);
+
     }
 
     g_arch_instruction_unlock_dest(instr);
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 9fc2767..8155fc5 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -634,7 +634,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
     GArchInstruction *instr;                /* Instruction à traiter       */
     size_t scount;                          /* Nbre de sources affichées   */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *source;                   /* Instruction diverse liée    */
+    const instr_link_t *source;             /* Instruction diverse liée    */
     const mrange_t *range;                  /* Emplacement d'instruction   */
     size_t linked;                          /* Indice lié à traiter        */
 
@@ -720,6 +720,8 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap
 
                 RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]);
 
+                unref_instr_link(source);
+
             }
 
             if (!apply)
diff --git a/src/analysis/decomp/il.c b/src/analysis/decomp/il.c
index 5827c4b..cbc0c37 100644
--- a/src/analysis/decomp/il.c
+++ b/src/analysis/decomp/il.c
@@ -618,7 +618,7 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB
     GArchInstruction *last;                 /* Dernière instruction de bloc*/
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t j;                               /* Boucle de parcours #2       */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     vmpa_t addr;                            /* Adresse d'une instruction   */
     bool jump_to_case;                      /* Suite dans le cas suivant ? */
 
@@ -659,6 +659,8 @@ static void close_case_decomp_instructions(GDecInstruction *case_dinstr, GInstrB
             else
                 is_common = (common_addr == addr);
 
+            unref_instr_link(dest);
+
         }
 
         g_arch_instruction_unlock_dest(last);
diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c
index 44d82da..04f5190 100644
--- a/src/analysis/disass/dragon.c
+++ b/src/analysis/disass/dragon.c
@@ -104,10 +104,10 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
     size_t scount;                          /* Nombre de liens de source   */
     bool cut;                               /* Un découpage a été réalisé ?*/
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *source;                   /* Instruction de source liée  */
+    const instr_link_t *source;             /* Instruction de source liée  */
     dragon_node *new;                       /* Nouvel élément à créer      */
     size_t dcount;                          /* Nombre de liens de dest.    */
-    instr_link_t *dest;                     /* Instruction de destination  */
+    const instr_link_t *dest;               /* Instruction de destination  */
 
     result = NULL;
     *count = 0;
@@ -204,6 +204,8 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
 
                 }
 
+                unref_instr_link(source);
+
             }
 
             g_arch_instruction_unlock_src(instr);
@@ -238,6 +240,8 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera
 
             }
 
+            unref_instr_link(dest);
+
         }
 
         g_arch_instruction_unlock_dest(instr);
@@ -448,7 +452,7 @@ void compute_all_paths(dragon_node *nodes, size_t count)
     {
         size_t dcount;                      /* Nombre de liens de dest.    */
         size_t i;                           /* Boucle de parcours          */
-        instr_link_t *dest;                 /* Instructions de destination */
+        const instr_link_t *dest;           /* Instructions de destination */
         dragon_node *next;                  /* Noeud suivant dans le code  */
         size_t id;                          /* Indice du bit associé       */
 
@@ -483,6 +487,8 @@ void compute_all_paths(dragon_node *nodes, size_t count)
 
             }
 
+            unref_instr_link(dest);
+
         }
 
         g_arch_instruction_unlock_dest(node->last);
@@ -535,7 +541,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count)
     dragon_node *predecessor;               /* Noeud prédécesseur direct   */
     size_t scount;                          /* Nombre de liens de source   */
     size_t i;                               /* Boucle de parcours #2       */
-    instr_link_t *source;                   /* Instruction d'origine       */
+    const instr_link_t *source;             /* Instruction d'origine       */
 
     inter = create_bit_field(count, false);
 
@@ -575,9 +581,9 @@ void compute_all_dominators(dragon_node *nodes, size_t count)
                         */
 
 
-                        if (predecessor == NULL) break;
+                        if (predecessor != NULL)
+                            and_bit_field(inter, predecessor->bits);
 
-                        and_bit_field(inter, predecessor->bits);
                         break;
 
                     default:
@@ -585,6 +591,8 @@ void compute_all_dominators(dragon_node *nodes, size_t count)
 
                 }
 
+                unref_instr_link(source);
+
             }
 
             g_arch_instruction_unlock_src(node->first);
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index ffdee36..381aedc 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -56,7 +56,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
 {
     size_t count;                           /* Nbre de sources affichées   */
     bool has_src;                           /* Présence de sources ?       */
-    instr_link_t *other;                    /* Instruction diverse liée    */
+    const instr_link_t *other;              /* Instruction diverse liée    */
     size_t i;                               /* Boucle de parcours          */
     bool no_natural;                        /* Aucun lien naturel présent  */
     bool no_need;                           /* Pas de besoin pour ce lien  */
@@ -79,6 +79,8 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
         if (other->type != ILT_REF)
             has_src = true;
 
+        unref_instr_link(other);
+
     }
 
     g_arch_instruction_unlock_src(instr);
@@ -135,6 +137,8 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
 
         }
 
+        unref_instr_link(other);
+
     }
 
  check_done:
@@ -173,6 +177,8 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)
 
             }
 
+            unref_instr_link(other);
+
         }
 
         g_arch_instruction_unlock_src(instr);
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c
index 9312917..40ce441 100644
--- a/src/analysis/disass/loop.c
+++ b/src/analysis/disass/loop.c
@@ -51,7 +51,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count)
     GArchInstruction *last;                 /* Instruction finale de noeud */
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours #2       */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     dragon_node *target;                    /* Noeud référence à tester    */
     size_t id;                              /* Indice du bit associé       */
 
@@ -104,6 +104,8 @@ static void detect_back_edges(dragon_node *nodes, size_t count)
 
             }
 
+            unref_instr_link(dest);
+
         }
 
         g_arch_instruction_unlock_dest(last);
diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c
index c31fd58..6e737a5 100644
--- a/src/analysis/disass/rank.c
+++ b/src/analysis/disass/rank.c
@@ -63,7 +63,7 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns
     GArchInstruction *last;                 /* Dernière instruction du bloc*/
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     const mrange_t *range;                  /* Emplacement d'une cible     */
     GFlowBlock *target;                     /* Bloc ciblé par un lien      */
     unsigned int rank;                      /* Rang à constituer           */
@@ -167,6 +167,8 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns
 
         }
 
+        unref_instr_link(dest);
+
         if (target != NULL)
         {
             rank = MAX(next, g_flow_block_get_rank(target));
@@ -308,7 +310,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
     GArchInstruction *last;                 /* Dernière instruction du bloc*/
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     InstructionLinkType type;               /* Raccourci pour confort      */
     GBasicBlock *target;                    /* Bloc ciblé par un lien      */
     unsigned int rank;                      /* Rang à constituer           */
@@ -327,7 +329,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
         type = dest->type;
 
         /* La boucle de remontée n'abaisse pas les rangs */
-        if (type == ILT_LOOP) continue;
+        if (type == ILT_LOOP) goto next_dest;
 
         /**
          * On se doit de suivre le même cheminement que celui emprunté lors
@@ -339,7 +341,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
             && type != ILT_CASE_JUMP
             && type != ILT_JUMP_IF_TRUE
             && type != ILT_JUMP_IF_FALSE)
-            continue;
+            goto next_dest;
 
         target = g_block_list_find_by_starting_instr(list, dest->linked);
 
@@ -368,6 +370,10 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)
 
         }
 
+ next_dest:
+
+        unref_instr_link(dest);
+
     }
 
     g_arch_instruction_unlock_dest(last);
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 1d03ad7..3b47930 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -1038,7 +1038,7 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
     GArchInstruction *instr;                /* Instruction correspondante  */
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     const mrange_t *irange;                 /* Emplacement d'instruction   */
     GLineCursor *cursor;                    /* Emplacement dans un tampon  */
     size_t index;                           /* Indice de ligne à traiter   */
@@ -1102,12 +1102,12 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
                     call_count++;
 
                     if (call_count > max_calls)
-                        continue;
+                        goto next_dest;
 
                     if (call_count == max_calls)
                     {
                         call_info = stradd(call_info, "\n ...");
-                        continue;
+                        goto next_dest;
                     }
 
                     irange = g_arch_instruction_get_range(instr);
@@ -1150,20 +1150,20 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
                 case ILT_REF:
 
                     if (!G_IS_RAW_INSTRUCTION(dest->linked))
-                        continue;
+                        goto next_dest;
 
                     if (!g_raw_instruction_is_string(G_RAW_INSTRUCTION(dest->linked)))
-                        continue;
+                        goto next_dest;
 
                     string_count++;
 
                     if (string_count > max_strings)
-                        continue;
+                        goto next_dest;
 
                     if (string_count == max_strings)
                     {
                         string_info = stradd(string_info, "\n ...");
-                        continue;
+                        goto next_dest;
                     }
 
                     irange = g_arch_instruction_get_range(dest->linked);
@@ -1208,6 +1208,10 @@ char *g_binary_routine_build_tooltip(const GBinRoutine *routine, const GLoadedBi
 
             }
 
+ next_dest:
+
+            unref_instr_link(dest);
+
         }
 
         g_arch_instruction_unlock_dest(instr);
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 88033c9..55aee49 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -741,7 +741,7 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct
     bool result;                            /* Bilan à retourner           */
     size_t count;                           /* Nombre de liens à parcourir */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dlink;                    /* Définition de destination   */
+    const instr_link_t *dlink;              /* Définition de destination   */
 
     result = false;
 
@@ -755,6 +755,8 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct
 
         result = (dlink->linked == dest);
 
+        unref_instr_link(dlink);
+
     }
 
     g_arch_instruction_unlock_dest(instr);
@@ -833,6 +835,15 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
 
     result = false;
 
+    /**
+     * Note : pour la récupération des liens de sources et de destinations,
+     * on n'utilise pas les fonctions g_arch_instruction_get_(source|destination)(),
+     * qui renvoient un pointeur non modifiable.
+     *
+     * On a en effet besoin de modifier le type de lien.
+     */
+
+
     g_arch_instruction_lock_src(dest);
 
     /* Côté destination */
@@ -841,7 +852,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
 
     for (i = 0; i < count; i++)
     {
-        slink = g_arch_instruction_get_source(dest, i);
+        slink = get_flat_array_item(dest->from, i, sizeof(instr_link_t));
 
         if (slink->linked == instr && slink->type == old)
             break;
@@ -857,7 +868,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d
 
     for (i = 0; i < count; i++)
     {
-        dlink = g_arch_instruction_get_destination(instr, i);
+        dlink = get_flat_array_item(instr->to, i, sizeof(instr_link_t));
 
         if (dlink->linked == dest && dlink->type == old)
             break;
@@ -920,12 +931,14 @@ size_t g_arch_instruction_count_sources(const GArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index)
+const instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index)
 {
     instr_link_t *result;                   /* Détails présents à renvoyer */
 
     result = get_flat_array_item(instr->from, index, sizeof(instr_link_t));
 
+    ref_instr_link(result);
+
     return result;
 
 }
@@ -967,12 +980,14 @@ size_t g_arch_instruction_count_destinations(const GArchInstruction *instr)
 *                                                                             *
 ******************************************************************************/
 
-instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index)
+const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index)
 {
     instr_link_t *result;                   /* Détails présents à renvoyer */
 
     result = get_flat_array_item(instr->to, index, sizeof(instr_link_t));
 
+    ref_instr_link(result);
+
     return result;
 
 }
@@ -996,7 +1011,7 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins
     GArchInstruction *result;               /* Résultat à remonter         */
     size_t count;                           /* Nombre de liens à parcourir */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dest;                     /* Destination à étudier       */
+    const instr_link_t *dest;               /* Destination à étudier       */
 
     result = NULL;
 
@@ -1014,6 +1029,8 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins
             g_object_ref(G_OBJECT(result));
         }
 
+        unref_instr_link(dest);
+
     }
 
     g_arch_instruction_unlock_dest(instr);
@@ -1287,7 +1304,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
     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   */
+    const instr_link_t *link;               /* Lien vers une instruction   */
 
     result = pack_mrange(&instr->range, pbuf);
 
@@ -1370,6 +1387,8 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
             if (link->type != ILT_REF)
                 kept++;
 
+            unref_instr_link(link);
+
         }
 
         result = extend_packed_buffer(pbuf, &kept, sizeof(size_t), true);
@@ -1378,6 +1397,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s
         {
             link = g_arch_instruction_get_destination(instr, i);
             result = serialize_link(link);
+            unref_instr_link(link);
         }
 
         g_arch_instruction_unlock_dest(instr);
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index aadd2fc..34dc59f 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -211,6 +211,10 @@ typedef struct _instr_link_t
 } instr_link_t;
 
 
+#define ref_instr_link(l) g_object_ref(G_OBJECT(l->linked));
+#define unref_instr_link(l) g_object_unref(G_OBJECT(l->linked));
+
+
 /* Met à disposition un encadrement des accès aux liens. */
 void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool);
 
@@ -230,7 +234,7 @@ bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, Inst
 size_t g_arch_instruction_count_sources(const GArchInstruction *);
 
 /* Fournit les détails d'une origine d'une instruction donnée. */
-instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t);
+const instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t);
 
 #define g_arch_instruction_lock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true)
 #define g_arch_instruction_unlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false)
@@ -239,7 +243,7 @@ instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t);
 size_t g_arch_instruction_count_destinations(const GArchInstruction *);
 
 /* Fournit les détails d'une destination d'une instruction. */
-instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t);
+const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t);
 
 /* Fournit la destination d'une instruction et d'un type donné. */
 GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *, InstructionLinkType);
diff --git a/src/debug/debugger.c b/src/debug/debugger.c
index 4a1d314..41feb4b 100644
--- a/src/debug/debugger.c
+++ b/src/debug/debugger.c
@@ -1034,12 +1034,12 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
     virt_t *result;                         /* Liste à retourner           */
     GArchProcessor *proc;                   /* Processeur lié au binaire   */
     vmpa2t addr;                            /* Localisation à cibler       */
-    instr_iter_t *iter;                     /* Parcours local d'adresses   */
+    const instr_iter_t *iter;               /* Parcours local d'adresses   */
     GArchInstruction *instr;                /* Instruction correspondante  */
     virt_t ret;                             /* Adresse de retour d'appel   */
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     const mrange_t *range;                  /* Emplacement d'instruction   */
 
     result = NULL;
@@ -1116,6 +1116,8 @@ virt_t *g_binary_debugger_get_next_pcs(GBinaryDebugger *debugger, virt_t pc, boo
 
                 }
 
+                unref_instr_link(dest);
+
             }
 
             g_arch_instruction_unlock_dest(instr);
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 57c1bfb..a156bfa 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -921,7 +921,7 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
     GArchInstruction *last;                 /* Dernière instruction du bloc*/
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours #1       */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     GGraphCluster *target;                  /* Bloc ciblé par un lien      */
     leaving_edge *leaving;                  /* Point de départ d'un lien   */
     unsigned int target_level;              /* Rang du bloc ciblé          */
@@ -1045,6 +1045,8 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
 
         }
 
+        unref_instr_link(dest);
+
     }
 
     g_arch_instruction_unlock_dest(last);
@@ -1530,7 +1532,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
 #endif
     size_t dcount;                          /* Nombre de liens de dest.    */
     size_t i;                               /* Boucle de parcours #1       */
-    instr_link_t *dest;                     /* Instr. visée par une autre  */
+    const instr_link_t *dest;               /* Instr. visée par une autre  */
     GBasicBlock *target;                    /* Bloc ciblé par un lien      */
     size_t j;                               /* Boucle de parcours #2       */
     bool changed;                           /* Un ajout a été effectué ?   */
@@ -1641,6 +1643,8 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
 
         }
 
+        unref_instr_link(dest);
+
     }
 
     g_arch_instruction_unlock_dest(last);
diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c
index 4d28e59..97c031e 100644
--- a/src/gui/dialogs/gotox.c
+++ b/src/gui/dialogs/gotox.c
@@ -289,7 +289,7 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
     GtkTreeStore *store;                    /* Modèle de gestion           */
     size_t count;                           /* Nombre d'éléments présents  */
     size_t i;                               /* Boucle de parcours          */
-    instr_link_t *item;                     /* Instruction diverse liée    */
+    const instr_link_t *item;               /* Instruction diverse liée    */
     const vmpa2t *addr;                     /* Adresse à considérer        */
 
     /* Mise en place de la boîte de dialogue */
@@ -317,6 +317,8 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
 
             add_new_location_to_list(store, binary, addr, NULL);
 
+            unref_instr_link(item);
+
         }
 
         g_arch_instruction_unlock_src(instr);
@@ -337,6 +339,8 @@ GtkWidget *create_gotox_dialog_for_cross_references(GtkWindow *parent, GLoadedBi
 
             add_new_location_to_list(store, binary, addr, NULL);
 
+            unref_instr_link(item);
+
         }
 
         g_arch_instruction_unlock_dest(instr);
-- 
cgit v0.11.2-87-g4458