diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2010-04-18 00:31:49 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2010-04-18 00:31:49 (GMT) | 
| commit | ef29fbc801e23f547b9ee7666b713bcf32d7e787 (patch) | |
| tree | fb7466a56e2246c53a51d0475c1b5fc70ef3b8f9 | |
| parent | 49468379e912806400c5874f8e359cb934516228 (diff) | |
Improved the Itanium demangler.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@152 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
| -rw-r--r-- | ChangeLog | 33 | ||||
| -rwxr-xr-x | src/analysis/Makefile.am | 1 | ||||
| -rw-r--r-- | src/analysis/routine.c | 96 | ||||
| -rw-r--r-- | src/analysis/routine.h | 10 | ||||
| -rw-r--r-- | src/analysis/type.c | 1377 | ||||
| -rw-r--r-- | src/analysis/type.h | 312 | ||||
| -rw-r--r-- | src/analysis/variable.c | 164 | ||||
| -rw-r--r-- | src/analysis/variable.h | 47 | ||||
| -rw-r--r-- | src/format/dwarf/Makefile.am | 2 | ||||
| -rw-r--r-- | src/format/elf/helper_x86.c | 12 | ||||
| -rw-r--r-- | src/format/mangling/Makefile.am | 2 | ||||
| -rw-r--r-- | src/format/mangling/itanium_gram.y | 515 | ||||
| -rw-r--r-- | src/format/mangling/itanium_tok.l | 12 | ||||
| -rw-r--r-- | src/main.c | 7 | 
14 files changed, 2482 insertions, 108 deletions
| @@ -1,3 +1,36 @@ +10-04-18  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/Makefile.am: +	Add the type.[ch] files to libanalysis_la_SOURCES. + +	* src/analysis/routine.c: +	* src/analysis/routine.h: +	Use the new types in routines. + +	* src/analysis/type.c: +	* src/analysis/type.h: +	New entries: define several kinds of types. + +	* src/analysis/variable.c: +	* src/analysis/variable.h: +	Create variable objects using GLib. + +	* src/format/dwarf/Makefile.am: +	Add LIBXML_CFLAGS to INCLUDES in order to fix compilation. + +	* src/format/elf/helper_x86.c: +	Disable the demangling process with symbols. + +	* src/format/mangling/itanium_gram.y: +	* src/format/mangling/itanium_tok.l: +	Improve the Itanium demangler. + +	* src/format/mangling/Makefile.am: +	Add LIBXML_CFLAGS to INCLUDES in order to fix compilation. + +	* src/main.c: +	Test the Itanium demangler. +  10-04-11  Cyrille Bagard <nocbos@gmail.com>  	* plugins/stackvars/operand.c: diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index d7f0f0e..3c22aa6 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -12,6 +12,7 @@ libanalysis_la_SOURCES =				\  	line_prologue.h line_prologue.c		\  	roptions.h roptions.c				\  	routine.h routine.c					\ +	type.h type.c						\  	variable.h variable.c  libanalysis_la_LDFLAGS =  diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 4bbd712..cfa7cd5 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -43,17 +43,15 @@ struct _GBinRoutine      RoutineType type;                       /* Type de routine             */ -    variable *ret_type;                     /* Type retourné               */ +    GOpenidaType *ret_type;                 /* Type retourné               */      char *name;                             /* Désignation humaine         */ +    GOpenidaType *full_name;                /* Désignation très complète   */ -    variable **args_types;                  /* Types d'arguments           */ -    size_t old_args_count;                      /* Nombre d'arguments          */ - -    GUnknownVariable **args;                /* Arguments de la routines    */ +    GBinVariable **args;                    /* Arguments de la routines    */      size_t args_count;                      /* Nombre d'arguments          */ -    GUnknownVariable **locals;              /* Variables locales du code   */ +    GBinVariable **locals;                  /* Variables locales du code   */      size_t locals_count;                    /* Nombre de variables locales */  }; @@ -356,6 +354,9 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name)  const char *g_binary_routine_get_name(const GBinRoutine *routine)  { +    if (routine->name == NULL && routine->full_name != NULL) +        g_binary_routine_set_name(routine, g_openida_type_to_string(routine->full_name)); +      return routine->name;  } @@ -364,7 +365,49 @@ const char *g_binary_routine_get_name(const GBinRoutine *routine)  /******************************************************************************  *                                                                             *  *  Paramètres  : routine = routine à mettre à jour.                           * -*                var     = variable représentant un type de retour.           * +*                type    = désignation complète du nom de la routine.         * +*                                                                             * +*  Description : Définit de façon indirecte le nom humain d'une routine.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_binary_routine_set_name_from_type(GBinRoutine *routine, GOpenidaType *type) +{ +    if (routine->full_name != NULL) +         g_object_unref(G_OBJECT(routine->full_name)); + +    routine->full_name = type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à consulter.                               * +*                                                                             * +*  Description : Fournit le type construisant le nom humain d'une routine.    * +*                                                                             * +*  Retour      : Eventuel type à l'origine du nom ou NULL.                    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const GOpenidaType *g_binary_routine_get_type_from_name(const GBinRoutine *routine) +{ +    return routine->full_name; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à mettre à jour.                           * +*                type    = indication sur le type de retour.                  *  *                                                                             *  *  Description : Définit le type de retour d'une routine.                     *  *                                                                             * @@ -374,12 +417,13 @@ const char *g_binary_routine_get_name(const GBinRoutine *routine)  *                                                                             *  ******************************************************************************/ -void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var) +void g_binary_routine_set_return_type(GBinRoutine *routine, GOpenidaType *type)  {      if (routine->ret_type != NULL) -        delete_var(routine->ret_type); +        g_object_unref(G_OBJECT(routine->ret_type)); -    routine->ret_type = var; +    routine->ret_type = type; +    g_object_ref(G_OBJECT(type));  } @@ -397,14 +441,14 @@ void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var)  *                                                                             *  ******************************************************************************/ -void g_binary_routine_add_arg(GBinRoutine *routine, variable *var) +void g_binary_routine_add_arg(GBinRoutine *routine, GBinVariable *var)  { -    routine->old_args_count++; +    routine->args_count++; -    routine->args_types = (variable **)realloc(routine->args_types, -                                               routine->old_args_count * sizeof(variable *)); +    routine->args = (GBinVariable **)realloc(routine->args, +                                             routine->args_count * sizeof(GBinVariable *)); -    routine->args_types[routine->old_args_count - 1] = var; +    routine->args[routine->args_count - 1] = var;  } @@ -425,6 +469,7 @@ void g_binary_routine_add_arg(GBinRoutine *routine, variable *var)  void g_binary_routine_register_if_needed(GBinRoutine *routine, size_t offset, bool local)  { +#if 0 /* FIXME */      GUnknownVariable ***list;               /* Liste à manipuler           */      size_t *count;                          /* Taille de la liste          */      bool found;                             /* Indication de présence      */ @@ -464,7 +509,7 @@ void g_binary_routine_register_if_needed(GBinRoutine *routine, size_t offset, bo      } - +#endif  } @@ -484,6 +529,7 @@ void g_binary_routine_register_if_needed(GBinRoutine *routine, size_t offset, bo  size_t g_binary_routine_get_var_index_from_offset(const GBinRoutine *routine, size_t offset, bool local)  { +#if 0 /* FIXME */      size_t result;                          /* Indice à renvoyer           */      GUnknownVariable ***list;               /* Liste à manipuler           */      size_t *count;                          /* Taille de la liste          */ @@ -507,6 +553,9 @@ size_t g_binary_routine_get_var_index_from_offset(const GBinRoutine *routine, si              result = i;      return result; +#endif + +    return SIZE_MAX;  } @@ -534,12 +583,12 @@ char *g_binary_routine_to_string(const GBinRoutine *routine)      switch (routine->type)      {          case RTT_CONSTRUCTOR: -            result = strdup(routine->name); +            result = strdup(g_binary_routine_get_name(routine));              result = stradd(result, "::");              break;          case RTT_DESTRUCTOR: -            result = strdup(routine->name); +            result = strdup(g_binary_routine_get_name(routine));              result = stradd(result, "::~");              break; @@ -548,8 +597,9 @@ char *g_binary_routine_to_string(const GBinRoutine *routine)              if (routine->ret_type == NULL) result = strdup("??? ");              else              { -                result = var_to_string(routine->ret_type); -                result = stradd(result, " "); +                result = g_openida_type_to_string(routine->ret_type); +                if (!g_openida_type_is_pointer(routine->ret_type, true)) +                    result = stradd(result, " ");              }              break; @@ -557,17 +607,17 @@ char *g_binary_routine_to_string(const GBinRoutine *routine)      /* Nom de la routine */ -    result = stradd(result, routine->name); +    result = stradd(result, g_binary_routine_get_name(routine));      /* Liste des arguments */      result = stradd(result, "("); -    for (i = 0; i < routine->old_args_count; i++) +    for (i = 0; i < routine->args_count; i++)      {          if (i > 0) result = stradd(result, ", "); -        typestr = var_to_string(routine->args_types[i]); +        typestr = g_binary_variable_to_string(routine->args[i]);          result = stradd(result, typestr);          free(typestr); diff --git a/src/analysis/routine.h b/src/analysis/routine.h index 4e47b5e..1a2b493 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -91,11 +91,17 @@ void g_binary_routine_set_name(GBinRoutine *, char *);  /* Désignation humainement lisible ou NULL si non définie. */  const char *g_binary_routine_get_name(const GBinRoutine *); +/* Définit de façon indirecte le nom humain d'une routine. */ +void g_binary_routine_set_name_from_type(GBinRoutine *, GOpenidaType *); + +/* Fournit le type construisant le nom humain d'une routine. */ +const GOpenidaType *g_binary_routine_get_type_from_name(const GBinRoutine *); +  /* Définit le type de retour d'une routine. */ -void g_binary_routine_set_return_type(GBinRoutine *, variable *); +void g_binary_routine_set_return_type(GBinRoutine *, GOpenidaType *);  /* Ajoute un argument à une routine. */ -void g_binary_routine_add_arg(GBinRoutine *, variable *); +void g_binary_routine_add_arg(GBinRoutine *, GBinVariable *);  /* S'assure qu'une variable est bien associée à une routine. */  void g_binary_routine_register_if_needed(GBinRoutine *, size_t, bool); diff --git a/src/analysis/type.c b/src/analysis/type.c new file mode 100644 index 0000000..c113499 --- /dev/null +++ b/src/analysis/type.c @@ -0,0 +1,1377 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * variable.h - prototypes pour la manipulation des variables en tout genre + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "type.h" + + +#include <malloc.h> +#include <stdarg.h> +#include <string.h> + + +#include "routine.h" +#include "../common/extstr.h" + + + +/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ + + +/* Décrit le type fourni sous forme de caractères. */ +typedef GOpenidaType * (* type_dup_fc) (const GOpenidaType *); + +/* Décrit le type fourni sous forme de caractères. */ +typedef char * (* type_to_string_fc) (const GOpenidaType *); + + +/* Description de type quelconque (instance) */ +struct _GOpenidaType +{ +    GObject parent;                         /* A laisser en premier        */ + +    type_dup_fc dup;                        /* Copie d'instance existante  */ +    type_to_string_fc to_string;            /* Conversion au format texte  */ + +    TypeQualifier qualifiers;               /* Eventuels qualificatifs     */ + +    GTypesManager *manager;                 /* Gestionnaire global         */ + +}; + +/* Description de type quelconque (classe) */ +struct _GOpenidaTypeClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types quelconques. */ +static void g_openida_type_class_init(GOpenidaTypeClass *); + +/* Initialise l'instance d'un type quelconque. */ +static void g_openida_type_init(GOpenidaType *); + + + +/* ---------------------------- TYPES DE DONNEES SIMPLES ---------------------------- */ + + +/* Description de type basique (instance) */ +struct _GBasicType +{ +    GOpenidaType parent;                    /* A laisser en premier        */ + +    BaseType type;                          /* Type représenté si connu    */ + +}; + +/* Description de type basique (classe) */ +struct _GBasicTypeClass +{ +    GOpenidaTypeClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types basiques. */ +static void g_basic_type_class_init(GBasicTypeClass *); + +/* Initialise l'instance d'un type basique. */ +static void g_basic_type_init(GBasicType *); + +/* Crée un copie d'un type existant. */ +static GOpenidaType *g_basic_type_dup(const GBasicType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_basic_type_to_string(const GBasicType *); + + + +/* -------------------------- VARIABLES DEPENDANT D'AUTRES -------------------------- */ + + +/* Description de type encapsulé (instance) */ +struct _GEncapsulatedType +{ +    GOpenidaType parent;                    /* A laisser en premier        */ + +    EncapsulationType type;                 /* Encapsulation utilisée      */ +    GOpenidaType *child;                    /* Sous-type encadré           */ +    GBinRoutine *routine;                   /* Routine pointée             */ + +}; + +/* Description de type encapsulé (classe) */ +struct _GEncapsulatedTypeClass +{ +    GOpenidaTypeClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types encapsulés. */ +static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *); + +/* Initialise l'instance d'un type encapsulé. */ +static void g_encapsulated_type_init(GEncapsulatedType *); + +/* Crée un copie d'un type existant. */ +static GOpenidaType *g_encapsulated_type_dup(const GEncapsulatedType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_encapsulated_type_to_string(const GEncapsulatedType *); + + + +/* ---------------------- CLASSES / STRUCTURES ET ENUMERATIONS ---------------------- */ + + +/* Description de type classe/structure et enumeration (instance) */ +struct _GClassEnumType +{ +    GOpenidaType parent;                    /* A laisser en premier        */ + +    ClassEnumType type;                     /* Type représenté si connu    */ +    char *name;                             /* Description humaine         */ + +}; + +/* Description de type classe/structure et enumeration (classe) */ +struct _GClassEnumTypeClass +{ +    GOpenidaTypeClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types classe ou assimilés. */ +static void g_class_enum_type_class_init(GClassEnumTypeClass *); + +/* Initialise l'instance d'un type classe ou assimilé. */ +static void g_class_enum_type_init(GClassEnumType *); + +/* Crée un copie d'un type existant. */ +static GOpenidaType *g_class_enum_type_dup(const GClassEnumType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_class_enum_type_to_string(const GClassEnumType *); + + + +/* ----------------------- ELEMENTS REPOSANT SUR DES GABARITS ----------------------- */ + + +/* Description de type reposant sur des gabarits (instance) */ +struct _GTemplateType +{ +    GClassEnumType parent;                  /* A laisser en premier        */ + +    GOpenidaType **models;                  /* Sous-types associés         */ +    size_t models_count;                    /* Quantité de ces modèles     */ + +}; + +/* Description de type reposant sur des gabarits (classe) */ +struct _GTemplateTypeClass +{ +    GClassEnumTypeClass parent;             /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types reposant sur des gabarits. */ +static void g_template_type_class_init(GTemplateTypeClass *); + +/* Initialise l'instance d'un type reposant sur des gabarits. */ +static void g_template_type_init(GTemplateType *); + +/* Crée un copie d'un type existant. */ +static GOpenidaType *g_template_type_dup(const GTemplateType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_template_type_to_string(const GTemplateType *); + + + +/* ---------------------- VALEUR LITERALE DES TYPES INSTANCIES ---------------------- */ + + +/* Description de type instancié avec une valeur litérale (instance) */ +struct _GLiteralType +{ +    GOpenidaType parent;                    /* A laisser en premier        */ + +    GOpenidaType *orig;                     /* Type instancié              */ +    literal_value value;                    /* Valeur d'instance           */ + +}; + +/* Description de type instancié avec une valeur litérale (classe) */ +struct _GLiteralTypeClass +{ +    GOpenidaTypeClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des types instanciés avec des valeurs. */ +static void g_literal_type_class_init(GLiteralTypeClass *); + +/* Initialise l'instance d'un type instancié avec une valeur. */ +static void g_literal_type_init(GLiteralType *); + +/* Crée un copie d'un type existant. */ +static GOpenidaType *g_literal_type_dup(const GLiteralType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_literal_type_to_string(const GLiteralType *); + + + +/* -------------------------- COLLECTE ET GESTION DE TYPES -------------------------- */ + + +/* Description de type quelconque (instance) */ +struct _GTypesManager +{ +    GObject parent;                         /* A laisser en premier        */ + +    MemoryDataSize wdsize;                  /* Taille d'un mot en octet    */ + +}; + +/* Description de type quelconque (classe) */ +struct _GTypesManagerClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des gestionnaires de types. */ +static void g_types_manager_class_init(GTypesManagerClass *); + +/* Initialise l'instance d'un gestionnaire de types. */ +static void g_types_manager_init(GTypesManager *manager); + + + +/* ---------------------------------------------------------------------------------- */ +/*                          REPRESENTATION INTERNE DES TYPES                          */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type quelconque. */ +G_DEFINE_TYPE(GOpenidaType, g_openida_type, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types quelconques.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_openida_type_class_init(GOpenidaTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type quelconque.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_openida_type_init(GOpenidaType *type) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_openida_type_dup(const GOpenidaType *type) +{ +    return type->dup(type); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *g_openida_type_to_string(const GOpenidaType *type) +{ +    char *result;                           /* Chaîne à retourner          */ + +    result = type->to_string(type); + +    if (type->qualifiers & TQF_RESTRICT) +        strprep(result, "restrict "); + +    if (type->qualifiers & TQF_VOLATILE) +        strprep(result, "volatile "); + +    if (type->qualifiers & TQF_CONST) +        strprep(result, "const "); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type      = instance à mettre à jour.                        * +*                qualifier = nouveau qualificatif pour la variable.           * +*                                                                             * +*  Description : Ajoute un qualificatif à une instance de type.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_openida_type_add_qualifier(GOpenidaType *type, TypeQualifier qualifier) +{ +    type->qualifiers |= qualifier; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à analyser.                                      * +*                large = doit-on aussi inclure les types 'référence' ?        * +*                                                                             * +*  Description : Indique la terminaison de la représentation du type.         * +*                                                                             * +*  Retour      : true ou false, selon le type fourni.                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_openida_type_is_pointer(const GOpenidaType *type, bool large) +{ +    bool result;                            /* Bilan à retourner           */ + +    result = G_IS_ENCAPSULATED_TYPE(type); + +    if (result) +        switch (G_ENCAPSULATED_TYPE(type)->type) +        { +            case ECT_POINTER: +                result = true; +                break; +            case ECT_REFERENCE: +            case ECT_RVALUE_REF: +                result = large; +                break; +            default: +                result = false; +                break; +        } + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                              TYPES DE DONNEES SIMPLES                              */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type basique. */ +G_DEFINE_TYPE(GBasicType, g_basic_type, G_TYPE_OPENIDA_TYPE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types basiques.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_basic_type_class_init(GBasicTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type basique.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_basic_type_init(GBasicType *type) +{ +    GOpenidaType *oida_type;                /* Version basique             */ + +    oida_type = G_OPENIDA_TYPE(type); + +    oida_type->dup = (type_dup_fc)g_basic_type_dup; +    oida_type->to_string = (type_to_string_fc)g_basic_type_to_string; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type simple à représenter.                            * +*                                                                             * +*  Description : Crée une représentation de type basique.                     * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_basic_type_new(BaseType type) +{ +    GBasicType *result;                 /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_BASIC_TYPE, NULL); + +    result->type = type; + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *g_basic_type_dup(const GBasicType *type) +{ +    return g_basic_type_new(type->type); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_basic_type_to_string(const GBasicType *type) +{ +    const char *desc;                       /* Représentation à copier     */ + +    switch (type->type) +    { +        case BTP_VOID: +            desc = "void"; +            break; + +        case BTP_WCHAR_T: +            desc = "wchar_t"; +            break; + +        case BTP_BOOL: +            desc = "bool"; +            break; + +        case BTP_CHAR: +            desc = "char"; +            break; + +        case BTP_SCHAR: +            desc = "signed char"; +            break; + +        case BTP_UCHAR: +            desc = "unsigned char"; +            break; + +        case BTP_SHORT: +            desc = "short"; +            break; + +        case BTP_USHORT: +            desc = "unsigned short"; +            break; + +        case BTP_INT: +            desc = "int"; +            break; + +        case BTP_UINT: +            desc = "unsigned int"; +            break; + +        case BTP_LONG: +            desc = "long"; +            break; + +        case BTP_ULONG: +            desc = "unsigned long"; +            break; + +        case BTP_LONG_LONG: +            desc = "long long"; +            break; + +        case BTP_ULONG_LONG: +            desc = "unsigned long long"; +            break; + +        case BTP_INT128: +            desc = "__int128"; +            break; + +        case BTP_UINT128: +            desc = "unsigned __int128"; +            break; + +        case BTP_FLOAT: +            desc = "float"; +            break; + +        case BTP_DOUBLE: +            desc = "double"; +            break; + +        case BTP_LONG_DOUBLE: +            desc = "long double"; +            break; + +        case BTP_FLOAT128: +            desc = "__float128"; +            break; + +        case BTP_ELLIPSIS: +            desc = "..."; +            break; + +        case BTP_754R_64: +            desc = "__float754r_64"; +            break; + +        case BTP_754R_128: +            desc = "__float754r_128"; +            break; + +        case BTP_754R_32: +            desc = "__float754r_32"; +            break; + +        case BTP_754R_16: +            desc = "__float754r_16"; +            break; + +        case BTP_CHAR32_T: +            desc = "char32_t"; +            break; + +        case BTP_CHAR16_T: +            desc = "char16_t"; +            break; + +        default: +        case BTP_OTHER: +            desc = "user"; +            break; + +    } + +    return strdup(desc); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                            VARIABLES DEPENDANT D'AUTRES                            */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type encapsulé. */ +G_DEFINE_TYPE(GEncapsulatedType, g_encapsulated_type, G_TYPE_OPENIDA_TYPE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types encapsulés.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type encapsulé.                   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_encapsulated_type_init(GEncapsulatedType *type) +{ +    GOpenidaType *oida_type;                /* Version basique             */ + +    oida_type = G_OPENIDA_TYPE(type); + +    oida_type->dup = (type_dup_fc)g_encapsulated_type_dup; +    oida_type->to_string = (type_to_string_fc)g_encapsulated_type_to_string; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type  = type d'extension à représenter.                      * +*                child = variable dont on doit dériver.                       * +*                                                                             * +*  Description : Crée une représentation de variable dérivée.                 * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_encapsulated_type_new(EncapsulationType type, ...) +{ +    GEncapsulatedType *result;              /* Structure à retourner       */ +    va_list ap;                             /* Liste variable d'arguments  */ + +    result = g_object_new(G_TYPE_ENCAPSULATED_TYPE, NULL); + +    result->type = type; + +    va_start(ap, type); + +    switch (type) +    { +        case ECT_ROUTINE: +            result->routine = va_arg(ap, GBinRoutine *); +            g_binary_routine_set_name(result->routine, "(*)"); +            break; + +        default: +            result->child = va_arg(ap, GOpenidaType *); +            break; + +    } + +    va_end(ap); + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *g_encapsulated_type_dup(const GEncapsulatedType *type) +{ +    GOpenidaType *result;                   /* Nouvelle instance à renvoyer*/ +    GOpenidaType *child;                    /* Copie du type interne       */ + +    switch (type->type) +    { +        case ECT_ROUTINE: +            g_object_ref(G_OBJECT(type->routine)); +            result = g_encapsulated_type_new(type->type, type->routine); +            break; + +        default: +            child = g_openida_type_dup(type->child); +            result = g_encapsulated_type_new(type->type, child); +            break; + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) +{ +    char *result;                           /* Chaîne finale à renvoyer    */ + +    switch (type->type) +    { +        case ECT_ROUTINE: +            result = g_binary_routine_to_string(type->routine); +            break; + +        default: +            result = g_openida_type_to_string(type->child); +            break; + +    } + +    switch (type->type) +    { +        case ECT_POINTER: + +            if (G_IS_ENCAPSULATED_TYPE(type->child) +                && G_ENCAPSULATED_TYPE(type->child)->type == ECT_ROUTINE) break; + +            if (!g_openida_type_is_pointer(type->child, false)) +                result = stradd(result, " "); +            result = stradd(result, "*"); + +            break; + +        case ECT_REFERENCE: +            result = stradd(result, " &"); +            break; +        case ECT_RVALUE_REF: +            result = stradd(result, " &&"); +            break; +        case ECT_COMPLEX: +            result = stradd(result, " complex"); +            break; +        case ECT_IMAGINARY: +            result = stradd(result, " imaginary"); +            break; + +        default: +            break; + +    } + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                        CLASSES / STRUCTURES ET ENUMERATIONS                        */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type classe ou assimilé. */ +G_DEFINE_TYPE(GClassEnumType, g_class_enum_type, G_TYPE_OPENIDA_TYPE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types classe ou assimilés.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type classe ou assimilé.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_class_enum_type_init(GClassEnumType *type) +{ +    GOpenidaType *oida_type;                /* Version basique             */ + +    oida_type = G_OPENIDA_TYPE(type); + +    oida_type->dup = (type_dup_fc)g_class_enum_type_dup; +    oida_type->to_string = (type_to_string_fc)g_class_enum_type_to_string; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type de structure à représenter.                      * +*                name = désignation humaine du type.                          * +*                                                                             * +*  Description : Crée une représentation de classe, structure ou énumération. * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_class_enum_type_new(ClassEnumType type, const char *name) +{ +    GClassEnumType *result;                 /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_CLASS_ENUM_TYPE, NULL); + +    result->type = type; +    result->name = strdup(name); + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *g_class_enum_type_dup(const GClassEnumType *type) +{ +    return g_class_enum_type_new(type->type, type->name); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_class_enum_type_to_string(const GClassEnumType *type) +{ +    return strdup(type->name); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                         ELEMENTS REPOSANT SUR DES GABARITS                         */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type reposant sur des gabarits. */ +G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types reposant sur des gabarits.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_template_type_class_init(GTemplateTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type reposant sur des gabarits.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_template_type_init(GTemplateType *type) +{ +    GOpenidaType *oida_type;                /* Version basique             */ +    GClassEnumType *ce_type;                /* Version basique #2          */ + +    oida_type = G_OPENIDA_TYPE(type); + +    oida_type->dup = (type_dup_fc)g_template_type_dup; +    oida_type->to_string = (type_to_string_fc)g_template_type_to_string; + +    ce_type = G_CLASS_ENUM_TYPE(type); + +    ce_type->type = CET_CLASS; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : name = désignation humaine du type.                          * +*                list = élements du modèle sur lequel doit reposer le type.   * +*                                                                             * +*  Description : Crée une représentation de type reposant sur des gabarits.   * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_template_type_new(const char *name, GSList *list) +{ +    GTemplateType *result;                  /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_TEMPLATE_TYPE, NULL); + +    G_CLASS_ENUM_TYPE(result)->name = strdup(name); + +    g_template_type_add_params(result, list); + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *g_template_type_dup(const GTemplateType *type) +{ +    GOpenidaType *result;                   /* Copie à retourner           */ +    GSList *list;                           /* Format de liste à fournir   */ +    size_t i;                               /* Boucle de parcours          */ + +    list = NULL; + +    for (i = 0; i < type->models_count; i++) +        list = g_slist_prepend(list, type->models[i]); + +    result = g_template_type_new(G_CLASS_ENUM_TYPE(type)->name, list); + +    g_slist_free(list); + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_template_type_to_string(const GTemplateType *type) +{ +    char *result;                           /* Valeur à renvoyer           */ +    size_t i;                               /* Boucle de parcours          */ +    char *sub;                              /* Sous-type à décrire         */ + +    result = g_class_enum_type_to_string(G_CLASS_ENUM_TYPE(type)); + +    result = stradd(result, "<"); + +    for (i = 0; i < type->models_count; i++) +    { +        if (i > 0) result = stradd(result, ", "); + +        sub = g_openida_type_to_string(type->models[i]); +        result = stradd(result, sub); +        free(sub); + +    } + +    result = stradd(result, ">"); + +    return result; + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à mettre à jour.                                 * +*                list = élements du modèle sur lequel doit reposer le type.   * +*                                                                             * +*  Description : Ajoute une série de paramètres à un gabarit.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : La liste doit contenir des éléments dans l'ordre inverse     * +*                d'apparition. De plus, elle est libérée dans cette fonction. * +*                                                                             * +******************************************************************************/ + +void g_template_type_add_params(GTemplateType *type, GSList *list) +{ +    GSList *iter;                           /* Boucle de parcours          */ + +    list = g_slist_reverse(list); +    for (iter = list; iter != NULL; iter = g_slist_next(iter)) +    { +        type->models = (GOpenidaType **)realloc(type->models, +                                                ++type->models_count * sizeof(GOpenidaType *)); +        type->models[type->models_count - 1] = G_OPENIDA_TYPE(iter->data); +    } +    g_slist_free(list); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type  = type à consulter.                                    * +*                index = indice du paramètre à retourner.                     * +*                                                                             * +*  Description : Fournit un paramètre donné du gabarit.                       * +*                                                                             * +*  Retour      : Type inclus dans le modèle ou NULL si mauvais indice.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_template_type_get_param(const GTemplateType *type, size_t index) +{ +    return (index < type->models_count ? type->models[index] : NULL); + +} + + +/* ---------------------------------------------------------------------------------- */ +/*                        VALEUR LITERALE DES TYPES INSTANCIES                        */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un type reposant sur des gabarits. */ +G_DEFINE_TYPE(GLiteralType, g_literal_type, G_TYPE_OPENIDA_TYPE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des types instanciés avec des valeurs.  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_literal_type_class_init(GLiteralTypeClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise l'instance d'un type instancié avec une valeur.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_literal_type_init(GLiteralType *type) +{ +    GOpenidaType *oida_type;                /* Version basique             */ + +    oida_type = G_OPENIDA_TYPE(type); + +    oida_type->dup = (type_dup_fc)g_literal_type_dup; +    oida_type->to_string = (type_to_string_fc)g_literal_type_to_string; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : orig  = type d'origine instancié.                            * +*                value = valeur de l'instanciation.                           * +*                                                                             * +*  Description : Crée une représentation de type instancié avec une valeur.   * +*                                                                             * +*  Retour      : Adresse de la structure mise en place.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GOpenidaType *g_literal_type_new(GOpenidaType *orig, literal_value value) +{ +    GLiteralType *result;                   /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_LITERAL_TYPE, NULL); + +    result->orig = orig; +    result->value = value; + +    g_object_ref(orig); + +    return G_OPENIDA_TYPE(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à dupliquer.                                     * +*                                                                             * +*  Description : Crée un copie d'un type existant.                            * +*                                                                             * +*  Retour      : Nouvelle instance de type identique à celle fournie.         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *g_literal_type_dup(const GLiteralType *type) +{ +    GOpenidaType *orig;                     /* Copie du type interne       */ + +    orig = g_openida_type_dup(type->orig); + +    return g_literal_type_new(orig, type->value); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type à convertir.                                     * +*                                                                             * +*  Description : Décrit le type fourni sous forme de caractères.              * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static char *g_literal_type_to_string(const GLiteralType *type) +{ +    char *result;                           /* Valeur à renvoyer           */ +    size_t max;                             /* Longueur totale du texte    */ + +    if (G_IS_BASIC_TYPE(type->orig)) +        switch (G_BASIC_TYPE(type->orig)->type) +        { +            case BTP_BOOL: +                result = strdup(type->value.int_val ? "true" : "false"); +                break; + +            case BTP_INT: +                max = strlen("2147483647" /* INT_MAX */) + 1; +                result = (char *)calloc(max, sizeof(char)); +                snprintf(result, max, "%d", type->value.int_val); +                break; + +            default: +                result = strdup("TODO"); +                break; + +    } +    else result = strdup("???"); + +    return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                            COLLECTE ET GESTION DE TYPES                            */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un gestionnaire de types. */ +G_DEFINE_TYPE(GTypesManager, g_types_manager, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des gestionnaires de types.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_types_manager_class_init(GTypesManagerClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : manager = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise l'instance d'un gestionnaire de types.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_types_manager_init(GTypesManager *manager) +{ + +} diff --git a/src/analysis/type.h b/src/analysis/type.h new file mode 100644 index 0000000..b127eb3 --- /dev/null +++ b/src/analysis/type.h @@ -0,0 +1,312 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * variable.h - prototypes pour la manipulation des variables en tout genre + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_TYPE_H +#define _ANALYSIS_TYPE_H + + +#include <glib.h> +#include <glib-object.h> + + +#include "../arch/archbase.h" +#include "../arch/processor.h" + + + +/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ + + +#define G_TYPE_OPENIDA_TYPE               g_openida_type_get_type() +#define G_OPENIDA_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_openida_type_get_type(), GOpenidaType)) +#define G_IS_OPENIDA_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_openida_type_get_type())) +#define G_OPENIDA_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_OPENIDA_TYPE, GOpenidaTypeClass)) +#define G_IS_OPENIDA_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_OPENIDA_TYPE)) +#define G_OPENIDA_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_OPENIDA_TYPE, GOpenidaTypeClass)) + + +/* Description de type quelconque (instance) */ +typedef struct _GOpenidaType GOpenidaType; + +/* Description de type quelconque (classe) */ +typedef struct _GOpenidaTypeClass GOpenidaTypeClass; + + +/* Qualificatifs de variables */ +typedef enum _TypeQualifier +{ +    TQF_RESTRICT    = (1 << 0),             /* restrict (C99)              */ +    TQF_VOLATILE    = (1 << 1),             /* volatile                    */ +    TQF_CONST       = (1 << 2)              /* const                       */ + +} TypeQualifier; + + +/* Indique le type défini pour un type quelconque. */ +GType g_openida_type_get_type(void); + +/* Crée un copie d'un type existant. */ +GOpenidaType *g_openida_type_dup(const GOpenidaType *); + +/* Décrit le type fourni sous forme de caractères. */ +char *g_openida_type_to_string(const GOpenidaType *); + +/* Ajoute un qualificatif à une instance de type. */ +void g_openida_type_add_qualifier(GOpenidaType *, TypeQualifier); + +/* Indique la terminaison de la représentation du type. */ +bool g_openida_type_is_pointer(const GOpenidaType *, bool); + + + +/* ---------------------------- TYPES DE DONNEES SIMPLES ---------------------------- */ + + +/* Liste des types de base existants */ +typedef enum _BaseType +{ +    BTP_VOID,                               /* void                        */ +    BTP_WCHAR_T,                            /* wchar_t                     */ +    BTP_BOOL,                               /* bool                        */ +    BTP_CHAR,                               /* char                        */ +    BTP_SCHAR,                              /* signed char                 */ +    BTP_UCHAR,                              /* unsigned char               */ +    BTP_SHORT,                              /* short                       */ +    BTP_USHORT,                             /* unsigned short              */ +    BTP_INT,                                /* int                         */ +    BTP_UINT,                               /* unsigned int                */ +    BTP_LONG,                               /* long                        */ +    BTP_ULONG,                              /* unsigned long               */ +    BTP_LONG_LONG,                          /* long long, __int64          */ +    BTP_ULONG_LONG,                         /* unsigned long long, __int64 */ +    BTP_INT128,                             /* __int128                    */ +    BTP_UINT128,                            /* unsigned __int128           */ +    BTP_FLOAT,                              /* float                       */ +    BTP_DOUBLE,                             /* double                      */ +    BTP_LONG_DOUBLE,                        /* long double, __float80      */ +    BTP_FLOAT128,                           /* __float128                  */ +    BTP_ELLIPSIS,                           /* ...                         */ +    BTP_754R_64,                            /* IEEE 754r float (64 bits)   */ +    BTP_754R_128,                           /* IEEE 754r float (128 bits)  */ +    BTP_754R_32,                            /* IEEE 754r float (32 bits)   */ +    BTP_754R_16,                            /* IEEE 754r float (16 bits)   */ +    BTP_CHAR32_T,                           /* char32_t                    */ +    BTP_CHAR16_T,                           /* char16_t                    */ +    BTP_OTHER                               /* Extension utilisateur       */ + +} BaseType; + + +#define G_TYPE_BASIC_TYPE               g_basic_type_get_type() +#define G_BASIC_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_basic_type_get_type(), GBasicType)) +#define G_IS_BASIC_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_basic_type_get_type())) +#define G_BASIC_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_TYPE, GBasicTypeClass)) +#define G_IS_BASIC_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_TYPE)) +#define G_BASIC_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_TYPE, GBasicTypeClass)) + + +/* Description de type basique (instance) */ +typedef struct _GBasicType GBasicType; + +/* Description de type basique (classe) */ +typedef struct _GBasicTypeClass GBasicTypeClass; + + +/* Indique le type défini pour un type basique. */ +GType g_basic_type_get_type(void); + +/* Crée une représentation de type basique. */ +GOpenidaType *g_basic_type_new(BaseType); + + + +/* -------------------------- VARIABLES DEPENDANT D'AUTRES -------------------------- */ + + +#define G_TYPE_ENCAPSULATED_TYPE               g_encapsulated_type_get_type() +#define G_ENCAPSULATED_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_encapsulated_type_get_type(), GEncapsulatedType)) +#define G_IS_ENCAPSULATED_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_encapsulated_type_get_type())) +#define G_ENCAPSULATED_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) +#define G_IS_ENCAPSULATED_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPSULATED_TYPE)) +#define G_ENCAPSULATED_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) + + +/* Description de type encapsulé (instance) */ +typedef struct _GEncapsulatedType GEncapsulatedType; + +/* Description de type encapsulé (classe) */ +typedef struct _GEncapsulatedTypeClass GEncapsulatedTypeClass; + + +/* Cas d'encapsulation possibles */ +typedef enum _EncapsulationType +{ +    ECT_POINTER,                            /* Pointeur                    */ +    ECT_REFERENCE,                          /* Référence                   */ +    ECT_RVALUE_REF,                         /* Référence ?? (C++0x)        */ +    ECT_COMPLEX,                            /* Complexe (C 2000)           */ +    ECT_IMAGINARY,                          /* Imaginaire (C 2000)         */ + +    ECT_ROUTINE                             /* Pointeur vers une routine   */ + +} EncapsulationType; + + +/* Indique le type défini pour un type encapsulé. */ +GType g_encapsulated_type_get_type(void); + +/* Crée une représentation de variable dérivée. */ +GOpenidaType *g_encapsulated_type_new(EncapsulationType, ...); + + + +/* ---------------------- CLASSES / STRUCTURES ET ENUMERATIONS ---------------------- */ + + +#define G_TYPE_CLASS_ENUM_TYPE               g_class_enum_type_get_type() +#define G_CLASS_ENUM_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_class_enum_type_get_type(), GClassEnumType)) +#define G_IS_CLASS_ENUM_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_class_enum_type_get_type())) +#define G_CLASS_ENUM_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) +#define G_IS_CLASS_ENUM_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CLASS_ENUM_TYPE)) +#define G_CLASS_ENUM_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) + + +/* Description de type classe/structure et enumeration (instance) */ +typedef struct _GClassEnumType GClassEnumType; + +/* Description de type classe/structure et enumeration (classe) */ +typedef struct _GClassEnumTypeClass GClassEnumTypeClass; + + +/* Type pris en compte */ +typedef enum _ClassEnumType +{ +    CET_UNKNOWN,                            /* Statut inconnu              */ +    CET_STRUCT,                             /* Structure                   */ +    CET_ENUM,                               /* Enumération                 */ +    CET_CLASS                               /* Classe                      */ + +} ClassEnumType; + + +/* Indique le type défini pour un type classe ou assimilé. */ +GType g_class_enum_type_get_type(void); + +/* Crée une représentation de classe, structure ou énumération. */ +GOpenidaType *g_class_enum_type_new(ClassEnumType, const char *); + + + +/* ----------------------- ELEMENTS REPOSANT SUR DES GABARITS ----------------------- */ + + +#define G_TYPE_TEMPLATE_TYPE               g_template_type_get_type() +#define G_TEMPLATE_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_template_type_get_type(), GTemplateType)) +#define G_IS_TEMPLATE_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_template_type_get_type())) +#define G_TEMPLATE_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) +#define G_IS_TEMPLATE_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TEMPLATE_TYPE)) +#define G_TEMPLATE_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) + + +/* Description de type reposant sur des gabarits (instance) */ +typedef struct _GTemplateType GTemplateType; + +/* Description de type reposant sur des gabarits (classe) */ +typedef struct _GTemplateTypeClass GTemplateTypeClass; + + +/* Indique le type défini pour un type reposant sur des gabarits. */ +GType g_template_type_get_type(void); + +/* Crée une représentation de type reposant sur des gabarits. */ +GOpenidaType *g_template_type_new(const char *, GSList *); + +/* Ajoute une série de paramètres à un gabarit. */ +void g_template_type_add_params(GTemplateType *, GSList *); + +/* Fournit un paramètre donné du gabarit. */ +GOpenidaType *g_template_type_get_param(const GTemplateType *, size_t); + + + +/* ---------------------- VALEUR LITERALE DES TYPES INSTANCIES ---------------------- */ + + +#define G_TYPE_LITERAL_TYPE               g_literal_type_get_type() +#define G_LITERAL_TYPE(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_literal_type_get_type(), GLiteralType)) +#define G_IS_LITERAL_TYPE(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_literal_type_get_type())) +#define G_LITERAL_TYPE_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) +#define G_IS_LITERAL_TYPE_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_TYPE)) +#define G_LITERAL_TYPE_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) + + +/* Description de type instancié avec une valeur litérale (instance) */ +typedef struct _GLiteralType GLiteralType; + +/* Description de type instancié avec une valeur litérale (classe) */ +typedef struct _GLiteralTypeClass GLiteralTypeClass; + + +/* Valeurs instanciées supportées */ +typedef union _literal_value +{ +    int int_val;                            /* Valeur entière              */ +    float float_val;                        /* Valeur flottante            */ + +} literal_value; + + +/* Indique le type défini pour un type instancié avec une valeur litérale. */ +GType g_literal_type_get_type(void); + +/* Crée une représentation de type instancié avec une valeur. */ +GOpenidaType *g_literal_type_new(GOpenidaType *, literal_value); + + + +/* -------------------------- COLLECTE ET GESTION DE TYPES -------------------------- */ + + +#define G_TYPE_TYPES_MANAGER               g_types_manager_get_type() +#define G_TYPES_MANAGER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_types_manager_get_type(), GTypesManager)) +#define G_IS_TYPES_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_types_manager_get_type())) +#define G_TYPES_MANAGER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TYPES_MANAGER, GTypesManagerClass)) +#define G_IS_TYPES_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TYPES_MANAGER)) +#define G_TYPES_MANAGER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TYPES_MANAGER, GTypesManagerClass)) + + +/* Description d'un gestionnaire de types (instance) */ +typedef struct _GTypesManager GTypesManager; + +/* Description d'un gestionnaire de types (classe) */ +typedef struct _GTypesManagerClass GTypesManagerClass; + + +/* Indique le type défini pour un gestionnaire de types. */ +GType g_types_manager_get_type(void); + + + + + +#endif  /* _ANALYSIS_TYPE_H */ diff --git a/src/analysis/variable.c b/src/analysis/variable.c index 01c780e..e24f7e1 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -24,6 +24,162 @@  #include "variable.h" +#include "../common/extstr.h" + + + +/* ------------------- ASSOCIATION D'UN TYPE ET D'UNE DESIGNATION ------------------- */ + + +/* Variable typée (instance) */ +struct _GBinVariable +{ +    GObject parent;                         /* A laisser en premier        */ + +    GOpenidaType *type;                     /* Type de la variable         */ +    char *name;                             /* Désignation humaine         */ + +}; + +/* Variable typée (classe) */ +struct _GBinVariableClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +}; + + +/* Initialise la classe des variables. */ +static void g_binary_variable_class_init(GBinVariableClass *); + +/* Initialise l'instande d'une variable. */ +static void g_binary_variable_init(GBinVariable *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                     ASSOCIATION D'UN TYPE ET D'UNE DESIGNATION                     */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une base de variable. */ +G_DEFINE_TYPE(GBinVariable, g_binary_variable, G_TYPE_OBJECT); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des variables.                          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_variable_class_init(GBinVariableClass *klass) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var = instance à initialiser.                                * +*                                                                             * +*  Description : Initialise l'instande d'une variable.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_variable_init(GBinVariable *var) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = type de la variable à mettre en place.                * +*                                                                             * +*  Description : Crée une représentation de variable de type donné.           * +*                                                                             * +*  Retour      : Variable mise en place.                                      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBinVariable *g_binary_variable_new(GOpenidaType *type) +{ +    GBinVariable *result;               /* Variable à retourner        */ + +    result = g_object_new(G_TYPE_BIN_VARIABLE, NULL); + +    result->type = type; +    g_object_ref(G_OBJECT(type)); + +    return result; + +} + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : var = variable à convertir.                                  * +*                                                                             * +*  Description : Décrit la variable donnée sous forme de caractères.          * +*                                                                             * +*  Retour      : Chaîne à libérer de la mémoire après usage.                  * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *g_binary_variable_to_string(const GBinVariable *var) +{ +    char *result;                           /* Valeur à retourner          */ + +    result = g_openida_type_to_string(var->type); + +    if (var->name != NULL) +    { +        if (!g_openida_type_is_pointer(var->type, true)) +            result = stradd(result, " "); + +        result = stradd(result, var->name); + +    } + +    return result; + +} + + + + + + + + + + + + + + + +  #include <malloc.h>  #include <stdint.h>  #include <string.h> @@ -34,6 +190,14 @@ + + + + + + + +  /* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ diff --git a/src/analysis/variable.h b/src/analysis/variable.h index f2bbb87..ab5a037 100644 --- a/src/analysis/variable.h +++ b/src/analysis/variable.h @@ -29,6 +29,46 @@  #include <glib-object.h> +#include "type.h" + + + +/* ------------------- ASSOCIATION D'UN TYPE ET D'UNE DESIGNATION ------------------- */ + + +#define G_TYPE_BIN_VARIABLE                 g_binary_variable_get_type() +#define G_BINARY_VARIABLE(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_binary_variable_get_type(), GBinVariable)) +#define G_IS_BIN_VARIABLE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_binary_variable_get_type())) +#define G_BINARY_VARIABLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BIN_VARIABLE, GBinVariableClass)) +#define G_IS_BIN_VARIABLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BIN_VARIABLE)) +#define G_BINARY_VARIABLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BIN_VARIABLE, GBinVariableClass)) + + +/* Base de variable (instance) */ +typedef struct _GBinVariable GBinVariable; + +/* Base de variable (classe) */ +typedef struct _GBinVariableClass GBinVariableClass; + + +/* Indique le type défini pour une base de variable. */ +GType g_binary_variable_get_type(void); + +/* Crée une représentation de variable de type donné. */ +GBinVariable *g_binary_variable_new(GOpenidaType *); + + + + +/* Décrit la variable donnée sous forme de caractères. */ +char *g_binary_variable_to_string(const GBinVariable *); + + + + + + +  /* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ @@ -79,6 +119,7 @@ typedef struct _variable variable;  /* Liste des types de base existants */ +#if 0  typedef enum _BaseType  {      BTP_VOID,                               /* void                        */ @@ -111,7 +152,7 @@ typedef enum _BaseType      BTP_OTHER                               /* Extension utilisateur       */  } BaseType; - +#endif  /* Variable repésentant un argument ou un type de retour */ @@ -144,6 +185,7 @@ typedef struct _complex_variable complex_variable;  /* Type de ces variables */ +#if 0  typedef enum _ClassEnumType  {      CET_UNKNOWN,                            /* Statut inconnu              */ @@ -152,6 +194,7 @@ typedef enum _ClassEnumType      CET_CLASS                               /* Classe                      */  } ClassEnumType; +#endif  /* Représentation des classes et des énumérations */ @@ -167,6 +210,7 @@ complex_variable *create_class_enum_var(char *);  /* Cas d'encapsulation possibles */ +#if 0  typedef enum _EncapsulationType  {      ECT_POINTER,                            /* Pointeur                    */ @@ -176,6 +220,7 @@ typedef enum _EncapsulationType      ECT_IMAGINARY                           /* Imaginaire (C 2000)         */  } EncapsulationType; +#endif  /* Représentation des variables dérivées */ diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am index 6c6491a..f166b5e 100644 --- a/src/format/dwarf/Makefile.am +++ b/src/format/dwarf/Makefile.am @@ -15,7 +15,7 @@ libformatdwarf_la_SOURCES =				\  libformatdwarf_la_LDFLAGS = $(LIBGTK_LIBS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)  AM_CPPFLAGS =  diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index 862b112..62464d3 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -109,7 +109,7 @@ bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx,                  name = get_elf_symbol_name(format, dynsym, dynstr, index); -                printf("got a jump ! >> %d - %s\n", index, name); +                //printf("got a jump ! >> %d - %s\n", index, name);                  if (name == NULL) @@ -295,7 +295,7 @@ void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instru                          printf("++ routine :: %s\n", g_binary_symbol_to_string(symbols[j]));                          fflush(NULL); -                        routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), "_ZN1N1TIiiE2mfES0_IddE"); +                        //routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), "_ZN1N1TIiiE2mfES0_IddE");                          routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), g_binary_symbol_to_string(symbols[j]));                          if (routine == NULL) @@ -418,16 +418,16 @@ 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 = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name); +            routine = NULL;//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");              }              else printf("++success\n"); diff --git a/src/format/mangling/Makefile.am b/src/format/mangling/Makefile.am index 80c0757..994919d 100644 --- a/src/format/mangling/Makefile.am +++ b/src/format/mangling/Makefile.am @@ -14,7 +14,7 @@ libformatmangling_la_SOURCES =			\  libformatmangling_la_LDFLAGS =  -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)  AM_CPPFLAGS =  diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y index da1ea10..e6078b0 100644 --- a/src/format/mangling/itanium_gram.y +++ b/src/format/mangling/itanium_gram.y @@ -32,6 +32,9 @@ typedef struct _itanium_demangler      size_t id_allocated;                    /* Taille allouée en mémoire   */      size_t id_used;                         /* Longueur de la chaîne       */ +    bool use_templates;                     /* Utilisation des gabarits    */ +    GSList *routines;                       /* Routines en cours de maj    */ +  } itanium_demangler; @@ -50,6 +53,27 @@ void reset_itanium_identifier_building(itanium_demangler *);  void build_itanium_identifier(itanium_demangler *, char); +/* Place sous le feu des projecteurs une nouvelle routine. */ +static GBinRoutine *push_routine(itanium_demangler *, GBinRoutine *); + +/* Remet une ancienne routine sous le feu des projecteurs. */ +static GBinRoutine *pop_routine(itanium_demangler *); + + + +/* 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); + +  /* Borne la longueur d'une chaîne à lire. */ @@ -90,26 +114,44 @@ char *strmerge(char *str1, const char *sep, char *str2);  %union { +    struct +    { +        union +        { +            char *str; +            void/*GOpenidaType*/ *type; +        }; +        int/*bool*/ is_string; + +    } str_or_type; +      char car;  	char *text;      unsigned int val;  	short/*s16_t*/ s16_val; +    void /*GOpenidaType*/ *type; +    void /*GTemplateType*/ *templtype; +      void/*simple_variable*/ *simple;      void/*complex_variable*/ *complex;      void/*variable*/ *var;      int/*VariableQualifier*/ qual; +    void/*GSList*/ *slist; +  }  %parse-param { itanium_demangler *demangler } +%parse-param { substi_list *substitutions }  %parse-param { GBinRoutine *routine } +  %token ITANIUM_SIGNATURE -%token EE NN II +%token EE NN II FF LL  %token C1 C2 C3 D1 D2 D3 @@ -130,6 +172,9 @@ char *strmerge(char *str1, const char *sep, char *str2);  %token OPER_LESS_EQ OPER_GREATER_EQ OPER_NOT OPER_AND_AND OPER_OR_OR OPER_PLUS_PLUS OPER_MINUS_MINUS  %token OPER_COMMA OPER_PRIV_MEMB OPER_POINTER_TO OPER_CLASS OPER_INDEX +%token SUBSTI_FIRST SUBSTI_N + +%token TPARAM_FIRST TPARAM_N  %token NUMBER CHAR @@ -161,29 +206,37 @@ char *strmerge(char *str1, const char *sep, char *str2);  %type <s16_val> DEC_16 +%type <str_or_type> name + +%type <text> unscoped_name +%type <type> nested_name + +%type <templtype> unscoped_template_name -%type <text> name unscoped_name unscoped_template_name nested_name  %type <text> unqualified_name operator_name -%type <text> prefix source_name +%type <text> prefix template_prefix source_name + +%type <type> template_param template_template_param -%type <var> type +%type <type> function_type type  %type <qual> qualifiers  %type <simple> builtin_type -%type <complex> class_enum_type +%type <type> class_enum_type + +%type <slist> template_args template_arg_list +%type <type> template_arg expr_primary -%type <text> template_args template_arg_list template_arg  %type <text> substitution  %type <car> CHAR -%type <val> NUMBER - +%type <val> NUMBER SUBSTI_N TPARAM_N  %{ @@ -204,21 +257,24 @@ extern void yy_delete_buffer(YY_BUFFER_STATE);  %% + +  input:  	ITANIUM_SIGNATURE encoding  	;  encoding: -    name bare_function_type +    name                            { $1.is_string ? g_binary_routine_set_name(routine, $1.str) : g_binary_routine_set_name_from_type(routine, $1.type); } +        bare_function_type          { ; }      ;  name: -    nested_name                     { $$ = $1; g_binary_routine_set_name(routine, $1); } -    | unscoped_name                 { $$ = $1; g_binary_routine_set_name(routine, $1); } -    | unscoped_template_name template_args  { $$ = stradd($1, $2); /* TODO : merge -> free */ } +    nested_name                             { $$.type = $1; $$.is_string = false; } +    | unscoped_name                         { $$.str = $1; $$.is_string = true; } +    | unscoped_template_name template_args  { $$.type = $1; $$.is_string = false; g_template_type_add_params($1, $2); }      ;  unscoped_name: @@ -227,27 +283,49 @@ unscoped_name:      ;  unscoped_template_name: -    unscoped_name                   { $$ = $1; } -    | substitution                  { $$ = $1; } +    unscoped_name                   { $$ = g_template_type_new($1, NULL); add_substitution_item(substitutions, $$); } +    | substitution                  { +        $$ = NULL;/*g_openida_type_to_string($1)*/; +        /*printf("unscoped sub name :: %s\n", $$); +          g_object_unref(G_OBJECT($1));*/ +    }      ;  nested_name: -    NN prefix unqualified_name EE   { $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); } +    NN prefix unqualified_name EE           { +                                                $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); +                                                $$ = g_class_enum_type_new(CET_UNKNOWN, $$); +                                            } +    | NN template_prefix template_args EE   { $$ = g_template_type_new($2, $3); }      ;  prefix: -    /* vide */                      { $$ = NULL; printf("passage E\n"); } +    /* vide */                      { $$ = NULL; /*printf("passage E\n")*/; }      | prefix unqualified_name       { $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); } -    | substitution                  { $$ = $1; } +    | template_prefix template_args     { $$ = g_template_type_new($1, $2); $$ = g_openida_type_to_string($$); /* FIXME : retourner un type ! */} +    | substitution                  { +        $$ = g_openida_type_to_string($1); +        printf("prefix substi :: %s\n", $$); +        g_object_unref(G_OBJECT($1)); +    } +    ; + +template_prefix: +    prefix unqualified_name                 { $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); } +    | template_param                        { +                                                $$ = g_openida_type_to_string($1); +                                                g_object_unref(G_OBJECT($1)); +                                            }      ; +  unqualified_name:      operator_name                   { printf("dup :: '%s'\n", $1); fflush(NULL) ;$$ = strdup($1) ; }      | ctor_dtor_name                { printf("passage C\n"); $$ = NULL; } @@ -258,7 +336,7 @@ unqualified_name:  source_name:      NUMBER                          { set_itanium_text_length($1); reset_itanium_identifier_building(demangler); }  -        identifier                  { $$ = strdup(demangler->identifier); } +        identifier                  { $$ = strdup(demangler->identifier); printf("==source name== :: %s\n", $$); }      ;  identifier: @@ -330,92 +408,154 @@ ctor_dtor_name:      ; +function_type: +    FF                              { routine = push_routine(demangler, routine); } +        bare_function_type EE       { +                                        $$ = g_encapsulated_type_new(ECT_ROUTINE, routine); +                                        routine = pop_routine(demangler); +                                        if (routine == NULL) YYERROR; +                                    } +    ; + +  type: -    builtin_type                    { $$ = create_var_from_simple_one($1); } -    | class_enum_type               { $$ = create_var_from_complex_one($1); } -    | substitution                  { $$ = create_var_from_complex_one(create_class_enum_var($1)); } -    | qualifiers type               { $$ = $2; add_qualifier_to_var($2, $1); } -    | TP type                       { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_POINTER, $2)); } -    | TR type                       { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_REFERENCE, $2)); } -    | TO type                       { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_RVALUE_REF, $2)); } -    | TC type                       { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_COMPLEX, $2)); } -    | TG type                       { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_IMAGINARY, $2)); } +    builtin_type                    { $$ = $1; printf("builtin '%s'\n", g_openida_type_to_string($1)); } +    | class_enum_type               { $$ = $1; add_substitution_item(substitutions, $1); } +    | substitution                  { $$ = $1; } +    | template_param                { $$ = $1; } +    | template_template_param template_args { +                                                $$ = g_template_type_new(g_openida_type_to_string($1), NULL); +                                                g_object_unref($1); +                                                g_template_type_add_params($$, $2); +                                            } +    | function_type                 { $$ = $1; } +    | qualifiers type               { +                                        $$ = g_openida_type_dup($2); +                                        g_openida_type_add_qualifier($$, $1); +                                        add_substitution_item(substitutions, $$); +                                    } +    | 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, $$); }      ;  qualifiers: -    QR                              { $$ = VQF_RESTRICT; } -    | QV                            { $$ = VQF_VOLATILE; } -    | QK                            { $$ = VQF_CONST; } +    QR                              { $$ = TQF_RESTRICT; } +    | QV                            { $$ = TQF_VOLATILE; } +    | QK                            { $$ = TQF_CONST; }      ;  builtin_type: -    V                               { $$ = create_typed_simple_var(BTP_VOID); } -    | W                             { $$ = create_typed_simple_var(BTP_WCHAR_T); } -    | B                             { $$ = create_typed_simple_var(BTP_BOOL); } -    | C                             { $$ = create_typed_simple_var(BTP_CHAR); } -    | A                             { $$ = create_typed_simple_var(BTP_SCHAR); } -    | H                             { $$ = create_typed_simple_var(BTP_UCHAR); } -    | S                             { $$ = create_typed_simple_var(BTP_SHORT); } -    | T                             { $$ = create_typed_simple_var(BTP_USHORT); } -    | I                             { $$ = create_typed_simple_var(BTP_INT); } -    | J                             { $$ = create_typed_simple_var(BTP_UINT); } -    | L                             { $$ = create_typed_simple_var(BTP_LONG); } -    | M                             { $$ = create_typed_simple_var(BTP_ULONG); } -    | X                             { $$ = create_typed_simple_var(BTP_LONG_LONG); } -    | Y                             { $$ = create_typed_simple_var(BTP_ULONG_LONG); } -    | N                             { $$ = create_typed_simple_var(BTP_INT128); } -    | O                             { $$ = create_typed_simple_var(BTP_UINT128); } -    | F                             { $$ = create_typed_simple_var(BTP_FLOAT); } -    | D                             { $$ = create_typed_simple_var(BTP_DOUBLE); } -    | E                             { $$ = create_typed_simple_var(BTP_LONG_DOUBLE); } -    | G                             { $$ = create_typed_simple_var(BTP_FLOAT128); } -    | Z                             { $$ = create_typed_simple_var(BTP_ELLIPSIS); } -    | DD                            { $$ = create_typed_simple_var(BTP_754R_64); } -    | DE                            { $$ = create_typed_simple_var(BTP_754R_128); } -    | DF                            { $$ = create_typed_simple_var(BTP_754R_32); } -    | DH                            { $$ = create_typed_simple_var(BTP_754R_16); } -    | DI                            { $$ = create_typed_simple_var(BTP_CHAR32_T); } -    | DS                            { $$ = create_typed_simple_var(BTP_CHAR16_T); } -    | U source_name                 { $$ = create_typed_simple_var(BTP_OTHER); /* TODO */ ; free($2); } +    V                               { $$ = g_basic_type_new(BTP_VOID); } +    | W                             { $$ = g_basic_type_new(BTP_WCHAR_T); } +    | B                             { $$ = g_basic_type_new(BTP_BOOL); } +    | C                             { $$ = g_basic_type_new(BTP_CHAR); } +    | A                             { $$ = g_basic_type_new(BTP_SCHAR); } +    | H                             { $$ = g_basic_type_new(BTP_UCHAR); } +    | S                             { $$ = g_basic_type_new(BTP_SHORT); } +    | T                             { $$ = g_basic_type_new(BTP_USHORT); } +    | I                             { $$ = g_basic_type_new(BTP_INT); } +    | J                             { $$ = g_basic_type_new(BTP_UINT); } +    | L                             { $$ = g_basic_type_new(BTP_LONG); } +    | M                             { $$ = g_basic_type_new(BTP_ULONG); } +    | X                             { $$ = g_basic_type_new(BTP_LONG_LONG); } +    | Y                             { $$ = g_basic_type_new(BTP_ULONG_LONG); } +    | N                             { $$ = g_basic_type_new(BTP_INT128); } +    | O                             { $$ = g_basic_type_new(BTP_UINT128); } +    | F                             { $$ = g_basic_type_new(BTP_FLOAT); } +    | D                             { $$ = g_basic_type_new(BTP_DOUBLE); } +    | E                             { $$ = g_basic_type_new(BTP_LONG_DOUBLE); } +    | G                             { $$ = g_basic_type_new(BTP_FLOAT128); } +    | Z                             { $$ = g_basic_type_new(BTP_ELLIPSIS); } +    | DD                            { $$ = g_basic_type_new(BTP_754R_64); } +    | DE                            { $$ = g_basic_type_new(BTP_754R_128); } +    | DF                            { $$ = g_basic_type_new(BTP_754R_32); } +    | DH                            { $$ = g_basic_type_new(BTP_754R_16); } +    | DI                            { $$ = g_basic_type_new(BTP_CHAR32_T); } +    | DS                            { $$ = g_basic_type_new(BTP_CHAR16_T); } +    | U source_name                 { $$ = g_basic_type_new(BTP_OTHER); /* TODO */ ; free($2); }      ;  bare_function_type: -    bare_function_type type         { g_binary_routine_add_arg(routine, $2); } -    | type                          { g_binary_routine_add_arg(routine, $1); } +    bare_function_type type         { g_binary_routine_add_arg(routine, g_binary_variable_new($2)); } +    | type                          { +                                        if (demangler->use_templates) +                                            g_binary_routine_set_return_type(routine, $1); +                                        else +                                            g_binary_routine_add_arg(routine, g_binary_variable_new($1)); +                                    }      ;  class_enum_type: -    name                            { $$ = create_class_enum_var($1); } +    name                            { $$ = $1.is_string ? g_class_enum_type_new(CET_UNKNOWN, $1.str) : $1.type; }      ; +template_param: +    TPARAM_FIRST                    { +                                        const GOpenidaType *type = g_binary_routine_get_type_from_name(routine); +                                        if (G_IS_TEMPLATE_TYPE(type)) +                                            $$ = g_template_type_get_param(G_TEMPLATE_TYPE(type), 0); +                                        else $$ = NULL; +                                        if ($$ == NULL) YYERROR; +                                    } +    | TPARAM_N                      { +                                        const GOpenidaType *type = g_binary_routine_get_type_from_name(routine); +                                        if (G_IS_TEMPLATE_TYPE(type)) +                                            $$ = g_template_type_get_param(G_TEMPLATE_TYPE(type), $1 + 1); +                                        else $$ = NULL; +                                        if ($$ == NULL) YYERROR; +                                    } +    ; + +template_template_param: +    template_param                  { $$ = $1; } +	| substitution                  { $$ = $1; } +    ; +  template_args: -    II template_arg_list EE         { printf("passage I\n"); $$ = stradd(strprep($2, "<"), ">"); } +    use_templates template_arg_list EE         { $$ = $2; } +    ; + +use_templates: +    II                              { printf("new template !!!\n"); demangler->use_templates = true; }      ;  template_arg_list: -    template_arg_list template_arg  { $$ = strmerge($1, ", ", $2); } -    | template_arg                  { $$ = $1; } +    template_arg_list template_arg  { $$ = g_slist_prepend($1, $2); } +    | template_arg                  { $$ = g_slist_prepend(NULL, $1); } +    | template_args                 { g_class_enum_type_new(CET_UNKNOWN, "template params"); }      ;  template_arg: -    type                            { $$ = var_to_string($1); delete_var($1); } +    type                                    { $$ = $1; } +    | expr_primary                          { $$ = $1; }      ; + +expr_primary: +    LL type NUMBER EE                       { $$ = $2; } +    ; + +  substitution: -    ST                              { $$ = strdup("std"); } -    | SA                            { $$ = strdup("std::allocator"); } -    | SB                            { $$ = strdup("std::basic_string"); } -    | SS                            { $$ = strdup("std::string"); } -    | SI                            { $$ = strdup("std::istream"); } -    | SO                            { $$ = strdup("std::ostream"); } -    | SD                            { $$ = strdup("std::iostream"); } +    ST                              { $$ = g_class_enum_type_new(CET_CLASS, "std"); } +    | SA                            { $$ = g_class_enum_type_new(CET_CLASS, "std::allocator"); } +    | SB                            { $$ = g_class_enum_type_new(CET_CLASS, "std::basic_string"); } +    | SS                            { $$ = g_class_enum_type_new(CET_CLASS, "std::string"); } +    | 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; }      ; @@ -516,15 +656,23 @@ bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name)  GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *name)  {      GBinRoutine *result;                    /* Construction à retourner    */ +    substi_list *substitutions;             /* Liste de substitutions      */  	YY_BUFFER_STATE buffer;                 /* Tampon pour bison           */  	int ret;                                /* Bilan de l'appel            */ +    /* TODO : reset ! */ +    demangler->use_templates = false; +      result = g_binary_routine_new(); +    substitutions = create_substitution_list(); +  	buffer = yy_scan_string(name); -	ret = yyparse(demangler, result); +	ret = yyparse(demangler, substitutions, result);  	yy_delete_buffer(buffer); +    //delete(substi_list *substitutions); +      if (ret != 0)      {          /*delete_binary_routine(result); FIXME */ @@ -581,3 +729,224 @@ void build_itanium_identifier(itanium_demangler *demangler, char value)      demangler->identifier[demangler->id_used] = 0;  } + + + + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à mettre à jour.                        * +*                previous  = routine à sauvegarder.                           * +*                                                                             * +*  Description : Place sous le feu des projecteurs une nouvelle routine.      * +*                                                                             * +*  Retour      : Nouvelle routine à compléter.                                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *previous) +{ +    GBinRoutine *result;                    /* Routine nouvelle à renvoyer */ + +    result = g_binary_routine_new(); + +    demangler->routines = g_slist_append(demangler->routines, previous); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à mettre à jour.                        * +*                                                                             * +*  Description : Remet une ancienne routine sous le feu des projecteurs.      * +*                                                                             * +*  Retour      : Routine sauvegardée.                                         * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GBinRoutine *pop_routine(itanium_demangler *demangler) +{ +    GBinRoutine *result;                    /* Routine nouvelle à renvoyer */ +    GSList *last;                           /* Dernier élément             */ + +    last = g_slist_last(demangler->routines); + +    if (last == NULL) result = NULL; +    else +    { +        result = G_BIN_ROUTINE(last->data); +        demangler->routines = g_slist_remove(demangler->routines, result); +    } + +    return result; + +} + + + + + +/****************************************************************************** +*                                                                             * +*  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°. * +*                                                                             * +*  Description : Ajoute un élément dans une liste de substitutions.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void add_substitution_item(substi_list *list, GOpenidaType *type) +{ +    g_object_ref(G_OBJECT(type)); + +    printf("push %p\n", type); + +    g_slist_append(list, type); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : list = ensemble des substitions enregistrées.                * +*                n    = indice de l'élément à fournir.                        * +*                                                                             * +*  Description : Fournit le nième élément d'une liste de substitutions.       * +*                                                                             * +*  Retour      : Type prêt à emploi.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static GOpenidaType *get_substitution_item(substi_list *list, guint n) +{ +    printf("get [%u] == %p\n", n, g_slist_nth_data(list, n + 1)); + +    return G_OPENIDA_TYPE(g_slist_nth_data(list, 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)"); + +    TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)"); + +    //TEST_ITANIUM_MANGLING("", ""); + + end_of_test: + +    ; + +} +#endif diff --git a/src/format/mangling/itanium_tok.l b/src/format/mangling/itanium_tok.l index bc5f5f1..e8fb7f1 100644 --- a/src/format/mangling/itanium_tok.l +++ b/src/format/mangling/itanium_tok.l @@ -29,6 +29,8 @@ _Z                      { return ITANIUM_SIGNATURE; }  E                       { return EE; }  N                       { return NN; }  I                       { return II; } +F                       { return FF; } +L                       { return LL; }  C1                      { return C1; }  C2                      { return C2; } @@ -133,13 +135,21 @@ cl                      { return OPER_CLASS; }  ix                      { return OPER_INDEX; } +S_                      { return SUBSTI_FIRST; } +S[0-9a-z]_              { yylval.val = atoi(yytext + 1); return SUBSTI_N; } + +T_                      { return TPARAM_FIRST; } +T[0-9]*_                { yylval.val = atoi(yytext + 1); return TPARAM_N; } + +  [0-9]+                  { yylval.val = atoi(yytext); return NUMBER; }  <identifier>.           { if (--itanium_txt_length == 0) BEGIN(INITIAL); yylval.car = *yytext; return CHAR; } -<*>.                    { printf("error  : '%s'\n", yytext); } +<*>[ ] +<*>.                    { printf("error  : '%s'\n", yytext); }  %% @@ -40,6 +40,10 @@  /////void test_gdb(void); + +//extern test_itanium_demangling(name_demangler *); + +  /******************************************************************************  *                                                                             *  *  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         * @@ -104,6 +108,9 @@ int main(int argc, char **argv)      /* Création de l'interface */ +    //test_itanium_demangling(get_demangler_by_type(DGT_ITANIUM)); +    //exit(-1); +      init_internal_panels();      editor = create_editor(); | 
