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(); | 
