diff options
Diffstat (limited to 'src/format/mangling/itanium_gram.y')
-rw-r--r-- | src/format/mangling/itanium_gram.y | 1222 |
1 files changed, 0 insertions, 1222 deletions
diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y deleted file mode 100644 index 0fd3b2b..0000000 --- a/src/format/mangling/itanium_gram.y +++ /dev/null @@ -1,1222 +0,0 @@ - -%{ - - -#include <malloc.h> -#include <stdio.h> -#include <string.h> - - -#include "context-int.h" -#include "itanium.h" -#include "../../common/extstr.h" -#include "../../analysis/types/cse.h" -#include "../../analysis/types/template.h" - - - -/** - * cf. http://www.codesourcery.com/cxx-abi/abi.html#mangling - */ - - - -/* --------------------- CONTEXTE POUR LE DECODAGE TYPE ITANIUM --------------------- */ - - -#define G_TYPE_ITANIUM_DCONTEXT g_itanium_dcontext_get_type() -#define G_ITANIUM_DCONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_itanium_dcontext_get_type(), GItaniumDContext)) -#define G_IS_ITANIUM_DCONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_itanium_dcontext_get_type())) -#define G_ITANIUM_DCONTEXT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_itanium_dcontext_get_type(), GItaniumDContextIface)) -#define G_ITANIUM_DCONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ITANIUM_DCONTEXT, GItaniumDContextClass)) - - -/* Contexte de décodage Itanium (instance) */ -struct _GItaniumDContext -{ - GDemanglingContext parent; /* 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 */ - - GSList *routines; /* Routines en cours de maj */ - - GSList *substitutions; /* Empilement des types créés */ - - bool start_args; /* Début de définitions d'args */ - unsigned int template_level; /* Compteur d'imbrications */ - -}; - -/* Contexte de décodage Itanium (classe) */ -struct _GItaniumDContextClass -{ - GDemanglingContextClass parent; /* A laisser en premier */ - -}; - - -/* Taille du bond pour les allocations */ -#define ITANIUM_ALLOC_CLUSTER 10 - - -/* Indique le type défini pour un contexte de décodage. */ -static GType g_itanium_dcontext_get_type(void); - -/* Initialise la classe des contextes de décodage. */ -static void g_itanium_dcontext_class_init(GItaniumDContextClass *); - -/* Initialise une instance de contexte pour décodage. */ -static void g_itanium_dcontext_init(GItaniumDContext *); - -/* Supprime toutes les références externes. */ -static void g_itanium_dcontext_dispose(GItaniumDContext *); - -/* Procède à la libération totale de la mémoire. */ -static void g_itanium_dcontext_finalize(GItaniumDContext *); - -/* Réinitialise le constructeur d'identifiants. */ -static void g_itanium_dcontext_reset_identifier(GItaniumDContext *); - -/* Construit à la volée un identifiant. */ -static void g_itanium_dcontext_build_identifier(GItaniumDContext *, char); - -/* Place sous le feu des projecteurs une nouvelle routine. */ -static GBinRoutine *g_itanium_dcontext_push_routine(GItaniumDContext *, GBinRoutine *); - -/* Remet une ancienne routine sous le feu des projecteurs. */ -static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *); - -/* Ajoute un élément dans une liste de substitutions. */ -static void g_itanium_dcontext_add_item(GItaniumDContext *, GDataType *); - -/* Fournit le nième élément d'une liste de substitutions. */ -static GDataType *g_itanium_dcontext_get_item(GItaniumDContext *, guint); - -/* Autorise ou non le dépilement des opérateurs. */ -static void g_itanium_dcontext_update(GItaniumDContext *); - - - -/* ------------------------ TRAITEMENT DE L'ENCODAGE ITANIUM ------------------------ */ - - -/* Fait sauter le premier argument en faveur du type de retour. */ -static void compute_routine_itanium_ret_type(GBinRoutine *); - -/* Recherche et fait sauter les premiers arguments rencontrés. */ -static void update_itanium_ret_type(GDataType *); - - - - - - - - - -/* Borne la longueur d'une chaîne à lire. */ -extern void set_itanium_text_length(unsigned int); - -/* Autorise la lecture des opérateurs. */ -extern void allow_itanium_operators(void); - -/* Autorise la lecture des opérateurs. */ -extern void exclude_itanium_operators(void); - - - - - - -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 { - - struct - { - union - { - char *str; - void/*GDataType*/ *type; - }; - int/*bool*/ is_string; - - } str_or_type; - - char car; - char *text; - unsigned int val; - short/*s16_t*/ s16_val; - - void /*GDataType*/ *type; - void /*GTemplateType*/ *templtype; - - void/*simple_variable*/ *simple; - void/*complex_variable*/ *complex; - void/*variable*/ *var; - - int/*VariableQualifier*/ qual; - - void/*GSList*/ *slist; - -} - -%parse-param { GItaniumDContext *context } -%parse-param { GBinRoutine *routine } - - - -%token ITANIUM_SIGNATURE - -%token EE NN II FF LL - -%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 OPER_NEW OPER_NEW_ARRAY OPER_DELETE OPER_DELETE_ARRAY OPER_PLUS_UNARY OPER_NEG_UNARY -%token OPER_AND_UNARY OPER_DE_UNARY OPER_COMPL OPER_PLUS OPER_MINUS OPER_MUL OPER_DIV OPER_MOD -%token OPER_AND OPER_OR OPER_EXCL_OR OPER_AS OPER_PLUS_EQ OPER_MINUS_EQ OPER_MUL_EQ OPER_DIV_EQ -%token OPER_MOD_EQ OPER_AND_EQ OPER_OR_EQ OPER_EXCL_OR_EQ OPER_LEFT_SHIFT OPER_RIGHT_SHIFT -%token OPER_LEFT_SHIFT_EQ OPER_RIGHT_SHIFT_EQ OPER_EQUAL OPER_NOT_EQ OPER_LESS OPER_GREATER -%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 - - - - - - - - - -%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 <str_or_type> name - -%type <text> unscoped_name - -%type <type> nested_name - -%type <templtype> unscoped_template_name - -%type <text> unqualified_name operator_name - -%type <text> registered_prefix - -%type <type> prefix - -%type <text> template_prefix source_name - -%type <type> registered_template_prefix - -%type <type> template_param template_template_param - -%type <type> function_type type - -%type <qual> qualifiers - -%type <simple> builtin_type - -%type <type> class_enum_type - - -%type <slist> template_args template_arg_list -%type <type> template_arg expr_primary - -%type <type> substitution - - -%type <car> CHAR -%type <val> NUMBER SUBSTI_N TPARAM_N - -%{ - -/* 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 { $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 { $$.type = $1; $$.is_string = false; } - | unscoped_name { $$.str = $1; $$.is_string = true; } - | unscoped_template_name template_args { - - if (G_IS_TEMPLATE_TYPE($1)) - { - g_template_type_add_params($1, $2); - - $$.type = $1; - $$.is_string = false; - - } - - else - { - char *tmp; - - tmp = g_data_type_to_string($1); - - $$.type = g_template_type_new(tmp, $2); - $$.is_string = false; - - free(tmp); - g_object_unref(G_OBJECT($1)); - - } - - //g_template_type_add_params($1, $2); - printf(" [name tmp:: %s]\n", g_data_type_to_string($$.type)); - } - ; - -unscoped_name: - unqualified_name { $$ = $1; } - | ST unqualified_name { $$ = strprep($2, "std::"); } - ; - -unscoped_template_name: - unscoped_name { $$ = g_template_type_new($1, NULL); g_itanium_dcontext_add_item(context, $$); } - | substitution { $$ = $1; } - ; - - -nested_name: - NN registered_prefix unqualified_name EE { - $$ = ($3 != NULL ? strmerge($2, "::", $3) : $2); printf("passage nested p+uq = '%s'\n", $$); - $$ = g_class_enum_type_new(CET_UNKNOWN, $$); g_itanium_dcontext_add_item(context, $$); - } - | NN qualifiers registered_prefix unqualified_name EE { - $$ = ($4 != NULL ? strmerge($3, "::", $4) : $3); printf("passage nested p+uq = '%s'\n", $$); - $$ = g_class_enum_type_new(CET_UNKNOWN, $$); g_itanium_dcontext_add_item(context, $$); - } - | NN registered_template_prefix template_args EE { $$ = $2; g_template_type_add_params($2, $3); printf(" [nested tmp:: %s]\n", g_data_type_to_string($$)); } - | NN qualifiers registered_template_prefix template_args EE { $$ = $3; g_template_type_add_params($3, $4); printf(" [nested tmp:: %s]\n", g_data_type_to_string($$)); } - ; - - - -registered_prefix: - prefix { - if ($1 == NULL) $$ = NULL; - else - { - g_itanium_dcontext_add_item(context, $1); - $$ = g_data_type_to_string($1); - } - } - | substitution { - $$ = g_data_type_to_string($1); - printf("prefix substi :: %s\n", g_data_type_to_string($1)); - } - ; - -prefix: - /* vide */ { $$ = NULL; } - | registered_prefix unqualified_name { $$ = ($2 != NULL ? g_class_enum_type_new(CET_CLASS, strmerge($1, "::", $2)) : $1); printf("passage p+uq = '%s'\n", g_data_type_to_string($$)); } - | registered_template_prefix template_args { $$ = $1; g_template_type_add_params($1, $2); printf("passage p_tmp = '%s'\n", g_data_type_to_string($$)); } - ; - -registered_template_prefix: - template_prefix { $$ = g_template_type_new($1, NULL); /*g_itanium_dcontext_add_item(context, $$);*/ } - ; - -template_prefix: - registered_prefix unqualified_name { - if ($1 != NULL) printf("$1 == '%s'\n", $1); - //if ($1 != NULL) if (strcmp($1, "std") != 0) g_itanium_dcontext_add_item(context, g_class_enum_type_new(CET_CLASS, $1)); - $$ = ($2 != NULL ? strmerge($1, "::", $2) : $1); - printf("$$ == '%s'\n", $$); - g_itanium_dcontext_add_item(context, g_class_enum_type_new(CET_CLASS, $$)); - } - | template_param { - $$ = g_data_type_to_string($1); - printf("[[ tmp param %s ]]\n", $$); - g_object_unref(G_OBJECT($1)); - } - | substitution { - $$ = g_data_type_to_string($1); - printf("template_prefix substi :: %s\n", $$); - 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; } - | source_name { $$ = $1; } - ; - - - -source_name: - NUMBER { set_itanium_text_length($1); g_itanium_dcontext_reset_identifier(context); } - identifier { $$ = strdup(context->identifier); printf("==source name== :: %s\n", $$); } - ; - -identifier: - identifier CHAR { g_itanium_dcontext_build_identifier(context, $2); } - | CHAR { g_itanium_dcontext_build_identifier(context, $1); } - ; - -operator_name: - OPER_NEW { $$ = "new"; } - | OPER_NEW_ARRAY { $$ = "new[]"; } - | OPER_DELETE { $$ = "delete"; } - | OPER_DELETE_ARRAY { $$ = "delete[]"; } - | OPER_PLUS_UNARY { $$ = "+"; } - | OPER_NEG_UNARY { $$ = "-"; } - | OPER_AND_UNARY { $$ = "&"; } - | OPER_DE_UNARY { $$ = "*"; } - | OPER_COMPL { $$ = "~"; } - | OPER_PLUS { $$ = "+"; } - | OPER_MINUS { $$ = "-"; } - | OPER_MUL { $$ = "*"; } - | OPER_DIV { $$ = "/"; } - | OPER_MOD { $$ = "%"; } - | OPER_AND { $$ = "&"; } - | OPER_OR { $$ = "|"; } - | OPER_EXCL_OR { $$ = "^"; } - | OPER_AS { $$ = "="; } - | OPER_PLUS_EQ { $$ = "+="; } - | OPER_MINUS_EQ { $$ = "-="; } - | OPER_MUL_EQ { $$ = "*="; } - | OPER_DIV_EQ { $$ = "/="; } - | OPER_MOD_EQ { $$ = "%)"; } - | OPER_AND_EQ { $$ = "&="; } - | OPER_OR_EQ { $$ = "|="; } - | OPER_EXCL_OR_EQ { $$ = "^="; } - | OPER_LEFT_SHIFT { $$ = "<<"; } - | OPER_RIGHT_SHIFT { $$ = ">>"; } - | OPER_LEFT_SHIFT_EQ { $$ = "<<="; } - | OPER_RIGHT_SHIFT_EQ { $$ = ">>="; } - | OPER_EQUAL { $$ = "=="; } - | OPER_NOT_EQ { $$ = "!="; } - | OPER_LESS { $$ = "<"; } - | OPER_GREATER { $$ = ">"; } - | OPER_LESS_EQ { $$ = "<="; } - | OPER_GREATER_EQ { $$ = ">="; } - | OPER_NOT { $$ = "!"; } - | OPER_AND_AND { $$ = "&&"; } - | OPER_OR_OR { $$ = "||"; } - | OPER_PLUS_PLUS { $$ = "++"; } - | OPER_MINUS_MINUS { $$ = "--"; } - | OPER_COMMA { $$ = ","; } - | OPER_PRIV_MEMB { $$ = "->*"; } - | OPER_POINTER_TO { $$ = "->"; } - | OPER_CLASS { $$ = "()"; } - | OPER_INDEX { $$ = "[]"; } - ; - - - - - - -ctor_dtor_name: - C1 { g_binary_routine_set_type(routine, RTT_CONSTRUCTOR); } - | C2 { g_binary_routine_set_type(routine, RTT_CONSTRUCTOR); } - | C3 { g_binary_routine_set_type(routine, RTT_CONSTRUCTOR); } - | D1 { g_binary_routine_set_type(routine, RTT_DESTRUCTOR); } - | D2 { g_binary_routine_set_type(routine, RTT_DESTRUCTOR); } - | D3 { g_binary_routine_set_type(routine, RTT_DESTRUCTOR); } - ; - - -function_type: - FF { - routine = g_itanium_dcontext_push_routine(context, routine); - context->start_args = true; - g_itanium_dcontext_update(context); - } - bare_function_type EE { - $$ = g_encapsulated_type_new(ECT_ROUTINE, routine); - routine = g_itanium_dcontext_pop_routine(context); - if (routine == NULL) YYERROR; - } - ; - - -type: - builtin_type { $$ = $1; printf("builtin '%s'\n", g_data_type_to_string($1)); } - | class_enum_type { $$ = $1; printf("type :: %p\n", $1); fflush(NULL); g_itanium_dcontext_add_item(context, $1); } - | substitution { $$ = $1; } - | template_param { $$ = $1; } - | template_template_param template_args { - $$ = g_template_type_new(g_data_type_to_string($1), NULL); - g_object_unref($1); - g_template_type_add_params($$, $2); - printf(" [type tmp:: %s]\n", g_data_type_to_string($$)); - } - | function_type { $$ = $1; } - | qualifiers type { - $$ = g_data_type_dup($2); - g_data_type_add_qualifier($$, $1); - g_itanium_dcontext_add_item(context, $$); - } - | TP type { $$ = g_encapsulated_type_new(ECT_POINTER, $2); g_itanium_dcontext_add_item(context, $$); } - | TR type { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); g_itanium_dcontext_add_item(context, $$); } - | TO type { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); g_itanium_dcontext_add_item(context, $$); } - | TC type { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); g_itanium_dcontext_add_item(context, $$); } - | TG type { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); g_itanium_dcontext_add_item(context, $$); } - ; - -qualifiers: - QR { $$ = TQF_RESTRICT; } - | QV { $$ = TQF_VOLATILE; } - | QK { $$ = TQF_CONST; } - ; - - - -builtin_type: - 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, g_binary_variable_new($2))/*TODO unref*/; } - | type { g_binary_routine_add_arg(routine, g_binary_variable_new($1))/*TODO unref*/; } - ; - -class_enum_type: - name { printf("is str ?? %d (%p)\n", $1.is_string, $1.type); fflush(NULL); $$ = $1.is_string ? g_class_enum_type_new(CET_UNKNOWN, $1.str) : $1.type; } - ; - - - - -template_param: - TPARAM_FIRST { - const GDataType *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; if (!G_IS_BASIC_TYPE($$)) g_itanium_dcontext_add_item(context, $$); - } - | TPARAM_N { - const GDataType *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; if (!G_IS_BASIC_TYPE($$)) g_itanium_dcontext_add_item(context, $$); - } - ; - -template_template_param: - template_param { $$ = $1; } - | substitution { $$ = $1; } - ; - -template_args: - use_templates template_arg_list EE { $$ = $2; - context->template_level--; - g_itanium_dcontext_update(context); - } - ; - -use_templates: - II { printf("new template !!!\n"); /* FIXME : régle désormais inutile ! -> remme */ - context->template_level++; - g_itanium_dcontext_update(context); - } - ; - -template_arg_list: - 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"); printf("??? tmp list\n"); } - ; - -template_arg: - type { $$ = $1; } - | expr_primary { $$ = $1; } - ; - - -expr_primary: - LL type NUMBER EE { $$ = $2; } - ; - - -substitution: - 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 { $$ = g_itanium_dcontext_get_item(context, 0); if ($$ == NULL) YYERROR; } - | SUBSTI_N { $$ = g_itanium_dcontext_get_item(context, $1 + 1); if ($$ == NULL) YYERROR; } - ; - - - - - - - -%% - - - -/* ---------------------------------------------------------------------------------- */ -/* CONTEXTE POUR LE DECODAGE TYPE ITANIUM */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour un contexte de décodage. */ -G_DEFINE_TYPE(GItaniumDContext, g_itanium_dcontext, G_TYPE_DEMANGLING_CONTEXT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des contextes de décodage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_class_init(GItaniumDContextClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = g_itanium_dcontext_dispose; - object->finalize = g_itanium_dcontext_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : context = instance à initialiser. * -* * -* Description : Initialise une instance de contexte pour décodage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_init(GItaniumDContext *context) -{ - context->substitutions = g_slist_alloc(); - -} - - -/****************************************************************************** -* * -* Paramètres : context = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_dispose(GItaniumDContext *context) -{ - gpointer data; /* Type à détacher */ - GBinRoutine *routine; /* Routine à détacher */ - gpointer obj_class; /* Classe parente */ - - while ((data = g_slist_nth_data(context->substitutions, 0)) != NULL) - { - g_object_unref(G_OBJECT(data)); - context->substitutions = g_slist_remove(context->substitutions, data); - } - - while ((routine = g_itanium_dcontext_pop_routine(context)) != NULL) - g_object_unref(G_OBJECT(routine)); - - obj_class = g_type_class_peek_parent(G_ITANIUM_DCONTEXT_GET_CLASS(context)); - - G_OBJECT_CLASS(obj_class)->dispose(G_OBJECT(context)); - -} - - -/****************************************************************************** -* * -* Paramètres : context = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_finalize(GItaniumDContext *context) -{ - gpointer obj_class; /* Classe parente */ - - if (context->identifier != NULL) - free(context->identifier); - - obj_class = g_type_class_peek_parent(G_ITANIUM_DCONTEXT_GET_CLASS(context)); - - G_OBJECT_CLASS(obj_class)->finalize(G_OBJECT(context)); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Prépare de quoi effectuer un décodage Itanium. * -* * -* Retour : Instance du contexte mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDemanglingContext *g_itanium_dcontext_new(void) -{ - GDemanglingContext *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_ITANIUM_DCONTEXT, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à mettre à jour. * -* * -* Description : Réinitialise le constructeur d'identifiants. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_reset_identifier(GItaniumDContext *context) -{ - context->id_used = 0; - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à mettre à jour. * -* value = caractère d'identifiant à mémoriser. * -* * -* Description : Construit à la volée un identifiant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_build_identifier(GItaniumDContext *context, char value) -{ - if ((context->id_used + 2) > context->id_allocated) - { - context->id_allocated += ITANIUM_ALLOC_CLUSTER; - context->identifier = (char *)realloc(context->identifier, - context->id_allocated * sizeof(char)); - } - - context->identifier[context->id_used++] = value; - context->identifier[context->id_used] = 0; - -} - - -/****************************************************************************** -* * -* Paramètres : context = 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 *g_itanium_dcontext_push_routine(GItaniumDContext *context, GBinRoutine *previous) -{ - GBinRoutine *result; /* Routine nouvelle à renvoyer */ - - result = g_binary_routine_new(); - - context->routines = g_slist_append(context->routines, previous); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à mettre à jour. * -* * -* Description : Remet une ancienne routine sous le feu des projecteurs. * -* * -* Retour : Routine sauvegardée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *context) -{ - GBinRoutine *result; /* Routine nouvelle à renvoyer */ - GSList *last; /* Dernier élément */ - - last = g_slist_last(context->routines); - - if (last == NULL) result = NULL; - else - { - result = G_BIN_ROUTINE(last->data); - context->routines = g_slist_remove(context->routines, result); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à mettre à jour. * -* type = élément à placer dans la liste des substitutions. * -* * -* Description : Ajoute un élément dans une liste de substitutions. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_add_item(GItaniumDContext *context, GDataType *type) -{ - g_object_ref(G_OBJECT(type)); - - printf(" [[ %u ]] PUSH '%s' (%p)\n", g_slist_length(context->substitutions) - 1, g_data_type_to_string(type), type); - - context->substitutions = g_slist_append(context->substitutions, type); - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à consulter. * -* 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 GDataType *g_itanium_dcontext_get_item(GItaniumDContext *context, guint n) -{ - printf("get [%u] == %p\n", n, g_slist_nth_data(context->substitutions, n + 1)); - - return G_DATA_TYPE(g_slist_nth_data(context->substitutions, n + 1)); - -} - - -/****************************************************************************** -* * -* Paramètres : context = décodeur à consulter. * -* * -* Description : Autorise ou non le dépilement des opérateurs. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_itanium_dcontext_update(GItaniumDContext *context) -{ - if (context->start_args || context->template_level > 0) - exclude_itanium_operators(); - - else allow_itanium_operators(); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRAITEMENT DE L'ENCODAGE ITANIUM */ -/* ---------------------------------------------------------------------------------- */ - - - - - - - - - - - - - - - - - - - -/** - * 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 : desc = chaîne de caractères à décoder. * -* * -* Description : Indique si une chaîne peut être traitée par le décodeur. * -* * -* Retour : Bilan de l'analyse. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool can_be_itanium_demangled(const char *desc) -{ - return (strncmp(desc, "_Z", 2) == 0); - -} - - -/****************************************************************************** -* * -* Paramètres : context = contexte de décodage à utiliser. * -* desc = 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 : - * -* * -******************************************************************************/ - -bool demangle_itanium_routine(GItaniumDContext *context, const char *desc) -{ - GBinRoutine *routine; /* Routine à construire */ - YY_BUFFER_STATE buffer; /* Tampon pour bison */ - int ret; /* Bilan de l'appel */ - GDataType *name_type; /* Nom basé sur un type ? */ - - routine = g_demangling_context_get_decoded_routine(G_DEMANGLING_CONTEXT(context)); - - allow_itanium_operators(); - - buffer = yy_scan_string(desc); - ret = yyparse(context, routine); - yy_delete_buffer(buffer); - - if (ret == 0) - { - name_type = g_binary_routine_get_type_from_name(routine); - - if (name_type != NULL && G_IS_TEMPLATE_TYPE(name_type)) - compute_routine_itanium_ret_type(routine); - - } - - return (ret == 0); - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à traiter si ce n'est pas déjà fait. * -* * -* Description : Fait sauter le premier argument en faveur du type de retour. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void compute_routine_itanium_ret_type(GBinRoutine *routine) -{ - size_t count; /* Nombre d'arguments présents */ - size_t i; /* Boucle de parcours */ - GBinVariable *arg; /* Argument de la routine */ - GDataType *type; /* Type associé à l'argument */ - - /* Traitement récursif des arguments */ - - type = g_binary_routine_get_type_from_name(routine); - - if (type != NULL) - { - update_itanium_ret_type(type); - - /* On force une actualisation au cas où... */ - g_binary_routine_set_name(routine, NULL); - - } - - count = g_binary_routine_get_args_count(routine); - if (count == 0) return; - - for (i = 0; i < count; i++) - { - arg = g_binary_routine_get_arg(routine, i); - type = g_binary_variable_get_vtype(arg); - - update_itanium_ret_type(type); - - } - - /* Basculement du premier argument */ - - /** - * Avec les références de type partagées, il - * se peut que la fonction soit déjà traitée. - */ - if (g_binary_routine_get_return_type(routine) != NULL) - return; - - arg = g_binary_routine_get_arg(routine, 0); - - type = g_binary_variable_get_vtype(arg); - g_object_ref(G_OBJECT(type)); - - g_binary_routine_remove_arg(routine, 0); - - g_binary_routine_set_return_type(routine, type); - -} - - -/****************************************************************************** -* * -* Paramètres : type = type à traiter si ce n'est pas déjà fait. * -* * -* Description : Recherche et fait sauter les premiers arguments rencontrés. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void update_itanium_ret_type(GDataType *type) -{ - GTemplateType *template; /* Gabarit à analyser */ - size_t max; /* Nombre d'itérations */ - size_t i; /* Boucle de parcours */ - GDataType *subtype; /* Type à traiter */ - GEncapsulatedType *encaps; /* Encapsulation quelconque */ - GBinRoutine *routine; /* Routine à traiter */ - - /* Gabarits */ - if (G_IS_TEMPLATE_TYPE(type)) - { - template = G_TEMPLATE_TYPE(type); - max = g_template_type_count_param(template); - - for (i = 0; i < max; i++) - { - subtype = g_template_type_get_param(template, i); - update_itanium_ret_type(subtype); - } - - } - - /* Encapsulations */ - else if (G_IS_ENCAPSULATED_TYPE(type)) - { - encaps = G_ENCAPSULATED_TYPE(type); - - switch (g_encapsulated_type_get_etype(encaps)) - { - case ECT_ROUTINE: - g_encapsulated_type_get_item(encaps, &routine); - compute_routine_itanium_ret_type(routine); - break; - - default: - g_encapsulated_type_get_item(encaps, &subtype); - update_itanium_ret_type(subtype); - break; - - } - - } - -} |