From 60f7839e36d0eaf5bcc90ffe1369dae56ed53dbe Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 26 Apr 2015 10:34:20 +0000
Subject: Loaded internal smybols ; created entry points only when needed.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@520 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  17 +++++-
 src/analysis/disass/output.c |   5 +-
 src/format/elf/symbols.c     | 103 +++++++++++++++++--------------
 src/format/format.c          | 140 +++++++++++++++++++++++++++++++++++++++++++
 src/format/format.h          |   6 ++
 src/gui/panels/symbols.c     |   4 +-
 6 files changed, 225 insertions(+), 50 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 479f470..17dce96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,19 @@
-15-04-25  Cyrille Bagard <nocbos@gmail.com>
+115-04-26  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/output.c:
+	Give more information about not found symbols.
+
+	* src/format/elf/symbols.c:
+	Load internal smybols ; create entry points only when needed.
+
+	* src/format/format.c:
+	* src/format/format.h:
+	Allow to remove symbols and/or routines.
+
+	* src/gui/panels/symbols.c
+	Display entry points as symbols too.
+
+115-04-25  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/macro.c:
 	Use an uniq coverage memory for all visited branches.
diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c
index f2c49bb..324975b 100644
--- a/src/analysis/disass/output.c
+++ b/src/analysis/disass/output.c
@@ -188,8 +188,9 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form
                  compared > 0;
                  compared = cmp_vmpa(iaddr, saddr))
             {
-                log_variadic_message(LMT_BAD_BINARY, _("Unable to find a proper location for symbol '%s'"),
-                                     g_binary_symbol_to_string(symbols[sym_index]));
+                log_variadic_message(LMT_BAD_BINARY,
+                                     _("Unable to find a proper location for symbol '%s' @ 0x%08x"),
+                                     g_binary_symbol_get_label(symbols[sym_index]), get_virt_addr(saddr));
 
                 if (++sym_index == sym_count)
                     goto no_more_symbol_finally;
diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c
index b57c601..4c1811f 100644
--- a/src/format/elf/symbols.c
+++ b/src/format/elf/symbols.c
@@ -93,7 +93,7 @@ static bool load_elf_external_symbols(GElfFormat *, const elf_shdr *);
 
 
 
-#include <stdlib.h>
+
 
 /******************************************************************************
 *                                                                             *
@@ -116,18 +116,10 @@ bool load_elf_symbols(GElfFormat *format)
 
     result = true;
 
+    /* Symboles internes */
 
+    result &= load_elf_internal_symbols(format);
 
-    result &= load_all_elf_basic_entry_points(format);
-
-
-
-
-
-    /* Symboles internes */
-#if 0
-    result = load_elf_internal_symbols(format);
-#endif
 
 
 
@@ -149,34 +141,9 @@ bool load_elf_symbols(GElfFormat *format)
 
 
 
-	qsort(G_BIN_FORMAT(format)->symbols, G_BIN_FORMAT(format)->symbols_count,
-		  sizeof(GBinSymbol *), (__compar_fn_t)g_binary_symbol_cmp);
+    /* Symboles d'entrée, si encore besoin */
 
-#if 0
-
-    const vmpa2t *saddr;                    /* Adresse de symbole          */
-    size_t i;                               /* Boucle de parcours #2       */
-    GBinSymbol **symbols;                   /* Symboles à représenter      */
-
-	symbols = G_BIN_FORMAT(format)->symbols;
-
-	for (i = 0; i < G_BIN_FORMAT(format)->symbols_count; i++)
-	{
-		saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[i]));
-		if (saddr == NULL) continue;
-
-		//if (g_binary_symbol_to_string(symbols[i]) == NULL) continue;
-
-		printf(" <symbol % 2zu> '% 22s'-> 0x%08lx  0x%08lx\n",
-			   i,
-			   g_binary_symbol_to_string(symbols[i]),
-			   saddr->physical,
-			   saddr->virtual);
-
-	}
-
-	//exit(0);
-#endif
+    result &= load_all_elf_basic_entry_points(format);
 
     return result;
 
@@ -220,13 +187,31 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
 
 	init_vmpa(&addr, VMPA_NO_PHYSICAL, vaddr);
 
-	init_mrange(&range, &addr, len);
+    if (g_binary_format_find_symbol_at(format, &addr, &symbol))
+    {
+        g_object_unref(G_OBJECT(routine));
+
+        routine = g_binary_symbol_get_routine(symbol);
+        g_object_ref(G_OBJECT(routine));
+
+        printf(" -- SYM CHANGE @ 0x%08x\n", vaddr);
 
-	g_binary_routine_set_range(routine, &range);
+        _g_binary_symbol_attach_routine(symbol, routine, STP_ENTRY_POINT);
+
+    }
+    else
+    {
+        printf(" -- SYM ENTRY @ 0x%08x\n", vaddr);
 
-	symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0);
-	g_binary_symbol_attach_routine(symbol, routine);
-	g_binary_format_add_symbol(base, symbol);
+        init_mrange(&range, &addr, len);
+
+        g_binary_routine_set_range(routine, &range);
+
+        symbol = g_binary_symbol_new(STP_ENTRY_POINT, "XXX", ~0);
+        g_binary_symbol_attach_routine(symbol, routine);
+        g_binary_format_add_symbol(base, symbol);
+
+    }
 
 }
 
@@ -530,6 +515,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
         off_t size;                         /* Taille de cette même zone   */
         off_t iter;                         /* Boucle de parcours          */
         elf_sym sym;                        /* Symbole aux infos visées    */
+        virt_t virt;                        /* Adresse virtuelle           */
         vmpa2t addr;                        /* Localisation d'une routine  */
         mrange_t range;                     /* Couverture mémoire associée */
         const char *name;                   /* Nom du symbole trouvé       */
@@ -546,6 +532,21 @@ static bool load_elf_internal_symbols(GElfFormat *format)
             result = read_elf_symbol(format, &iter, &sym);
             if (!result) break;
 
+            /* On rejette les symboles qui ne sont pas définis au sein du binaire */
+            if (ELF_SYM(format, sym, st_shndx) == 0) continue;
+
+#if 0
+
+            Elf64_Word    st_name;                /* Symbol name (string tbl index) */
+  unsigned char st_info;                /* Symbol type and binding */
+  unsigned char st_other;               /* Symbol visibility */
+  Elf64_Section st_shndx;               /* Section index */
+  Elf64_Addr    st_value;               /* Symbol value */
+  Elf64_Xword   st_size;                /* Symbol size */
+
+#endif
+
+
             if (ELF_SYM(format, sym, st_value) == 0) continue;
 
             /* Résolution précise d'adresse */
@@ -553,10 +554,20 @@ static bool load_elf_internal_symbols(GElfFormat *format)
 
             /* TODO */
 
-            init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL);
+            //init_vmpa(&addr, VMPA_NO_PHYSICAL, ELF_SYM(format, sym, st_value));
+
+            virt = ELF_SYM(format, sym, st_value);
+
+            if (ELF_HDR(format, format->header, e_machine) == EM_ARM)
+                virt &= ~0x1;
+
+            if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, &addr))
+                continue;
+
 
 
-            init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+            //init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
+            init_mrange(&range, &addr, 0);
 
 
             /* Première ébauche de nom */
@@ -609,7 +620,7 @@ static bool load_elf_internal_symbols(GElfFormat *format)
 
                     /* Routine */
 
-					printf("ADDING>> '%s'\n", name);
+					printf("SYM ADDING>> '%s'\n", name);
 
                     routine = try_to_demangle_routine(name);
 
diff --git a/src/format/format.c b/src/format/format.c
index 5478d3c..2256160 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -49,6 +49,9 @@ static void g_binary_format_class_init(GBinFormatClass *);
 /* Initialise une instance de format binaire générique. */
 static void g_binary_format_init(GBinFormat *);
 
+/* Retire un symbole de la collection du format binaire. */
+static void _g_binary_format_remove_symbol(GBinFormat *, size_t);
+
 
 
 /* Indique le type défini pour un format binaire générique. */
@@ -222,6 +225,96 @@ void g_binary_format_add_symbol(GBinFormat *format, GBinSymbol *symbol)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format = informations chargées à compléter.                  *
+*                index  = indice du symbole à retirer de la liste.            *
+*                                                                             *
+*  Description : Retire un symbole de la collection du format binaire.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _g_binary_format_remove_symbol(GBinFormat *format, size_t index)
+{
+    GBinSymbol *symbol;                     /* Symbole visé par l'opération*/
+    GBinRoutine *routine;                   /* Eventuelle routine associée */
+    size_t i;                               /* Boucle de parcours          */
+
+    /**
+     * TODO : envoyer un signal pour avertir les opérandes concernées.
+     */
+
+    symbol = format->symbols[index];
+
+    switch (g_binary_symbol_get_target_type(symbol))
+    {
+        case STP_ROUTINE:
+        case STP_ENTRY_POINT:
+
+            routine = g_binary_symbol_get_routine(symbol);
+
+            for (i = 0; i < format->routines_count; i++)
+                if (format->routines[i] == routine)
+                    break;
+
+            assert(i < format->routines_count);
+
+            if ((i + 1) < format->routines_count)
+                memmove(&format->routines[i], &format->routines[i + 1],
+                        (format->routines_count - i - 1) * sizeof(GBinRoutine *));
+
+            format->routines = (GBinRoutine **)realloc(format->routines,
+                                                       --format->routines_count * sizeof(GBinRoutine *));
+
+            break;
+
+        default:
+            break;
+
+    }
+
+    assert(index < format->symbols_count);
+
+    if ((index + 1) < format->symbols_count)
+        memmove(&format->symbols[index], &format->symbols[index + 1],
+                (format->symbols_count - index - 1) * sizeof(GBinSymbol *));
+
+    format->symbols = (GBinSymbol **)realloc(format->symbols,
+                                             --format->symbols_count * sizeof(GBinSymbol *));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = informations chargées à compléter.                  *
+*                symbol = symbole à retirer de la liste.                      *
+*                                                                             *
+*  Description : Retire un symbole de la collection du format binaire.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_format_remove_symbol(GBinFormat *format, GBinSymbol *symbol)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < format->symbols_count; i++)
+        if (format->symbols[i] == symbol)
+            break;
+
+    _g_binary_format_remove_symbol(format, i);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format = informations chargées à consulter.                  *
 *                count  = taille du tableau créé. [OUT]                       *
 *                                                                             *
@@ -480,6 +573,53 @@ void g_binary_format_add_routine(GBinFormat *format, GBinRoutine *routine)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : format  = informations chargées à compléter.                 *
+*                routine = routine à ajouter à la liste.                      *
+*                                                                             *
+*  Description : Retire une routine de la collection du format binaire.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_format_remove_routine(GBinFormat *format, GBinRoutine *routine)
+{
+    size_t index;                           /* Indice trouvé à utiliser    */
+    size_t i;                               /* Boucle de parcours          */
+    GBinSymbol *symbol;                     /* Symbole en cours d'analyse  */
+
+    index = format->symbols_count;
+
+    for (i = 0; i < format->symbols_count && index == format->symbols_count; i++)
+    {
+        symbol = format->symbols[i];
+
+        switch (g_binary_symbol_get_target_type(symbol))
+        {
+            case STP_ROUTINE:
+            case STP_ENTRY_POINT:
+
+                if (g_binary_symbol_get_routine(symbol) == routine)
+                    index = i;
+
+                break;
+
+            default:
+                break;
+
+        }
+
+    }
+
+    _g_binary_format_remove_symbol(format, index);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : format = informations chargées à consulter.                  *
 *                count  = taille du tableau créé. [OUT]                       *
 *                                                                             *
diff --git a/src/format/format.h b/src/format/format.h
index 38418b3..66f014b 100644
--- a/src/format/format.h
+++ b/src/format/format.h
@@ -67,6 +67,9 @@ void g_binary_format_setup_disassembling_context(const GBinFormat *, GProcContex
 /* Ajoute un symbole à la collection du format binaire. */
 void g_binary_format_add_symbol(GBinFormat *, GBinSymbol *);
 
+/* Retire un symbole de la collection du format binaire. */
+void g_binary_format_remove_symbol(GBinFormat *, GBinSymbol *);
+
 /* Fournit la liste de tous les symboles détectés. */
 GBinSymbol **g_binary_format_get_symbols(const GBinFormat *, size_t *);
 
@@ -85,6 +88,9 @@ bool g_binary_format_resolve_symbol(const GBinFormat *, const vmpa2t *, GBinSymb
 /* Ajoute une routine à la collection du format binaire. */
 void g_binary_format_add_routine(GBinFormat *, GBinRoutine *) __attribute__ ((deprecated));
 
+/* Retire une routine de la collection du format binaire. */
+void g_binary_format_remove_routine(GBinFormat *, GBinRoutine *);
+
 /* Fournit le prototype de toutes les routines détectées. */
 GBinRoutine **g_binary_format_get_routines(const GBinFormat *, size_t *);
 
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index b523cd2..42098c8 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -662,6 +662,7 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
         switch (g_binary_symbol_get_target_type(symbols[i]))
         {
             case STP_ROUTINE:
+            case STP_ENTRY_POINT:
                 icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
                 break;
             case STP_OBJECT:
@@ -843,6 +844,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
         switch (g_binary_symbol_get_target_type(symbols[i]))
         {
             case STP_ROUTINE:
+            case STP_ENTRY_POINT:
                 icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
                 break;
             case STP_OBJECT:
@@ -1044,7 +1046,7 @@ static bool is_symbol_filtered(GSymbolsPanel *panel, const GBinSymbol *symbol)
 
     type = g_binary_symbol_get_target_type(symbol);
 
-    if (type != STP_ROUTINE && type != STP_OBJECT)
+    if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT)
         return true;
 
     if (panel->filter == NULL)
-- 
cgit v0.11.2-87-g4458