diff options
Diffstat (limited to 'src')
28 files changed, 2691 insertions, 610 deletions
diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 6e56e2d..08160b8 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -183,7 +183,7 @@ GBinRoutine *g_binary_routine_new_constructor(GDataType *type) result = g_object_new(G_TYPE_BIN_ROUTINE, NULL); - g_binary_routine_set_name(result, _g_data_type_to_string(type, true)); + g_binary_routine_set_name(result, g_data_type_to_string(type, true)); return result; @@ -257,6 +257,9 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, const char *sep) { + if (routine->namespace != NULL) + g_object_unref(G_OBJECT(routine->namespace)); + routine->namespace = namespace; routine->ns_sep = sep; @@ -267,11 +270,11 @@ void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, /****************************************************************************** * * -* Paramètres : routine = routine à mettre à jour. * +* Paramètres : routine = routine à consulter. * * * * Description : Fournit le groupe d'appartenance d'une routine donnée. * * * -* Retour : éventuelle instance d'appartenance ou NULL. * +* Retour : Eventuelle instance d'appartenance ou NULL. * * * * Remarques : - * * * @@ -279,7 +282,14 @@ void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, GDataType *g_binary_routine_get_namespace(const GBinRoutine *routine) { - return routine->namespace; + GDataType *result; /* Espace à renvoyer */ + + result = routine->namespace; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } @@ -375,7 +385,7 @@ GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* type = indication sur le type de retour. * +* ret = indication sur le type de retour. * * * * Description : Définit le type de retour d'une routine. * * * @@ -385,15 +395,12 @@ GDataType *g_binary_routine_get_type_from_name(const GBinRoutine *routine) * * ******************************************************************************/ -void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *type) +void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *ret) { if (routine->ret_type != NULL) g_object_unref(G_OBJECT(routine->ret_type)); - routine->ret_type = type; - - if (type != NULL) - g_object_ref(G_OBJECT(type)); + routine->ret_type = ret; } @@ -412,7 +419,14 @@ void g_binary_routine_set_return_type(GBinRoutine *routine, GDataType *type) GDataType *g_binary_routine_get_return_type(const GBinRoutine *routine) { - return routine->ret_type; + GDataType *result; /* Type de retour à renvoyer */ + + result = routine->ret_type; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } @@ -544,7 +558,7 @@ static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* full = indique si la liste des arguments est à ajouter. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Fournit le nom humain d'une routine. * * * @@ -554,7 +568,7 @@ static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) * * ******************************************************************************/ -const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) +const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool include) { char *new; /* Nouvelle description */ char *namespace; /* Groupe d'appartenance */ @@ -564,13 +578,13 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) if (routine->cached_decl == NULL) { if (routine->full_name != NULL) - new = _g_data_type_to_string(routine->full_name, false); + new = g_data_type_to_string(routine->full_name, include); else new = strdup(routine->name != NULL ? routine->name : ""); if (routine->namespace != NULL) { - namespace = _g_data_type_to_string(routine->namespace, false); + namespace = g_data_type_to_string(routine->namespace, include); new = strprep(new, routine->ns_sep); new = strprep(new, namespace); @@ -585,7 +599,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) } - if (full && routine->cached_full_decl == NULL) + if (include && routine->cached_full_decl == NULL) { /* Type de retour */ @@ -593,9 +607,11 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) new = strdup("??? "); else { - new = _g_data_type_to_string(routine->ret_type, true); - if (!g_data_type_is_pointer(routine->ret_type, true)) + new = g_data_type_to_string(routine->ret_type, include); + + if (!(g_data_type_is_pointer(routine->ret_type) || g_data_type_is_reference(routine->ret_type))) new = stradd(new, " "); + } /* Nom de la routine */ @@ -610,7 +626,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) { if (i > 0) new = stradd(new, ", "); - typestr = g_binary_variable_to_string(routine->args[i], true); + typestr = g_binary_variable_to_string(routine->args[i], include); new = stradd(new, typestr); free(typestr); @@ -624,7 +640,7 @@ const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) } - return (full ? routine->cached_full_decl : routine->cached_decl); + return (include ? routine->cached_full_decl : routine->cached_decl); } @@ -844,6 +860,7 @@ void g_binary_routine_set_decomp_instructions(GBinRoutine *routine, GDecInstruct /****************************************************************************** * * * Paramètres : routine = routine à consulter. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le prototype de la routine sous forme de caractères. * * * @@ -853,7 +870,7 @@ void g_binary_routine_set_decomp_instructions(GBinRoutine *routine, GDecInstruct * * ******************************************************************************/ -char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOptions options) +char *g_binary_routine_to_string(const GBinRoutine *routine, bool include) { char *result; /* Chaîne à renvoyer */ char *namespace; /* Groupe d'appartenance */ @@ -880,9 +897,11 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti if (routine->ret_type == NULL) result = strdup("??? "); else { - result = _g_data_type_to_string(routine->ret_type, !(options & RSO_LONG_TYPE)); - if (!g_data_type_is_pointer(routine->ret_type, true)) + result = g_data_type_to_string(routine->ret_type, include); + + if (!(g_data_type_is_pointer(routine->ret_type) || g_data_type_is_reference(routine->ret_type))) result = stradd(result, " "); + } break; @@ -890,12 +909,12 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti /* Nom de la routine */ - if (options & RSO_NAMESPACE && routine->namespace != NULL) + if (routine->namespace != NULL) { - namespace = g_data_type_to_string(routine->namespace); + namespace = g_data_type_to_string(routine->namespace, include); result = stradd(result, namespace); - result = stradd(result, "." /* FIXME */); + result = stradd(result, routine->ns_sep); free(namespace); @@ -914,7 +933,7 @@ char *_g_binary_routine_to_string(const GBinRoutine *routine, Routine2StringOpti { if (i > 0) result = stradd(result, ", "); - typestr = g_binary_variable_to_string(routine->args[i], !(options & RSO_LONG_TYPE)); + typestr = g_binary_variable_to_string(routine->args[i], include); result = stradd(result, typestr); free(typestr); diff --git a/src/analysis/routine.h b/src/analysis/routine.h index e364c93..e1a3523 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -62,17 +62,6 @@ typedef struct _GBinRoutine GBinRoutine; typedef struct _GBinRoutineClass GBinRoutineClass; -/* Modalités de représentation en chaîne */ -typedef enum _Routine2StringOptions -{ - RSO_LONG_TYPE = (1 << 0), /* Type avec espace de noms */ - RSO_NAMESPACE = (1 << 1) /* Affichage de l'appartenance */ - -} Routine2StringOptions; - -#define RSO_ALL (RSO_LONG_TYPE | RSO_NAMESPACE) - - /* Indique le type définit pour une représentation de routine. */ GType g_bin_routine_get_type(void); @@ -143,9 +132,7 @@ void g_binary_routine_set_basic_blocks(GBinRoutine *, GBlockList *); //void g_binary_routine_set_decomp_instructions(GBinRoutine *, GDecInstruction *); /* Décrit le prototype de la routine sous forme de caractères. */ -char *_g_binary_routine_to_string(const GBinRoutine *, Routine2StringOptions); - -#define g_binary_routine_to_string(r) _g_binary_routine_to_string((r), RSO_ALL) +char *g_binary_routine_to_string(const GBinRoutine *, bool); /* Procède à l'impression de la description d'une routine. */ //void g_binary_routine_output_info(const GBinRoutine *, GLangOutput *, GCodeBuffer *); diff --git a/src/analysis/type-int.h b/src/analysis/type-int.h index 51e4954..3c34680 100644 --- a/src/analysis/type-int.h +++ b/src/analysis/type-int.h @@ -33,10 +33,14 @@ typedef GDataType * (* type_dup_fc) (const GDataType *); /* Décrit le type fourni sous forme de caractères. */ -typedef char * (* type_to_string_fc) (const GDataType *); +typedef char * (* type_to_string_fc) (const GDataType *, bool); + +/* Indique si le type est un pointeur. */ +typedef bool (* type_is_pointer_fc) (const GDataType *); + +/* Indique si le type est une référence. */ +typedef bool (* type_is_reference_fc) (const GDataType *); -/* Procède à l'impression de la description d'un type. */ -//typedef void (* output_type_fc) (const GDataType *, GLangOutput *, GBufferLine *, bool, bool); /* Description de type quelconque (instance) */ @@ -44,11 +48,9 @@ struct _GDataType { GObject parent; /* A laisser en premier */ - type_dup_fc dup; /* Copie d'instance existante */ - type_to_string_fc to_string; /* Conversion au format texte */ - //output_type_fc output; /* Impression à l'écran */ - GDataType *namespace; /* Espace de noms / classe */ + const char *ns_sep; /* Séparateur d'éléments */ + TypeQualifier qualifiers; /* Eventuels qualificatifs */ }; @@ -58,6 +60,14 @@ struct _GDataTypeClass { GObjectClass parent; /* A laisser en premier */ + bool handle_ns; /* Gestion au niveau de base ? */ + + type_dup_fc dup; /* Copie d'instance existante */ + type_to_string_fc to_string; /* Conversion au format texte */ + + type_is_pointer_fc is_pointer; /* Représentation de pointeur ?*/ + type_is_reference_fc is_reference; /* Représentation de référence?*/ + }; diff --git a/src/analysis/type.c b/src/analysis/type.c index 6d09f4b..cc446cb 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -24,29 +24,26 @@ #include "type.h" -#include <stdarg.h> +#include <malloc.h> -#include "routine.h" #include "type-int.h" #include "../common/extstr.h" -/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ - - /* Initialise la classe des types quelconques. */ static void g_data_type_class_init(GDataTypeClass *); /* Initialise l'instance d'un type quelconque. */ static void g_data_type_init(GDataType *); +/* Supprime toutes les références externes. */ +static void g_data_type_dispose(GDataType *); +/* Procède à la libération totale de la mémoire. */ +static void g_data_type_finalize(GDataType *); -/* ---------------------------------------------------------------------------------- */ -/* REPRESENTATION INTERNE DES TYPES */ -/* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour un type quelconque. */ @@ -67,6 +64,14 @@ G_DEFINE_TYPE(GDataType, g_data_type, G_TYPE_OBJECT); static void g_data_type_class_init(GDataTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_data_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_data_type_finalize; + + klass->handle_ns = true; } @@ -91,29 +96,31 @@ static void g_data_type_init(GDataType *type) /****************************************************************************** * * -* Paramètres : type = type à dupliquer. * +* Paramètres : type = instance d'objet GLib à traiter. * * * -* Description : Crée un copie d'un type existant. * +* Description : Supprime toutes les références externes. * * * -* Retour : Nouvelle instance de type identique à celle fournie. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GDataType *g_data_type_dup(const GDataType *type) +static void g_data_type_dispose(GDataType *type) { - return type->dup(type); + if (type->namespace != NULL) + g_object_unref(G_OBJECT(type->namespace)); + + G_OBJECT_CLASS(g_data_type_parent_class)->dispose(G_OBJECT(type)); } /****************************************************************************** * * -* Paramètres : type = type à mettre à jour. * -* namespace = instance d'appartenance. * +* Paramètres : type = instance d'objet GLib à traiter. * * * -* Description : Définit le groupe d'appartenance d'un type donné. * +* Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * @@ -121,19 +128,52 @@ GDataType *g_data_type_dup(const GDataType *type) * * ******************************************************************************/ -void g_data_type_set_namespace(GDataType *type, GDataType *namespace) +static void g_data_type_finalize(GDataType *type) { - g_object_ref(G_OBJECT(namespace)); + G_OBJECT_CLASS(g_data_type_parent_class)->finalize(G_OBJECT(type)); - type->namespace = namespace; +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_data_type_dup(const GDataType *type) +{ + GDataType *result; /* Copie à retourner */ + GDataTypeClass *class; /* Classe du type */ + GDataType *ns; /* Eventuel espace de noms */ + + class = G_DATA_TYPE_GET_CLASS(type); + + result = class->dup(type); + + if (type->namespace != NULL) + { + ns = g_data_type_dup(type->namespace); + g_data_type_set_namespace(result, ns, type->ns_sep); + } + + result->qualifiers = type->qualifiers; + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * -* simple = indique si l'espace de noms doit être exclus ou non.* +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -143,25 +183,26 @@ void g_data_type_set_namespace(GDataType *type, GDataType *namespace) * * ******************************************************************************/ -char *_g_data_type_to_string(const GDataType *type, bool simple) +char *g_data_type_to_string(const GDataType *type, bool include) { char *result; /* Chaîne à retourner */ - const GDataType *parent; /* Espace supérieur */ + GDataTypeClass *class; /* Classe du type */ char *namespace; /* Groupe d'appartenance */ - result = type->to_string(type); + class = G_DATA_TYPE_GET_CLASS(type); + + result = class->to_string(type, include); - if (!simple) - for (parent = type->namespace; parent != NULL; parent = parent->namespace) - { - namespace = g_data_type_to_string(parent); + if (include && type->namespace != NULL && class->handle_ns) + { + namespace = g_data_type_to_string(type->namespace, true); - result = strprep(result, "." /* FIXME */); - result = strprep(result, namespace); + result = strprep(result, type->ns_sep); + result = strprep(result, namespace); - free(namespace); + free(namespace); - } + } if (type->qualifiers & TQF_RESTRICT) result = strprep(result, "restrict "); @@ -179,26 +220,53 @@ char *_g_data_type_to_string(const GDataType *type, bool simple) /****************************************************************************** * * -* Paramètres : type = routine à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à mettre à jour. * +* namespace = instance d'appartenance. * +* sep = séparateur à utiliser entre les éléments. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Définit le groupe d'appartenance d'un type donné. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ -/* -void g_data_type_output(const GDataType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +void g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char *sep) { - type->output(type, lang, line, info, full); + if (type->namespace != NULL) + g_object_unref(G_OBJECT(type->namespace)); + + type->namespace = namespace; + type->ns_sep = sep; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le groupe d'appartenance d'un type donné. * +* * +* Retour : Eventuelle instance d'appartenance ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_data_type_get_namespace(const GDataType *type) +{ + GDataType *result; /* Espace à renvoyer */ + + result = type->namespace; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; } -*/ /****************************************************************************** @@ -223,37 +291,56 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) /****************************************************************************** * * -* Paramètres : type = type à analyser. * -* large = doit-on aussi inclure les types 'référence' ? * +* Paramètres : type = type à consulter. * * * -* Description : Indique la terminaison de la représentation du type. * +* Description : Indique si le type est un pointeur. * * * -* Retour : true ou false, selon le type fourni. * +* Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ -bool g_data_type_is_pointer(const GDataType *type, bool large) +bool g_data_type_is_pointer(const GDataType *type) { bool result; /* Bilan à retourner */ + GDataTypeClass *class; /* Classe du type */ + + class = G_DATA_TYPE_GET_CLASS(type); + + if (class->is_pointer != NULL) + result = class->is_pointer(type); + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si le type est une référence. * +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_data_type_is_reference(const GDataType *type) +{ + bool result; /* Bilan à retourner */ + GDataTypeClass *class; /* Classe du type */ + + class = G_DATA_TYPE_GET_CLASS(type); - result = G_IS_ENCAPSULATED_TYPE(type); - - if (result) - switch (g_encapsulated_type_get_etype(G_ENCAPSULATED_TYPE(type))) - { - case ECT_POINTER: - result = true; - break; - case ECT_REFERENCE: - case ECT_RVALUE_REF: - result = large; - break; - default: - result = false; - break; - } + if (class->is_reference != NULL) + result = class->is_reference(type); + else + result = false; return result; diff --git a/src/analysis/type.h b/src/analysis/type.h index 1ea1b2f..bd80f18 100644 --- a/src/analysis/type.h +++ b/src/analysis/type.h @@ -25,18 +25,10 @@ #define _ANALYSIS_TYPE_H -#include <glib.h> #include <glib-object.h> #include <stdbool.h> -#include "../arch/archbase.h" -#include "../glibext/gbufferline.h" - - - -/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */ - #define G_TYPE_DATA_TYPE g_data_type_get_type() #define G_DATA_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DATA_TYPE, GDataType)) @@ -70,22 +62,23 @@ GType g_data_type_get_type(void); /* Crée un copie d'un type existant. */ GDataType *g_data_type_dup(const GDataType *); -/* Définit le groupe d'appartenance d'un type donné. */ -void g_data_type_set_namespace(GDataType *, GDataType *); - /* Décrit le type fourni sous forme de caractères. */ -char *_g_data_type_to_string(const GDataType *, bool); +char *g_data_type_to_string(const GDataType *, bool); + +/* Définit le groupe d'appartenance d'un type donné. */ +void g_data_type_set_namespace(GDataType *, GDataType *, const char *); -#define g_data_type_to_string(t) _g_data_type_to_string((t), true) +/* Fournit le groupe d'appartenance d'un type donné. */ +GDataType *g_data_type_get_namespace(const GDataType *); /* Ajoute un qualificatif à une instance de type. */ void g_data_type_add_qualifier(GDataType *, TypeQualifier); -/* Indique la terminaison de la représentation du type. */ -bool g_data_type_is_pointer(const GDataType *, bool); +/* Indique si le type est un pointeur. */ +bool g_data_type_is_pointer(const GDataType *); -/* Procède à l'impression de la description d'un type. */ -//void g_data_type_output(const GDataType *, GLangOutput *, GBufferLine *, bool, bool); +/* Indique si le type est une référence. */ +bool g_data_type_is_reference(const GDataType *); diff --git a/src/analysis/types/Makefile.am b/src/analysis/types/Makefile.am index 13215f2..2d11642 100644 --- a/src/analysis/types/Makefile.am +++ b/src/analysis/types/Makefile.am @@ -2,11 +2,14 @@ noinst_LTLIBRARIES = libanalysistypes.la libanalysistypes_la_SOURCES = \ + array.h array.c \ basic.h basic.c \ - cse-int.h \ cse.h cse.c \ encaps.h encaps.c \ + expr.h expr.c \ literal.h literal.c \ + override.h override.c \ + proto.h proto.c \ template.h template.c libanalysistypes_la_LIBADD = diff --git a/src/analysis/types/array.c b/src/analysis/types/array.c new file mode 100644 index 0000000..714ab58 --- /dev/null +++ b/src/analysis/types/array.c @@ -0,0 +1,429 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.c - manipulation des types de tableaux + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "array.h" + + +#include <assert.h> +#include <malloc.h> +#include <string.h> + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de tableau (instance) */ +struct _GArrayType +{ + GDataType parent; /* A laisser en premier */ + + bool numbered; /* Dimension chiffrée ? */ + + union + { + ssize_t dim_number; /* Taille en chiffre */ + char *dim_expr; /* Taille via expression */ + + }; + + GDataType *members; /* Type des membres */ + +}; + +/* Description de tableau (classe) */ +struct _GArrayTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des tableaux. */ +static void g_array_type_class_init(GArrayTypeClass *); + +/* Initialise l'instance d'un tableau. */ +static void g_array_type_init(GArrayType *); + +/* Supprime toutes les références externes. */ +static void g_array_type_dispose(GArrayType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_array_type_finalize(GArrayType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_array_type_dup(const GArrayType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_array_type_to_string(const GArrayType *, bool); + + + +/* Indique le type défini pour un tableau. */ +G_DEFINE_TYPE(GArrayType, g_array_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des tableaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_class_init(GArrayTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_array_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_array_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_array_type_dup; + type->to_string = (type_to_string_fc)g_array_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_init(GArrayType *type) +{ + type->numbered = true; + + type->dim_number = -1; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_dispose(GArrayType *type) +{ + if (type->members != NULL) + g_object_unref(G_OBJECT(type->members)); + + G_OBJECT_CLASS(g_array_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_array_type_finalize(GArrayType *type) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + G_OBJECT_CLASS(g_array_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : members = type des membres du tableau. * +* * +* Description : Crée une représentation de tableau. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_array_type_new(GDataType *members) +{ + GArrayType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARRAY_TYPE, NULL); + + result->members = members; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_array_type_dup(const GArrayType *type) +{ + GDataType *result; /* Nouvelle instance à renvoyer*/ + GDataType *members; /* Copie du type interne */ + + members = g_data_type_dup(type->members); + result = g_array_type_new(members); + + if (type->numbered) + g_array_type_set_dimension_number(G_ARRAY_TYPE(result), type->dim_number); + + else if (type->dim_expr != NULL) + g_array_type_set_dimension_expression(G_ARRAY_TYPE(result), strdup(type->dim_expr)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_array_type_to_string(const GArrayType *type, bool include) +{ + char *result; /* Chaîne finale à renvoyer */ + char *tmp; /* Transcription temporaire */ + + result = g_data_type_to_string(type->members, include); + if (result == NULL) goto exit; + + result = stradd(result, "["); + + if (type->numbered) + { + if (type->dim_number != -1) + { + asprintf(&tmp, "%zd", type->dim_number); + result = stradd(result, tmp); + free(tmp); + } + } + + else + result = stradd(result, type->dim_expr); + + result = stradd(result, "]"); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type des membres du tableau. * +* * +* Retour : Instance d'un autre type. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_array_type_get_members_type(const GArrayType *type) +{ + GDataType *result; /* Type à retourner */ + + result = type->members; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si la dimension du tableau est chiffrée. * +* * +* Retour : true si la dimension est chiffrée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_array_type_is_dimension_numbered(const GArrayType *type) +{ + bool result; /* Etat à retourner */ + + result = type->numbered; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Dimension positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ssize_t g_array_type_get_dimension_number(const GArrayType *type) +{ + ssize_t result; /* Taille à retourner */ + + assert(type->numbered); + + result = (type->numbered ? type->dim_number : 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* dim = dimension positive ou nulle. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_array_type_set_dimension_number(GArrayType *type, ssize_t dim) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + type->numbered = true; + + type->dim_number = dim; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la dimension associée au tableau. * +* * +* Retour : Expression de dimension. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_array_type_get_dimension_expression(const GArrayType *type) +{ + char *result; /* Expression à retourner */ + + assert(!type->numbered); + + result = (type->numbered ? NULL : type->dim_expr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* expr = expression de dimension. * +* * +* Description : Définit la dimension associée au tableau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_array_type_set_dimension_expression(GArrayType *type, char *expr) +{ + if (!type->numbered && type->dim_expr != NULL) + free(type->dim_expr); + + type->numbered = false; + + type->dim_expr = expr; + +} diff --git a/src/analysis/types/array.h b/src/analysis/types/array.h new file mode 100644 index 0000000..d432c22 --- /dev/null +++ b/src/analysis/types/array.h @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * array.h - prototypes pour la manipulation des types de tableaux + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_TYPES_ARRAY_H +#define _ANALYSIS_TYPES_ARRAY_H + + +#include <glib-object.h> + + +#include "../type.h" + + + +#define G_TYPE_ARRAY_TYPE g_array_type_get_type() +#define G_ARRAY_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ARRAY_TYPE, GArrayType)) +#define G_IS_ARRAY_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ARRAY_TYPE)) +#define G_ARRAY_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARRAY_TYPE, GArrayTypeClass)) +#define G_IS_ARRAY_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARRAY_TYPE)) +#define G_ARRAY_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARRAY_TYPE, GArrayTypeClass)) + + +/* Description de tableau (instance) */ +typedef struct _GArrayType GArrayType; + +/* Description de tableau (classe) */ +typedef struct _GArrayTypeClass GArrayTypeClass; + + +/* Indique le type défini pour un tableau. */ +GType g_array_type_get_type(void); + +/* Crée une représentation de tableau. */ +GDataType *g_array_type_new(GDataType *); + +/* Fournit le type des membres du tableau. */ +GDataType *g_array_type_get_members_type(const GArrayType *); + +/* Indique si la dimension du tableau est chiffrée. */ +bool g_array_type_is_dimension_numbered(const GArrayType *); + +/* Fournit la dimension associée au tableau. */ +ssize_t g_array_type_get_dimension_number(const GArrayType *); + +/* Définit la dimension associée au tableau. */ +void g_array_type_set_dimension_number(GArrayType *, ssize_t); + +/* Fournit la dimension associée au tableau. */ +const char *g_array_type_get_dimension_expression(const GArrayType *); + +/* Définit la dimension associée au tableau. */ +void g_array_type_set_dimension_expression(GArrayType *, char *); + + + +#endif /* _ANALYSIS_TYPES_ARRAY_H */ diff --git a/src/analysis/types/basic.c b/src/analysis/types/basic.c index 9e0239a..4ac7f2a 100644 --- a/src/analysis/types/basic.c +++ b/src/analysis/types/basic.c @@ -24,7 +24,7 @@ #include "basic.h" -#include <malloc.h> +#include <assert.h> #include <string.h> @@ -55,14 +55,17 @@ static void g_basic_type_class_init(GBasicTypeClass *); /* Initialise l'instance d'un type basique. */ static void g_basic_type_init(GBasicType *); +/* Supprime toutes les références externes. */ +static void g_basic_type_dispose(GBasicType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_basic_type_finalize(GBasicType *); + /* Crée un copie d'un type existant. */ static GDataType *g_basic_type_dup(const GBasicType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_basic_type_to_string(const GBasicType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_basic_type_output(const GBasicType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_basic_type_to_string(const GBasicType *, bool); @@ -84,6 +87,18 @@ G_DEFINE_TYPE(GBasicType, g_basic_type, G_TYPE_DATA_TYPE); static void g_basic_type_class_init(GBasicTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_basic_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_basic_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_basic_type_dup; + type->to_string = (type_to_string_fc)g_basic_type_to_string; } @@ -102,13 +117,45 @@ static void g_basic_type_class_init(GBasicTypeClass *klass) static void g_basic_type_init(GBasicType *type) { - GDataType *data_type; /* Version basique */ + type->type = BTP_INVALID; - data_type = G_DATA_TYPE(type); +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_basic_type_dispose(GBasicType *type) +{ + G_OBJECT_CLASS(g_basic_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - data_type->dup = (type_dup_fc)g_basic_type_dup; - data_type->to_string = (type_to_string_fc)g_basic_type_to_string; - //data_type->output = (output_type_fc)g_basic_type_output; +static void g_basic_type_finalize(GBasicType *type) +{ + G_OBJECT_CLASS(g_basic_type_parent_class)->finalize(G_OBJECT(type)); } @@ -152,14 +199,19 @@ GDataType *g_basic_type_new(BaseType type) static GDataType *g_basic_type_dup(const GBasicType *type) { - return g_basic_type_new(type->type); + GDataType *result; /* Copie à retourner */ + + result = g_basic_type_new(type->type); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -169,7 +221,7 @@ static GDataType *g_basic_type_dup(const GBasicType *type) * * ******************************************************************************/ -static char *g_basic_type_to_string(const GBasicType *type) +static char *g_basic_type_to_string(const GBasicType *type, bool include) { const char *desc; /* Représentation à copier */ @@ -284,47 +336,15 @@ static char *g_basic_type_to_string(const GBasicType *type) break; default: - case BTP_OTHER: - desc = "user"; + assert(false); + desc = NULL; break; } - return strdup(desc); - -} - - -/****************************************************************************** -* * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'un type. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -static void g_basic_type_output(const GBasicType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - char *text; /* Version humaine à imprimer */ - size_t len; /* Taille de cette version */ - - text = g_basic_type_to_string(type); - len = strlen(text); - - g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); - - free(text); + return (desc != NULL ? strdup(desc) : NULL); } -#endif /****************************************************************************** @@ -339,7 +359,7 @@ static void g_basic_type_output(const GBasicType *type, GLangOutput *lang, GBuff * * ******************************************************************************/ -BaseType g_basic_type_get_btype(const GBasicType *type) +BaseType g_basic_type_get_base_type(const GBasicType *type) { return type->type; diff --git a/src/analysis/types/basic.h b/src/analysis/types/basic.h index 6dba6ae..29d14b1 100644 --- a/src/analysis/types/basic.h +++ b/src/analysis/types/basic.h @@ -62,19 +62,18 @@ typedef enum _BaseType BTP_754R_16, /* IEEE 754r float (16 bits) */ BTP_CHAR32_T, /* char32_t */ BTP_CHAR16_T, /* char16_t */ - BTP_OTHER, /* Extension utilisateur */ BTP_INVALID } BaseType; -#define G_TYPE_BASIC_TYPE g_basic_type_get_type() -#define G_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_basic_type_get_type(), GBasicType)) -#define G_IS_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_basic_type_get_type())) -#define G_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_TYPE, GBasicTypeClass)) -#define G_IS_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_TYPE)) -#define G_BASIC_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_TYPE, GBasicTypeClass)) +#define G_TYPE_BASIC_TYPE g_basic_type_get_type() +#define G_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BASIC_TYPE, GBasicType)) +#define G_IS_BASIC_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_BASIC_TYPE)) +#define G_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BASIC_TYPE, GBasicTypeClass)) +#define G_IS_BASIC_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BASIC_TYPE)) +#define G_BASIC_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BASIC_TYPE, GBasicTypeClass)) /* Description de type basique (instance) */ @@ -91,7 +90,7 @@ GType g_basic_type_get_type(void); GDataType *g_basic_type_new(BaseType); /* Fournit le type de base géré par le type. */ -BaseType g_basic_type_get_btype(const GBasicType *); +BaseType g_basic_type_get_base_type(const GBasicType *); diff --git a/src/analysis/types/cse-int.h b/src/analysis/types/cse-int.h deleted file mode 100644 index 0272435..0000000 --- a/src/analysis/types/cse-int.h +++ /dev/null @@ -1,59 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * cse-int.h - prototypes pour la définition interne des types classes / structures / énumérations - * - * Copyright (C) 2012-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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. - * - * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. - */ - - -#ifndef _ANALYSIS_TYPES_CSE_INT_H -#define _ANALYSIS_TYPES_CSE_INT_H - - -#include "cse.h" -#include "../type-int.h" - - - -/* Description de type classe/structure et enumeration (instance) */ -struct _GClassEnumType -{ - GDataType parent; /* A laisser en premier */ - - ClassEnumType type; /* Type représenté si connu */ - char *name; /* Description humaine */ - -}; - -/* Description de type classe/structure et enumeration (classe) */ -struct _GClassEnumTypeClass -{ - GDataTypeClass parent; /* A laisser en premier */ - -}; - - -/* Décrit le type fourni sous forme de caractères. */ -char *g_class_enum_type_to_string(const GClassEnumType *); - -/* Procède à l'impression de la description d'un type. */ -//void g_class_enum_type_output(const GClassEnumType *, GLangOutput *, GBufferLine *, bool, bool); - - - -#endif /* _ANALYSIS_TYPES_CSE_INT_H */ diff --git a/src/analysis/types/cse.c b/src/analysis/types/cse.c index f20f340..a543630 100644 --- a/src/analysis/types/cse.c +++ b/src/analysis/types/cse.c @@ -24,22 +24,50 @@ #include "cse.h" +#include <malloc.h> #include <string.h> -#include "cse-int.h" +#include "../type-int.h" +/* Description de type classe/structure et énumération (instance) */ +struct _GClassEnumType +{ + GDataType parent; /* A laisser en premier */ + + ClassEnumType type; /* Type représenté si connu */ + char *name; /* Description humaine */ + +}; + +/* Description de type classe/structure et énumération (classe) */ +struct _GClassEnumTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + /* Initialise la classe des types classe ou assimilés. */ static void g_class_enum_type_class_init(GClassEnumTypeClass *); /* Initialise l'instance d'un type classe ou assimilé. */ static void g_class_enum_type_init(GClassEnumType *); +/* Supprime toutes les références externes. */ +static void g_class_enum_type_dispose(GClassEnumType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_class_enum_type_finalize(GClassEnumType *); + /* Crée un copie d'un type existant. */ static GDataType *g_class_enum_type_dup(const GClassEnumType *); +/* Décrit le type fourni sous forme de caractères. */ +static char *g_class_enum_type_to_string(const GClassEnumType *, bool); + /* Indique le type défini pour un type classe ou assimilé. */ @@ -60,6 +88,18 @@ G_DEFINE_TYPE(GClassEnumType, g_class_enum_type, G_TYPE_DATA_TYPE); static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_class_enum_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_class_enum_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_class_enum_type_dup; + type->to_string = (type_to_string_fc)g_class_enum_type_to_string; } @@ -78,13 +118,49 @@ static void g_class_enum_type_class_init(GClassEnumTypeClass *klass) static void g_class_enum_type_init(GClassEnumType *type) { - GDataType *data_type; /* Version basique */ + type->type = CET_COUNT; + type->name = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_class_enum_type_dispose(GClassEnumType *type) +{ + G_OBJECT_CLASS(g_class_enum_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - data_type = G_DATA_TYPE(type); +static void g_class_enum_type_finalize(GClassEnumType *type) +{ + if (type->name != NULL) + free(type->name); - data_type->dup = (type_dup_fc)g_class_enum_type_dup; - data_type->to_string = (type_to_string_fc)g_class_enum_type_to_string; - //data_type->output = (output_type_fc)g_class_enum_type_output; + G_OBJECT_CLASS(g_class_enum_type_parent_class)->finalize(G_OBJECT(type)); } @@ -130,14 +206,22 @@ GDataType *g_class_enum_type_new(ClassEnumType type, char *name) static GDataType *g_class_enum_type_dup(const GClassEnumType *type) { - return g_class_enum_type_new(type->type, type->name); + GDataType *result; /* Copie à retourner */ + char *name; /* Nouveau nom copié */ + + name = (type->name != NULL ? strdup(type->name) : NULL); + + result = g_class_enum_type_new(type->type, name); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -147,33 +231,72 @@ static GDataType *g_class_enum_type_dup(const GClassEnumType *type) * * ******************************************************************************/ -char *g_class_enum_type_to_string(const GClassEnumType *type) +static char *g_class_enum_type_to_string(const GClassEnumType *type, bool include) { - return strdup(type->name); + char *result; /* Valeur à renvoyer */ + + switch (type->type) + { + case CET_VIRTUAL_TABLE: + result = strdup("vtable"); + break; + + case CET_VIRTUAL_STRUCT: + result = strdup("vstruct"); + break; + + default: + result = (type->name != NULL ? strdup(type->name) : NULL); + break; + + } + + return result; } /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à consulter. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Fournit le type pris en compte géré par le type. * * * -* Retour : - * +* Retour : Type pris en compte. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ClassEnumType g_class_enum_type_get_base(const GClassEnumType *type) +{ + ClassEnumType result; /* Type de base à renvoyer */ + + result = type->type; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Donne la désignation de la classe / structure / énumération. * +* * +* Retour : Chaîne de caractères. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -void g_class_enum_type_output(const GClassEnumType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +const char *g_class_enum_type_get_name(const GClassEnumType *type) { - g_buffer_line_append_text(line, BLC_LAST_USED, type->name, strlen(type->name), - info ? RTT_COMMENT : RTT_RAW, NULL); + char *result; /* Valeur à renvoyer */ + + result = type->name; + + return result; } -#endif diff --git a/src/analysis/types/cse.h b/src/analysis/types/cse.h index 184062d..cb4b228 100644 --- a/src/analysis/types/cse.h +++ b/src/analysis/types/cse.h @@ -32,18 +32,18 @@ -#define G_TYPE_CLASS_ENUM_TYPE g_class_enum_type_get_type() -#define G_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_class_enum_type_get_type(), GClassEnumType)) -#define G_IS_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_class_enum_type_get_type())) -#define G_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) -#define G_IS_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CLASS_ENUM_TYPE)) -#define G_CLASS_ENUM_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) +#define G_TYPE_CLASS_ENUM_TYPE g_class_enum_type_get_type() +#define G_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumType)) +#define G_IS_CLASS_ENUM_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CLASS_ENUM_TYPE)) +#define G_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) +#define G_IS_CLASS_ENUM_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CLASS_ENUM_TYPE)) +#define G_CLASS_ENUM_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CLASS_ENUM_TYPE, GClassEnumTypeClass)) -/* Description de type classe/structure et enumeration (instance) */ +/* Description de type classe/structure et énumération (instance) */ typedef struct _GClassEnumType GClassEnumType; -/* Description de type classe/structure et enumeration (classe) */ +/* Description de type classe/structure et énumération (classe) */ typedef struct _GClassEnumTypeClass GClassEnumTypeClass; @@ -53,7 +53,12 @@ typedef enum _ClassEnumType CET_UNKNOWN, /* Statut inconnu */ CET_STRUCT, /* Structure */ CET_ENUM, /* Enumération */ - CET_CLASS /* Classe */ + CET_CLASS, /* Classe */ + CET_NAMESPACE, /* Espace de nom */ + CET_VIRTUAL_TABLE, /* Table virtuelle */ + CET_VIRTUAL_STRUCT, /* Indice de construction VT */ + + CET_COUNT } ClassEnumType; @@ -64,6 +69,12 @@ GType g_class_enum_type_get_type(void); /* Crée une représentation de classe, structure ou énumération. */ GDataType *g_class_enum_type_new(ClassEnumType, char *); +/* Fournit le type pris en compte géré par le type. */ +ClassEnumType g_class_enum_type_get_base(const GClassEnumType *); + +/* Donne la désignation de la classe / structure / énumération. */ +const char *g_class_enum_type_get_name(const GClassEnumType *); + #endif /* _ANALYSIS_TYPES_CSE_H */ diff --git a/src/analysis/types/encaps.c b/src/analysis/types/encaps.c index 36dc71a..dc1bb3e 100644 --- a/src/analysis/types/encaps.c +++ b/src/analysis/types/encaps.c @@ -25,9 +25,9 @@ #include <assert.h> +#include <malloc.h> -#include "../routine.h" #include "../type-int.h" #include "../../common/extstr.h" @@ -40,7 +40,6 @@ struct _GEncapsulatedType EncapsulationType type; /* Encapsulation utilisée */ GDataType *child; /* Sous-type encadré */ - GBinRoutine *routine; /* Routine pointée */ size_t dimension; /* Dimension quand applicable */ @@ -60,14 +59,23 @@ static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *); /* Initialise l'instance d'un type encapsulé. */ static void g_encapsulated_type_init(GEncapsulatedType *); +/* Supprime toutes les références externes. */ +static void g_encapsulated_type_dispose(GEncapsulatedType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_encapsulated_type_finalize(GEncapsulatedType *); + /* Crée un copie d'un type existant. */ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_encapsulated_type_to_string(const GEncapsulatedType *); +static char *g_encapsulated_type_to_string(const GEncapsulatedType *, bool); -/* Procède à l'impression de la description d'un type. */ -//static void g_encapsulated_type_output(const GEncapsulatedType *, GLangOutput *, GBufferLine *, bool, bool); +/* Indique si le type est un pointeur. */ +static bool g_encapsulated_type_is_pointer(const GEncapsulatedType *); + +/* Indique si le type est une référence. */ +static bool g_encapsulated_type_is_reference(const GEncapsulatedType *); @@ -89,6 +97,21 @@ G_DEFINE_TYPE(GEncapsulatedType, g_encapsulated_type, G_TYPE_DATA_TYPE); static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_encapsulated_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_encapsulated_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_encapsulated_type_dup; + type->to_string = (type_to_string_fc)g_encapsulated_type_to_string; + + type->is_pointer = (type_is_pointer_fc)g_encapsulated_type_is_pointer; + type->is_reference = (type_is_reference_fc)g_encapsulated_type_is_reference; } @@ -107,13 +130,51 @@ static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass) static void g_encapsulated_type_init(GEncapsulatedType *type) { - GDataType *data_type; /* Version basique */ + type->type = ECT_COUNT; + type->child = NULL; + + type->dimension = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_encapsulated_type_dispose(GEncapsulatedType *type) +{ + if (type->child != NULL) + g_object_unref(G_OBJECT(type->child)); + + G_OBJECT_CLASS(g_encapsulated_type_parent_class)->dispose(G_OBJECT(type)); + +} - data_type = G_DATA_TYPE(type); - data_type->dup = (type_dup_fc)g_encapsulated_type_dup; - data_type->to_string = (type_to_string_fc)g_encapsulated_type_to_string; - //data_type->output = (output_type_fc)g_encapsulated_type_output; +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_encapsulated_type_finalize(GEncapsulatedType *type) +{ + G_OBJECT_CLASS(g_encapsulated_type_parent_class)->finalize(G_OBJECT(type)); } @@ -121,7 +182,7 @@ static void g_encapsulated_type_init(GEncapsulatedType *type) /****************************************************************************** * * * Paramètres : type = type d'extension à représenter. * -* child = variable dont on doit dériver. * +* child = base dont on doit dériver. * * * * Description : Crée une représentation de variable dérivée. * * * @@ -131,33 +192,14 @@ static void g_encapsulated_type_init(GEncapsulatedType *type) * * ******************************************************************************/ -GDataType *g_encapsulated_type_new(EncapsulationType type, ...) +GDataType *g_encapsulated_type_new(EncapsulationType type, GDataType *child) { GEncapsulatedType *result; /* Structure à retourner */ - va_list ap; /* Liste variable d'arguments */ result = g_object_new(G_TYPE_ENCAPSULATED_TYPE, NULL); result->type = type; - - va_start(ap, type); - - switch (type) - { - case ECT_ROUTINE: - result->routine = va_arg(ap, GBinRoutine *); - assert(result->routine != NULL); - g_binary_routine_set_name(result->routine, "(*)"); - break; - - default: - result->child = va_arg(ap, GDataType *); - assert(result->child != NULL); - break; - - } - - va_end(ap); + result->child = child; return G_DATA_TYPE(result); @@ -181,19 +223,8 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) GDataType *result; /* Nouvelle instance à renvoyer*/ GDataType *child; /* Copie du type interne */ - switch (type->type) - { - case ECT_ROUTINE: - g_object_ref(G_OBJECT(type->routine)); - result = g_encapsulated_type_new(type->type, type->routine); - break; - - default: - child = g_data_type_dup(type->child); - result = g_encapsulated_type_new(type->type, child); - break; - - } + child = g_data_type_dup(type->child); + result = g_encapsulated_type_new(type->type, child); return result; @@ -202,7 +233,8 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -212,34 +244,20 @@ static GDataType *g_encapsulated_type_dup(const GEncapsulatedType *type) * * ******************************************************************************/ -static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) +static char *g_encapsulated_type_to_string(const GEncapsulatedType *type, bool include) { char *result; /* Chaîne finale à renvoyer */ size_t i; /* Boucle de parcours */ - switch (type->type) - { - case ECT_ROUTINE: - result = g_binary_routine_to_string(type->routine); - break; - - default: - result = g_data_type_to_string(type->child); - break; - - } + result = g_data_type_to_string(type->child, include); + if (result == NULL) goto exit; switch (type->type) { case ECT_POINTER: - - if (G_IS_ENCAPSULATED_TYPE(type->child) - && G_ENCAPSULATED_TYPE(type->child)->type == ECT_ROUTINE) break; - - if (!g_data_type_is_pointer(type->child, false)) + if (!g_data_type_is_pointer(type->child)) result = stradd(result, " "); result = stradd(result, "*"); - break; case ECT_ARRAY: @@ -247,25 +265,37 @@ static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) for (i = 0; i < type->dimension; i++) result = stradd(result, "[]"); break; + case ECT_REFERENCE: - result = stradd(result, " &"); + if (!g_data_type_is_reference(type->child)) + result = stradd(result, " "); + result = stradd(result, "&"); break; + case ECT_RVALUE_REF: - result = stradd(result, " &&"); + if (!g_data_type_is_reference(type->child)) + result = stradd(result, " "); + result = stradd(result, "&&"); break; + case ECT_COMPLEX: result = stradd(result, " complex"); break; + case ECT_IMAGINARY: result = stradd(result, " imaginary"); break; - case ECT_ROUTINE: /* Pour GCC */ default: + assert(false); + free(result); + result = NULL; break; } + exit: + return result; } @@ -273,26 +303,48 @@ static char *g_encapsulated_type_to_string(const GEncapsulatedType *type) /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à consulter. * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Indique si le type est un pointeur. * * * -* Retour : - * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_encapsulated_type_is_pointer(const GEncapsulatedType *type) +{ + bool result; /* Bilan à retourner */ + + result = (type->type == ECT_POINTER); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique si le type est une référence. * +* * +* Retour : Bilan de la consultation. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -static void g_encapsulated_type_output(const GEncapsulatedType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +static bool g_encapsulated_type_is_reference(const GEncapsulatedType *type) { - g_buffer_line_append_text(line, BLC_LAST_USED, "!TODO!", 6, info ? RTT_COMMENT : RTT_RAW, NULL); + bool result; /* Bilan à retourner */ + + result = (type->type == ECT_REFERENCE || type->type == ECT_RVALUE_REF); + + return result; } -#endif /****************************************************************************** @@ -317,39 +369,25 @@ EncapsulationType g_encapsulated_type_get_etype(const GEncapsulatedType *type) /****************************************************************************** * * * Paramètres : type = type à consulter. * -* ... = sous-type ou routine encapsulée dans le type. [OUT] * * * -* Description : Fournit la routine encapsulée dans le type. * +* Description : Fournit le type encapsulée dans le type. * * * -* Retour : - * +* Retour : Sous-type encapsulé dans le type. * * * * Remarques : - * * * ******************************************************************************/ -void g_encapsulated_type_get_item(const GEncapsulatedType *type, ...) +GDataType *g_encapsulated_type_get_item(const GEncapsulatedType *type) { - va_list ap; /* Liste variable d'arguments */ - GDataType **child; /* Adresse pour sous-type */ - GBinRoutine **routine; /* Adresse pour routine */ + GDataType *result; /* Type à retourner */ - va_start(ap, type); + result = type->child; - switch (type->type) - { - case ECT_ROUTINE: - routine = va_arg(ap, GBinRoutine **); - *routine = type->routine; - break; + if (result != NULL) + g_object_ref(G_OBJECT(result)); - default: - child = va_arg(ap, GDataType **); - *child = type->child; - break; - - } - - va_end(ap); + return result; } diff --git a/src/analysis/types/encaps.h b/src/analysis/types/encaps.h index 7ea8b9e..d8b70b0 100644 --- a/src/analysis/types/encaps.h +++ b/src/analysis/types/encaps.h @@ -32,12 +32,12 @@ -#define G_TYPE_ENCAPSULATED_TYPE g_encapsulated_type_get_type() -#define G_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_encapsulated_type_get_type(), GEncapsulatedType)) -#define G_IS_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_encapsulated_type_get_type())) -#define G_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) -#define G_IS_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPSULATED_TYPE)) -#define G_ENCAPSULATED_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) +#define G_TYPE_ENCAPSULATED_TYPE g_encapsulated_type_get_type() +#define G_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedType)) +#define G_IS_ENCAPSULATED_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_ENCAPSULATED_TYPE)) +#define G_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) +#define G_IS_ENCAPSULATED_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ENCAPSULATED_TYPE)) +#define G_ENCAPSULATED_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ENCAPSULATED_TYPE, GEncapsulatedTypeClass)) /* Description de type encapsulé (instance) */ @@ -57,7 +57,7 @@ typedef enum _EncapsulationType ECT_COMPLEX, /* Complexe (C 2000) */ ECT_IMAGINARY, /* Imaginaire (C 2000) */ - ECT_ROUTINE /* Pointeur vers une routine */ + ECT_COUNT } EncapsulationType; @@ -66,13 +66,13 @@ typedef enum _EncapsulationType GType g_encapsulated_type_get_type(void); /* Crée une représentation de variable dérivée. */ -GDataType *g_encapsulated_type_new(EncapsulationType, ...); +GDataType *g_encapsulated_type_new(EncapsulationType, GDataType *); /* Fournit le type d'encapsulation gérée par le type. */ EncapsulationType g_encapsulated_type_get_etype(const GEncapsulatedType *); -/* Fournit la routine encapsulée dans le type. */ -void g_encapsulated_type_get_item(const GEncapsulatedType *, ...); +/* Fournit le type encapsulée dans le type. */ +GDataType *g_encapsulated_type_get_item(const GEncapsulatedType *); /* Fournit la dimension éventuellement associée au type. */ size_t g_encapsulated_type_get_dimension(const GEncapsulatedType *); diff --git a/src/analysis/types/expr.c b/src/analysis/types/expr.c new file mode 100644 index 0000000..376b0b4 --- /dev/null +++ b/src/analysis/types/expr.c @@ -0,0 +1,258 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.c - manipulation de types sous forme d'expressions + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "expr.h" + + +#include <malloc.h> +#include <string.h> + + +#include "../type-int.h" + + + +/* Description de type sous forme d'expressions (instance) */ +struct _GExprType +{ + GDataType parent; /* A laisser en premier */ + + char *value; /* Valeur brute de l'expression*/ + +}; + +/* Description de type sous forme d'expressions (classe) */ +struct _GExprTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des types sous forme d'expressions. */ +static void g_expr_type_class_init(GExprTypeClass *); + +/* Initialise l'instance d'un type sous forme d'expressions. */ +static void g_expr_type_init(GExprType *); + +/* Supprime toutes les références externes. */ +static void g_expr_type_dispose(GExprType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_expr_type_finalize(GExprType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_expr_type_dup(const GExprType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_expr_type_to_string(const GExprType *, bool); + + + +/* Indique le type défini pour un type sous forme d'expressions. */ +G_DEFINE_TYPE(GExprType, g_expr_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des types sous forme d'expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_class_init(GExprTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_expr_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_expr_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_expr_type_dup; + type->to_string = (type_to_string_fc)g_expr_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un type sous forme d'expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_init(GExprType *type) +{ + type->value = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_dispose(GExprType *type) +{ + G_OBJECT_CLASS(g_expr_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_expr_type_finalize(GExprType *type) +{ + if (type->value != NULL) + free(type->value); + + G_OBJECT_CLASS(g_expr_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : value = valeur brute de l'expression. * +* * +* Description : Crée une représentation de type sous forme d'expressions. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_expr_type_new(char *value) +{ + GExprType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_EXPR_TYPE, NULL); + + result->value = value; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_expr_type_dup(const GExprType *type) +{ + GDataType *result; /* Copie à retourner */ + + result = g_expr_type_new(strdup(type->value)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_expr_type_to_string(const GExprType *type, bool include) +{ + char *result; /* Valeur à renvoyer */ + + result = strdup(type->value); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit la valeur d'un type fourni sous forme de caractères. * +* * +* Retour : Chaîne formant une expression. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_expr_type_get_value(const GExprType *type) +{ + char *result; /* Valeur à renvoyer */ + + result = type->value; + + return result; + +} diff --git a/src/analysis/types/expr.h b/src/analysis/types/expr.h new file mode 100644 index 0000000..3f7c953 --- /dev/null +++ b/src/analysis/types/expr.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * expr.h - prototypes pour la manipulation de types sous forme d'expressions + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_TYPES_EXPR_H +#define _ANALYSIS_TYPES_EXPR_H + + +#include <glib-object.h> + + +#include "../type.h" + + + +#define G_TYPE_EXPR_TYPE g_expr_type_get_type() +#define G_EXPR_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_EXPR_TYPE, GExprType)) +#define G_IS_EXPR_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_EXPR_TYPE)) +#define G_EXPR_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_EXPR_TYPE, GExprTypeClass)) +#define G_IS_EXPR_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_EXPR_TYPE)) +#define G_EXPR_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_EXPR_TYPE, GExprTypeClass)) + + +/* Description de type sous forme d'expressions (instance) */ +typedef struct _GExprType GExprType; + +/* Description de type sous forme d'expressions (classe) */ +typedef struct _GExprTypeClass GExprTypeClass; + + +/* Indique le type défini pour un type sous forme d'expressions. */ +GType g_expr_type_get_type(void); + +/* Crée une représentation de type sous forme d'expressions. */ +GDataType *g_expr_type_new(char *); + +/* Fournit la valeur d'un type fourni sous forme de caractères. */ +const char *g_expr_type_get_value(const GExprType *); + + + +#endif /* _ANALYSIS_TYPES_EXPR_H */ diff --git a/src/analysis/types/literal.c b/src/analysis/types/literal.c index 7a0c4f7..f284310 100644 --- a/src/analysis/types/literal.c +++ b/src/analysis/types/literal.c @@ -58,14 +58,17 @@ static void g_literal_type_class_init(GLiteralTypeClass *); /* Initialise l'instance d'un type instancié avec une valeur. */ static void g_literal_type_init(GLiteralType *); +/* Supprime toutes les références externes. */ +static void g_literal_type_dispose(GLiteralType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_literal_type_finalize(GLiteralType *); + /* Crée un copie d'un type existant. */ static GDataType *g_literal_type_dup(const GLiteralType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_literal_type_to_string(const GLiteralType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_literal_type_output(const GLiteralType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_literal_type_to_string(const GLiteralType *, bool); @@ -87,6 +90,18 @@ G_DEFINE_TYPE(GLiteralType, g_literal_type, G_TYPE_DATA_TYPE); static void g_literal_type_class_init(GLiteralTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_literal_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_literal_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_literal_type_dup; + type->to_string = (type_to_string_fc)g_literal_type_to_string; } @@ -105,13 +120,48 @@ static void g_literal_type_class_init(GLiteralTypeClass *klass) static void g_literal_type_init(GLiteralType *type) { - GDataType *data_type; /* Version basique */ + type->orig = NULL; - data_type = G_DATA_TYPE(type); +} - data_type->dup = (type_dup_fc)g_literal_type_dup; - data_type->to_string = (type_to_string_fc)g_literal_type_to_string; - //data_type->output = (output_type_fc)g_literal_type_output; + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_literal_type_dispose(GLiteralType *type) +{ + if (type->orig != NULL) + g_object_unref(G_OBJECT(type->orig)); + + G_OBJECT_CLASS(g_literal_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_literal_type_finalize(GLiteralType *type) +{ + G_OBJECT_CLASS(g_literal_type_parent_class)->finalize(G_OBJECT(type)); } @@ -129,18 +179,23 @@ static void g_literal_type_init(GLiteralType *type) * * ******************************************************************************/ -GDataType *g_literal_type_new(GDataType *orig, literal_value value) +GDataType *g_literal_type_new(GDataType *orig, const literal_value *value) { GLiteralType *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_LITERAL_TYPE, NULL); + if (!G_IS_BASIC_TYPE(orig)) + result = NULL; - result->orig = orig; - result->value = value; + else + { + result = g_object_new(G_TYPE_LITERAL_TYPE, NULL); - g_object_ref(orig); + result->orig = orig; + result->value = *value; - return G_DATA_TYPE(result); + } + + return (result != NULL ? G_DATA_TYPE(result) : NULL); } @@ -159,18 +214,22 @@ GDataType *g_literal_type_new(GDataType *orig, literal_value value) static GDataType *g_literal_type_dup(const GLiteralType *type) { + GDataType *result; /* Copie à retourner */ GDataType *orig; /* Copie du type interne */ orig = g_data_type_dup(type->orig); - return g_literal_type_new(orig, type->value); + result = g_literal_type_new(orig, &type->value); + + return result; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit le type fourni sous forme de caractères. * * * @@ -180,63 +239,27 @@ static GDataType *g_literal_type_dup(const GLiteralType *type) * * ******************************************************************************/ -static char *g_literal_type_to_string(const GLiteralType *type) +static char *g_literal_type_to_string(const GLiteralType *type, bool include) { char *result; /* Valeur à renvoyer */ - size_t max; /* Longueur totale du texte */ - if (G_IS_BASIC_TYPE(type->orig)) - switch (g_basic_type_get_btype(G_BASIC_TYPE(type->orig))) - { - case BTP_BOOL: - result = strdup(type->value.int_val ? "true" : "false"); - break; + switch (g_basic_type_get_base_type(G_BASIC_TYPE(type->orig))) + { + case BTP_BOOL: + result = strdup(type->value.int_val ? "true" : "false"); + break; - case BTP_INT: - max = strlen("2147483647" /* INT_MAX */) + 1; - result = (char *)calloc(max, sizeof(char)); - snprintf(result, max, "%d", type->value.int_val); - break; + case BTP_INT: + default: + asprintf(&result, "%d", type->value.int_val); + break; - default: - result = strdup("TODO"); - break; + case BTP_FLOAT: + asprintf(&result, "%f", type->value.float_val); + break; } - else result = strdup("???"); return result; } - - -/****************************************************************************** -* * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'un type. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -static void g_literal_type_output(const GLiteralType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - char *text; /* Version humaine à imprimer */ - size_t len; /* Taille de cette version */ - - text = g_literal_type_to_string(type); - len = strlen(text); - - g_buffer_line_append_text(line, BLC_LAST_USED, text, len, info ? RTT_COMMENT : RTT_RAW, NULL); - - free(text); - -} -#endif diff --git a/src/analysis/types/literal.h b/src/analysis/types/literal.h index 032ba8b..48a543a 100644 --- a/src/analysis/types/literal.h +++ b/src/analysis/types/literal.h @@ -32,12 +32,12 @@ -#define G_TYPE_LITERAL_TYPE g_literal_type_get_type() -#define G_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_literal_type_get_type(), GLiteralType)) -#define G_IS_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_literal_type_get_type())) -#define G_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) -#define G_IS_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_TYPE)) -#define G_LITERAL_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) +#define G_TYPE_LITERAL_TYPE g_literal_type_get_type() +#define G_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LITERAL_TYPE, GLiteralType)) +#define G_IS_LITERAL_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LITERAL_TYPE)) +#define G_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) +#define G_IS_LITERAL_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LITERAL_TYPE)) +#define G_LITERAL_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LITERAL_TYPE, GLiteralTypeClass)) /* Description de type instancié avec une valeur litérale (instance) */ @@ -60,7 +60,7 @@ typedef union _literal_value GType g_literal_type_get_type(void); /* Crée une représentation de type instancié avec une valeur. */ -GDataType *g_literal_type_new(GDataType *, literal_value); +GDataType *g_literal_type_new(GDataType *, const literal_value *); diff --git a/src/analysis/types/override.c b/src/analysis/types/override.c new file mode 100644 index 0000000..a535e80 --- /dev/null +++ b/src/analysis/types/override.c @@ -0,0 +1,365 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.c - manipulation des types pointant sur une fonction virtuelle + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "override.h" + + +#include <assert.h> +#include <malloc.h> +#include <string.h> + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de fonction virtuelle (instance) */ +struct _GOverrideType +{ + GDataType parent; /* A laisser en premier */ + + GDataType *base; /* Type de base à traiter */ + call_offset_t offsets[2]; /* Décalages à appliquer */ + bool with_covariant; /* Variation avec covariant */ + +}; + +/* Description de fonction virtuelle (classe) */ +struct _GOverrideTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des fonctions virtuelles. */ +static void g_override_type_class_init(GOverrideTypeClass *); + +/* Initialise l'instance d'une fonction virtuelle. */ +static void g_override_type_init(GOverrideType *); + +/* Supprime toutes les références externes. */ +static void g_override_type_dispose(GOverrideType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_override_type_finalize(GOverrideType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_override_type_dup(const GOverrideType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_override_type_to_string(const GOverrideType *, bool); + + + +/* Indique le type défini pour une fonction virtuelle. */ +G_DEFINE_TYPE(GOverrideType, g_override_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des fonctions virtuelles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_class_init(GOverrideTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_override_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_override_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_override_type_dup; + type->to_string = (type_to_string_fc)g_override_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'une fonction virtuelle. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_init(GOverrideType *type) +{ + type->base = NULL; + memset(type->offsets, 0, sizeof(type->offsets)); + type->with_covariant = false; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_dispose(GOverrideType *type) +{ + if (type->base != NULL) + g_object_unref(G_OBJECT(type->base)); + + G_OBJECT_CLASS(g_override_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_override_type_finalize(GOverrideType *type) +{ + G_OBJECT_CLASS(g_override_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : base = type de base sur lequel s'appuyer. * +* offset = décalage à appliquer. * +* * +* Description : Crée une représentation de fonction virtuelle. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_new(GDataType *base, const call_offset_t *offset) +{ + GOverrideType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_OVERRIDE_TYPE, NULL); + + result->base = base; + result->offsets[0] = *offset; + result->with_covariant = false; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : base = type de base sur lequel s'appuyer. * +* off0 = premier décalage à appliquer. * +* off1 = second décalage à appliquer. * +* * +* Description : Crée une représentation de fonction virtuelle avec covariant.* +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_new_with_covariant(GDataType *base, const call_offset_t *off0, const call_offset_t *off1) +{ + GOverrideType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_OVERRIDE_TYPE, NULL); + + result->base = base; + result->offsets[0] = *off0; + result->offsets[1] = *off1; + result->with_covariant = true; + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_override_type_dup(const GOverrideType *type) +{ + GDataType *result; /* Nouvelle instance à renvoyer*/ + GDataType *base; /* Copie du type interne */ + + base = g_data_type_dup(type->base); + + if (type->with_covariant) + result = g_override_type_new_with_covariant(base, &type->offsets[0], &type->offsets[1]); + + else + result = g_override_type_new(base, &type->offsets[0]); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_override_type_to_string(const GOverrideType *type, bool include) +{ + char *result; /* Chaîne finale à renvoyer */ + + result = g_data_type_to_string(type->base, include); + if (result == NULL) goto exit; + + char *offset_to_string(const call_offset_t *off, char *base) + { + char *tmp; /* Conversion temporaire */ + + asprintf(&tmp, "%zd", off->values[0]); + base = stradd(base, tmp); + free(tmp); + + if (off->virtual) + { + base = stradd(base, "_"); + + asprintf(&tmp, "%zd", off->values[1]); + base = stradd(base, tmp); + free(tmp); + + } + + return base; + + } + + result = offset_to_string(&type->offsets[0], result); + + if (type->with_covariant) + result = offset_to_string(&type->offsets[0], result); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type de base comportant la fonction virtuelle. * +* * +* Retour : Type de base traité. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_override_type_get_base(const GOverrideType *type) +{ + GDataType *result; /* Type à retourner */ + + result = type->base; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* off0 = premier décalage à appliquer. [OUT] * +* off1 = second décalage à appliquer. [OUT] * +* * +* Description : Fournit les décalages appliquée pour une fonction virtuelle. * +* * +* Retour : true si un covariant est pris en compte, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_override_type_get_offsets(const GOverrideType *type, call_offset_t *off0, call_offset_t *off1) +{ + bool result; /* Nature à retourner */ + + result = type->with_covariant; + + *off0 = type->offsets[0]; + *off1 = type->offsets[1]; + + return result; + +} diff --git a/src/analysis/types/override.h b/src/analysis/types/override.h new file mode 100644 index 0000000..7136e40 --- /dev/null +++ b/src/analysis/types/override.h @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * override.h - prototypes pour la manipulation des types pointant sur une fonction virtuelle + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_TYPES_OVERRIDE_H +#define _ANALYSIS_TYPES_OVERRIDE_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include "../type.h" + + + +#define G_TYPE_OVERRIDE_TYPE g_override_type_get_type() +#define G_OVERRIDE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_OVERRIDE_TYPE, GOverrideType)) +#define G_IS_OVERRIDE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_OVERRIDE_TYPE)) +#define G_OVERRIDE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_OVERRIDE_TYPE, GOverrideTypeClass)) +#define G_IS_OVERRIDE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_OVERRIDE_TYPE)) +#define G_OVERRIDE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_OVERRIDE_TYPE, GOverrideTypeClass)) + + +/* Description de fonction virtuelle (instance) */ +typedef struct _GOverrideType GOverrideType; + +/* Description de fonction virtuelle (classe) */ +typedef struct _GOverrideTypeClass GOverrideTypeClass; + + +/* Indications de sauts */ +typedef struct _call_offset_t +{ + ssize_t values[2]; /* Décalages à appliquer */ + bool virtual; /* Appel virtuel ? */ + +} call_offset_t; + + +/* Indique le type défini pour une fonction virtuelle. */ +GType g_override_type_get_type(void); + +/* Crée une représentation de fonction virtuelle. */ +GDataType *g_override_type_new(GDataType *, const call_offset_t *); + +/* Crée une représentation de fonction virtuelle avec covariant. */ +GDataType *g_override_type_new_with_covariant(GDataType *, const call_offset_t *, const call_offset_t *); + +/* Fournit le type de base comportant la fonction virtuelle. */ +GDataType *g_override_type_get_base(const GOverrideType *); + +/* Fournit les décalages appliquée pour une fonction virtuelle. */ +bool g_override_type_get_offsets(const GOverrideType *, call_offset_t *, call_offset_t *); + + + +#endif /* _ANALYSIS_TYPES_OVERRIDE_H */ diff --git a/src/analysis/types/proto.c b/src/analysis/types/proto.c new file mode 100644 index 0000000..362bd88 --- /dev/null +++ b/src/analysis/types/proto.c @@ -0,0 +1,441 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.c - manipulation des prototypes + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "proto.h" + + +#include <assert.h> +#include <malloc.h> +#include <string.h> + + +#include "../type-int.h" +#include "../../common/extstr.h" + + + +/* Description de prototype (instance) */ +struct _GProtoType +{ + GDataType parent; /* A laisser en premier */ + + GDataType *ret_type; /* Type retourné */ + + GDataType **args; /* Sous-types associés */ + size_t count; /* Quantité de ces arguments */ + +}; + +/* Description de prototype (classe) */ +struct _GProtoTypeClass +{ + GDataTypeClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des prototypes. */ +static void g_proto_type_class_init(GProtoTypeClass *); + +/* Initialise l'instance d'un prototype. */ +static void g_proto_type_init(GProtoType *); + +/* Supprime toutes les références externes. */ +static void g_proto_type_dispose(GProtoType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_proto_type_finalize(GProtoType *); + +/* Crée un copie d'un type existant. */ +static GDataType *g_proto_type_dup(const GProtoType *); + +/* Décrit le type fourni sous forme de caractères. */ +static char *g_proto_type_to_string(const GProtoType *, bool); + + + +/* Indique le type défini pour un prototype. */ +G_DEFINE_TYPE(GProtoType, g_proto_type, G_TYPE_DATA_TYPE); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des prototypes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_class_init(GProtoTypeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_proto_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_proto_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->handle_ns = false; + + type->dup = (type_dup_fc)g_proto_type_dup; + type->to_string = (type_to_string_fc)g_proto_type_to_string; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à initialiser. * +* * +* Description : Initialise l'instance d'un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_init(GProtoType *type) +{ + type->ret_type = NULL; + + type->args = NULL; + type->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_dispose(GProtoType *type) +{ + size_t i; /* Boucle de parcours */ + + if (type->ret_type != NULL) + g_object_unref(G_OBJECT(type->ret_type)); + + for (i = 0; i < type->count; i++) + g_object_unref(G_OBJECT(type->args[i])); + + G_OBJECT_CLASS(g_proto_type_parent_class)->dispose(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_proto_type_finalize(GProtoType *type) +{ + if (type->args != NULL) + free(type->args); + + G_OBJECT_CLASS(g_proto_type_parent_class)->finalize(G_OBJECT(type)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une représentation de prototype. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_new(void) +{ + GProtoType *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_PROTO_TYPE, NULL); + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à dupliquer. * +* * +* Description : Crée un copie d'un type existant. * +* * +* Retour : Nouvelle instance de type identique à celle fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDataType *g_proto_type_dup(const GProtoType *type) +{ + GProtoType *result; /* Copie à retourner */ + GDataType *ret_type; /* Type de retour */ + size_t i; /* Boucle de parcours */ + GDataType *arg; /* Argument copié */ + + result = G_PROTO_TYPE(g_proto_type_new()); + + if (type->ret_type != NULL) + { + ret_type = g_data_type_dup(type->ret_type); + g_proto_type_set_return_type(result, ret_type); + } + + for (i = 0; i < type->count; i++) + { + arg = g_data_type_dup(type->args[i]); + g_proto_type_add_arg(result, arg); + } + + return G_DATA_TYPE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * +* * +* Description : Décrit le type fourni sous forme de caractères. * +* * +* Retour : Chaîne à libérer de la mémoire après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *g_proto_type_to_string(const GProtoType *type, bool include) +{ + char *result; /* Valeur à renvoyer */ + GDataType *base; /* Version d'instance parente */ + char *namespace; /* Groupe d'appartenance */ + size_t i; /* Boucle de parcours */ + char *arg; /* Argument à décrire */ + + if (type->ret_type != NULL) + { + result = g_data_type_to_string(type->ret_type, include); + if (result == NULL) goto exit; + + result = stradd(result, " "); + + } + else + result = NULL; + + result = stradd(result, "("); + + base = G_DATA_TYPE(type); + + if (include && base->namespace != NULL) + { + namespace = g_data_type_to_string(base->namespace, true); + if (namespace == NULL) goto error; + + result = stradd(result, namespace); + result = stradd(result, base->ns_sep); + + free(namespace); + + } + + result = stradd(result, "*) ("); + + for (i = 0; i < type->count; i++) + { + if (i > 0) result = stradd(result, ", "); + + arg = g_data_type_to_string(type->args[i], include); + if (arg == NULL) goto error; + + result = stradd(result, arg); + free(arg); + + } + + result = stradd(result, ")"); + + exit: + + return result; + + error: + + free(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à mettre à jour. * +* ret = indication sur le type de retour. * +* * +* Description : Définit le type de retour d'un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proto_type_set_return_type(GProtoType *type, GDataType *ret) +{ + if (type->ret_type != NULL) + g_object_unref(G_OBJECT(type->ret_type)); + + type->ret_type = ret; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Fournit le type de retour d'un prototype. * +* * +* Retour : Indication sur le type de retour en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_get_return_type(const GProtoType *type) +{ + GDataType *result; /* Type de retour à renvoyer */ + + result = type->ret_type; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à mettre à jour. * +* arg = nouvel argument à intégrer au prototype. * +* * +* Description : Ajoute un argument à un prototype. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_proto_type_add_arg(GProtoType *type, GDataType *arg) +{ + type->args = (GDataType **)realloc(type->args, ++type->count * sizeof(GDataType *)); + type->args[type->count - 1] = arg; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* * +* Description : Indique le nombre d'arguments associés au prototype. * +* * +* Retour : Nombre de paramètres inclus dans le gabarit. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t g_proto_type_count_args(const GProtoType *type) +{ + return type->count; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type à consulter. * +* index = indice du type d'argument à retourner. * +* * +* Description : Fournit un argument donné du prototype. * +* * +* Retour : Type d'argument ou NULL si mauvais indice. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDataType *g_proto_type_get_arg(const GProtoType *type, size_t index) +{ + GDataType *result; /* Argument à retourner */ + + assert(index < type->count); + + if (index < type->count) + { + result = type->args[index]; + g_object_ref(G_OBJECT(result)); + } + + else + result = NULL; + + return result; + +} diff --git a/src/analysis/types/proto.h b/src/analysis/types/proto.h new file mode 100644 index 0000000..a0dedb0 --- /dev/null +++ b/src/analysis/types/proto.h @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * proto.h - prototypes pour la manipulation des prototypes + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_TYPES_PROTO_H +#define _ANALYSIS_TYPES_PROTO_H + + +#include <glib-object.h> + + +#include "../type.h" + + + +#define G_TYPE_PROTO_TYPE g_proto_type_get_type() +#define G_PROTO_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PROTO_TYPE, GProtoType)) +#define G_IS_PROTO_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PROTO_TYPE)) +#define G_PROTO_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PROTO_TYPE, GProtoTypeClass)) +#define G_IS_PROTO_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PROTO_TYPE)) +#define G_PROTO_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PROTO_TYPE, GProtoTypeClass)) + + +/* Description de prototype (instance) */ +typedef struct _GProtoType GProtoType; + +/* Description de prototype (classe) */ +typedef struct _GProtoTypeClass GProtoTypeClass; + + +/* Indique le type défini pour un prototype. */ +GType g_proto_type_get_type(void); + +/* Crée une représentation de prototype. */ +GDataType *g_proto_type_new(void); + +/* Définit le type de retour d'un prototype. */ +void g_proto_type_set_return_type(GProtoType *, GDataType *); + +/* Fournit le type de retour d'un prototype. */ +GDataType *g_proto_type_get_return_type(const GProtoType *); + +/* Ajoute un argument à un prototype. */ +void g_proto_type_add_arg(GProtoType *, GDataType *); + +/* Indique le nombre d'arguments associés au prototype. */ +size_t g_proto_type_count_args(const GProtoType *); + +/* Fournit un argument donné du prototype. */ +GDataType *g_proto_type_get_arg(const GProtoType *, size_t); + + + +#endif /* _ANALYSIS_TYPES_PROTO_H */ diff --git a/src/analysis/types/template.c b/src/analysis/types/template.c index 5e6e95f..5555985 100644 --- a/src/analysis/types/template.c +++ b/src/analysis/types/template.c @@ -24,11 +24,11 @@ #include "template.h" +#include <assert.h> #include <malloc.h> #include <string.h> -#include "cse-int.h" #include "../type-int.h" #include "../../common/extstr.h" @@ -37,17 +37,19 @@ /* Description de type reposant sur des gabarits (instance) */ struct _GTemplateType { - GClassEnumType parent; /* A laisser en premier */ + GDataType parent; /* A laisser en premier */ - GDataType **models; /* Sous-types associés */ - size_t models_count; /* Quantité de ces modèles */ + char *name; /* Désignation de la base */ + + GDataType **params; /* Sous-types associés */ + size_t count; /* Quantité de ces paramètres */ }; /* Description de type reposant sur des gabarits (classe) */ struct _GTemplateTypeClass { - GClassEnumTypeClass parent; /* A laisser en premier */ + GDataTypeClass parent; /* A laisser en premier */ }; @@ -58,19 +60,22 @@ static void g_template_type_class_init(GTemplateTypeClass *); /* Initialise l'instance d'un type reposant sur des gabarits. */ static void g_template_type_init(GTemplateType *); +/* Supprime toutes les références externes. */ +static void g_template_type_dispose(GTemplateType *); + +/* Procède à la libération totale de la mémoire. */ +static void g_template_type_finalize(GTemplateType *); + /* Crée un copie d'un type existant. */ static GDataType *g_template_type_dup(const GTemplateType *); /* Décrit le type fourni sous forme de caractères. */ -static char *g_template_type_to_string(const GTemplateType *); - -/* Procède à l'impression de la description d'un type. */ -//static void g_template_type_output(const GTemplateType *, GLangOutput *, GBufferLine *, bool, bool); +static char *g_template_type_to_string(const GTemplateType *, bool); /* Indique le type défini pour un type reposant sur des gabarits. */ -G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE); +G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_DATA_TYPE); /****************************************************************************** @@ -87,6 +92,18 @@ G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE); static void g_template_type_class_init(GTemplateTypeClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GDataTypeClass *type; /* Version parente et basique */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_template_type_dispose; + object->finalize = (GObjectFinalizeFunc)g_template_type_finalize; + + type = G_DATA_TYPE_CLASS(klass); + + type->dup = (type_dup_fc)g_template_type_dup; + type->to_string = (type_to_string_fc)g_template_type_to_string; } @@ -105,26 +122,66 @@ static void g_template_type_class_init(GTemplateTypeClass *klass) static void g_template_type_init(GTemplateType *type) { - GDataType *data_type; /* Version basique */ - GClassEnumType *ce_type; /* Version basique #2 */ + type->name = NULL; + + type->params = NULL; + type->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_template_type_dispose(GTemplateType *type) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < type->count; i++) + g_object_unref(G_OBJECT(type->params[i])); - data_type = G_DATA_TYPE(type); + G_OBJECT_CLASS(g_template_type_parent_class)->dispose(G_OBJECT(type)); - data_type->dup = (type_dup_fc)g_template_type_dup; - data_type->to_string = (type_to_string_fc)g_template_type_to_string; - //data_type->output = (output_type_fc)g_template_type_output; +} + + +/****************************************************************************** +* * +* Paramètres : type = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_template_type_finalize(GTemplateType *type) +{ + if (type->name != NULL) + free(type->name); - ce_type = G_CLASS_ENUM_TYPE(type); + if (type->params != NULL) + free(type->params); - ce_type->type = CET_CLASS; + G_OBJECT_CLASS(g_template_type_parent_class)->finalize(G_OBJECT(type)); } /****************************************************************************** * * -* Paramètres : name = désignation humaine du type. * -* list = élements du modèle sur lequel doit reposer le type. * +* Paramètres : - * * * * Description : Crée une représentation de type reposant sur des gabarits. * * * @@ -134,16 +191,12 @@ static void g_template_type_init(GTemplateType *type) * * ******************************************************************************/ -GDataType *g_template_type_new(const char *name, GSList *list) +GDataType *g_template_type_new(void) { GTemplateType *result; /* Structure à retourner */ result = g_object_new(G_TYPE_TEMPLATE_TYPE, NULL); - G_CLASS_ENUM_TYPE(result)->name = strdup(name); - - g_template_type_add_params(result, list); - return G_DATA_TYPE(result); } @@ -151,138 +204,152 @@ GDataType *g_template_type_new(const char *name, GSList *list) /****************************************************************************** * * -* Paramètres : type = type à dupliquer. * +* Paramètres : type = type base sur des gabarits à modifier. * * * -* Description : Crée un copie d'un type existant. * +* Description : Indique la désignation principale du type. * * * -* Retour : Nouvelle instance de type identique à celle fournie. * +* Retour : Désignation humaine du type. * * * * Remarques : - * * * ******************************************************************************/ -static GDataType *g_template_type_dup(const GTemplateType *type) +const char *g_template_type_get_name(GTemplateType *type) { - GDataType *result; /* Copie à retourner */ - GSList *list; /* Format de liste à fournir */ - size_t i; /* Boucle de parcours */ + char *result; /* Désignation à retourner */ - list = NULL; + result = type->name; - for (i = 0; i < type->models_count; i++) - list = g_slist_prepend(list, type->models[i]); + return result; - result = g_template_type_new(G_CLASS_ENUM_TYPE(type)->name, list); +} - return G_DATA_TYPE(result); + +/****************************************************************************** +* * +* Paramètres : type = type base sur des gabarits à modifier. * +* name = désignation humaine du type. * +* * +* Description : Précise la désignation principale du type. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_template_type_set_name(GTemplateType *type, char *name) +{ + if (type->name != NULL) + free(type->name); + + type->name = name; } /****************************************************************************** * * -* Paramètres : type = type à convertir. * +* Paramètres : type = type à dupliquer. * * * -* Description : Décrit le type fourni sous forme de caractères. * +* Description : Crée un copie d'un type existant. * * * -* Retour : Chaîne à libérer de la mémoire après usage. * +* Retour : Nouvelle instance de type identique à celle fournie. * * * * Remarques : - * * * ******************************************************************************/ -static char *g_template_type_to_string(const GTemplateType *type) +static GDataType *g_template_type_dup(const GTemplateType *type) { - char *result; /* Valeur à renvoyer */ + GTemplateType *result; /* Copie à retourner */ size_t i; /* Boucle de parcours */ - char *sub; /* Sous-type à décrire */ + GDataType *param; /* Paramètre copié */ - result = g_class_enum_type_to_string(G_CLASS_ENUM_TYPE(type)); + result = G_TEMPLATE_TYPE(g_template_type_new()); - result = stradd(result, "<"); + if (type->name != NULL) + g_template_type_set_name(result, strdup(type->name)); - for (i = 0; i < type->models_count; i++) + for (i = 0; i < type->count; i++) { - if (i > 0) result = stradd(result, ", "); - - sub = g_data_type_to_string(type->models[i]); - result = stradd(result, sub); - free(sub); - + param = g_data_type_dup(type->params[i]); + g_template_type_add_param(result, param); } - result = stradd(result, ">"); - - return result; + return G_DATA_TYPE(result); } /****************************************************************************** * * -* Paramètres : type = type à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * +* Paramètres : type = type à convertir. * +* include = doit-on inclure les espaces de noms ? * * * -* Description : Procède à l'impression de la description d'un type. * +* Description : Décrit le type fourni sous forme de caractères. * * * -* Retour : - * +* Retour : Chaîne à libérer de la mémoire après usage. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -static void g_template_type_output(const GTemplateType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) + +static char *g_template_type_to_string(const GTemplateType *type, bool include) { + char *result; /* Valeur à renvoyer */ size_t i; /* Boucle de parcours */ + char *param; /* Paramètre à décrire */ - g_class_enum_type_output(G_CLASS_ENUM_TYPE(type), lang, line, info, full); + if (type->name != NULL) + result = strdup(type->name); + else + result = NULL; - g_buffer_line_append_text(line, BLC_LAST_USED, "<", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); + result = stradd(result, "<"); - for (i = 0; i < type->models_count; i++) + for (i = 0; i < type->count; i++) { - if (i > 0) - g_buffer_line_append_text(line, BLC_LAST_USED, ", ", 2, info ? RTT_COMMENT : RTT_SIGNS, NULL); + if (i > 0) result = stradd(result, ", "); - g_data_type_output(type->models[i], lang, line, info, full); + param = g_data_type_to_string(type->params[i], include); + if (param == NULL) goto error; + + result = stradd(result, param); + free(param); } - g_buffer_line_append_text(line, BLC_LAST_USED, ">", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); + result = stradd(result, ">"); + + return result; + + error: + + free(result); + + return NULL; } -#endif /****************************************************************************** * * -* Paramètres : type = type à mettre à jour. * -* list = élements du modèle sur lequel doit reposer le type. * +* Paramètres : type = type à mettre à jour. * +* param = nouveau paramètre à intégrer au gabarit. * * * -* Description : Ajoute une série de paramètres à un gabarit. * +* Description : Ajoute un paramètre à un gabarit. * * * * Retour : - * * * -* Remarques : La liste doit contenir des éléments dans l'ordre inverse * -* d'apparition. De plus, elle est libérée dans cette fonction. * +* Remarques : - * * * ******************************************************************************/ -void g_template_type_add_params(GTemplateType *type, GSList *list) +void g_template_type_add_param(GTemplateType *type, GDataType *param) { - GSList *iter; /* Boucle de parcours */ - - list = g_slist_reverse(list); - for (iter = list; iter != NULL; iter = g_slist_next(iter)) - { - type->models = (GDataType **)realloc(type->models, - ++type->models_count * sizeof(GDataType *)); - type->models[type->models_count - 1] = G_DATA_TYPE(iter->data); - } - g_slist_free(list); + type->params = (GDataType **)realloc(type->params, ++type->count * sizeof(GDataType *)); + type->params[type->count - 1] = param; } @@ -291,7 +358,7 @@ void g_template_type_add_params(GTemplateType *type, GSList *list) * * * Paramètres : type = type à consulter. * * * -* Description : Indique le nombre de paramètres associés du gabarit. * +* Description : Indique le nombre de paramètres associés au gabarit. * * * * Retour : Nombre de paramètres inclus dans le gabarit. * * * @@ -299,9 +366,9 @@ void g_template_type_add_params(GTemplateType *type, GSList *list) * * ******************************************************************************/ -size_t g_template_type_count_param(const GTemplateType *type) +size_t g_template_type_count_params(const GTemplateType *type) { - return type->models_count; + return type->count; } @@ -321,6 +388,19 @@ size_t g_template_type_count_param(const GTemplateType *type) GDataType *g_template_type_get_param(const GTemplateType *type, size_t index) { - return (index < type->models_count ? type->models[index] : NULL); + GDataType *result; /* Paramètre à retourner */ + + assert(index < type->count); + + if (index < type->count) + { + result = type->params[index]; + g_object_ref(G_OBJECT(result)); + } + + else + result = NULL; + + return result; } diff --git a/src/analysis/types/template.h b/src/analysis/types/template.h index 567822e..fd9ad81 100644 --- a/src/analysis/types/template.h +++ b/src/analysis/types/template.h @@ -32,12 +32,12 @@ -#define G_TYPE_TEMPLATE_TYPE g_template_type_get_type() -#define G_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_template_type_get_type(), GTemplateType)) -#define G_IS_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_template_type_get_type())) -#define G_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) -#define G_IS_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TEMPLATE_TYPE)) -#define G_TEMPLATE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) +#define G_TYPE_TEMPLATE_TYPE g_template_type_get_type() +#define G_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TEMPLATE_TYPE, GTemplateType)) +#define G_IS_TEMPLATE_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TEMPLATE_TYPE)) +#define G_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) +#define G_IS_TEMPLATE_TYPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TEMPLATE_TYPE)) +#define G_TEMPLATE_TYPE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TEMPLATE_TYPE, GTemplateTypeClass)) /* Description de type reposant sur des gabarits (instance) */ @@ -51,13 +51,19 @@ typedef struct _GTemplateTypeClass GTemplateTypeClass; GType g_template_type_get_type(void); /* Crée une représentation de type reposant sur des gabarits. */ -GDataType *g_template_type_new(const char *, GSList *); +GDataType *g_template_type_new(void); -/* Ajoute une série de paramètres à un gabarit. */ -void g_template_type_add_params(GTemplateType *, GSList *); +/* Indique la désignation principale du type. */ +const char *g_template_type_get_name(GTemplateType *); -/* Indique le nombre de paramètres associés du gabarit. */ -size_t g_template_type_count_param(const GTemplateType *); +/* Précise la désignation principale du type. */ +void g_template_type_set_name(GTemplateType *, char *); + +/* Ajoute un paramètre à un gabarit. */ +void g_template_type_add_param(GTemplateType *, GDataType *); + +/* Indique le nombre de paramètres associés au gabarit. */ +size_t g_template_type_count_params(const GTemplateType *); /* Fournit un paramètre donné du gabarit. */ GDataType *g_template_type_get_param(const GTemplateType *, size_t); diff --git a/src/analysis/variable.c b/src/analysis/variable.c index b983b73..9fb2e81 100644 --- a/src/analysis/variable.c +++ b/src/analysis/variable.c @@ -25,6 +25,7 @@ #include <malloc.h> +#include <stdint.h> #include <string.h> @@ -273,8 +274,8 @@ void g_binary_variable_set_owner(GBinVariable *var, GDataType *owner) /****************************************************************************** * * -* Paramètres : var = variable à convertir. * -* simple = indique si l'espace de noms doit être exclus ou non.* +* Paramètres : var = variable à convertir. * +* include = doit-on inclure les espaces de noms ? * * * * Description : Décrit la variable donnée sous forme de caractères. * * * @@ -284,18 +285,15 @@ void g_binary_variable_set_owner(GBinVariable *var, GDataType *owner) * * ******************************************************************************/ -char *g_binary_variable_to_string(const GBinVariable *var, bool simple) +char *g_binary_variable_to_string(const GBinVariable *var, bool include) { char *result; /* Valeur à retourner */ - /* FIXME : décompilation sans type ! */ - result = _g_data_type_to_string(var->type, simple); - - //result = strdup(""); + result = g_data_type_to_string(var->type, include); if (var->name != NULL) { - if (!g_data_type_is_pointer(var->type, true) /* FIXME */ && strlen(result) > 0 /* FIXME */) + if (!(g_data_type_is_pointer(var->type) || g_data_type_is_reference(var->type))) result = stradd(result, " "); result = stradd(result, var->name); @@ -307,39 +305,6 @@ char *g_binary_variable_to_string(const GBinVariable *var, bool simple) } -/****************************************************************************** -* * -* Paramètres : var = variable à afficher. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* info = nature du cadre de destination. * -* full = besoin de descriptions étendues ? * -* * -* Description : Procède à l'impression de la description d'une variable. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -void g_binary_variable_output(const GBinVariable *var, GLangOutput *lang, GBufferLine *line, bool info, bool full) -{ - g_data_type_output(var->type, lang, line, info, full); - - if (var->name != NULL) - { - if (!g_data_type_is_pointer(var->type, true)) - g_buffer_line_append_text(line, BLC_LAST_USED, " ", 1, RTT_COMMENT, NULL); - - g_buffer_line_append_text(line, BLC_LAST_USED, var->name, strlen(var->name), RTT_COMMENT, NULL); - - } - -} -#endif - - /* ---------------------------------------------------------------------------------- */ /* BASE DE VARIABLES OU VARIABLES INCONNUES */ diff --git a/src/analysis/variable.h b/src/analysis/variable.h index 94ac432..b173f6d 100644 --- a/src/analysis/variable.h +++ b/src/analysis/variable.h @@ -76,9 +76,6 @@ void g_binary_variable_set_owner(GBinVariable *, GDataType *); /* Décrit la variable donnée sous forme de caractères. */ char *g_binary_variable_to_string(const GBinVariable *, bool); -/* Procède à l'impression de la description d'une variable. */ -//void g_binary_variable_output(const GBinVariable *, GLangOutput *, GBufferLine *, bool, bool); - /* -------------------- BASE DE VARIABLES OU VARIABLES INCONNUES -------------------- */ diff --git a/src/mangling/java_gram.y b/src/mangling/java_gram.y index cb60d82..9f167c2 100644 --- a/src/mangling/java_gram.y +++ b/src/mangling/java_gram.y @@ -128,13 +128,11 @@ full_class_name: TEXT { $$ = g_class_enum_type_new(CET_CLASS, $1); } | full_class_name SLASH TEXT { $$ = g_class_enum_type_new(CET_CLASS, $3); - g_data_type_set_namespace($$, $1); - g_object_unref($1); + g_data_type_set_namespace($$, $1, "."); } | full_class_name DOLLAR TEXT { $$ = g_class_enum_type_new(CET_CLASS, $3); - g_data_type_set_namespace($$, $1); - g_object_unref($1); + g_data_type_set_namespace($$, $1, "."); } ; |