summaryrefslogtreecommitdiff
path: root/src/format
diff options
context:
space:
mode:
Diffstat (limited to 'src/format')
-rw-r--r--src/format/Makefile.am2
-rw-r--r--src/format/mangling/Makefile.am25
-rw-r--r--src/format/mangling/demangler-int.h53
-rw-r--r--src/format/mangling/demangler.c134
-rw-r--r--src/format/mangling/demangler.h59
-rw-r--r--src/format/mangling/itanium.h37
-rw-r--r--src/format/mangling/itanium_gram.y518
-rw-r--r--src/format/mangling/itanium_tok.l116
8 files changed, 943 insertions, 1 deletions
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);
+
+}