diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | src/format/elf/helper_x86.c | 10 | ||||
-rw-r--r-- | src/format/mangling/context-int.h | 1 | ||||
-rw-r--r-- | src/format/mangling/context.c | 20 | ||||
-rw-r--r-- | src/format/mangling/context.h | 3 | ||||
-rw-r--r-- | src/format/mangling/demangler.c | 131 | ||||
-rw-r--r-- | src/format/mangling/demangler.h | 21 | ||||
-rw-r--r-- | src/format/mangling/itanium.h | 29 | ||||
-rw-r--r-- | src/format/mangling/itanium_gram.y | 412 | ||||
-rw-r--r-- | src/main.c | 5 |
10 files changed, 405 insertions, 244 deletions
@@ -1,5 +1,22 @@ 10-08-01 Cyrille Bagard <nocbos@gmail.com> + * src/format/elf/helper_x86.c: + Print more warnings on decoding failures. + + * src/format/mangling/context.c: + * src/format/mangling/context.h: + * src/format/mangling/context-int.h: + * src/format/mangling/demangler.c: + * src/format/mangling/demangler.h: + * src/format/mangling/itanium_gram.y: + * src/format/mangling/itanium.h: + Update Itanium demangling by using the new contexts. + + * src/main.c: + Update code. + +10-08-01 Cyrille Bagard <nocbos@gmail.com> + * src/arch/artificial.c: Destroy the instruction on loading error. diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index 62464d3..d74c7dd 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -303,6 +303,7 @@ void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instru routine = g_binary_routine_new(); g_binary_routine_set_name(routine, strdup(g_binary_symbol_to_string(symbols[j]))); printf("++failed\n"); + //exit(0); } else printf("++success\n"); @@ -418,16 +419,17 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru /* Routine */ - //printf("++ routine :: %s\n", name); - //fflush(NULL); + printf("++ routine :: %s\n", name); + fflush(NULL); - routine = NULL;//try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name); + routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name); if (routine == NULL) { routine = g_binary_routine_new(); g_binary_routine_set_name(routine, strdup(name)); - //printf("++failed\n"); + printf("++failed\n"); + //exit(0); } else printf("++success\n"); 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); + +} @@ -39,7 +39,8 @@ -//extern test_itanium_demangling(name_demangler *); +#include "format/mangling/demangler.h" + /****************************************************************************** @@ -95,7 +96,7 @@ int main(int argc, char **argv) /* Création de l'interface */ - //test_itanium_demangling(get_demangler_by_type(DGT_ITANIUM)); + //test_itanium_demangling(); //exit(-1); init_internal_panels(); |