From ade3ee4fd3b78e96deb08210838643969f2f6699 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 4 Jul 2018 14:39:01 +0200
Subject: Updated the API for building symbol labels.

---
 plugins/elf/symbols.c                   |  16 +++-
 plugins/pychrysalide/analysis/routine.c |   1 +
 plugins/pychrysalide/format/symbol.c    |   6 +-
 src/analysis/disass/output.c            |  15 ++-
 src/analysis/disass/routines.c          |  16 +++-
 src/analysis/routine.c                  | 164 +++++---------------------------
 src/analysis/routine.h                  |   3 -
 src/arch/target.c                       |  17 +++-
 src/format/format.c                     |   4 +-
 src/format/symbol-int.h                 |   2 +-
 src/format/symbol.c                     |  39 ++++++--
 src/format/symbol.h                     |   2 +-
 src/gtkext/gtkstatusstack.c             |   4 +-
 src/gui/dialogs/gotox.c                 |  17 +++-
 src/gui/panels/strings.c                |   9 +-
 src/gui/panels/symbols.c                |  46 +++++----
 16 files changed, 165 insertions(+), 196 deletions(-)

diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 949e495..90b9488 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -1185,7 +1185,7 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
     uint64_t index;                         /* Indice du symbole concerné  */
     char *name;                             /* Nouvelle désignation        */
 #ifndef NDEBUG
-    const char *label;                      /* Etiquette courante          */
+    char *label;                            /* Etiquette courante          */
 #endif
 
     result = false;
@@ -1225,11 +1225,17 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
 
     label = g_binary_symbol_get_label(symbol);
 
-    if (strncmp(label, "sub_", 4) != 0 && strncmp(label, "loc_", 4) != 0)
+    if (label != NULL)
     {
-        if (strncmp(name, label, strlen(label)) != 0)
-            g_binary_format_add_error(G_BIN_FORMAT(format), BFE_SPECIFICATION, get_mrange_addr(range),
-                                      _("Mismatch detected in the ELF symbol address"));
+        if (strncmp(label, "sub_", 4) != 0 && strncmp(label, "loc_", 4) != 0)
+        {
+            if (strncmp(name, label, strlen(label)) != 0)
+                g_binary_format_add_error(G_BIN_FORMAT(format), BFE_SPECIFICATION, get_mrange_addr(range),
+                                          _("Mismatch detected in the ELF symbol address"));
+        }
+
+        free(label);
+
     }
 
 #endif
diff --git a/plugins/pychrysalide/analysis/routine.c b/plugins/pychrysalide/analysis/routine.c
index f8bc009..a95131d 100644
--- a/plugins/pychrysalide/analysis/routine.c
+++ b/plugins/pychrysalide/analysis/routine.c
@@ -139,6 +139,7 @@ static PyObject *py_binary_routine_get_name(PyObject *self, void *closure)
 
     if (name != NULL)
         result = PyUnicode_FromString(name);
+
     else
     {
         result = Py_None;
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c
index ae13cf2..7dcb0eb 100644
--- a/plugins/pychrysalide/format/symbol.c
+++ b/plugins/pychrysalide/format/symbol.c
@@ -25,6 +25,7 @@
 #include "symbol.h"
 
 
+#include <malloc.h>
 #include <pygobject.h>
 
 
@@ -238,13 +239,16 @@ static PyObject *py_binary_symbol_get_label(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Valeur à retourner          */
     GBinSymbol *symbol;                     /* Elément à consulter         */
-    const char *label;                      /* Désignation courante        */
+    char *label;                            /* Désignation courante        */
 
     symbol = G_BIN_SYMBOL(pygobject_get(self));
     label = g_binary_symbol_get_label(symbol);
 
     if (label != NULL)
+    {
         result = PyUnicode_FromString(label);
+        free(label);
+    }
 
     else
     {
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index 928ee16..b9b0f1f 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -83,6 +83,7 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
     GLineGenerator *generator;              /* Générateur de contenu ajouté*/
     const vmpa2t *saddr;                    /* Adresse de symbole          */
     int compared;                           /* Bilan d'une comparaison     */
+    char *label;                            /* Etiquette de symbole        */
     char *errmsg;                           /* Description d'une erreur    */
     SymbolType stype;                       /* Type de symbole trouvé      */
     vmpa2t intro_addr;                      /* Adresse de début de code    */
@@ -212,12 +213,16 @@ void print_disassembled_instructions(GBufferCache *cache, GCodingLanguage *lang,
                 if (compared <= 0)
                     break;
 
-                log_variadic_message(LMT_BAD_BINARY,
-                                     _("Unable to find a proper location for symbol '%s' @ 0x%08x"),
-                                     g_binary_symbol_get_label(symbol), get_phy_addr(saddr));
+                label = g_binary_symbol_get_label(symbol);
 
-                asprintf(&errmsg, _("Unable to find a proper location for symbol '%s'"),
-                         g_binary_symbol_get_label(symbol));
+                if (label == NULL)
+                    asprintf(&errmsg, _("Unable to find a proper location for symbol"));
+
+                else
+                {
+                    asprintf(&errmsg, _("Unable to find a proper location for symbol '%s'"), label);
+                    free(label);
+                }
 
                 g_arch_processor_add_error(proc, APE_LABEL, saddr, errmsg);
 
diff --git a/src/analysis/disass/routines.c b/src/analysis/disass/routines.c
index a0f756c..f04611f 100644
--- a/src/analysis/disass/routines.c
+++ b/src/analysis/disass/routines.c
@@ -24,6 +24,9 @@
 #include "routines.h"
 
 
+#include <malloc.h>
+
+
 #include "dragon.h"
 #include "limit.h"
 #include "loop.h"
@@ -336,6 +339,7 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, GBinRoutine *routine,
     const mrange_t *range;                  /* Couverture d'une routine    */
     const vmpa2t *start;                    /* Adresse de départ           */
     const instr_coverage *coverage;         /* Instructions couvertes      */
+    char *label;                            /* Etiquette du symbole        */
     VMPA_BUFFER(loc);                       /* Position de la routine      */
     dragon_knight *knight;                  /* Complexité de code posée    */
     GBlockList *blocks;                     /* Liste de blocs basiques     */
@@ -358,10 +362,18 @@ void g_routines_study_handle_blocks(GRoutinesStudy *study, GBinRoutine *routine,
      */
     if (coverage == NULL)
     {
+        label = g_binary_symbol_get_label(symbol);
+
         vmpa2_to_string(start, MDS_UNDEFINED, loc, NULL);
 
-        log_variadic_message(LMT_BAD_BINARY, _("Skipped out of bound routine '%s' @ %s"),
-                             g_binary_routine_get_name(routine), loc);
+        if (label == NULL)
+            log_variadic_message(LMT_BAD_BINARY, _("Skipped out of bound routine @ %s"), loc);
+
+        else
+        {
+            log_variadic_message(LMT_BAD_BINARY, _("Skipped out of bound routine '%s' @ %s"), label, loc);
+            free(label);
+        }
 
         return;
 
diff --git a/src/analysis/routine.c b/src/analysis/routine.c
index 08160b8..43097cc 100644
--- a/src/analysis/routine.c
+++ b/src/analysis/routine.c
@@ -57,9 +57,6 @@ struct _GBinRoutine
     GBinVariable **args;                    /* Arguments de la routines    */
     size_t args_count;                      /* Nombre d'arguments          */
 
-    char *cached_decl;                      /* Cache pour désignation #1   */
-    char *cached_full_decl;                 /* Cache pour désignation #2   */
-
     GBinVariable **locals;                  /* Variables locales du code   */
     size_t locals_count;                    /* Nombre de variables locales */
 
@@ -83,11 +80,8 @@ static void g_bin_routine_class_init(GBinRoutineClass *);
 /* Initialise une instance représentation de routine. */
 static void g_bin_routine_init(GBinRoutine *);
 
-/* Vide le cache des descriptions humaines. */
-static void g_binary_routine_reset_declarator(GBinRoutine *, bool);
-
 /* Fournit une étiquette pour viser une routine. */
-static const char *g_binary_routine_get_label(const GBinRoutine *);
+static char *g_binary_routine_get_label(const GBinRoutine *);
 
 
 
@@ -263,8 +257,6 @@ void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace,
     routine->namespace = namespace;
     routine->ns_sep = sep;
 
-    g_binary_routine_reset_declarator(routine, false);
-
 }
 
 
@@ -314,8 +306,6 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name)
 
     routine->name = name;
 
-    g_binary_routine_reset_declarator(routine, true);
-
 }
 
 
@@ -358,8 +348,6 @@ void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type)
 
     routine->full_name = type;
 
-    g_binary_routine_reset_declarator(routine, true);
-
 }
 
 
@@ -377,7 +365,14 @@ void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type)
 
 GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine)
 {
-    return routine->full_name;
+    GDataType *result;                      /* Type à retourner            */
+
+    result = routine->full_name;
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
 
 }
 
@@ -527,40 +522,9 @@ void g_binary_routine_remove_arg(GBinRoutine *routine, size_t index)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : routine = routine à mettre à jour.                           *
-*                full    = indique la portée de la réinitialisation.          *
-*                                                                             *
-*  Description : Vide le cache des descriptions humaines.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full)
-{
-    if (full && routine->cached_decl != NULL)
-    {
-        free(routine->cached_decl);
-        routine->cached_decl = NULL;
-    }
-
-    if (routine->cached_full_decl != NULL)
-    {
-        free(routine->cached_full_decl);
-        routine->cached_full_decl = NULL;
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : routine = routine à mettre à jour.                           *
-*                include = doit-on inclure les espaces de noms ?              *
+*  Paramètres  : routine = routine à manipuler.                               *
 *                                                                             *
-*  Description : Fournit le nom humain d'une routine.                         *
+*  Description : Fournit une étiquette pour viser une routine.                *
 *                                                                             *
 *  Retour      : Désignation humainement lisible ou NULL si non définie.      *
 *                                                                             *
@@ -568,98 +532,17 @@ static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full)
 *                                                                             *
 ******************************************************************************/
 
-const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool include)
+static char *g_binary_routine_get_label(const GBinRoutine *routine)
 {
-    char *new;                              /* Nouvelle description        */
-    char *namespace;                        /* Groupe d'appartenance       */
-    size_t i;                               /* Boucle de parcours          */
-    char *typestr;                          /* Stockage de nom temporaire  */
-
-    if (routine->cached_decl == NULL)
-    {
-        if (routine->full_name != NULL)
-            new = g_data_type_to_string(routine->full_name, include);
-        else
-            new = strdup(routine->name != NULL ? routine->name : "");
-
-        if (routine->namespace != NULL)
-        {
-            namespace = g_data_type_to_string(routine->namespace, include);
-
-            new = strprep(new, routine->ns_sep);
-            new = strprep(new, namespace);
-
-            free(namespace);
-
-        }
-
-        /* Mémorisation finale */
-
-        routine->cached_decl = new;
-
-    }
-
-    if (include && routine->cached_full_decl == NULL)
-    {
-        /* Type de retour */
-
-        if (routine->ret_type == NULL)
-            new = strdup("??? ");
-        else
-        {
-            new = g_data_type_to_string(routine->ret_type, include);
-
-            if (!(g_data_type_is_pointer(routine->ret_type) || g_data_type_is_reference(routine->ret_type)))
-                new = stradd(new, " ");
-
-        }
-
-        /* Nom de la routine */
-
-        new = stradd(new, routine->cached_decl);
-
-        /* Liste des arguments */
-
-        new = stradd(new, "(");
-
-        for (i = 0; i < routine->args_count; i++)
-        {
-            if (i > 0) new = stradd(new, ", ");
-
-            typestr = g_binary_variable_to_string(routine->args[i], include);
-            new = stradd(new, typestr);
-            free(typestr);
-
-        }
-
-        new = stradd(new, ")");
-
-        /* Mémorisation finale */
-
-        routine->cached_full_decl = new;
-
-    }
-
-    return (include ? routine->cached_full_decl : routine->cached_decl);
-
-}
+    char *result;                           /* Etiquette à renvoyer        */
 
+    if (routine->full_name != NULL)
+        result = g_data_type_to_string(routine->full_name, false);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : routine = routine à manipuler.                               *
-*                                                                             *
-*  Description : Fournit une étiquette pour viser une routine.                *
-*                                                                             *
-*  Retour      : Désignation humainement lisible ou NULL si non définie.      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+    else
+        result = strdup(routine->name != NULL ? routine->name : "");
 
-static const char *g_binary_routine_get_label(const GBinRoutine *routine)
-{
-    return g_binary_routine_get_declarator(routine, false);
+    return result;
 
 }
 
@@ -874,7 +757,7 @@ char *g_binary_routine_to_string(const GBinRoutine *routine, bool include)
 {
     char *result;                           /* Chaîne à renvoyer           */
     char *namespace;                        /* Groupe d'appartenance       */
-    const char *name;                       /* Désignation de la routine   */
+    char *name;                             /* Désignation de la routine   */
     size_t i;                               /* Boucle de parcours          */
     char *typestr;                          /* Stockage de nom temporaire  */
 
@@ -883,12 +766,12 @@ char *g_binary_routine_to_string(const GBinRoutine *routine, bool include)
     switch (routine->type)
     {
         case RTT_CONSTRUCTOR:
-            result = strdup(g_binary_routine_get_name(routine));
+            result = g_binary_routine_get_label(routine);
             result = stradd(result, "." /* FIXME */);
             break;
 
         case RTT_DESTRUCTOR:
-            result = strdup(g_binary_routine_get_name(routine));
+            result = g_binary_routine_get_label(routine);
             result = stradd(result, "::~");
             break;
 
@@ -920,10 +803,13 @@ char *g_binary_routine_to_string(const GBinRoutine *routine, bool include)
 
     }
 
-    name = g_binary_routine_get_name(routine);
+    name = g_binary_routine_get_label(routine);
 
     if (name != NULL)
+    {
         result = stradd(result, name);
+        free(name);
+    }
 
     /* Liste des arguments */
 
diff --git a/src/analysis/routine.h b/src/analysis/routine.h
index e1a3523..0a4917f 100644
--- a/src/analysis/routine.h
+++ b/src/analysis/routine.h
@@ -110,9 +110,6 @@ GBinVariable *g_binary_routine_get_arg(GBinRoutine *, size_t);
 /* Retire un argument d'une routine. */
 void g_binary_routine_remove_arg(GBinRoutine *, size_t);
 
-/* Fournit le nom humain d'une routine. */
-const char *g_binary_routine_get_declarator(GBinRoutine *, bool);
-
 /* S'assure qu'une variable est bien associée à une routine. */
 void g_binary_routine_register_if_needed(GBinRoutine *, size_t, bool);
 
diff --git a/src/arch/target.c b/src/arch/target.c
index a297a3c..036aad0 100644
--- a/src/arch/target.c
+++ b/src/arch/target.c
@@ -283,17 +283,18 @@ static int g_target_operand_compare(const GTargetOperand *a, const GTargetOperan
 
 static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *line, AsmSyntax syntax)
 {
-    const char *label;                      /* Etiquette liée à un symbole */
+    char *label;                            /* Etiquette liée à un symbole */
     vmpa2t tmp;                             /* Coquille vide pour argument */
     VMPA_BUFFER(value);                     /* Adresse brute à imprimer    */
     size_t len;                             /* Taille de l'élément inséré  */
 
-    if (operand->symbol != NULL /* FIXME */ && g_binary_symbol_get_label(operand->symbol) != NULL /* FIXME */)
+    label = g_binary_symbol_get_label(operand->symbol);
+
+    if (operand->symbol != NULL && label != NULL)
     {
         if (operand->diff > 0)
             g_buffer_line_append_text(line, BLC_MAIN, "<", 1, RTT_LTGT, NULL);
 
-        label = g_binary_symbol_get_label(operand->symbol);
         g_buffer_line_append_text(line, BLC_MAIN, label, strlen(label), RTT_LABEL, G_OBJECT(operand));
 
         if (operand->diff > 0)
@@ -318,6 +319,9 @@ static void g_target_operand_print(const GTargetOperand *operand, GBufferLine *l
 
     }
 
+    if (label != NULL)
+        free(label);
+
 }
 
 
@@ -510,7 +514,12 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
 
         if (stype == STP_STRING || stype == STP_RO_STRING)
         {
-            if (g_binary_symbol_get_label(symbol) == NULL)
+            label = g_binary_symbol_get_label(symbol);
+
+            if (label != NULL)
+                free(label);
+
+            else
             {
                 range = g_binary_symbol_get_range(symbol);
 
diff --git a/src/format/format.c b/src/format/format.c
index fa11663..439bd3e 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -961,7 +961,7 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
 {
     bool result;                            /* Bilan à retourner           */
     size_t i;                               /* Boucle de parcours          */
-    const char *cur_lbl;                    /* Etiquette courante          */
+    char *cur_lbl;                          /* Etiquette courante          */
 
     result = false;
 
@@ -981,6 +981,8 @@ bool g_binary_format_find_symbol_by_label(GBinFormat *format, const char *label,
 
         }
 
+        free(cur_lbl);
+
     }
 
     g_binary_format_unlock_symbols_rd(format);
diff --git a/src/format/symbol-int.h b/src/format/symbol-int.h
index 780a510..1b8672d 100644
--- a/src/format/symbol-int.h
+++ b/src/format/symbol-int.h
@@ -30,7 +30,7 @@
 
 
 /* Fournit une étiquette pour viser un symbole. */
-typedef const char * (* get_symbol_label_fc) (GBinSymbol *);
+typedef char * (* get_symbol_label_fc) (const GBinSymbol *);
 
 
 
diff --git a/src/format/symbol.c b/src/format/symbol.c
index 13ce23d..3f8e808 100644
--- a/src/format/symbol.c
+++ b/src/format/symbol.c
@@ -25,6 +25,7 @@
 
 
 #include <assert.h>
+#include <malloc.h>
 #include <string.h>
 
 
@@ -396,12 +397,12 @@ SymbolStatus g_binary_symbol_get_status(const GBinSymbol *symbol)
 *                                                                             *
 ******************************************************************************/
 
-const char *g_binary_symbol_get_label(const GBinSymbol *symbol)
+char *g_binary_symbol_get_label(const GBinSymbol *symbol)
 {
-    const char *result;                     /* Etiquette à retourner       */
+    char *result;                           /* Etiquette à retourner       */
 
     if (symbol->alt != NULL)
-        result = symbol->alt;
+        result = strdup(symbol->alt);
 
     else if (G_BIN_SYMBOL_GET_CLASS(symbol)->get_label != NULL)
         result = G_BIN_SYMBOL_GET_CLASS(symbol)->get_label(symbol);
@@ -461,11 +462,18 @@ void g_binary_symbol_set_alt_label(GBinSymbol *symbol, const char *alt)
 GLineGenerator *g_binary_symbol_produce_label(GBinSymbol *symbol)
 {
     GLineGenerator *result;                 /* Instance à retourner        */
-    const char *label;                      /* Etiquette à insérer         */
+    char *label;                            /* Etiquette à insérer         */
 
     label = g_binary_symbol_get_label(symbol);
 
-    result = (label != NULL ? G_LINE_GENERATOR(symbol) : NULL);
+    if (label == NULL)
+        result = NULL;
+
+    else
+    {
+        result = G_LINE_GENERATOR(symbol);
+        free(label);
+    }
 
     return result;
 
@@ -590,14 +598,27 @@ static BufferLineFlags g_binary_symbol_get_flags(const GBinSymbol *symbol, size_
 
 static void g_binary_symbol_print(GBinSymbol *symbol, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
 {
-    const char *label;                      /* Etiquette à insérer         */
+    char *label;                            /* Etiquette à insérer         */
 
     g_buffer_line_fill_vmpa(line, get_mrange_addr(&symbol->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
 
     label = g_binary_symbol_get_label(symbol);
 
-    g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(label), RTT_LABEL, NULL);
-    g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
+    /**
+     * Normalement, l'étiquette n'est pas vide car le générateur provient de
+     * g_binary_symbol_produce_label(), qui filtre.
+     *
+     * Mais le symbole a pu être manipulé entre temps, donc on évite un assert().
+     */
+
+    if (label != NULL)
+    {
+        g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD);
+        g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(label), RTT_LABEL, NULL);
+        g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, ":", 1, RTT_PUNCT, NULL);
+
+        free(label);
+
+    }
 
 }
diff --git a/src/format/symbol.h b/src/format/symbol.h
index 881c2f2..13747d4 100644
--- a/src/format/symbol.h
+++ b/src/format/symbol.h
@@ -109,7 +109,7 @@ void g_binary_symbol_set_status(GBinSymbol *, SymbolStatus);
 SymbolStatus g_binary_symbol_get_status(const GBinSymbol *);
 
 /* Fournit une étiquette pour viser un symbole. */
-const char *g_binary_symbol_get_label(const GBinSymbol *);
+char *g_binary_symbol_get_label(const GBinSymbol *);
 
 /* Définit un autre nom pour le symbole. */
 void g_binary_symbol_set_alt_label(GBinSymbol *, const char *);
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index 0d24095..0bcb903 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -514,7 +514,7 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
     const char *text;                       /* Texte au contenu à copier   */
     GBinSymbol *symbol;                     /* Symbole présent à l'adresse */
     phys_t diff;                            /* Décalage de l'adresse       */
-    const char *label;                      /* Description d'un symbole    */
+    char *label;                            /* Description d'un symbole    */
     vmpa2t tmp;                             /* Zone de construction temp.  */
     VMPA_BUFFER(offset);                    /* Décalage physique           */
 
@@ -571,7 +571,7 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
 
         if (label != NULL)
         {
-            info->symbol = strdup(label);
+            info->symbol = label;
 
             info->symbol = stradd(info->symbol, "+");
 
diff --git a/src/gui/dialogs/gotox.c b/src/gui/dialogs/gotox.c
index f28654d..72c2f8c 100644
--- a/src/gui/dialogs/gotox.c
+++ b/src/gui/dialogs/gotox.c
@@ -372,7 +372,7 @@ static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary,
     size_t index;                           /* Indice de ligne à traiter   */
     GBufferLine *line;                      /* Ligne présente à l'adresse  */
     char *virtual;                          /* Transcription d'adresse     */
-    const char *label;                      /* Etiquette de symbole trouvé */
+    char *label;                            /* Etiquette de symbole trouvé */
     GBinFormat *format;                     /* Format associé au binaire   */
     GBinSymbol *symbol;                     /* Symbole associé à l'adresse */
     phys_t diff;                            /* Décalage vis à vis du début */
@@ -410,7 +410,17 @@ static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary,
 
         label = g_binary_symbol_get_label(hint);
 
-        name = make_symbol_offset(label, 0);
+        /**
+         * Cf. commentaire suivant.
+         */
+        if (label == NULL)
+            name = strdup(_("<no symbol found>"));
+
+        else
+        {
+            name = make_symbol_offset(label, 0);
+            free(label);
+        }
 
     }
     else
@@ -430,7 +440,10 @@ static void add_new_location_to_list(GtkTreeStore *store, GLoadedBinary *binary,
                 name = strdup(_("<no symbol found>"));
 
             else
+            {
                 name = make_symbol_offset(label, diff);
+                free(label);
+            }
 
         }
         else
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 4828038..a50eeae 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -26,8 +26,9 @@
 
 
 #include <assert.h>
-#include <string.h>
 #include <inttypes.h>
+#include <malloc.h>
+#include <string.h>
 
 
 #include "panel-int.h"
@@ -1360,7 +1361,7 @@ static bool is_string_name_matching(const strings_update_data *data, GtkTreeMode
 #ifndef NDEBUG
     SymbolType type;                        /* Type associé au symbole     */
 #endif
-    const char *label;                      /* Etiquette à analyser        */
+    char *label;                            /* Etiquette à analyser        */
 
     gtk_tree_model_get(model, iter, STC_SYMBOL, &symbol, -1);
     assert(symbol != NULL);
@@ -1377,8 +1378,12 @@ static bool is_string_name_matching(const strings_update_data *data, GtkTreeMode
 
     if (label == NULL)
         result = false;
+
     else
+    {
         result = is_content_matching(data->filter, label, match);
+        free(label);
+    }
 
     g_object_unref(G_OBJECT(symbol));
 
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 94605b3..0c88bce 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -727,7 +727,7 @@ static void reload_symbols_for_new_list_view(const GSymbolsPanel *panel, GtkStat
     cairo_surface_t *icon;                  /* Image associée au symbole   */
     regmatch_t match;                       /* Récupération des trouvailles*/
     bool matched;                           /* Correspondance de sélection */
-    const char *original;                   /* Etiquette brute d'origine   */
+    char *original;                         /* Etiquette brute d'origine   */
     char *name;                             /* Etiquette mise en relief    */
     const vmpa2t *addr;                     /* Localisation d'un symbole   */
     VMPA_BUFFER(virt);                      /* Version humainement lisible */
@@ -775,6 +775,8 @@ static void reload_symbols_for_new_list_view(const GSymbolsPanel *panel, GtkStat
         else
             name = NULL;
 
+        free(original);
+
         addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
@@ -939,8 +941,7 @@ static GtkTreeIter ensure_symbol_node_exist(const GSymbolsPanel *panel, GtkTreeI
 static bool find_parent_for_symbol(const GSymbolsPanel *panel, const GBinSymbol *symbol, GtkTreeIter *parent, const regmatch_t *match, size_t *last)
 {
     bool result;                            /* Bilan à retourner           */
-    const char *label;                      /* Etiquette immuable          */
-    char *string;                           /* Etiquette modifiable        */
+    char *label;                            /* Etiquette modifiable        */
     char *start;                            /* Début de boucle de parcours */
     char *token;                            /* Partie de texte isolée      */ 
     char *next;                             /* Prochaine partie à traiter  */
@@ -952,24 +953,22 @@ static bool find_parent_for_symbol(const GSymbolsPanel *panel, const GBinSymbol
     label = g_binary_symbol_get_label(symbol);
     if (label == NULL) return false;
 
-    string = strdup(label);
-
-    for (start = string, token = strtok_w(&start, panel->sep); ; token = next)
+    for (start = label, token = strtok_w(&start, panel->sep); ; token = next)
     {
         next = strtok_w(&start, panel->sep);
         if (next == NULL)
         {
-            *last = (token - string);
+            *last = (token - label);
             break;
         }
 
-        *parent = ensure_symbol_node_exist(panel, (token == string ? NULL : parent), token, match, token - string);
+        *parent = ensure_symbol_node_exist(panel, (token == label ? NULL : parent), token, match, token - label);
 
         result = true;
 
     }
 
-    free(string);
+    free(label);
 
     return result;
 
@@ -1005,7 +1004,7 @@ static void reload_symbols_for_new_tree_view(const GSymbolsPanel *panel, GtkStat
     bool matched;                           /* Correspondance de sélection */
     GtkTreeIter parent;                     /* Point d'insertion parent    */
     size_t last;                            /* Position du dernier élément */
-    const char *original;                   /* Etiquette brute d'origine   */
+    char *original;                         /* Etiquette brute d'origine   */
     char *name;                             /* Etiquette mise en relief    */
     const vmpa2t *addr;                     /* Localisation d'un symbole   */
     char virt[VMPA_MAX_LEN];                /* Version humainement lisible */
@@ -1066,6 +1065,8 @@ static void reload_symbols_for_new_tree_view(const GSymbolsPanel *panel, GtkStat
         else
             name = NULL;
 
+        free(original);
+
         addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
@@ -1258,8 +1259,7 @@ static GtkTreeIter update_symbol_partial_name_in_tree_view(GtkTreeStore *store,
 
 static void update_symbol_name_in_tree_view(const GSymbolsPanel *panel, GtkTreeStore *store, const GBinSymbol *symbol, const regmatch_t *match)
 {
-    const char *label;                      /* Etiquette immuable          */
-    char *string;                           /* Etiquette modifiable        */
+    char *label;                            /* Etiquette modifiable        */
     GtkTreeIter parent;                     /* Point d'analyse courant     */
     char *start;                            /* Début de boucle de parcours */
     char *token;                            /* Partie de texte isolée      */
@@ -1268,17 +1268,15 @@ static void update_symbol_name_in_tree_view(const GSymbolsPanel *panel, GtkTreeS
 
     if (label != NULL)
     {
-        string = strdup(label);
-
-        for (start = string, token = strtok_w(&start, panel->sep);
+        for (start = label, token = strtok_w(&start, panel->sep);
              token != NULL;
              token = strtok_w(&start, panel->sep))
         {
-            parent = update_symbol_partial_name_in_tree_view(store, (token == string ? NULL : &parent),
-                                                             token, match, token - string);
+            parent = update_symbol_partial_name_in_tree_view(store, (token == label ? NULL : &parent),
+                                                             token, match, token - label);
         }
 
-        free(string);
+        free(label);
 
     }
 
@@ -1420,6 +1418,7 @@ static bool is_symbol_matching(const symbols_update_data *data, const GBinSymbol
 #ifndef NDEBUG
     SymbolType type;                        /* Type associé au symbole     */
 #endif
+    char *label;                            /* Etiquette à analyser        */
 
 #ifndef NDEBUG
 
@@ -1429,7 +1428,16 @@ static bool is_symbol_matching(const symbols_update_data *data, const GBinSymbol
 
 #endif
 
-    result = is_content_matching(data->filter, g_binary_symbol_get_label(symbol), match);
+    label = g_binary_symbol_get_label(symbol);
+
+    if (label == NULL)
+        result = false;
+
+    else
+    {
+        result = is_content_matching(data->filter, label, match);
+        free(label);
+    }
 
     return result;
 
-- 
cgit v0.11.2-87-g4458