diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-04-18 00:31:49 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-04-18 00:31:49 (GMT) |
commit | ef29fbc801e23f547b9ee7666b713bcf32d7e787 (patch) | |
tree | fb7466a56e2246c53a51d0475c1b5fc70ef3b8f9 /src/format | |
parent | 49468379e912806400c5874f8e359cb934516228 (diff) |
Improved the Itanium demangler.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@152 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/dwarf/Makefile.am | 2 | ||||
-rw-r--r-- | src/format/elf/helper_x86.c | 12 | ||||
-rw-r--r-- | src/format/mangling/Makefile.am | 2 | ||||
-rw-r--r-- | src/format/mangling/itanium_gram.y | 515 | ||||
-rw-r--r-- | src/format/mangling/itanium_tok.l | 12 |
5 files changed, 461 insertions, 82 deletions
diff --git a/src/format/dwarf/Makefile.am b/src/format/dwarf/Makefile.am index 6c6491a..f166b5e 100644 --- a/src/format/dwarf/Makefile.am +++ b/src/format/dwarf/Makefile.am @@ -15,7 +15,7 @@ libformatdwarf_la_SOURCES = \ libformatdwarf_la_LDFLAGS = $(LIBGTK_LIBS) -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index 862b112..62464d3 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -109,7 +109,7 @@ bool load_elf_x86_relocated_symbols(GElfFormat *format, const elf_shdr *relxxx, name = get_elf_symbol_name(format, dynsym, dynstr, index); - printf("got a jump ! >> %d - %s\n", index, name); + //printf("got a jump ! >> %d - %s\n", index, name); if (name == NULL) @@ -295,7 +295,7 @@ void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instru printf("++ routine :: %s\n", g_binary_symbol_to_string(symbols[j])); fflush(NULL); - routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), "_ZN1N1TIiiE2mfES0_IddE"); + //routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), "_ZN1N1TIiiE2mfES0_IddE"); routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), g_binary_symbol_to_string(symbols[j])); if (routine == NULL) @@ -418,16 +418,16 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru /* Routine */ - printf("++ routine :: %s\n", name); - fflush(NULL); + //printf("++ routine :: %s\n", name); + //fflush(NULL); - routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name); + routine = NULL;//try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name); if (routine == NULL) { routine = g_binary_routine_new(); g_binary_routine_set_name(routine, strdup(name)); - printf("++failed\n"); + //printf("++failed\n"); } else printf("++success\n"); diff --git a/src/format/mangling/Makefile.am b/src/format/mangling/Makefile.am index 80c0757..994919d 100644 --- a/src/format/mangling/Makefile.am +++ b/src/format/mangling/Makefile.am @@ -14,7 +14,7 @@ libformatmangling_la_SOURCES = \ libformatmangling_la_LDFLAGS = -INCLUDES = $(LIBGTK_CFLAGS) +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y index da1ea10..e6078b0 100644 --- a/src/format/mangling/itanium_gram.y +++ b/src/format/mangling/itanium_gram.y @@ -32,6 +32,9 @@ typedef struct _itanium_demangler size_t id_allocated; /* Taille allouée en mémoire */ size_t id_used; /* Longueur de la chaîne */ + bool use_templates; /* Utilisation des gabarits */ + GSList *routines; /* Routines en cours de maj */ + } itanium_demangler; @@ -50,6 +53,27 @@ void reset_itanium_identifier_building(itanium_demangler *); void build_itanium_identifier(itanium_demangler *, char); +/* Place sous le feu des projecteurs une nouvelle routine. */ +static GBinRoutine *push_routine(itanium_demangler *, GBinRoutine *); + +/* Remet une ancienne routine sous le feu des projecteurs. */ +static GBinRoutine *pop_routine(itanium_demangler *); + + + +/* Liste de substitutions */ +typedef GSList substi_list; + +/* Met en place une liste pour recueillir les substitutions. */ +static substi_list *create_substitution_list(void); + +/* Ajoute un élément dans une liste de substitutions. */ +static void add_substitution_item(substi_list *, GOpenidaType *); + +/* Fournit le nième élément d'une liste de substitutions. */ +static GOpenidaType *get_substitution_item(substi_list *, guint); + + /* Borne la longueur d'une chaîne à lire. */ @@ -90,26 +114,44 @@ char *strmerge(char *str1, const char *sep, char *str2); %union { + struct + { + union + { + char *str; + void/*GOpenidaType*/ *type; + }; + int/*bool*/ is_string; + + } str_or_type; + char car; char *text; unsigned int val; short/*s16_t*/ s16_val; + void /*GOpenidaType*/ *type; + void /*GTemplateType*/ *templtype; + void/*simple_variable*/ *simple; void/*complex_variable*/ *complex; void/*variable*/ *var; int/*VariableQualifier*/ qual; + void/*GSList*/ *slist; + } %parse-param { itanium_demangler *demangler } +%parse-param { substi_list *substitutions } %parse-param { GBinRoutine *routine } + %token ITANIUM_SIGNATURE -%token EE NN II +%token EE NN II FF LL %token C1 C2 C3 D1 D2 D3 @@ -130,6 +172,9 @@ char *strmerge(char *str1, const char *sep, char *str2); %token OPER_LESS_EQ OPER_GREATER_EQ OPER_NOT OPER_AND_AND OPER_OR_OR OPER_PLUS_PLUS OPER_MINUS_MINUS %token OPER_COMMA OPER_PRIV_MEMB OPER_POINTER_TO OPER_CLASS OPER_INDEX +%token SUBSTI_FIRST SUBSTI_N + +%token TPARAM_FIRST TPARAM_N %token NUMBER CHAR @@ -161,29 +206,37 @@ char *strmerge(char *str1, const char *sep, char *str2); %type <s16_val> DEC_16 +%type <str_or_type> name + +%type <text> unscoped_name +%type <type> nested_name + +%type <templtype> unscoped_template_name -%type <text> name unscoped_name unscoped_template_name nested_name %type <text> unqualified_name operator_name -%type <text> prefix source_name +%type <text> prefix template_prefix source_name + +%type <type> template_param template_template_param -%type <var> type +%type <type> function_type type %type <qual> qualifiers %type <simple> builtin_type -%type <complex> class_enum_type +%type <type> class_enum_type + +%type <slist> template_args template_arg_list +%type <type> template_arg expr_primary -%type <text> template_args template_arg_list template_arg %type <text> substitution %type <car> CHAR -%type <val> NUMBER - +%type <val> NUMBER SUBSTI_N TPARAM_N %{ @@ -204,21 +257,24 @@ extern void yy_delete_buffer(YY_BUFFER_STATE); %% + + input: ITANIUM_SIGNATURE encoding ; encoding: - name bare_function_type + name { $1.is_string ? g_binary_routine_set_name(routine, $1.str) : g_binary_routine_set_name_from_type(routine, $1.type); } + bare_function_type { ; } ; name: - nested_name { $$ = $1; g_binary_routine_set_name(routine, $1); } - | unscoped_name { $$ = $1; g_binary_routine_set_name(routine, $1); } - | unscoped_template_name template_args { $$ = stradd($1, $2); /* TODO : merge -> free */ } + nested_name { $$.type = $1; $$.is_string = false; } + | unscoped_name { $$.str = $1; $$.is_string = true; } + | unscoped_template_name template_args { $$.type = $1; $$.is_string = false; g_template_type_add_params($1, $2); } ; unscoped_name: @@ -227,27 +283,49 @@ unscoped_name: ; unscoped_template_name: - unscoped_name { $$ = $1; } - | substitution { $$ = $1; } + unscoped_name { $$ = g_template_type_new($1, NULL); add_substitution_item(substitutions, $$); } + | substitution { + $$ = NULL;/*g_openida_type_to_string($1)*/; + /*printf("unscoped sub name :: %s\n", $$); + g_object_unref(G_OBJECT($1));*/ + } ; nested_name: - NN prefix unqualified_name EE { $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); } + NN prefix unqualified_name EE { + $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); + $$ = g_class_enum_type_new(CET_UNKNOWN, $$); + } + | NN template_prefix template_args EE { $$ = g_template_type_new($2, $3); } ; prefix: - /* vide */ { $$ = NULL; printf("passage E\n"); } + /* vide */ { $$ = NULL; /*printf("passage E\n")*/; } | prefix unqualified_name { $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); } - | substitution { $$ = $1; } + | template_prefix template_args { $$ = g_template_type_new($1, $2); $$ = g_openida_type_to_string($$); /* FIXME : retourner un type ! */} + | substitution { + $$ = g_openida_type_to_string($1); + printf("prefix substi :: %s\n", $$); + g_object_unref(G_OBJECT($1)); + } + ; + +template_prefix: + prefix unqualified_name { $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); } + | template_param { + $$ = g_openida_type_to_string($1); + g_object_unref(G_OBJECT($1)); + } ; + unqualified_name: operator_name { printf("dup :: '%s'\n", $1); fflush(NULL) ;$$ = strdup($1) ; } | ctor_dtor_name { printf("passage C\n"); $$ = NULL; } @@ -258,7 +336,7 @@ unqualified_name: source_name: NUMBER { set_itanium_text_length($1); reset_itanium_identifier_building(demangler); } - identifier { $$ = strdup(demangler->identifier); } + identifier { $$ = strdup(demangler->identifier); printf("==source name== :: %s\n", $$); } ; identifier: @@ -330,92 +408,154 @@ ctor_dtor_name: ; +function_type: + FF { routine = push_routine(demangler, routine); } + bare_function_type EE { + $$ = g_encapsulated_type_new(ECT_ROUTINE, routine); + routine = pop_routine(demangler); + if (routine == NULL) YYERROR; + } + ; + + type: - builtin_type { $$ = create_var_from_simple_one($1); } - | class_enum_type { $$ = create_var_from_complex_one($1); } - | substitution { $$ = create_var_from_complex_one(create_class_enum_var($1)); } - | qualifiers type { $$ = $2; add_qualifier_to_var($2, $1); } - | TP type { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_POINTER, $2)); } - | TR type { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_REFERENCE, $2)); } - | TO type { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_RVALUE_REF, $2)); } - | TC type { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_COMPLEX, $2)); } - | TG type { $$ = create_var_from_complex_one(create_encapsulated_var(ECT_IMAGINARY, $2)); } + builtin_type { $$ = $1; printf("builtin '%s'\n", g_openida_type_to_string($1)); } + | class_enum_type { $$ = $1; add_substitution_item(substitutions, $1); } + | substitution { $$ = $1; } + | template_param { $$ = $1; } + | template_template_param template_args { + $$ = g_template_type_new(g_openida_type_to_string($1), NULL); + g_object_unref($1); + g_template_type_add_params($$, $2); + } + | function_type { $$ = $1; } + | qualifiers type { + $$ = g_openida_type_dup($2); + g_openida_type_add_qualifier($$, $1); + add_substitution_item(substitutions, $$); + } + | TP type { $$ = g_encapsulated_type_new(ECT_POINTER, $2); add_substitution_item(substitutions, $$); } + | TR type { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); add_substitution_item(substitutions, $$); } + | TO type { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); add_substitution_item(substitutions, $$); } + | TC type { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); add_substitution_item(substitutions, $$); } + | TG type { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); add_substitution_item(substitutions, $$); } ; qualifiers: - QR { $$ = VQF_RESTRICT; } - | QV { $$ = VQF_VOLATILE; } - | QK { $$ = VQF_CONST; } + QR { $$ = TQF_RESTRICT; } + | QV { $$ = TQF_VOLATILE; } + | QK { $$ = TQF_CONST; } ; builtin_type: - V { $$ = create_typed_simple_var(BTP_VOID); } - | W { $$ = create_typed_simple_var(BTP_WCHAR_T); } - | B { $$ = create_typed_simple_var(BTP_BOOL); } - | C { $$ = create_typed_simple_var(BTP_CHAR); } - | A { $$ = create_typed_simple_var(BTP_SCHAR); } - | H { $$ = create_typed_simple_var(BTP_UCHAR); } - | S { $$ = create_typed_simple_var(BTP_SHORT); } - | T { $$ = create_typed_simple_var(BTP_USHORT); } - | I { $$ = create_typed_simple_var(BTP_INT); } - | J { $$ = create_typed_simple_var(BTP_UINT); } - | L { $$ = create_typed_simple_var(BTP_LONG); } - | M { $$ = create_typed_simple_var(BTP_ULONG); } - | X { $$ = create_typed_simple_var(BTP_LONG_LONG); } - | Y { $$ = create_typed_simple_var(BTP_ULONG_LONG); } - | N { $$ = create_typed_simple_var(BTP_INT128); } - | O { $$ = create_typed_simple_var(BTP_UINT128); } - | F { $$ = create_typed_simple_var(BTP_FLOAT); } - | D { $$ = create_typed_simple_var(BTP_DOUBLE); } - | E { $$ = create_typed_simple_var(BTP_LONG_DOUBLE); } - | G { $$ = create_typed_simple_var(BTP_FLOAT128); } - | Z { $$ = create_typed_simple_var(BTP_ELLIPSIS); } - | DD { $$ = create_typed_simple_var(BTP_754R_64); } - | DE { $$ = create_typed_simple_var(BTP_754R_128); } - | DF { $$ = create_typed_simple_var(BTP_754R_32); } - | DH { $$ = create_typed_simple_var(BTP_754R_16); } - | DI { $$ = create_typed_simple_var(BTP_CHAR32_T); } - | DS { $$ = create_typed_simple_var(BTP_CHAR16_T); } - | U source_name { $$ = create_typed_simple_var(BTP_OTHER); /* TODO */ ; free($2); } + V { $$ = g_basic_type_new(BTP_VOID); } + | W { $$ = g_basic_type_new(BTP_WCHAR_T); } + | B { $$ = g_basic_type_new(BTP_BOOL); } + | C { $$ = g_basic_type_new(BTP_CHAR); } + | A { $$ = g_basic_type_new(BTP_SCHAR); } + | H { $$ = g_basic_type_new(BTP_UCHAR); } + | S { $$ = g_basic_type_new(BTP_SHORT); } + | T { $$ = g_basic_type_new(BTP_USHORT); } + | I { $$ = g_basic_type_new(BTP_INT); } + | J { $$ = g_basic_type_new(BTP_UINT); } + | L { $$ = g_basic_type_new(BTP_LONG); } + | M { $$ = g_basic_type_new(BTP_ULONG); } + | X { $$ = g_basic_type_new(BTP_LONG_LONG); } + | Y { $$ = g_basic_type_new(BTP_ULONG_LONG); } + | N { $$ = g_basic_type_new(BTP_INT128); } + | O { $$ = g_basic_type_new(BTP_UINT128); } + | F { $$ = g_basic_type_new(BTP_FLOAT); } + | D { $$ = g_basic_type_new(BTP_DOUBLE); } + | E { $$ = g_basic_type_new(BTP_LONG_DOUBLE); } + | G { $$ = g_basic_type_new(BTP_FLOAT128); } + | Z { $$ = g_basic_type_new(BTP_ELLIPSIS); } + | DD { $$ = g_basic_type_new(BTP_754R_64); } + | DE { $$ = g_basic_type_new(BTP_754R_128); } + | DF { $$ = g_basic_type_new(BTP_754R_32); } + | DH { $$ = g_basic_type_new(BTP_754R_16); } + | DI { $$ = g_basic_type_new(BTP_CHAR32_T); } + | DS { $$ = g_basic_type_new(BTP_CHAR16_T); } + | U source_name { $$ = g_basic_type_new(BTP_OTHER); /* TODO */ ; free($2); } ; bare_function_type: - bare_function_type type { g_binary_routine_add_arg(routine, $2); } - | type { g_binary_routine_add_arg(routine, $1); } + bare_function_type type { g_binary_routine_add_arg(routine, g_binary_variable_new($2)); } + | type { + if (demangler->use_templates) + g_binary_routine_set_return_type(routine, $1); + else + g_binary_routine_add_arg(routine, g_binary_variable_new($1)); + } ; class_enum_type: - name { $$ = create_class_enum_var($1); } + name { $$ = $1.is_string ? g_class_enum_type_new(CET_UNKNOWN, $1.str) : $1.type; } ; +template_param: + TPARAM_FIRST { + const GOpenidaType *type = g_binary_routine_get_type_from_name(routine); + if (G_IS_TEMPLATE_TYPE(type)) + $$ = g_template_type_get_param(G_TEMPLATE_TYPE(type), 0); + else $$ = NULL; + if ($$ == NULL) YYERROR; + } + | TPARAM_N { + const GOpenidaType *type = g_binary_routine_get_type_from_name(routine); + if (G_IS_TEMPLATE_TYPE(type)) + $$ = g_template_type_get_param(G_TEMPLATE_TYPE(type), $1 + 1); + else $$ = NULL; + if ($$ == NULL) YYERROR; + } + ; + +template_template_param: + template_param { $$ = $1; } + | substitution { $$ = $1; } + ; + template_args: - II template_arg_list EE { printf("passage I\n"); $$ = stradd(strprep($2, "<"), ">"); } + use_templates template_arg_list EE { $$ = $2; } + ; + +use_templates: + II { printf("new template !!!\n"); demangler->use_templates = true; } ; template_arg_list: - template_arg_list template_arg { $$ = strmerge($1, ", ", $2); } - | template_arg { $$ = $1; } + template_arg_list template_arg { $$ = g_slist_prepend($1, $2); } + | template_arg { $$ = g_slist_prepend(NULL, $1); } + | template_args { g_class_enum_type_new(CET_UNKNOWN, "template params"); } ; template_arg: - type { $$ = var_to_string($1); delete_var($1); } + type { $$ = $1; } + | expr_primary { $$ = $1; } ; + +expr_primary: + LL type NUMBER EE { $$ = $2; } + ; + + substitution: - ST { $$ = strdup("std"); } - | SA { $$ = strdup("std::allocator"); } - | SB { $$ = strdup("std::basic_string"); } - | SS { $$ = strdup("std::string"); } - | SI { $$ = strdup("std::istream"); } - | SO { $$ = strdup("std::ostream"); } - | SD { $$ = strdup("std::iostream"); } + ST { $$ = g_class_enum_type_new(CET_CLASS, "std"); } + | SA { $$ = g_class_enum_type_new(CET_CLASS, "std::allocator"); } + | SB { $$ = g_class_enum_type_new(CET_CLASS, "std::basic_string"); } + | SS { $$ = g_class_enum_type_new(CET_CLASS, "std::string"); } + | SI { $$ = g_class_enum_type_new(CET_CLASS, "std::istream"); } + | SO { $$ = g_class_enum_type_new(CET_CLASS, "std::ostream"); } + | SD { $$ = g_class_enum_type_new(CET_CLASS, "std::iostream"); } + | SUBSTI_FIRST { $$ = get_substitution_item(substitutions, 0); if ($$ == NULL) YYERROR; } + | SUBSTI_N { $$ = get_substitution_item(substitutions, $1 + 1); if ($$ == NULL) YYERROR; } ; @@ -516,15 +656,23 @@ bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name) GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *name) { GBinRoutine *result; /* Construction à retourner */ + substi_list *substitutions; /* Liste de substitutions */ YY_BUFFER_STATE buffer; /* Tampon pour bison */ int ret; /* Bilan de l'appel */ + /* TODO : reset ! */ + demangler->use_templates = false; + result = g_binary_routine_new(); + substitutions = create_substitution_list(); + buffer = yy_scan_string(name); - ret = yyparse(demangler, result); + ret = yyparse(demangler, substitutions, result); yy_delete_buffer(buffer); + //delete(substi_list *substitutions); + if (ret != 0) { /*delete_binary_routine(result); FIXME */ @@ -581,3 +729,224 @@ void build_itanium_identifier(itanium_demangler *demangler, char value) demangler->identifier[demangler->id_used] = 0; } + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : demangler = décodeur à mettre à jour. * +* previous = routine à sauvegarder. * +* * +* Description : Place sous le feu des projecteurs une nouvelle routine. * +* * +* Retour : Nouvelle routine à compléter. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *previous) +{ + GBinRoutine *result; /* Routine nouvelle à renvoyer */ + + result = g_binary_routine_new(); + + demangler->routines = g_slist_append(demangler->routines, previous); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : demangler = décodeur à mettre à jour. * +* * +* Description : Remet une ancienne routine sous le feu des projecteurs. * +* * +* Retour : Routine sauvegardée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBinRoutine *pop_routine(itanium_demangler *demangler) +{ + GBinRoutine *result; /* Routine nouvelle à renvoyer */ + GSList *last; /* Dernier élément */ + + last = g_slist_last(demangler->routines); + + if (last == NULL) result = NULL; + else + { + result = G_BIN_ROUTINE(last->data); + demangler->routines = g_slist_remove(demangler->routines, result); + } + + return result; + +} + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Met en place une liste pour recueillir les substitutions. * +* * +* Retour : Nouvelle liste vierge pour les substitutions. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static substi_list *create_substitution_list(void) +{ + return g_slist_alloc(); + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble des substitions enregistrées. * +* type = nouvel élément à placer dans la liste des substitut°. * +* * +* Description : Ajoute un élément dans une liste de substitutions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void add_substitution_item(substi_list *list, GOpenidaType *type) +{ + g_object_ref(G_OBJECT(type)); + + printf("push %p\n", type); + + g_slist_append(list, type); + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble des substitions enregistrées. * +* n = indice de l'élément à fournir. * +* * +* Description : Fournit le nième élément d'une liste de substitutions. * +* * +* Retour : Type prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GOpenidaType *get_substitution_item(substi_list *list, guint n) +{ + printf("get [%u] == %p\n", n, g_slist_nth_data(list, n + 1)); + + return G_OPENIDA_TYPE(g_slist_nth_data(list, n + 1)); + +} + + + +/****************************************************************************** +* * +* Paramètres : demangler = décodeur à utiliser. * +* * +* Description : Procède au test de décodages de chaînes de caractères. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +#ifdef DEBUG +void test_itanium_demangling(itanium_demangler *demangler) +{ + GBinRoutine *routine; + char *human; + char stop; + +#define TEST_ITANIUM_MANGLING(name, ref) \ + do \ + { \ + printf(" >> %s\n", name); \ + routine = demangle_itanium_routine(demangler, name); \ + if (routine == NULL) \ + { \ + printf("Error with %s\n", name); \ + stop = true; \ + } \ + else \ + { \ + human = g_binary_routine_to_string(routine); \ + printf(" >> %s\n", human); \ + stop = (strcmp(ref, human) != 0); \ + printf(" >> ok ? %s\n", (!stop ? "oui" : "non")); \ + if (stop) printf(" >> expected '%s'\n", ref); \ + free(human); \ + } \ + if (stop) goto end_of_test; \ + else printf("\n"); \ + } \ + while (0) + + /** + * Tests de : + * http://www.codesourcery.com/public/cxx-abi/abi-examples.html#mangling + */ + + TEST_ITANIUM_MANGLING("_Z1fv", "??? f(void)"); + + TEST_ITANIUM_MANGLING("_Z1fi", "??? f(int)"); + + TEST_ITANIUM_MANGLING("_Z3foo3bar", "??? foo(bar)"); + + TEST_ITANIUM_MANGLING("_Zrm1XS_", "??? %(X, X)"); + + TEST_ITANIUM_MANGLING("_ZplR1XS0_", "??? +(X &, X &)"); + + TEST_ITANIUM_MANGLING("_ZlsRK1XS1_", "??? <<(const X &, const X &)"); + + TEST_ITANIUM_MANGLING("_Z1fIiEvi", "void f<int>(int)"); + + TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)"); + + TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)"); + + TEST_ITANIUM_MANGLING("_Z3fooIiPFidEiEvv", "void foo<int, int (*)(double), int>(void)"); + + TEST_ITANIUM_MANGLING("_ZN6System5Sound4beepEv", "??? System::Sound::beep(void)"); + + TEST_ITANIUM_MANGLING("_Z1fI1XE vPV N1AIT_E1TE", "void f<X>(volatile A<X>::T *)"); + + //// TODO :: TEST_ITANIUM_MANGLING("_ZngILi42EE v N1A I XplT_Li2EE E 1TE", ""); + + TEST_ITANIUM_MANGLING("_Z4makeI7FactoryiE T_IT0_E v", "Factory<int> make<Factory, int>(void)"); + + TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)"); + + //TEST_ITANIUM_MANGLING("", ""); + + end_of_test: + + ; + +} +#endif diff --git a/src/format/mangling/itanium_tok.l b/src/format/mangling/itanium_tok.l index bc5f5f1..e8fb7f1 100644 --- a/src/format/mangling/itanium_tok.l +++ b/src/format/mangling/itanium_tok.l @@ -29,6 +29,8 @@ _Z { return ITANIUM_SIGNATURE; } E { return EE; } N { return NN; } I { return II; } +F { return FF; } +L { return LL; } C1 { return C1; } C2 { return C2; } @@ -133,13 +135,21 @@ cl { return OPER_CLASS; } ix { return OPER_INDEX; } +S_ { return SUBSTI_FIRST; } +S[0-9a-z]_ { yylval.val = atoi(yytext + 1); return SUBSTI_N; } + +T_ { return TPARAM_FIRST; } +T[0-9]*_ { yylval.val = atoi(yytext + 1); return TPARAM_N; } + + [0-9]+ { yylval.val = atoi(yytext); return NUMBER; } <identifier>. { if (--itanium_txt_length == 0) BEGIN(INITIAL); yylval.car = *yytext; return CHAR; } -<*>. { printf("error : '%s'\n", yytext); } +<*>[ ] +<*>. { printf("error : '%s'\n", yytext); } %% |