summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2009-03-08 22:05:09 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2009-03-08 22:05:09 (GMT)
commit29a22c425f492427f45b71de937f2d99587c8d34 (patch)
tree36e8bb3ef73bc91e812ed63205d10bfced578660 /src/analysis
parent674739bedc853681be5a2657a7a4f497d6e82c9b (diff)
Added a partial support of the Itanium C++ ABI mangling.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@52 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis')
-rwxr-xr-xsrc/analysis/Makefile.am4
-rw-r--r--src/analysis/prototype.c260
-rw-r--r--src/analysis/prototype.h69
-rw-r--r--src/analysis/variable.c728
-rw-r--r--src/analysis/variable.h176
5 files changed, 1236 insertions, 1 deletions
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index c3b2e64..e652f5d 100755
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -2,7 +2,9 @@
lib_LIBRARIES = libanalysis.a
libanalysis_a_SOURCES = \
- line.h line.c
+ line.h line.c \
+ prototype.h prototype.c \
+ variable.h variable.c
libanalysis_a_CFLAGS = $(AM_CFLAGS)
diff --git a/src/analysis/prototype.c b/src/analysis/prototype.c
new file mode 100644
index 0000000..aa3ca2f
--- /dev/null
+++ b/src/analysis/prototype.c
@@ -0,0 +1,260 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * prototype.c - manipulation des prototypes de fonctions et de variables
+ *
+ * Copyright (C) 2008 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 "prototype.h"
+
+
+#include <malloc.h>
+
+
+#include "../common/extstr.h"
+
+
+
+/* Variable représentant un prototype de routine */
+struct _bin_routine
+{
+ RoutineType type; /* Type de routine */
+
+ variable *ret_type; /* Type retourné */
+
+ char *name; /* Désignation humaine */
+
+ variable **args_types; /* Types d'arguments */
+ size_t args_count; /* Nombre d'arguments */
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une représentation de routine. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bin_routine *create_binary_routine(void)
+{
+ bin_routine *result; /* Structure à retourner */
+
+ result = (bin_routine *)calloc(1, sizeof(bin_routine));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à effacer. *
+* *
+* Description : Supprime une représentation de routine de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_binary_routine(bin_routine *routine)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (routine->ret_type)
+ delete_var(routine->ret_type);
+
+ if (routine->name != NULL)
+ free(routine->name);
+
+ for (i = 0; i < routine->args_count; i++)
+ delete_var(routine->args_types[i]);
+
+ free(routine);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à mettre à jour. *
+* type = type de routine spécifié. *
+* *
+* Description : Définit le type d'une routine. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_binary_routine_type(bin_routine *routine, RoutineType type)
+{
+ routine->type = type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à mettre à jour. *
+* name = désignation humainement lisible. *
+* *
+* Description : Définit le nom humain d'une routine. *
+* *
+* Retour : - *
+* *
+* Remarques : Le nom ne doit pas ensuite être libéré par l'appelant ! *
+* *
+******************************************************************************/
+
+void set_binary_routine_name(bin_routine *routine, char *name)
+{
+ if (routine->name != NULL)
+ free(routine->name);
+
+ routine->name = name;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à mettre à jour. *
+* var = variable représentant un type de retour. *
+* *
+* Description : Définit le type de retour d'une routine. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_binary_routine_return_type(bin_routine *routine, variable *var)
+{
+ if (routine->ret_type != NULL)
+ delete_var(routine->ret_type);
+
+ routine->ret_type = var;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à mettre à jour. *
+* var = variable représentant un argument supplémentaire. *
+* *
+* Description : Ajoute un argument à une routine. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void add_arg_to_binary_routine(bin_routine *routine, variable *var)
+{
+ routine->args_count++;
+
+ routine->args_types = (variable **)realloc(routine->args_types,
+ routine->args_count * sizeof(variable *));
+
+ routine->args_types[routine->args_count - 1] = var;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : routine = routine à consulter. *
+* *
+* Description : Décrit le prototype de la routine sous forme de caractères. *
+* *
+* Retour : Chaîne de caractères à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *routine_to_string(const bin_routine *routine)
+{
+ char *result; /* Chaîne à renvoyer */
+ size_t i; /* Boucle de parcours */
+ char *typestr; /* Stockage de nom temporaire */
+
+ /* Retour de la fonction */
+
+ switch (routine->type)
+ {
+ case RTT_CONSTRUCTOR:
+ result = strdup(routine->name);
+ result = stradd(result, "::");
+ break;
+
+ case RTT_DESTRUCTOR:
+ result = strdup(routine->name);
+ result = stradd(result, "::~");
+ break;
+
+ default: /* Pour gcc */
+ case RTT_CLASSIC:
+ if (routine->ret_type == NULL) result = strdup("??? ");
+ else
+ {
+ result = var_to_string(routine->ret_type);
+ result = stradd(result, " ");
+ }
+ break;
+
+ }
+
+ /* Nom de la routine */
+
+ result = stradd(result, routine->name);
+
+ /* Liste des arguments */
+
+ result = stradd(result, "(");
+
+ for (i = 0; i < routine->args_count; i++)
+ {
+ if (i > 0) result = stradd(result, ", ");
+
+ typestr = var_to_string(routine->args_types[i]);
+ result = stradd(result, typestr);
+ free(typestr);
+
+ }
+
+ result = stradd(result, ")");
+
+ return result;
+
+}
diff --git a/src/analysis/prototype.h b/src/analysis/prototype.h
new file mode 100644
index 0000000..f86d541
--- /dev/null
+++ b/src/analysis/prototype.h
@@ -0,0 +1,69 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * prototype.h - prototypes pour la manipulation des prototypes de fonctions et de variables
+ *
+ * Copyright (C) 2008 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_PROTOTYPE_H
+#define _ANALYSIS_PROTOTYPE_H
+
+
+#include "variable.h"
+
+
+
+/* Type de routine traitée */
+typedef enum _RoutineType
+{
+ RTT_CLASSIC, /* Fonction ou méthode */
+ RTT_CONSTRUCTOR, /* Constructeur */
+ RTT_DESTRUCTOR /* Destructeur */
+
+} RoutineType;
+
+
+/* Variable représentant un prototype de routine */
+typedef struct _bin_routine bin_routine;
+
+
+/* Crée une représentation de routine. */
+bin_routine *create_binary_routine(void);
+
+/* Supprime une représentation de routine de la mémoire. */
+void delete_binary_routine(bin_routine *);
+
+/* Définit le type d'une routine. */
+void set_binary_routine_type(bin_routine *, RoutineType);
+
+/* Définit le nom humain d'une routine. */
+void set_binary_routine_name(bin_routine *, char *);
+
+/* Définit le type de retour d'une routine. */
+void set_binary_routine_return_type(bin_routine *, variable *);
+
+/* Ajoute un argument à une routine. */
+void add_arg_to_binary_routine(bin_routine *, variable *);
+
+/* Décrit le prototype de la routine sous forme de caractères. */
+char *routine_to_string(const bin_routine *);
+
+
+
+#endif /* _ANALYSIS_PROTOTYPE_H */
diff --git a/src/analysis/variable.c b/src/analysis/variable.c
new file mode 100644
index 0000000..058c152
--- /dev/null
+++ b/src/analysis/variable.c
@@ -0,0 +1,728 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * variable.c - manipulation des variables en tout genre
+ *
+ * Copyright (C) 2008 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 "variable.h"
+
+
+#include <malloc.h>
+#include <stdbool.h>
+#include <string.h>
+
+
+#include "../common/extstr.h"
+
+
+
+/* ---------------------------- TYPES DE DONNEES SIMPLES ---------------------------- */
+
+
+/* Variable représentant un argument ou un type de retour */
+struct _simple_variable
+{
+ BaseType type; /* Type représenté */
+
+};
+
+
+/* Décrit la variable simple sous forme de caractères. */
+char *simple_var_to_string(const simple_variable *);
+
+/* Supprime de la mémoire une variable de type simple. */
+void delete_simple_var(simple_variable *);
+
+
+
+/* --------------------- ENCAPSULATIONS DES VARIABLES COMPLEXES --------------------- */
+
+
+/* Supprime de la mémoire une variable de type complexe. */
+typedef void (* delete_complex_fc) (complex_variable *);
+
+/* Décrit la variable complexe sous forme de caractères. */
+typedef char * (* complex_to_string_fc) (const complex_variable *);
+
+
+/* Représentation d'une variable complexe */
+struct _complex_variable
+{
+ delete_complex_fc delete; /* Procédure de suppression */
+ complex_to_string_fc to_string; /* Conversion en chaîne */
+
+};
+
+
+/* Initialise une représentation de variable complexe. */
+void init_complex_var(complex_variable *);
+
+/* Supprime de la mémoire une variable de type complexe. */
+void delete_complex_var(complex_variable *);
+
+/* Décrit la variable simple sous forme de caractères. */
+char *complex_var_to_string(const complex_variable *);
+
+
+
+/* ---------------------- VARIABLES DE CLASSES ET ENUMERATIONS ---------------------- */
+
+
+/* Représentation des classes et des énumérations */
+struct _class_enum_variable
+{
+ complex_variable complex; /* A laisser en premier */
+
+ ClassEnumType type; /* Type représenté si connu */
+
+ char *desc; /* Description humaine */
+
+};
+
+
+/* Supprime de la mémoire une variable de classe/enumération. */
+void delete_class_enum_var(class_enum_variable *);
+
+/* Décrit la variable complexe sous forme de caractères. */
+char *class_enum_var_to_string(const class_enum_variable *);
+
+
+
+/* -------------------------- VARIABLES DEPENDANT D'AUTRES -------------------------- */
+
+
+/* Représentation des variables dérivées */
+struct _encapsulated_variable
+{
+ complex_variable complex; /* A laisser en premier */
+
+ EncapsulationType type; /* Encapsulation utilisée */
+ variable *child; /* Sous-type encadré */
+
+};
+
+
+/* Supprime de la mémoire une variable dérivée. */
+void delete_encapsulated_var(encapsulated_variable *);
+
+/* Décrit la variable dérivée sous forme de caractères. */
+char *encapsulated_var_to_string(const encapsulated_variable *);
+
+
+
+/* ---------------------- MANIPULATION GENERIQUE DES VARIABLES ---------------------- */
+
+
+/* Variable représentant un argument ou un type de retour */
+struct _variable
+{
+ union
+ {
+ simple_variable *simple; /* Variable simple */
+ complex_variable *complex; /* Variable plus compliquée */
+
+ } value;
+
+ bool is_simple; /* Choix du champ valide */
+
+ VariableQualifier qualifiers; /* Eventuels qualificatifs */
+
+};
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* TYPES DE DONNEES SIMPLES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée une représentation de variable. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+simple_variable *create_simple_var(void)
+{
+ simple_variable *result; /* Structure à retourner */
+
+ result = (simple_variable *)calloc(1, sizeof(simple_variable));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de base à représenter. *
+* *
+* Description : Crée une représentation de variable à type connu. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+simple_variable *create_typed_simple_var(BaseType type)
+{
+ simple_variable *result; /* Structure à retourner */
+
+ result = create_simple_var();
+
+ set_simple_var_type(result, type);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à effacer. *
+* *
+* Description : Supprime de la mémoire une variable de type simple. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_simple_var(simple_variable *var)
+{
+ free(var);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à mettre à jour. *
+* type = type de base à représenter. *
+* *
+* Description : Définit le type d'une variable simple. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void set_simple_var_type(simple_variable *var, BaseType type)
+{
+ var->type = type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à consulter. *
+* *
+* Description : Décrit la variable simple sous forme de caractères. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *simple_var_to_string(const simple_variable *var)
+{
+ char *result; /* Chaîne à renvoyer */
+
+ switch (var->type)
+ {
+ case BTP_VOID:
+ result = "void";
+ break;
+ case BTP_WCHAR_T:
+ result = "wchar_t";
+ break;
+ case BTP_BOOL:
+ result = "bool";
+ break;
+ case BTP_CHAR:
+ result = "char";
+ break;
+ case BTP_SCHAR:
+ result = "signed char";
+ break;
+ case BTP_UCHAR:
+ result = "unsigned char";
+ break;
+ case BTP_SHORT:
+ result = "short";
+ break;
+ case BTP_USHORT:
+ result = "unsigned short";
+ break;
+ case BTP_INT:
+ result = "int";
+ break;
+ case BTP_UINT:
+ result = "unsigned int";
+ break;
+ case BTP_LONG:
+ result = "long";
+ break;
+ case BTP_ULONG:
+ result = "unsigned long";
+ break;
+ case BTP_LONG_LONG:
+ result = "long long";
+ break;
+ case BTP_ULONG_LONG:
+ result = "unsigned long long";
+ break;
+ case BTP_INT128:
+ result = "__int128";
+ break;
+ case BTP_UINT128:
+ result = "__uint128";
+ break;
+ case BTP_FLOAT:
+ result = "float";
+ break;
+ case BTP_DOUBLE:
+ result = "double";
+ break;
+ case BTP_LONG_DOUBLE:
+ result = "__float80";
+ break;
+ case BTP_FLOAT128:
+ result = "__float128";
+ break;
+ case BTP_ELLIPSIS:
+ result = "...";
+ break;
+ case BTP_754R_64:
+ result = "754r_float64";
+ break;
+ case BTP_754R_128:
+ result = "754r_float128";
+ break;
+ case BTP_754R_32:
+ result = "754r_float32";
+ break;
+ case BTP_754R_16:
+ result = "754r_float16";
+ break;
+ case BTP_CHAR32_T:
+ result = "char32_t";
+ break;
+ case BTP_CHAR16_T:
+ result = "char16_t";
+ break;
+ case BTP_OTHER:
+ result = "[toto]"; /* FIXME */
+ break;
+ default:
+ result = "/* pour gcc */";
+ break;
+ }
+
+ result = strdup(result);
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ENCAPSULATIONS DES VARIABLES COMPLEXES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : var = structure vierge à préparer. *
+* *
+* Description : Initialise une représentation de variable complexe. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void init_complex_var(complex_variable *var)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à effacer. *
+* *
+* Description : Supprime de la mémoire une variable de type complexe. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_complex_var(complex_variable *var)
+{
+ var->delete(var);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à consulter. *
+* *
+* Description : Décrit la variable complexe sous forme de caractères. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *complex_var_to_string(const complex_variable *var)
+{
+ return var->to_string(var);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VARIABLES DE CLASSES ET ENUMERATIONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de base à représenter. *
+* desc = description humaine de la variable. *
+* *
+* Description : Crée une représentation de variable de classe/enumération. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : La description ne doit pas être libérée par l'appelant ! *
+* *
+******************************************************************************/
+
+complex_variable *create_class_enum_var(char *desc)
+{
+ class_enum_variable *result; /* Structure à retourner */
+
+ result = (class_enum_variable *)calloc(1, sizeof(class_enum_variable));
+
+ init_complex_var(COMPLEX_VAR(result));
+
+ COMPLEX_VAR(result)->delete = (delete_complex_fc)delete_class_enum_var;
+ COMPLEX_VAR(result)->to_string = (complex_to_string_fc)class_enum_var_to_string;
+
+ result->desc = desc;
+
+ return COMPLEX_VAR(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à effacer. *
+* *
+* Description : Supprime de la mémoire une variable de classe/enumération. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_class_enum_var(class_enum_variable *var)
+{
+ free(var->desc);
+
+ free(var);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à consulter. *
+* *
+* Description : Décrit la variable complexe sous forme de caractères. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *class_enum_var_to_string(const class_enum_variable *var)
+{
+ return strdup(var->desc);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VARIABLES DEPENDANT D'AUTRES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
+
+complex_variable *create_encapsulated_var(EncapsulationType type, variable *child)
+{
+ encapsulated_variable *result; /* Structure à retourner */
+
+ result = (encapsulated_variable *)calloc(1, sizeof(encapsulated_variable));
+
+ init_complex_var(COMPLEX_VAR(result));
+
+ COMPLEX_VAR(result)->delete = (delete_complex_fc)delete_encapsulated_var;
+ COMPLEX_VAR(result)->to_string = (complex_to_string_fc)encapsulated_var_to_string;
+
+ result->type = type;
+ result->child = child;
+
+ return COMPLEX_VAR(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à effacer. *
+* *
+* Description : Supprime de la mémoire une variable dérivée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_encapsulated_var(encapsulated_variable *var)
+{
+ delete_var(var->child);
+
+ free(var);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à consulter. *
+* *
+* Description : Décrit la variable dérivée sous forme de caractères. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *encapsulated_var_to_string(const encapsulated_variable *var)
+{
+ char *result; /* Chaîne finale à renvoyer */
+
+ result = var_to_string(var->child);
+
+ switch (var->type)
+ {
+ case ECT_POINTER:
+ if (result[strlen(result) - 1] == '*') result = stradd(result, "*");
+ else result = stradd(result, " *");
+ break;
+ case ECT_REFERENCE:
+ result = stradd(result, " &");
+ break;
+ case ECT_RVALUE_REF:
+ result = stradd(result, " [[rval ???]]") /* FIXME */;
+ break;
+ case ECT_COMPLEX:
+ result = stradd(result, " complex");
+ break;
+ case ECT_IMAGINARY:
+ result = stradd(result, " imaginary");
+ break;
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MANIPULATION GENERIQUE DES VARIABLES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à emballer. *
+* *
+* Description : Crée une représentation de variable (simple). *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+variable *create_var_from_simple_one(simple_variable *var)
+{
+ variable *result; /* Structure à retourner */
+
+ result = (variable *)calloc(1, sizeof(variable));
+
+ result->value.simple = var;
+ result->is_simple = true;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à emballer. *
+* *
+* Description : Crée une représentation de variable (complexe). *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+variable *create_var_from_complex_one(complex_variable *var)
+{
+ variable *result; /* Structure à retourner */
+
+ result = (variable *)calloc(1, sizeof(variable));
+
+ result->value.complex = var;
+ result->is_simple = false;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à effecer. *
+* *
+* Description : Supprime la représentation de variable de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void delete_var(variable *var)
+{
+ if (var->is_simple) delete_simple_var(var->value.simple);
+ else delete_complex_var(var->value.complex);
+
+ free(var);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à mettre à jour. *
+* qualifier = nouveau qualificatif pour la variable. *
+* *
+* Description : Ajoute un qualificatif à la variable. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void add_qualifier_to_var(variable *var, VariableQualifier qualifier)
+{
+ var->qualifiers |= qualifier;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : var = variable à consulter. *
+* *
+* Description : Décrit la variable sous forme de caractères. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *var_to_string(const variable *var)
+{
+ char *result; /* Chaîne à renvoyer */
+
+ if (var->is_simple) result = simple_var_to_string(var->value.simple);
+ else result = complex_var_to_string(var->value.complex);
+
+ if (var->qualifiers & VQF_RESTRICT)
+ strprep(result, "restrict ");
+
+ if (var->qualifiers & VQF_VOLATILE)
+ strprep(result, "volatile ");
+
+ if (var->qualifiers & VQF_CONST)
+ strprep(result, "const ");
+
+ return result;
+
+}
diff --git a/src/analysis/variable.h b/src/analysis/variable.h
new file mode 100644
index 0000000..8b50cf4
--- /dev/null
+++ b/src/analysis/variable.h
@@ -0,0 +1,176 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * variable.h - prototypes pour la manipulation des variables en tout genre
+ *
+ * Copyright (C) 2008 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_VARIABLE_H
+#define _ANALYSIS_VARIABLE_H
+
+
+
+/* Variable repésentant un argument ou un type de retour */
+typedef struct _variable variable;
+
+
+
+/* ---------------------------- 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;
+
+
+
+/* Variable repésentant un argument ou un type de retour */
+typedef struct _simple_variable simple_variable;
+
+
+/* Crée une représentation de variable. */
+simple_variable *create_simple_var(void);
+
+/* Crée une représentation de variable à type connu. */
+simple_variable *create_typed_simple_var(BaseType);
+
+/* Définit le type d'une variable simple. */
+void set_simple_var_type(simple_variable *, BaseType);
+
+
+
+/* --------------------- ENCAPSULATIONS DES VARIABLES COMPLEXES --------------------- */
+
+
+/* Représentation d'une variable complexe */
+typedef struct _complex_variable complex_variable;
+
+
+#define COMPLEX_VAR(v) ((complex_variable *)v)
+
+
+
+/* ---------------------- VARIABLES DE CLASSES ET ENUMERATIONS ---------------------- */
+
+
+/* Type de ces variables */
+typedef enum _ClassEnumType
+{
+ CET_UNKNOWN, /* Statut inconnu */
+ CET_STRUCT, /* Structure */
+ CET_ENUM, /* Enumération */
+ CET_CLASS /* Classe */
+
+} ClassEnumType;
+
+
+/* Représentation des classes et des énumérations */
+typedef struct _class_enum_variable class_enum_variable;
+
+
+/* Crée une représentation de variable de classe/enumération. */
+complex_variable *create_class_enum_var(char *);
+
+
+
+/* -------------------------- VARIABLES DEPENDANT D'AUTRES -------------------------- */
+
+
+/* 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) */
+
+} EncapsulationType;
+
+
+/* Représentation des variables dérivées */
+typedef struct _encapsulated_variable encapsulated_variable;
+
+
+/* Crée une représentation de variable dérivée. */
+complex_variable *create_encapsulated_var(EncapsulationType, variable *);
+
+
+
+/* ---------------------- MANIPULATION GENERIQUE DES VARIABLES ---------------------- */
+
+
+/* Qualificatifs de variables */
+typedef enum _VariableQualifier
+{
+ VQF_RESTRICT = (1 << 0), /* restrict (C99) */
+ VQF_VOLATILE = (1 << 1), /* volatile */
+ VQF_CONST = (1 << 2) /* const */
+
+} VariableQualifier;
+
+
+/* Crée une représentation de variable (simple). */
+variable *create_var_from_simple_one(simple_variable *);
+
+/* Crée une représentation de variable (complexe). */
+variable *create_var_from_complex_one(complex_variable *);
+
+/* Supprime la représentation de variable de la mémoire. */
+void delete_var(variable *);
+
+/* Ajoute un qualificatif à la variable. */
+void add_qualifier_to_var(variable *, VariableQualifier);
+
+/* Décrit la variable sous forme de caractères. */
+char *var_to_string(const variable *);
+
+
+
+#endif /* _ANALYSIS_VARIABLE_H */