summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-04-18 00:31:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-04-18 00:31:49 (GMT)
commitef29fbc801e23f547b9ee7666b713bcf32d7e787 (patch)
treefb7466a56e2246c53a51d0475c1b5fc70ef3b8f9 /src
parent49468379e912806400c5874f8e359cb934516228 (diff)
Improved the Itanium demangler.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@152 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rwxr-xr-xsrc/analysis/Makefile.am1
-rw-r--r--src/analysis/routine.c96
-rw-r--r--src/analysis/routine.h10
-rw-r--r--src/analysis/type.c1377
-rw-r--r--src/analysis/type.h312
-rw-r--r--src/analysis/variable.c164
-rw-r--r--src/analysis/variable.h47
-rw-r--r--src/format/dwarf/Makefile.am2
-rw-r--r--src/format/elf/helper_x86.c12
-rw-r--r--src/format/mangling/Makefile.am2
-rw-r--r--src/format/mangling/itanium_gram.y515
-rw-r--r--src/format/mangling/itanium_tok.l12
-rw-r--r--src/main.c7
13 files changed, 2449 insertions, 108 deletions
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); }
%%
diff --git a/src/main.c b/src/main.c
index 3c22711..f927563 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();