summaryrefslogtreecommitdiff
path: root/src/format/mangling
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
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')
-rw-r--r--src/format/mangling/context-int.h1
-rw-r--r--src/format/mangling/context.c20
-rw-r--r--src/format/mangling/context.h3
-rw-r--r--src/format/mangling/demangler.c131
-rw-r--r--src/format/mangling/demangler.h21
-rw-r--r--src/format/mangling/itanium.h29
-rw-r--r--src/format/mangling/itanium_gram.y412
7 files changed, 379 insertions, 238 deletions
diff --git a/src/format/mangling/context-int.h b/src/format/mangling/context-int.h
index e8e6ec0..ba4a1a9 100644
--- a/src/format/mangling/context-int.h
+++ b/src/format/mangling/context-int.h
@@ -36,6 +36,7 @@ struct _GDemanglingContext
union
{
+ GBinRoutine *routine; /* Routine décodée */
GOpenidaType *type; /* Type décodé */
};
diff --git a/src/format/mangling/context.c b/src/format/mangling/context.c
index 0d57937..05fc9a2 100644
--- a/src/format/mangling/context.c
+++ b/src/format/mangling/context.c
@@ -72,6 +72,26 @@ static void g_demangling_context_class_init(GDemanglingContextClass *klass)
static void g_demangling_context_init(GDemanglingContext *context)
{
+ context->routine = g_binary_routine_new();
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : context = instance à consulter. *
+* *
+* Description : Fournit la routine créé à l'issue du codage. *
+* *
+* Retour : Instance en place ou NULL en cas d'erreur fatale. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *context)
+{
+ return context->routine;
}
diff --git a/src/format/mangling/context.h b/src/format/mangling/context.h
index 3ede4da..c584838 100644
--- a/src/format/mangling/context.h
+++ b/src/format/mangling/context.h
@@ -49,6 +49,9 @@ typedef struct _GDemanglingContextClass GDemanglingContextClass;
/* Indique le type défini pour un contexte de décodage. */
GType g_demangling_context_get_type(void);
+/* Fournit la routine créé à l'issue du codage. */
+GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *);
+
/* Fournit le type créé à l'issue du codage. */
GOpenidaType *g_demangling_context_get_decoded_type(const GDemanglingContext *);
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
diff --git a/src/format/mangling/demangler.h b/src/format/mangling/demangler.h
index 0cdadb5..54ca0c0 100644
--- a/src/format/mangling/demangler.h
+++ b/src/format/mangling/demangler.h
@@ -25,9 +25,6 @@
#define _FORMAT_MANGLING_DEMANGLER_H
-#include <stdbool.h>
-
-
#include "../../analysis/routine.h"
@@ -43,11 +40,12 @@ typedef enum _DemanglerType
} DemanglerType;
-/* Décodeur de nom d'éléments */
-typedef struct _name_demangler name_demangler;
+/* Décodeur de nom d'éléments */
+typedef struct _name_demangler name_demangler;
+
/* Fournit la référence correspondant à un décodeur donné. */
name_demangler *get_demangler_by_type(DemanglerType);
@@ -55,9 +53,22 @@ name_demangler *get_demangler_by_type(DemanglerType);
GBinRoutine *try_to_demangle_routine(name_demangler *, const char *);
+
+
+
+/* Tente de décoder une chaîne de caractères donnée. */
+GBinRoutine *demangle_routine(DemanglerType, const char *);
+
/* Tente de décoder une chaîne de caractères donnée. */
GOpenidaType *demangle_type(DemanglerType, const char *);
+/* Procède au test de décodages de chaînes de caractères. */
+#ifdef DEBUG
+void test_itanium_demangling(void);
+#endif
+
+
+
#endif /* _FORMAT_MANGLING_DEMANGLER_H */
diff --git a/src/format/mangling/itanium.h b/src/format/mangling/itanium.h
index 8482af3..7cdf97e 100644
--- a/src/format/mangling/itanium.h
+++ b/src/format/mangling/itanium.h
@@ -25,12 +25,37 @@
#define _FORMAT_MANGLING_ITANIUM_H
+#include <stdbool.h>
+
+
+#include "context.h"
#include "demangler.h"
-/* Définit un décodeur répondant à la norme d'Intel. */
-name_demangler *create_itanium_demangler(void);
+/* --------------------- CONTEXTE POUR LE DECODAGE TYPE ITANIUM --------------------- */
+
+
+/* Contexte de décodage Itanium (instance) */
+typedef struct _GItaniumDContext GItaniumDContext;
+
+/* Contexte de décodage Itanium (classe) */
+typedef struct _GItaniumDContextClass GItaniumDContextClass;
+
+
+/* Prépare de quoi effectuer un décodage Itanium. */
+GDemanglingContext *g_itanium_dcontext_new(void);
+
+
+
+
+
+
+/* Procède au décodage d'une chaîne de caractères. */
+bool demangle_itanium_routine(GItaniumDContext *, const char *);
+
+
+
diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y
index e6078b0..9291f57 100644
--- a/src/format/mangling/itanium_gram.y
+++ b/src/format/mangling/itanium_gram.y
@@ -7,6 +7,7 @@
#include <string.h>
+#include "context-int.h"
#include "demangler-int.h"
#include "itanium.h"
#include "../../common/extstr.h"
@@ -18,15 +19,21 @@
*/
-/* Taille du bond pour les allocations */
-#define ITANIUM_ALLOC_CLUSTER 10
+
+/* --------------------- CONTEXTE POUR LE DECODAGE TYPE ITANIUM --------------------- */
+#define G_TYPE_ITANIUM_DCONTEXT g_itanium_dcontext_get_type()
+#define G_ITANIUM_DCONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_itanium_dcontext_get_type(), GItaniumDContext))
+#define G_IS_ITANIUM_DCONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_itanium_dcontext_get_type()))
+#define G_ITANIUM_DCONTEXT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_itanium_dcontext_get_type(), GItaniumDContextIface))
+#define G_ITANIUM_DCONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ITANIUM_DCONTEXT, GItaniumDContextClass))
-/* Décodeur de nom d'éléments selon la définition Intel */
-typedef struct _itanium_demangler
+
+/* Contexte de décodage Itanium (instance) */
+struct _GItaniumDContext
{
- name_demangler common; /* A laisser en premier */
+ GDemanglingContext parent; /* A laisser en premier */
char *identifier; /* Identifiant en construction */
size_t id_allocated; /* Taille allouée en mémoire */
@@ -35,43 +42,57 @@ typedef struct _itanium_demangler
bool use_templates; /* Utilisation des gabarits */
GSList *routines; /* Routines en cours de maj */
-} itanium_demangler;
+ GSList *substitutions; /* Empilement des types créés */
+
+};
+/* Contexte de décodage Itanium (classe) */
+struct _GItaniumDContextClass
+{
+ GDemanglingContextClass parent; /* A laisser en premier */
+
+};
+
+
+/* Taille du bond pour les allocations */
+#define ITANIUM_ALLOC_CLUSTER 10
-/* Indique si une chaîne peut être traitée par le décodeur. */
-bool can_be_itanium_demangled(itanium_demangler *, const char *);
-/* Procède au décodage d'une chaîne de caractères. */
-GBinRoutine *demangle_itanium_routine(itanium_demangler *, const char *);
+/* Indique le type défini pour un contexte de décodage. */
+static GType g_itanium_dcontext_get_type(void);
+/* Initialise la classe des contextes de décodage. */
+static void g_itanium_dcontext_class_init(GItaniumDContextClass *);
+/* Initialise une instance de contexte pour décodage. */
+static void g_itanium_dcontext_init(GItaniumDContext *);
/* Réinitialise le constructeur d'identifiants. */
-void reset_itanium_identifier_building(itanium_demangler *);
+static void g_itanium_dcontext_reset_identifier(GItaniumDContext *);
/* Construit à la volée un identifiant. */
-void build_itanium_identifier(itanium_demangler *, char);
-
+static void g_itanium_dcontext_build_identifier(GItaniumDContext *, char);
/* Place sous le feu des projecteurs une nouvelle routine. */
-static GBinRoutine *push_routine(itanium_demangler *, GBinRoutine *);
+static GBinRoutine *g_itanium_dcontext_push_routine(GItaniumDContext *, GBinRoutine *);
/* Remet une ancienne routine sous le feu des projecteurs. */
-static GBinRoutine *pop_routine(itanium_demangler *);
+static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *);
+
+/* Ajoute un élément dans une liste de substitutions. */
+static void g_itanium_dcontext_add_item(GItaniumDContext *, GOpenidaType *);
+
+/* Fournit le nième élément d'une liste de substitutions. */
+static GOpenidaType *g_itanium_dcontext_get_item(GItaniumDContext *, guint);
+
+
+
-/* Liste de substitutions */
-typedef GSList substi_list;
-/* Met en place une liste pour recueillir les substitutions. */
-static substi_list *create_substitution_list(void);
-/* Ajoute un élément dans une liste de substitutions. */
-static void add_substitution_item(substi_list *, GOpenidaType *);
-/* Fournit le nième élément d'une liste de substitutions. */
-static GOpenidaType *get_substitution_item(substi_list *, guint);
@@ -143,8 +164,7 @@ char *strmerge(char *str1, const char *sep, char *str2);
}
-%parse-param { itanium_demangler *demangler }
-%parse-param { substi_list *substitutions }
+%parse-param { GItaniumDContext *context }
%parse-param { GBinRoutine *routine }
@@ -283,7 +303,7 @@ unscoped_name:
;
unscoped_template_name:
- unscoped_name { $$ = g_template_type_new($1, NULL); add_substitution_item(substitutions, $$); }
+ unscoped_name { $$ = g_template_type_new($1, NULL); g_itanium_dcontext_add_item(context, $$); }
| substitution {
$$ = NULL;/*g_openida_type_to_string($1)*/;
/*printf("unscoped sub name :: %s\n", $$);
@@ -335,13 +355,13 @@ unqualified_name:
source_name:
- NUMBER { set_itanium_text_length($1); reset_itanium_identifier_building(demangler); }
- identifier { $$ = strdup(demangler->identifier); printf("==source name== :: %s\n", $$); }
+ NUMBER { set_itanium_text_length($1); g_itanium_dcontext_reset_identifier(context); }
+ identifier { $$ = strdup(context->identifier); printf("==source name== :: %s\n", $$); }
;
identifier:
- identifier CHAR { build_itanium_identifier(demangler, $2); }
- | CHAR { build_itanium_identifier(demangler, $1); }
+ identifier CHAR { g_itanium_dcontext_build_identifier(context, $2); }
+ | CHAR { g_itanium_dcontext_build_identifier(context, $1); }
;
operator_name:
@@ -409,10 +429,10 @@ ctor_dtor_name:
function_type:
- FF { routine = push_routine(demangler, routine); }
+ FF { routine = g_itanium_dcontext_push_routine(context, routine); }
bare_function_type EE {
$$ = g_encapsulated_type_new(ECT_ROUTINE, routine);
- routine = pop_routine(demangler);
+ routine = g_itanium_dcontext_pop_routine(context);
if (routine == NULL) YYERROR;
}
;
@@ -420,7 +440,7 @@ function_type:
type:
builtin_type { $$ = $1; printf("builtin '%s'\n", g_openida_type_to_string($1)); }
- | class_enum_type { $$ = $1; add_substitution_item(substitutions, $1); }
+ | class_enum_type { $$ = $1; g_itanium_dcontext_add_item(context, $1); }
| substitution { $$ = $1; }
| template_param { $$ = $1; }
| template_template_param template_args {
@@ -432,13 +452,13 @@ type:
| qualifiers type {
$$ = g_openida_type_dup($2);
g_openida_type_add_qualifier($$, $1);
- add_substitution_item(substitutions, $$);
+ g_itanium_dcontext_add_item(context, $$);
}
- | TP type { $$ = g_encapsulated_type_new(ECT_POINTER, $2); add_substitution_item(substitutions, $$); }
- | TR type { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); add_substitution_item(substitutions, $$); }
- | TO type { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); add_substitution_item(substitutions, $$); }
- | TC type { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); add_substitution_item(substitutions, $$); }
- | TG type { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); add_substitution_item(substitutions, $$); }
+ | TP type { $$ = g_encapsulated_type_new(ECT_POINTER, $2); g_itanium_dcontext_add_item(context, $$); }
+ | TR type { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); g_itanium_dcontext_add_item(context, $$); }
+ | TO type { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); g_itanium_dcontext_add_item(context, $$); }
+ | TC type { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); g_itanium_dcontext_add_item(context, $$); }
+ | TG type { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); g_itanium_dcontext_add_item(context, $$); }
;
qualifiers:
@@ -485,7 +505,7 @@ builtin_type:
bare_function_type:
bare_function_type type { g_binary_routine_add_arg(routine, g_binary_variable_new($2)); }
| type {
- if (demangler->use_templates)
+ if (context->use_templates)
g_binary_routine_set_return_type(routine, $1);
else
g_binary_routine_add_arg(routine, g_binary_variable_new($1));
@@ -526,7 +546,7 @@ template_args:
;
use_templates:
- II { printf("new template !!!\n"); demangler->use_templates = true; }
+ II { printf("new template !!!\n"); context->use_templates = true; }
;
template_arg_list:
@@ -554,8 +574,8 @@ substitution:
| SI { $$ = g_class_enum_type_new(CET_CLASS, "std::istream"); }
| SO { $$ = g_class_enum_type_new(CET_CLASS, "std::ostream"); }
| SD { $$ = g_class_enum_type_new(CET_CLASS, "std::iostream"); }
- | SUBSTI_FIRST { $$ = get_substitution_item(substitutions, 0); if ($$ == NULL) YYERROR; }
- | SUBSTI_N { $$ = get_substitution_item(substitutions, $1 + 1); if ($$ == NULL) YYERROR; }
+ | SUBSTI_FIRST { $$ = g_itanium_dcontext_get_item(context, 0); if ($$ == NULL) YYERROR; }
+ | SUBSTI_N { $$ = g_itanium_dcontext_get_item(context, $1 + 1); if ($$ == NULL) YYERROR; }
;
@@ -567,38 +587,21 @@ substitution:
%%
-/**
- * Affiche un message d'erreur concernant l'analyse.
- * @param yyloc informations concernant les coordonnées du soucis.
- * @param hunt indique le type de passe réalisée.
- * @param ucode code résultant compilé.
- * @param index indice de commande à mettre à jour.
- * @param msg indications humaines sur l'événement.
- * @return 0.
- */
-int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *index, */char *msg)
-{
-
-
-
- fprintf(stderr, "ERREUR !\n");
- fprintf(stderr, "%s\n", msg);
-
- return -1;
-
-}
-
-
+/* ---------------------------------------------------------------------------------- */
+/* CONTEXTE POUR LE DECODAGE TYPE ITANIUM */
+/* ---------------------------------------------------------------------------------- */
+/* Indique le type défini pour un contexte de décodage. */
+G_DEFINE_TYPE(GItaniumDContext, g_itanium_dcontext, G_TYPE_DEMANGLING_CONTEXT);
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : klass = classe à initialiser. *
* *
-* Description : Définit un décodeur répondant à la norme d'Intel. *
+* Description : Initialise la classe des contextes de décodage. *
* *
* Retour : - *
* *
@@ -606,78 +609,48 @@ int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *inde
* *
******************************************************************************/
-name_demangler *create_itanium_demangler(void)
+static void g_itanium_dcontext_class_init(GItaniumDContextClass *klass)
{
- itanium_demangler *result; /* Structure à retourner */
-
- result = (itanium_demangler *)calloc(1, sizeof(itanium_demangler));
-
- NAME_DEMANGLER(result)->can_be_demangled = (can_be_demangled_fc)can_be_itanium_demangled;
- NAME_DEMANGLER(result)->demangle_routine = (demangle_routine_fc)demangle_itanium_routine;
-
- return NAME_DEMANGLER(result);
}
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à utiliser. *
-* name = chaîne de caractères à analyser. *
+* Paramètres : context = instance à initialiser. *
* *
-* Description : Indique si une chaîne peut être traitée par le décodeur. *
+* Description : Initialise une instance de contexte pour décodage. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name)
+static void g_itanium_dcontext_init(GItaniumDContext *context)
{
- return (strncmp(name, "_Z", 2) == 0);
+ context->substitutions = g_slist_alloc();
}
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à utiliser. *
-* name = chaîne de caractères à décoder. *
+* Paramètres : - *
* *
-* Description : Procède au décodage d'une chaîne de caractères. *
+* Description : Prépare de quoi effectuer un décodage Itanium. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Instance du contexte mis en place. *
* *
* Remarques : - *
* *
******************************************************************************/
-GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *name)
+GDemanglingContext *g_itanium_dcontext_new(void)
{
- GBinRoutine *result; /* Construction à retourner */
- substi_list *substitutions; /* Liste de substitutions */
- YY_BUFFER_STATE buffer; /* Tampon pour bison */
- int ret; /* Bilan de l'appel */
+ GDemanglingContext *result; /* Structure à retourner */
- /* TODO : reset ! */
- demangler->use_templates = false;
-
- result = g_binary_routine_new();
-
- substitutions = create_substitution_list();
-
- buffer = yy_scan_string(name);
- ret = yyparse(demangler, substitutions, result);
- yy_delete_buffer(buffer);
-
- //delete(substi_list *substitutions);
-
- if (ret != 0)
- {
- /*delete_binary_routine(result); FIXME */
- result = NULL;
- }
+ result = g_object_new(G_TYPE_ITANIUM_DCONTEXT, NULL);
return result;
@@ -686,7 +659,7 @@ GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à mettre à jour. *
+* Paramètres : context = décodeur à mettre à jour. *
* *
* Description : Réinitialise le constructeur d'identifiants. *
* *
@@ -696,17 +669,17 @@ GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *
* *
******************************************************************************/
-void reset_itanium_identifier_building(itanium_demangler *demangler)
+static void g_itanium_dcontext_reset_identifier(GItaniumDContext *context)
{
- demangler->id_used = 0;
+ context->id_used = 0;
}
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à mettre à jour. *
-* value = caractère d'identifiant à mémoriser. *
+* Paramètres : context = décodeur à mettre à jour. *
+* value = caractère d'identifiant à mémoriser. *
* *
* Description : Construit à la volée un identifiant. *
* *
@@ -716,33 +689,25 @@ void reset_itanium_identifier_building(itanium_demangler *demangler)
* *
******************************************************************************/
-void build_itanium_identifier(itanium_demangler *demangler, char value)
+static void g_itanium_dcontext_build_identifier(GItaniumDContext *context, char value)
{
- if ((demangler->id_used + 2) > demangler->id_allocated)
+ if ((context->id_used + 2) > context->id_allocated)
{
- demangler->id_allocated += ITANIUM_ALLOC_CLUSTER;
- demangler->identifier = (char *)realloc(demangler->identifier,
- demangler->id_allocated * sizeof(char));
+ context->id_allocated += ITANIUM_ALLOC_CLUSTER;
+ context->identifier = (char *)realloc(context->identifier,
+ context->id_allocated * sizeof(char));
}
- demangler->identifier[demangler->id_used++] = value;
- demangler->identifier[demangler->id_used] = 0;
+ context->identifier[context->id_used++] = value;
+ context->identifier[context->id_used] = 0;
}
-
-
-
-
-
-
-
-
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à mettre à jour. *
-* previous = routine à sauvegarder. *
+* Paramètres : context = décodeur à mettre à jour. *
+* previous = routine à sauvegarder. *
* *
* Description : Place sous le feu des projecteurs une nouvelle routine. *
* *
@@ -752,13 +717,13 @@ void build_itanium_identifier(itanium_demangler *demangler, char value)
* *
******************************************************************************/
-static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *previous)
+static GBinRoutine *g_itanium_dcontext_push_routine(GItaniumDContext *context, GBinRoutine *previous)
{
GBinRoutine *result; /* Routine nouvelle à renvoyer */
result = g_binary_routine_new();
- demangler->routines = g_slist_append(demangler->routines, previous);
+ context->routines = g_slist_append(context->routines, previous);
return result;
@@ -767,7 +732,7 @@ static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *prev
/******************************************************************************
* *
-* Paramètres : demangler = décodeur à mettre à jour. *
+* Paramètres : context = décodeur à mettre à jour. *
* *
* Description : Remet une ancienne routine sous le feu des projecteurs. *
* *
@@ -777,18 +742,18 @@ static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *prev
* *
******************************************************************************/
-static GBinRoutine *pop_routine(itanium_demangler *demangler)
+static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *context)
{
GBinRoutine *result; /* Routine nouvelle à renvoyer */
GSList *last; /* Dernier élément */
- last = g_slist_last(demangler->routines);
+ last = g_slist_last(context->routines);
if (last == NULL) result = NULL;
else
{
result = G_BIN_ROUTINE(last->data);
- demangler->routines = g_slist_remove(demangler->routines, result);
+ context->routines = g_slist_remove(context->routines, result);
}
return result;
@@ -796,32 +761,10 @@ static GBinRoutine *pop_routine(itanium_demangler *demangler)
}
-
-
-
/******************************************************************************
* *
-* Paramètres : - *
-* *
-* Description : Met en place une liste pour recueillir les substitutions. *
-* *
-* Retour : Nouvelle liste vierge pour les substitutions. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static substi_list *create_substitution_list(void)
-{
- return g_slist_alloc();
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : list = ensemble des substitions enregistrées. *
-* type = nouvel élément à placer dans la liste des substitut°. *
+* Paramètres : context = décodeur à mettre à jour. *
+* type = élément à placer dans la liste des substitutions. *
* *
* Description : Ajoute un élément dans une liste de substitutions. *
* *
@@ -831,21 +774,21 @@ static substi_list *create_substitution_list(void)
* *
******************************************************************************/
-static void add_substitution_item(substi_list *list, GOpenidaType *type)
+static void g_itanium_dcontext_add_item(GItaniumDContext *context, GOpenidaType *type)
{
g_object_ref(G_OBJECT(type));
printf("push %p\n", type);
- g_slist_append(list, type);
+ context->substitutions = g_slist_append(context->substitutions, type);
}
/******************************************************************************
* *
-* Paramètres : list = ensemble des substitions enregistrées. *
-* n = indice de l'élément à fournir. *
+* Paramètres : context = décodeur à consulter. *
+* n = indice de l'élément à fournir. *
* *
* Description : Fournit le nième élément d'une liste de substitutions. *
* *
@@ -855,98 +798,107 @@ static void add_substitution_item(substi_list *list, GOpenidaType *type)
* *
******************************************************************************/
-static GOpenidaType *get_substitution_item(substi_list *list, guint n)
+static GOpenidaType *g_itanium_dcontext_get_item(GItaniumDContext *context, guint n)
{
- printf("get [%u] == %p\n", n, g_slist_nth_data(list, n + 1));
+ printf("get [%u] == %p\n", n, g_slist_nth_data(context->substitutions, n + 1));
- return G_OPENIDA_TYPE(g_slist_nth_data(list, n + 1));
+ return G_OPENIDA_TYPE(g_slist_nth_data(context->substitutions, n + 1));
}
-/******************************************************************************
-* *
-* Paramètres : demangler = décodeur à utiliser. *
-* *
-* 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(itanium_demangler *demangler)
-{
- GBinRoutine *routine;
- char *human;
- char stop;
-#define TEST_ITANIUM_MANGLING(name, ref) \
- do \
- { \
- printf(" >> %s\n", name); \
- routine = demangle_itanium_routine(demangler, 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)");
+/**
+ * Affiche un message d'erreur concernant l'analyse.
+ * @param yyloc informations concernant les coordonnées du soucis.
+ * @param hunt indique le type de passe réalisée.
+ * @param ucode code résultant compilé.
+ * @param index indice de commande à mettre à jour.
+ * @param msg indications humaines sur l'événement.
+ * @return 0.
+ */
+int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *index, */char *msg)
+{
- TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)");
- //TEST_ITANIUM_MANGLING("", "");
- end_of_test:
+ fprintf(stderr, "ERREUR !\n");
+ fprintf(stderr, "%s\n", msg);
- ;
+ return -1;
}
+
+
+
+
+
+
+#if 0
+
+/******************************************************************************
+* *
+* Paramètres : demangler = décodeur à utiliser. *
+* name = chaîne de caractères à analyser. *
+* *
+* Description : Indique si une chaîne peut être traitée par le décodeur. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name)
+{
+ return (strncmp(name, "_Z", 2) == 0);
+
+}
+
+
#endif
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : context = contexte de décodage à utiliser. *
+* desc = chaîne de caractères à décoder. *
+* *
+* Description : Procède au décodage d'une chaîne de caractères. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool demangle_itanium_routine(GItaniumDContext *context, const char *desc)
+{
+ YY_BUFFER_STATE buffer; /* Tampon pour bison */
+ int ret; /* Bilan de l'appel */
+
+ buffer = yy_scan_string(desc);
+ ret = yyparse(context, g_demangling_context_get_decoded_routine(G_DEMANGLING_CONTEXT(context)));
+ yy_delete_buffer(buffer);
+
+ return (ret == 0);
+
+}