summaryrefslogtreecommitdiff
path: root/src/format/mangling/demangler.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-08-01 12:25:05 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-08-01 12:25:05 (GMT)
commit8725bd7f911369b04a507040256bf889517b377e (patch)
tree4c40501c0e5163ba5fb30207631f845ff8899df3 /src/format/mangling/demangler.c
parent290f48b2c2008a3479cd1585eb04b89c5744f034 (diff)
Updated Itanium demangling by using the new contexts.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@177 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/mangling/demangler.c')
-rw-r--r--src/format/mangling/demangler.c131
1 files changed, 130 insertions, 1 deletions
diff --git a/src/format/mangling/demangler.c b/src/format/mangling/demangler.c
index 47ffd36..de9fbbb 100644
--- a/src/format/mangling/demangler.c
+++ b/src/format/mangling/demangler.c
@@ -46,6 +46,7 @@ typedef struct _demangling_properties
{
create_context_fc create_context; /* Création de contextes */
+ demangle_type_fc demangle_routine; /* Décodage d'une routine */
demangle_type_fc demangle_type; /* Décodage d'un type */
} demangling_properties;
@@ -55,12 +56,14 @@ typedef struct _demangling_properties
static demangling_properties demanglers[DGT_COUNT] = {
[DGT_ITANIUM] = {
- .create_context = (create_context_fc)NULL,
+ .create_context = (create_context_fc)g_itanium_dcontext_new,
+ .demangle_routine = (demangle_type_fc)demangle_itanium_routine,
.demangle_type = (demangle_type_fc)NULL
},
[DGT_JAVA] = {
.create_context = (create_context_fc)g_java_dcontext_new,
+ .demangle_routine = (demangle_type_fc)NULL,
.demangle_type = (demangle_type_fc)demangle_java_type
}
@@ -131,6 +134,45 @@ GBinRoutine *try_to_demangle_routine(name_demangler *demangler, const char *name
* *
******************************************************************************/
+GBinRoutine *demangle_routine(DemanglerType type, const char *desc)
+{
+ GBinRoutine *result; /* Construction à remonter */
+ GDemanglingContext *context; /* Contexte pour le décodage */
+
+ result = NULL;
+ /*
+ if (demangler->can_be_demangled(demangler, name))
+ result = demangler->demangle_routine(demangler, name);
+ */
+
+ context = demanglers[type].create_context();
+
+ if (demanglers[type].demangle_routine(context, desc))
+ {
+ result = g_demangling_context_get_decoded_routine(context);
+ g_object_ref(result);
+ }
+
+ 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 : - *
+* *
+******************************************************************************/
+
GOpenidaType *demangle_type(DemanglerType type, const char *desc)
{
GOpenidaType *result; /* Construction à remonter */
@@ -155,3 +197,90 @@ GOpenidaType *demangle_type(DemanglerType type, const char *desc)
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 : - *
+* *
+******************************************************************************/
+#ifdef DEBUG
+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)
+
+ /**
+ * 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("", "");
+
+ end_of_test:
+
+ ;
+
+}
+#endif