diff options
| -rw-r--r-- | ChangeLog | 44 | ||||
| -rw-r--r-- | configure.ac | 3 | ||||
| -rw-r--r-- | src/Makefile.am | 3 | ||||
| -rwxr-xr-x | src/analysis/Makefile.am | 4 | ||||
| -rw-r--r-- | src/analysis/prototype.c | 260 | ||||
| -rw-r--r-- | src/analysis/prototype.h | 69 | ||||
| -rw-r--r-- | src/analysis/variable.c | 728 | ||||
| -rw-r--r-- | src/analysis/variable.h | 176 | ||||
| -rw-r--r-- | src/binary.c | 2 | ||||
| -rwxr-xr-x | src/common/Makefile.am | 3 | ||||
| -rw-r--r-- | src/common/extstr.c | 85 | ||||
| -rw-r--r-- | src/common/extstr.h | 37 | ||||
| -rw-r--r-- | src/editor.c | 4 | ||||
| -rw-r--r-- | src/format/Makefile.am | 2 | ||||
| -rw-r--r-- | src/format/mangling/Makefile.am | 25 | ||||
| -rw-r--r-- | src/format/mangling/demangler-int.h | 53 | ||||
| -rw-r--r-- | src/format/mangling/demangler.c | 134 | ||||
| -rw-r--r-- | src/format/mangling/demangler.h | 59 | ||||
| -rw-r--r-- | src/format/mangling/itanium.h | 37 | ||||
| -rw-r--r-- | src/format/mangling/itanium_gram.y | 518 | ||||
| -rw-r--r-- | src/format/mangling/itanium_tok.l | 116 | 
21 files changed, 2358 insertions, 4 deletions
| @@ -1,5 +1,49 @@  2009-03-04  Cyrille Bagard <nocbos@gmail.com> +	* configure.ac: +	Look for the lex and yacc programs. Add the new Makefile from +	'src/format/mangling' directory to AC_CONFIG_FILES. + +	* src/analysis/Makefile.am: +	Add prototype.h.[ch] and variable.h.[ch] to libanalysis_a_SOURCES. + +	* src/analysis/prototype.c: +	* src/analysis/prototype.h: +	* src/analysis/variable.c: +	* src/analysis/variable.h: +	New entries: create an abstract representation of prototypes, types +	and variables. + +	* src/binary.c: +	Load strings and symbols again. + +	* src/common/extstr.c: +	* src/common/extstr.h: +	New entries: provide an extension to usual string functions. + +	* src/common/Makefile.am: +	Add extstr.[ch] to libcommon_a_SOURCES. + +	* src/editor.c: +	Load all demanglers. + +	* src/format/Makefile.am: +	Add mangling to SUBDIRS. + +	* src/format/mangling/demangler.c: +	* src/format/mangling/demangler.h: +	* src/format/mangling/demangler-int.h: +	* src/format/mangling/itanium_gram.y: +	* src/format/mangling/itanium.h: +	* src/format/mangling/itanium_tok.l: +	* src/format/mangling/Makefile.am: +	New entries: support (partially) Itanium C++ ABI mangling. + +	* src/Makefile.am: +	Add format/mangling/libformatmangling.a to openida_LDADD and reorder it. + +2009-03-04  Cyrille Bagard <nocbos@gmail.com> +  	* src/analysis/line.c:  	* src/analysis/line.h:  	Add a line type for binary code display and some generic diff --git a/configure.ac b/configure.ac index 86334a5..7a95ffd 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,8 @@ AC_CONFIG_SRCDIR([src/editor.c])  AC_PROG_CC  AM_PROG_CC_C_O +AC_PROG_LEX +AC_PROG_YACC  AC_PROG_INSTALL  AC_PROG_MAKE_SET  AC_PROG_LIBTOOL @@ -190,6 +192,7 @@ AC_CONFIG_FILES([Makefile                   src/format/dwarf/Makefile                   src/format/elf/Makefile                   src/format/java/Makefile +                 src/format/mangling/Makefile                   src/format/pe/Makefile                   src/gtkext/Makefile                   src/panel/Makefile]) diff --git a/src/Makefile.am b/src/Makefile.am index 948cc32..30dc2d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,16 +27,17 @@ openida_LDFLAGS = $(LIBGTK_LIBS) -L/usr/X11R6/lib -ldl -lm $(LIBXML_LIBS) `pkg-c  openida_LDADD = $(LIBINTL) 				\ -	analysis/libanalysis.a				\  	arch/libarch.a						\  	arch/x86/libarchx86.a				\  	format/libformat.a					\  	format/dwarf/libformatdwarf.a		\  	format/elf/libformatelf.a			\  	format/java/libformatjava.a			\ +	format/mangling/libformatmangling.a	\  	format/pe/libformatpe.a				\  	gtkext/libgtkext.a					\  	panel/libpanel.a					\ +	analysis/libanalysis.a				\  	common/libcommon.a 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 */ diff --git a/src/binary.c b/src/binary.c index d55eb4a..427ad4e 100644 --- a/src/binary.c +++ b/src/binary.c @@ -549,6 +549,8 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel, GtkWidget *panel2)      gtk_snippet_set_rendering_lines(snippet, lines); +    handle_new_exe_on_symbols_panel(panel, format); +    handle_new_exe_on_strings_panel(panel2, format);      return; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index a27a192..6ad3fc3 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -3,7 +3,8 @@ lib_LIBRARIES = libcommon.a  libcommon_a_SOURCES =					\  	dllist.h dllist.c					\ -	endianness.h endianness.c +	endianness.h endianness.c			\ +	extstr.h extstr.c  libcommon_a_CFLAGS = $(AM_CFLAGS) diff --git a/src/common/extstr.c b/src/common/extstr.c new file mode 100644 index 0000000..aba9830 --- /dev/null +++ b/src/common/extstr.c @@ -0,0 +1,85 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * extstr.c - extension des fonctions relatives aux chaînes + * + * 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 "extstr.h" + + +#include <malloc.h> +#include <string.h> + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : str1 = chaîne de caractères à compléter.                     * +*                str2 = chaîne de caractères à ajouter.                       * +*                                                                             * +*  Description : Complète une chaîne de caractères avec une autre.            * +*                                                                             * +*  Retour      : Chaîne de caractères complétée, à libérer de la mémoire.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *stradd(char *str1, const char *str2) +{ +    char *result;                           /* Chaîne à renvoyer           */ + +    result = (char *)realloc(str1, (strlen(str1) + strlen(str2) + 1) * sizeof(char)); + +    strcat(result, str2); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : str1 = chaîne de caractères à compléter.                     * +*                str2 = chaîne de caractères à ajouter.                       * +*                                                                             * +*  Description : Fait précéder une chaîne de caractères par une autre.        * +*                                                                             * +*  Retour      : Chaîne de caractères complétée, à libérer de la mémoire.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char *strprep(char *str1, const char *str2) +{ +    char *result;                           /* Chaîne à renvoyer           */ +    size_t len2;                            /* Taille de la seconde chaîne */ + +    result = (char *)realloc(str1, (strlen(str1) + strlen(str2) + 1) * sizeof(char)); + +    len2 = strlen(str2); + +    memmove(&result[len2], result, strlen(result) + 1); +    memcpy(result, str2, len2); + +    return result; + +} diff --git a/src/common/extstr.h b/src/common/extstr.h new file mode 100644 index 0000000..8975000 --- /dev/null +++ b/src/common/extstr.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * extstr.h - prototypes pour une extension des fonctions relatives aux chaînes + * + * 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 _COMMON_EXTSTR_H +#define _COMMON_EXTSTR_H + + + +/* Complète une chaîne de caractères avec une autre. */ +char *stradd(char *str1, const char *str2); + +/* Fait précéder une chaîne de caractères par une autre. */ +char *strprep(char *, const char *); + + + +#endif  /* _COMMON_EXTSTR_H */ diff --git a/src/editor.c b/src/editor.c index e6d7516..c1041c6 100644 --- a/src/editor.c +++ b/src/editor.c @@ -57,6 +57,7 @@  #include "pan_strings.h"  #include "pan_symbols.h"  #include "gtkext/gtkdockpanel.h" +#include "format/mangling/demangler.h"  #include "panel/panels.h" @@ -161,6 +162,9 @@ int main(int argc, char **argv)      add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps");      /* Initialisation du programme */ +    init_all_demanglers(); + +    /* Création de l'interface */      editor = create_editor();      gtk_widget_show(editor); diff --git a/src/format/Makefile.am b/src/format/Makefile.am index 7c2c524..13f80a6 100644 --- a/src/format/Makefile.am +++ b/src/format/Makefile.am @@ -16,4 +16,4 @@ AM_CPPFLAGS =  AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) -SUBDIRS = dwarf elf java pe +SUBDIRS = dwarf elf java mangling pe diff --git a/src/format/mangling/Makefile.am b/src/format/mangling/Makefile.am new file mode 100644 index 0000000..71a0923 --- /dev/null +++ b/src/format/mangling/Makefile.am @@ -0,0 +1,25 @@ + +BUILT_SOURCES = itanium_gram.h + +AM_YFLAGS = -d + +lib_LIBRARIES = libformatmangling.a + +libformatmangling_a_SOURCES =			\ +	demangler.h demangler.c				\ +	itanium.h							\ +	itanium_gram.y						\ +	itanium_tok.l + +libformatmangling_a_CFLAGS = $(AM_CFLAGS) + + +INCLUDES = $(LIBGTK_CFLAGS) + +AM_CPPFLAGS =  + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) + + +# Automake fait les choses à moitié +CLEANFILES = itanium_gram.h itanium_gram.c itanium_tok.c diff --git a/src/format/mangling/demangler-int.h b/src/format/mangling/demangler-int.h new file mode 100644 index 0000000..2189bd0 --- /dev/null +++ b/src/format/mangling/demangler-int.h @@ -0,0 +1,53 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * demangler-int.h - prototypes internes pour le décodage des noms d'éléments + * + * 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 _FORMAT_MANGLING_DEMANGLER_INT_H +#define _FORMAT_MANGLING_DEMANGLER_INT_H + + +#include "demangler.h" +#include "../../analysis/prototype.h" + + + +/* Indique si une chaîne peut être traitée par le décodeur. */ +typedef bool (* can_be_demangled_fc) (name_demangler *, const char *); + +/* Procède au décodage d'une chaîne de caractères. */ +typedef bin_routine * (* demangle_routine_fc) (name_demangler *, const char *); + + +/* Décodeur de nom d'éléments */ +struct _name_demangler +{ +    can_be_demangled_fc can_be_demangled;   /* Capacité de traitement      */ +    demangle_routine_fc demangle_routine;   /* Décodage de chaînes         */ + +}; + + +#define NAME_DEMANGLER(dmgl) ((name_demangler *)dmgl) + + + +#endif  /* _FORMAT_MANGLING_DEMANGLER_INT_H */ diff --git a/src/format/mangling/demangler.c b/src/format/mangling/demangler.c new file mode 100644 index 0000000..5675800 --- /dev/null +++ b/src/format/mangling/demangler.c @@ -0,0 +1,134 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * demangler.c - décodage des noms d'éléments + * + * 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 "demangler.h" + + +#include <malloc.h> + + +#include "demangler-int.h" +#include "itanium.h" + + + +static name_demangler **demanglers = NULL; +static size_t demanglers_count = 0; + + + +/* Enregistre un nouveau décodeur de noms. */ +void register_new_demangler(name_demangler *); + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Procède au chargement des différents décodeurs de noms.      * +*                                                                             * +*  Retour      : true pour indiquer un chargement réussi, false sinon.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool init_all_demanglers(void) +{ +    register_new_demangler(create_itanium_demangler()); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur opérationnel.                           * +*                                                                             * +*  Description : Enregistre un nouveau décodeur de noms.                      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void register_new_demangler(name_demangler *demangler) +{ +    demanglers = (name_demangler **)realloc(demanglers, ++demanglers_count * sizeof(name_demangler *)); +    demanglers[demanglers_count - 1] = demangler; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : type = identifiant du décodeur visé.                         * +*                                                                             * +*  Description : Fournit la référence correspondant à un décodeur donné.      * +*                                                                             * +*  Retour      : Adresse du décodeur trouvé ou NULL.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +name_demangler *get_demangler_by_type(DemanglerType type) +{ +    name_demangler *result;                 /* Adresse à retourner         */ + +    result = demanglers[0]; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à utiliser.                             * +*                name      = chaîne de caractères à décoder.                  * +*                                                                             * +*  Description : Tente de décoder une chaîne de caractères donnée.            * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bin_routine *try_to_demangle_routine(name_demangler *demangler, const char *name) +{ +    bin_routine *result;                    /* Construction à remonter     */ + +    result = NULL; + +    if (demangler->can_be_demangled(demangler, name)) +        result = demangler->demangle_routine(demangler, name); + +    return result; + +} diff --git a/src/format/mangling/demangler.h b/src/format/mangling/demangler.h new file mode 100644 index 0000000..259d73d --- /dev/null +++ b/src/format/mangling/demangler.h @@ -0,0 +1,59 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * demangler.h - prototypes pour le décodage des noms d'éléments + * + * 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 _FORMAT_MANGLING_DEMANGLER_H +#define _FORMAT_MANGLING_DEMANGLER_H + + +#include <stdbool.h> + + +#include "../../analysis/prototype.h" + + + +/* Identifiant des décodeurs existants */ +typedef enum _DemanglerType +{ +    DGT_ITANIUM                             /* Gnu V3                      */ + +} DemanglerType; + + +/* Décodeur de nom d'éléments */ +typedef struct _name_demangler name_demangler; + + + +/* Procède au chargement des différents décodeurs de noms. */ +bool init_all_demanglers(void); + +/* Fournit la référence correspondant à un décodeur donné. */ +name_demangler *get_demangler_by_type(DemanglerType); + +/* Tente de décoder une chaîne de caractères donnée. */ +bin_routine *try_to_demangle_routine(name_demangler *, const char *); + + + +#endif  /* _FORMAT_MANGLING_DEMANGLER_H */ diff --git a/src/format/mangling/itanium.h b/src/format/mangling/itanium.h new file mode 100644 index 0000000..8482af3 --- /dev/null +++ b/src/format/mangling/itanium.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * itanium.h - prototypes pour le décodage des noms d'éléments selon Intel + * + * 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 _FORMAT_MANGLING_ITANIUM_H +#define _FORMAT_MANGLING_ITANIUM_H + + +#include "demangler.h" + + + +/* Définit un décodeur répondant à la norme d'Intel. */ +name_demangler *create_itanium_demangler(void); + + + +#endif  /* _FORMAT_MANGLING_ITANIUM_H */ diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y new file mode 100644 index 0000000..7c13c79 --- /dev/null +++ b/src/format/mangling/itanium_gram.y @@ -0,0 +1,518 @@ + +%{ + + +#include <malloc.h> +#include <stdio.h> +#include <string.h> + + +#include "demangler-int.h" +#include "itanium.h" +#include "../../common/extstr.h" + + + +/** + * cf. http://www.codesourcery.com/cxx-abi/abi.html#mangling + */ + + +/* Taille du bond pour les allocations */ +#define ITANIUM_ALLOC_CLUSTER   10 + + + +/* Décodeur de nom d'éléments selon la définition Intel */ +typedef struct _itanium_demangler +{ +    name_demangler common;                  /* A laisser en premier        */ + +    char *identifier;                       /* Identifiant en construction */ +    size_t id_allocated;                    /* Taille allouée en mémoire   */ +    size_t id_used;                         /* Longueur de la chaîne       */ + +} itanium_demangler; + + +/* Indique si une chaîne peut être traitée par le décodeur. */ +bool can_be_itanium_demangled(itanium_demangler *, const char *); + +/* Procède au décodage d'une chaîne de caractères. */ +bin_routine *demangle_itanium_routine(itanium_demangler *, const char *); + + + +/* Réinitialise le constructeur d'identifiants. */ +void reset_itanium_identifier_building(itanium_demangler *); + +/* Construit à la volée un identifiant. */ +void build_itanium_identifier(itanium_demangler *, char); + + + + +/* Borne la longueur d'une chaîne à lire. */ +extern void set_itanium_text_length(unsigned int); + + + + + +char *strmerge(char *str1, const char *sep, char *str2); + char *strmerge(char *str1, const char *sep, char *str2) +{ +    char *result; + +    if (str1 == NULL) result = str2; +    else if (str2 == NULL) result = str1; +    else +    { +        result = (char *)calloc(strlen(str1) + strlen(sep) + strlen(str2) + 1, sizeof(char)); + +        strcpy(result, str1); +        strcat(result, sep); +        strcat(result, str2); + +        free(str1); +        free(str2); + +    } + +    return result; + +} + + + +%} + + +%union { + +    char car; +	char *text; +    unsigned int val; +	short/*s16_t*/ s16_val; + +    void/*simple_variable*/ *simple; +    void/*complex_variable*/ *complex; +    void/*variable*/ *var; + +    int/*VariableQualifier*/ qual; + +} + +%parse-param { itanium_demangler *demangler } +%parse-param { bin_routine *routine } + + +%token ITANIUM_SIGNATURE + +%token EE NN II + +%token C1 C2 C3 D1 D2 D3 + +%token V W B C A H S T I J L M X Y N O F D E G Z DD DE DF DH DI DS U + +%token TP TR TO TC TG + +%token QR QV QK + +%token ST SA SB SS SI SO SD + + +%token NUMBER CHAR + + + + + + + + + +%token LPART MPART RPART + + +%token POSITION POSITION_ABS IMAGE + +%token RECT + +%token O_BRACKET C_BRACKET + +%token PATH +%token DEC_16 + +%token TEXT + + +%type <text> TEXT PATH + +%type <s16_val> DEC_16 + + + + +%type <text> name unscoped_name unscoped_template_name nested_name +%type <text> unqualified_name +%type <text> prefix source_name + + +%type <var> type + +%type <qual> qualifiers + +%type <simple> builtin_type + +%type <complex> class_enum_type + + +%type <text> template_args template_arg_list template_arg +%type <text> substitution + + +%type <car> CHAR +%type <val> NUMBER + + +%{ + +/* De lexi.c... */ +/*int yylex(YYSTYPE *, YYLTYPE *);*/ +void yyrestart(FILE *); +typedef struct yy_buffer_state *YY_BUFFER_STATE; +extern YY_BUFFER_STATE yy_scan_string(const char *); +extern void yy_delete_buffer(YY_BUFFER_STATE); + + +/* Affiche un message d'erreur concernant l'analyse. */ +/*int yyerror(const YYLTYPE *, bool, char **, unsigned char *, char *);*/ + +%} + + +%% + + +input: +	ITANIUM_SIGNATURE encoding +	; + +encoding: +    name bare_function_type +    ; + + + + +name: +    nested_name                     { $$ = $1; set_binary_routine_name(routine, $1); } +    | unscoped_name                 { $$ = $1; /*set_binary_routine_name(routine, $1);*/ } +    | unscoped_template_name template_args  { $$ = stradd($1, $2); /* TODO : merge -> free */ } +    ; + +unscoped_name: +    unqualified_name                { $$ = $1; } +    | ST unqualified_name           { $$ = strprep($2, "std::"); } +    ; + +unscoped_template_name: +    unscoped_name                   { $$ = $1; } +    | substitution                  { $$ = $1; } +    ; + + + +nested_name: +    NN prefix unqualified_name EE   { $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); } +    ; + + + +prefix: +    /* vide */                      { $$ = NULL; } +    | prefix unqualified_name       { $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); } +    ; + + + + +unqualified_name: +    ctor_dtor_name                  { $$ = NULL; } +    | source_name                   { $$ = $1; } +    ; + + + +source_name: +    NUMBER                          { set_itanium_text_length($1); reset_itanium_identifier_building(demangler); }  +        identifier                  { $$ = strdup(demangler->identifier); } +    ; + +identifier: +    identifier CHAR                 { build_itanium_identifier(demangler, $2); } +    | CHAR                          { build_itanium_identifier(demangler, $1); } +    ; + +ctor_dtor_name: +    C1                              { set_binary_routine_type(routine, RTT_CONSTRUCTOR); } +    | C2                            { set_binary_routine_type(routine, RTT_CONSTRUCTOR); } +    | C3                            { set_binary_routine_type(routine, RTT_CONSTRUCTOR); } +    | D1                            { set_binary_routine_type(routine, RTT_DESTRUCTOR); } +    | D2                            { set_binary_routine_type(routine, RTT_DESTRUCTOR); } +    | D3                            { set_binary_routine_type(routine, RTT_DESTRUCTOR); } +    ; + + +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)); } +    ; + +qualifiers: +    QR                              { $$ = VQF_RESTRICT; } +    | QV                            { $$ = VQF_VOLATILE; } +    | QK                            { $$ = VQF_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); } +    ; + + + +bare_function_type: +    bare_function_type type         { add_arg_to_binary_routine(routine, $2); } +    | type                          { add_arg_to_binary_routine(routine, $1); } +    ; + +class_enum_type: +    name                            { $$ = create_class_enum_var($1); } +    ; + + + + +template_args: +    II template_arg_list EE         { $$ = stradd(strprep($2, "<"), ">"); } +    ; + +template_arg_list: +    template_arg_list template_arg  { $$ = strmerge($1, ", ", $2); } +    | template_arg                  { $$ = $1; } +    ; + +template_arg: +    type                            { $$ = var_to_string($1); delete_var($1); } +    ; + +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"); } +    ; + + + + + + + +%% + + +/** + * Affiche un message d'erreur concernant l'analyse. + * @param yyloc informations concernant les coordonnées du soucis. + * @param hunt indique le type de passe réalisée. + * @param ucode code résultant compilé. + * @param index indice de commande à mettre à jour. + * @param msg indications humaines sur l'événement. + * @return 0. + */ +int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *index, */char *msg) +{ + + + +	fprintf(stderr, "ERREUR !\n"); +	fprintf(stderr, "%s\n", msg); + +	return -1; + +} + + + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Définit un décodeur répondant à la norme d'Intel.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +name_demangler *create_itanium_demangler(void) +{ +    itanium_demangler *result;              /* Structure à retourner       */ + +    result = (itanium_demangler *)calloc(1, sizeof(itanium_demangler)); + +    NAME_DEMANGLER(result)->can_be_demangled = (can_be_demangled_fc)can_be_itanium_demangled; +    NAME_DEMANGLER(result)->demangle_routine = (demangle_routine_fc)demangle_itanium_routine; + +    return NAME_DEMANGLER(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à utiliser.                             * +*                name      = chaîne de caractères à analyser.                 * +*                                                                             * +*  Description : Indique si une chaîne peut être traitée par le décodeur.     * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name) +{ +    return (strncmp(name, "_Z", 2) == 0); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à utiliser.                             * +*                name      = chaîne de caractères à décoder.                  * +*                                                                             * +*  Description : Procède au décodage d'une chaîne de caractères.              * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bin_routine *demangle_itanium_routine(itanium_demangler *demangler, const char *name) +{ +    bin_routine *result;                    /* Construction à retourner    */ +	YY_BUFFER_STATE buffer;                 /* Tampon pour bison           */ +	int ret;                                /* Bilan de l'appel            */ + +    result = create_binary_routine(); + +	buffer = yy_scan_string(name); +	ret = yyparse(demangler, result); +	yy_delete_buffer(buffer); + +    if (ret != 0) +    { +        delete_binary_routine(result); +        result = NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à mettre à jour.                        * +*                                                                             * +*  Description : Réinitialise le constructeur d'identifiants.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void reset_itanium_identifier_building(itanium_demangler *demangler) +{ +    demangler->id_used = 0; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : demangler = décodeur à mettre à jour.                        * +*                value     = caractère d'identifiant à mémoriser.             * +*                                                                             * +*  Description : Construit à la volée un identifiant.                         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void build_itanium_identifier(itanium_demangler *demangler, char value) +{ +    if ((demangler->id_used + 2) > demangler->id_allocated) +    { +        demangler->id_allocated += ITANIUM_ALLOC_CLUSTER; +        demangler->identifier = (char *)realloc(demangler->identifier, +                                                demangler->id_allocated * sizeof(char)); +    } + +    demangler->identifier[demangler->id_used++] = value; +    demangler->identifier[demangler->id_used] = 0; + +} diff --git a/src/format/mangling/itanium_tok.l b/src/format/mangling/itanium_tok.l new file mode 100644 index 0000000..5eef799 --- /dev/null +++ b/src/format/mangling/itanium_tok.l @@ -0,0 +1,116 @@ + +%{ + +#include "itanium_gram.h"  + + +static unsigned int itanium_txt_length = 0; + + +/* Borne la longueur d'une chaîne à lire. */ +void set_itanium_text_length(unsigned int); + + +%} + + +%option noyywrap +%option yylineno + + +%x identifier + + +%% + + +_Z                      { return ITANIUM_SIGNATURE; } + +E                       { return EE; } +N                       { return NN; } +I                       { return II; } + +C1                      { return C1; } +C2                      { return C2; } +C3                      { return C3; } +D0                      { return C1; } +D1                      { return D2; } +D2                      { return D3; } + +v                       { return V; } +w                       { return W; } +b                       { return B; } +c                       { return C; } +a                       { return A; } +h                       { return H; } +s                       { return S; } +t                       { return T; } +i                       { return I; } +j                       { return J; } +l                       { return L; } +m                       { return M; } +x                       { return X; } +y                       { return Y; } +n                       { return N; } +o                       { return O; } +f                       { return F; } +d                       { return D; } +e                       { return E; } +g                       { return G; } +z                       { return Z; } +Dd                      { return DD; } +De                      { return DE; } +Df                      { return DF; } +Dh                      { return DH; } +Di                      { return DI; } +Ds                      { return DS; } +u                       { return U; } + +P                       { return TP; } +R                       { return TR; } +O                       { return TO; } +C                       { return TC; } +G                       { return TG; } + +r                       { return QR; } +V                       { return QV; } +K                       { return QK; } + +St                      { return ST; } +Sa                      { return SA; } +Sb                      { return SB; } +Ss                      { return SS; } +Si                      { return SI; } +So                      { return SO; } +Sd                      { return SD; } + + +[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); } + + +%% + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : length = taille de chaîne à lire.                            * +*                                                                             * +*  Description : Borne la longueur d'une chaîne à lire.                       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void set_itanium_text_length(unsigned int length) +{ +    itanium_txt_length = length; + +    BEGIN(identifier); + +} | 
