From 21af77b7c44126c05b62319f99a679fc748b579e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 8 Jul 2018 23:54:13 +0200
Subject: Cleaned the demangling system.

---
 plugins/dex/pool.c         |   4 +-
 plugins/elf/symbols.c      |  15 +-
 plugins/mobicore/symbols.c |   2 +-
 src/format/dwarf/symbols.c |   2 +-
 src/format/format-int.h    |  16 ++-
 src/format/format.c        |  71 ++++++++++
 src/mangling/demangler.c   | 335 ---------------------------------------------
 src/mangling/demangler.h   |  32 -----
 8 files changed, 97 insertions(+), 380 deletions(-)

diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index 081c178..8c740bc 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -280,7 +280,6 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
     type_id_item type_id;                   /* Définition de la classe     */
     string_id_item str_id;                  /* Identifiant de chaîne       */
     string_data_item str_data;              /* Description de chaîne       */
-    GCompDemangler *demangler;              /* Accès plus lisible          */
 
     result = NULL;
 
@@ -309,8 +308,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
         if (!read_dex_string_data_item(format, &addr, &str_data))
             goto gtfdp_error;
 
-        demangler = G_BIN_FORMAT(format)->demangler;
-        format->types[index] = g_compiler_demangler_decode_type(demangler, (char *)str_data.data);
+        format->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data);
 
     }
 
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 90b9488..08d9377 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -232,6 +232,7 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
 
 static bool load_all_elf_basic_entry_points(GElfFormat *format)
 {
+    GBinFormat *base;                       /* Autre version du format     */
     virt_t ep;                              /* Point d'entrée détecté      */
     GBinRoutine *routine;                   /* Routine à associer à un pt. */
     elf_phdr dynamic;                       /* En-tête de programme DYNAMIC*/
@@ -244,13 +245,15 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
     uint32_t virt_32;                       /* Adresse virtuelle sur 32b   */
     uint64_t virt_64;                       /* Adresse virtuelle sur 64b   */
 
+    base = G_BIN_FORMAT(format);
+
     /* Point d'entrée principal éventuel */
 
     ep = ELF_HDR(format, format->header, e_entry);
 
     if (ep != 0x0)
     {
-        routine = try_to_demangle_routine("entry_point");
+        routine = g_binary_format_decode_routine(base, "entry_point");
         register_elf_entry_point(format, ep, 0, routine);
     }
 
@@ -267,7 +270,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
 
         if (ep != 0x0)
         {
-            routine = try_to_demangle_routine("init_function");
+            routine = g_binary_format_decode_routine(base, "init_function");
             register_elf_entry_point(format, ep, 0, routine);
         }
 
@@ -279,7 +282,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
 
         if (ep != 0x0)
         {
-            routine = try_to_demangle_routine("termination_function");
+            routine = g_binary_format_decode_routine(base, "termination_function");
             register_elf_entry_point(format, ep, 0, routine);
         }
 
@@ -332,7 +335,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
             {
                 snprintf(fullname, sizeof(fullname), "%s%u", prefix, i);
 
-                routine = try_to_demangle_routine(fullname);
+                routine = g_binary_format_decode_routine(base, fullname);
                 register_elf_entry_point(fmt, ep, 0, routine);
 
             }
@@ -403,7 +406,7 @@ static bool load_all_elf_basic_entry_points(GElfFormat *format)
 
                 if (ep != 0x0)
                 {
-                    routine = try_to_demangle_routine("plt_entry");
+                    routine = g_binary_format_decode_routine(base, "plt_entry");
                     register_elf_entry_point(format, ep, 0, routine);
                     break;
                 }
@@ -526,7 +529,7 @@ static bool do_elf_symbol_loading(GElfLoading *loading, GElfFormat *format, bool
                 break;
             }
 
-            routine = try_to_demangle_routine(name);
+            routine = g_binary_format_decode_routine(base, name);
             symbol = G_BIN_SYMBOL(routine);
 
             init_mrange(&range, &addr, ELF_SYM(format, sym, st_size));
diff --git a/plugins/mobicore/symbols.c b/plugins/mobicore/symbols.c
index 5b612cc..df8d62f 100644
--- a/plugins/mobicore/symbols.c
+++ b/plugins/mobicore/symbols.c
@@ -114,7 +114,7 @@ static bool load_all_mclf_basic_entry_points(GMCLFFormat *format)
 
     if (ep != 0x0)
     {
-        routine = try_to_demangle_routine("entry_point");
+        routine = g_binary_format_decode_routine(G_BIN_FORMAT(format), "entry_point");
         register_mclf_entry_point(format, ep, 0, routine);
     }
 
diff --git a/src/format/dwarf/symbols.c b/src/format/dwarf/symbols.c
index f0a7300..3ddfb96 100644
--- a/src/format/dwarf/symbols.c
+++ b/src/format/dwarf/symbols.c
@@ -110,7 +110,7 @@ static bool load_routine_as_symbol_from_dwarf(GDwarfFormat *format, const dw_die
 
     /* Intégration en bonne et due forme */
 
-    routine = try_to_demangle_routine(name);
+    routine = g_binary_format_decode_routine(G_BIN_FORMAT(format), name);
     symbol = G_BIN_SYMBOL(routine);
 
     g_binary_symbol_set_range(symbol, &range);
diff --git a/src/format/format-int.h b/src/format/format-int.h
index 354e616..6c83590 100644
--- a/src/format/format-int.h
+++ b/src/format/format-int.h
@@ -78,8 +78,6 @@ struct _GBinFormat
 
     GBinContent *content;                   /* Contenu binaire à étudier   */
 
-    GCompDemangler *demangler;              /* Décodage de noms privilégié */
-
     virt_t *entry_points;                   /* Points d'entrée du code     */
     size_t ep_count;                        /* Nombre de ces points        */
 
@@ -91,6 +89,8 @@ struct _GBinFormat
 
     GPreloadInfo *info;                     /* Préchargements du format    */
 
+    GCompDemangler *demangler;              /* Décodage de noms privilégié */
+
     GBinSymbol **symbols;                   /* Liste des symboles trouvés  */
     size_t sym_count;                       /* Quantité de ces symboles    */
     unsigned int sym_stamp;                 /* Marque de suivi des modifs  */
@@ -138,4 +138,16 @@ void g_binary_format_set_content(GBinFormat *, GBinContent *);
 
 
 
+
+/* ------------------------------ DECODAGE DE SYMBOLES ------------------------------ */
+
+
+/* Décode une chaîne de caractères donnée en type. */
+GDataType *g_binary_format_decode_type(const GBinFormat *, const char *);
+
+/* Décode une chaîne de caractères donnée en routine. */
+GBinRoutine *g_binary_format_decode_routine(const GBinFormat *, const char *);
+
+
+
 #endif  /* _FORMAT_FORMAT_INT_H */
diff --git a/src/format/format.c b/src/format/format.c
index 439bd3e..5ff08e6 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -477,6 +477,77 @@ void g_binary_format_complete_analysis(GBinFormat *format, wgroup_id_t gid, GtkS
 
 
 /* ---------------------------------------------------------------------------------- */
+/*                                DECODAGE DE SYMBOLES                                */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = format binaire à consulter pour l'opération.        *
+*                desc   = chaîne de caractères à décoder.                     *
+*                                                                             *
+*  Description : Décode une chaîne de caractères donnée en type.              *
+*                                                                             *
+*  Retour      : Instance obtenue ou NULL en cas d'échec.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDataType *g_binary_format_decode_type(const GBinFormat *format, const char *desc)
+{
+    GDataType *result;                      /* Construction à remonter     */
+    GCompDemangler *demangler;              /* Accès plus lisible          */
+
+    demangler = G_BIN_FORMAT(format)->demangler;
+
+    if (demangler != NULL)
+        result = g_compiler_demangler_decode_type(demangler, desc);
+    else
+        result = NULL;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = format binaire à consulter pour l'opération.        *
+*                desc   = chaîne de caractères à décoder.                     *
+*                                                                             *
+*  Description : Décode une chaîne de caractères donnée en routine.           *
+*                                                                             *
+*  Retour      : Instance obtenue ou NULL en cas d'échec.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinRoutine *g_binary_format_decode_routine(const GBinFormat *format, const char *desc)
+{
+    GBinRoutine *result;                    /* Construction à remonter     */
+    GCompDemangler *demangler;              /* Accès plus lisible          */
+
+    demangler = G_BIN_FORMAT(format)->demangler;
+
+    if (demangler != NULL)
+        result = g_compiler_demangler_decode_routine(demangler, desc);
+    else
+        result = NULL;
+
+    if (result == NULL)
+    {
+        result = g_binary_routine_new();
+        g_binary_routine_set_name(result, strdup(desc));
+    }
+
+    return result;
+
+}
+
+
+/* ---------------------------------------------------------------------------------- */
 /*                        RASSEMBLEMENT ET GESTION DE SYMBOLES                        */
 /* ---------------------------------------------------------------------------------- */
 
diff --git a/src/mangling/demangler.c b/src/mangling/demangler.c
index f46badd..65bdcaf 100644
--- a/src/mangling/demangler.c
+++ b/src/mangling/demangler.c
@@ -188,338 +188,3 @@ GBinRoutine *g_compiler_demangler_decode_routine(const GCompDemangler *demangler
     return result;
 
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#include <malloc.h>
-#include <string.h>
-
-
-//#include "itanium.h"
-#include "java.h"
-
-
-
-/* Indique si une chaîne peut être traitée par le décodeur. */
-typedef bool (* can_be_demangled_fc) (const char *);
-
-/* Prépare de quoi effectuer un décodage. */
-typedef GDemanglingContext * (* create_context_fc) (void);
-
-/* Procède au décodage d'une chaîne de caractères. */
-typedef bool (* demangle_fc) (GDemanglingContext *, const char *);
-
-
-
-/* Appels liés à un décodeur */
-typedef struct _demangling_properties
-{
-    can_be_demangled_fc can_demangle;       /* Possibilité de traitement   */
-
-    create_context_fc create_context;       /* Création de contextes       */
-
-    demangle_fc demangle_routine;           /* Décodage d'une routine      */
-    demangle_fc demangle_type;              /* Décodage d'un type          */
-
-} demangling_properties;
-
-
-/* Liste des décodeurs */
-static demangling_properties demanglers[/*DGT_COUNT*/] = {
-
-    /*
-    [DGT_ITANIUM] = {
-        .can_demangle = (can_be_demangled_fc)can_be_itanium_demangled,
-        .create_context = (create_context_fc)g_itanium_dcontext_new,
-        .demangle_routine = (demangle_fc)demangle_itanium_routine,
-        .demangle_type = (demangle_fc)NULL
-    },
-    */
-    /*
-    [DGT_JAVA] = {
-        .can_demangle = (can_be_demangled_fc)NULL,
-        .create_context = (create_context_fc)g_java_dcontext_new,
-        .demangle_routine = (demangle_fc)NULL,
-        .demangle_type = (demangle_fc)demangle_java_type
-    }
-    */
-};
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : desc = chaîne de caractères à décoder.                       *
-*                                                                             *
-*  Description : Tente de décoder une chaîne de caractères donnée.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBinRoutine *try_to_demangle_routine(const char *desc)
-{
-    GBinRoutine *result;                    /* Construction à remonter     */
-
-    result = g_binary_routine_new();
-    g_binary_routine_set_name(result, strdup(desc));
-
-    return result;
-
-
-#if 0
-    GBinRoutine *result;                    /* Construction à remonter     */
-    DemanglerType i;                        /* Boucle de parcours          */
-
-    static int counter = 0;
-
-    result = NULL;
-
-    if (strcmp(desc, "_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_") == 0
-        || strcmp(desc, "_ZSt12partial_sortIN9__gnu_cxx17__normal_iteratorIP28CPR_MAI_ADPTY_SectorSequenceSt6vectorIS2_SaIS2_EEEEEvT_S8_S8_") == 0
-        || strcmp(desc, "_ZSt22__merge_without_bufferIN9__gnu_cxx17__normal_iteratorIP15CProfStringListSt6vectorIS2_SaIS2_EEEEiEvT_S8_S8_T0_S9_") == 0
-        || strcmp(desc, "_ZSt11__push_heapIN9__gnu_cxx17__normal_iteratorIP8DRIVE_IDSt6vectorIS2_SaIS2_EEEEiS2_EvT_T0_S9_T1_") == 0    // Intéressant
-        //|| strcmp(desc, "") == 0
-        )
-        goto exit;
-
-    for (i = 0; i < DGT_COUNT; i++)
-    {
-        if (demanglers[i].can_demangle == NULL)
-            continue;
-
-        if (!demanglers[i].can_demangle(desc))
-            continue;
-
-        printf("++ [%d] routine :: %s\n", ++counter, desc);
-        fflush(NULL);
-
-        result = demangle_routine(i, desc);
-
-        /* FIXME : à supprimer quand mature */
-        if (result == NULL)
-        {
-            printf("++failed :: %s\n", desc);
-
-            if (strcmp(desc, "_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_") != 0
-                && strcmp(desc, "_ZSt12partial_sortIN9__gnu_cxx17__normal_iteratorIP28CPR_MAI_ADPTY_SectorSequenceSt6vectorIS2_SaIS2_EEEEEvT_S8_S8_") != 0
-                )
-                exit(-1);
-
-        }
-        else printf(" -->> '%s'\n\n", g_binary_routine_get_name(result));
-
-        if (result != NULL) break;
-
-    }
-
- exit:
-
-    if (result == NULL)
-    {
-        result = g_binary_routine_new();
-        g_binary_routine_set_name(result, strdup(desc));
-    }
-
-    return result;
-#endif
-
-    return NULL;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = type de décodeur à utiliser.                          *
-*                desc = chaîne de caractères à décoder.                       *
-*                                                                             *
-*  Description : Tente de décoder une chaîne de caractères donnée.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GBinRoutine *demangle_routine(GType type, const char *desc)
-{
-    GBinRoutine *result;                    /* Construction à remonter     */
-    GDemanglingContext *context;            /* Contexte pour le décodage   */
-
-    context = g_object_new(type, NULL);
-
-    result = g_demangling_context_get_decoded_routine(context, desc);
-
-    g_object_unref(context);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = type de décodeur à utiliser.                          *
-*                desc = chaîne de caractères à décoder.                       *
-*                                                                             *
-*  Description : Tente de décoder une chaîne de caractères donnée.            *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GDataType *demangle_type(GType type, const char *desc)
-{
-    GBinRoutine *result;                    /* Construction à remonter     */
-    GDemanglingContext *context;            /* Contexte pour le décodage   */
-
-    context = g_object_new(type, NULL);
-
-    result = g_demangling_context_get_decoded_type(context, desc);
-
-    g_object_unref(context);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Procède au test de décodages de chaînes de caractères.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-#if 0
-void test_itanium_demangling(void)
-{
-    GBinRoutine *routine;
-    char *human;
-    char stop;
-
-#define TEST_ITANIUM_MANGLING(name, ref)                            \
-    do                                                              \
-    {                                                               \
-        printf(" >> %s\n", name);                                   \
-        routine = demangle_routine(DGT_ITANIUM, name);              \
-        if (routine == NULL)                                        \
-        {                                                           \
-            printf("Error with %s\n", name);                        \
-            stop = true;                                            \
-        }                                                           \
-        else                                                        \
-        {                                                           \
-            human = g_binary_routine_to_string(routine);            \
-            printf(" >> %s\n", human);                              \
-            stop = (strcmp(ref, human) != 0);                       \
-            printf(" >> ok ? %s\n", (!stop ? "oui" : "non"));       \
-            if (stop) printf(" >> expected '%s'\n", ref);           \
-            free(human);                                            \
-        }                                                           \
-        if (stop) goto end_of_test;                                 \
-        else printf("\n");                                          \
-    }                                                               \
-    while (0)
-
-    //goto last;
-
-    /**
-     * Tests de :
-     * http://www.codesourcery.com/public/cxx-abi/abi-examples.html#mangling
-     */
-
-    TEST_ITANIUM_MANGLING("_Z1fv", "??? f(void)");
-
-    TEST_ITANIUM_MANGLING("_Z1fi", "??? f(int)");
-
-    TEST_ITANIUM_MANGLING("_Z3foo3bar", "??? foo(bar)");
-
-    TEST_ITANIUM_MANGLING("_Zrm1XS_", "??? %(X, X)");
-
-    TEST_ITANIUM_MANGLING("_ZplR1XS0_", "??? +(X &, X &)");
-
-    TEST_ITANIUM_MANGLING("_ZlsRK1XS1_", "??? <<(const X &, const X &)");
-
-    TEST_ITANIUM_MANGLING("_Z1fIiEvi", "void f<int>(int)");
-
-    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)");
-
-    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)");
-
-    TEST_ITANIUM_MANGLING("_Z3fooIiPFidEiEvv", "void foo<int, int (*)(double), int>(void)");
-
-    TEST_ITANIUM_MANGLING("_ZN6System5Sound4beepEv", "??? System::Sound::beep(void)");
-
-    TEST_ITANIUM_MANGLING("_Z1fI1XE vPV N1AIT_E1TE", "void f<X>(volatile A<X>::T *)");
-
-    //// TODO :: TEST_ITANIUM_MANGLING("_ZngILi42EE v N1A I XplT_Li2EE E 1TE", "");
-
-    TEST_ITANIUM_MANGLING("_Z4makeI7FactoryiE T_IT0_E v", "Factory<int> make<Factory, int>(void)");
-
-    TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)");
-
-    //TEST_ITANIUM_MANGLING("", "");
-
-    /**
-     * Tests de :
-     * http://www.codesourcery.com/public/cxx-abi/abi.html#mangling
-     */
-
-    TEST_ITANIUM_MANGLING("_ZN1N1TIiiE2mfES0_IddE", "??? N::T<int, int>::mf(N::T<double, double>)");
-
-    /**
-     * Tests de :
-     * (nero.so).
-     */
-
-    TEST_ITANIUM_MANGLING("_ZNSt6vectorItSaItEE6insertEN9__gnu_cxx17__normal_iteratorIPtS1_EERKt", "??? std::vector<unsigned short, std::allocator<unsigned short>>::insert(__gnu_cxx::__normal_iterator<unsigned short *, std::vector<unsigned short, std::allocator<unsigned short>>>, const unsigned short &)");
-
-    TEST_ITANIUM_MANGLING("_ZSt26__uninitialized_fill_n_auxIP15CProfStringListiS0_ET_S2_T0_RKT1_12__false_type", "CProfStringList *std::__uninitialized_fill_n_aux<CProfStringList *, int, CProfStringList>(CProfStringList *, int, const CProfStringList &, __false_type)");
-
-    // TODO TEST_ITANIUM_MANGLING("_ZN21IUDFSettingsValidator15IdNotIllegalStdEN13UDFParameters12UDF_STANDARDES1_", "");
-
-    TEST_ITANIUM_MANGLING("_ZNSbI26NeroMediumFeatureSpecifierSt11char_traitsIS_ESaIS_EE4_Rep10_M_destroyERKS2_", "??? std::basic_string<NeroMediumFeatureSpecifier, std::char_traits<NeroMediumFeatureSpecifier>, std::allocator<NeroMediumFeatureSpecifier>>::_Rep::_M_destroy(const std::allocator<NeroMediumFeatureSpecifier> &)");
-
- last:
-
-    /* 80 */
-    TEST_ITANIUM_MANGLING("_ZNSt6vectorIlSaIlEE6insertEN9__gnu_cxx17__normal_iteratorIPlS1_EERKl", "??? std::vector<long, std::allocator<long>>::insert(__gnu_cxx::__normal_iterator<long *, std::vector<long, std::allocator<long>>>, const long &)");
-
- end_of_test:
-
-    ;
-
-}
-#endif
diff --git a/src/mangling/demangler.h b/src/mangling/demangler.h
index fd209ea..2879e3c 100644
--- a/src/mangling/demangler.h
+++ b/src/mangling/demangler.h
@@ -55,36 +55,4 @@ GBinRoutine *g_compiler_demangler_decode_routine(const GCompDemangler *, const c
 
 
 
-
-
-
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////
-
-
-/* Tente de décoder une chaîne de caractères donnée. */
-GBinRoutine *try_to_demangle_routine(const char *);
-
-/* Tente de décoder une chaîne de caractères donnée. */
-GBinRoutine *demangle_routine(GType, const char *);
-
-/* Tente de décoder une chaîne de caractères donnée. */
-GDataType *demangle_type(GType, const char *);
-
-
-
-/* Procède au test de décodages de chaînes de caractères. */
-#ifdef DEBUG
-void test_itanium_demangling(void);
-#endif
-
-
-
 #endif  /* _MANGLING_DEMANGLER_H */
-- 
cgit v0.11.2-87-g4458