diff options
Diffstat (limited to 'tools/d2c/conv/manager.c')
-rw-r--r-- | tools/d2c/conv/manager.c | 518 |
1 files changed, 518 insertions, 0 deletions
diff --git a/tools/d2c/conv/manager.c b/tools/d2c/conv/manager.c new file mode 100644 index 0000000..c04a49e --- /dev/null +++ b/tools/d2c/conv/manager.c @@ -0,0 +1,518 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * manager.c - substitutions de valeurs depuis un contenu binaire + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "manager.h" + + +#include <assert.h> +#include <ctype.h> +#include <malloc.h> +#include <stdbool.h> +#include <string.h> + + +#include "../helpers.h" +#include "../qckcall.h" + + + +/* ---------------------------- CONVERSION DES ARGUMENTS ---------------------------- */ + + +/* Fonction de conversion */ +struct _conv_func +{ + bool declared; /* Expression déjà déclarée ? */ + bool defined; /* Expression déjà définie ? */ + + char *dest; /* Variable de destination */ + + bool is_expr; /* Choix du contenu réel */ + + union + { + arg_expr_t *expr; /* Valeur expressive directe */ + + struct + { + char *name; /* Fonction de conversion */ + arg_list_t *args; /* Liste des arguments */ + + }; + + }; + +}; + + + +/* ---------------------------- ENSEMBLES DE CONVERSIONS ---------------------------- */ + + +/* Liste des fonctions de conversions présentes */ +struct _conv_list +{ + conv_func **functions; /* Fonctions de conversion */ + size_t func_count; /* Nombre de ces fonctions */ + +}; + + + +/* ---------------------------------------------------------------------------------- */ +/* CONVERSION DES ARGUMENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : dest = désignation de la variable de destination. * +* expr = expression dont la valeur est à assigner. * +* * +* Description : Définit une conversion à partir d'une simple expression. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *make_conv_from_expr(char *dest, arg_expr_t *expr) +{ + conv_func *result; /* Conversion à retourner */ + + result = (conv_func *)calloc(1, sizeof(conv_func)); + + result->dest = make_string_lower(dest); + + result->is_expr = true; + result->expr = expr; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = désignation de la variable de destination. * +* func = nom de la fonction assurant le calcul de valeur. * +* args = argument(s) à fournir à cette fonction. * +* * +* Description : Définit une conversion à partir d'une function à appeler. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *make_conv_from_func(char *dest, char *func, arg_list_t *args) +{ + conv_func *result; /* Conversion à retourner */ + + result = (conv_func *)calloc(1, sizeof(conv_func)); + + result->dest = make_string_lower(dest); + + result->is_expr = false; + result->name = func; + result->args = args; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = éléments de conversion à supprimer de la mémoire. * +* * +* Description : Libère de la mémoire une conversion enregistrée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_conv_func(conv_func *func) +{ + if (func->is_expr) + delete_arg_expr(func->expr); + + else + { + free(func->name); + delete_arg_list(func->args); + } + + free(func); + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à consulter. * +* * +* Description : Indique la variable de destination d'une conversion. * +* * +* Retour : Désignation humaine de la variable de destination. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_conv_dest_name(const conv_func *func) +{ + return func->dest; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à consulter. * +* * +* Description : Indique la nature d'une conversion : fonction ou expression ?* +* * +* Retour : Indication sur la constitution interne de la conversion. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool is_conv_func_expression(const conv_func *func) +{ + return func->is_expr; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à consulter. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* size = taille déterminée avec précision. [OUT] * +* * +* Description : Détermine la taille en bits du résultat d'une fonction. * +* * +* Retour : true si la taille a pu être déterminée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, const conv_list *list, unsigned int *size) +{ + bool result; /* Bilan à retourner */ + + result = func->is_expr; + + if (result) + result = compute_arg_expr_size(func->expr, bits, list, size); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Marque les champs utilisés par une fonction de conversion. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à remonter */ + + if (func->is_expr) + result = ensure_arg_expr_content_fully_marked(func->expr, bits, list); + else + result = ensure_arg_list_content_fully_marked(func->args, bits, list); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* fd = descripteur d'un flux ouvert en écriture. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* wide = taille des mots décodés. * +* * +* Description : Déclare les variables associées à une fonction de conversion.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide) +{ + bool result; /* Bilan à remonter */ + + /* Si la fonction a déjà été définie lors d'un précédent besoin... */ + if (func->declared) return true; + + if (func->is_expr) + result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, wide); + + else + result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide); + + func->declared = result; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : func = fonction de conversion à manipuler. * +* last = précise si la conversion est la dernière. * +* internal = indique le type de manipulation finale. * +* fd = descripteur d'un flux ouvert en écriture. * +* arch = architecture visée par l'opération globale. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* pp = pré-processeur pour les échanges de chaînes. * +* * +* Description : Définit les variables associées à une fonction de conversion.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp) +{ + bool result; /* Bilan à remonter */ + const char *callable; /* Fonction à appeler */ + + /* Si la fonction a déjà été définie lors d'un précédent besoin... */ + if (func->defined) return true; + + if (func->is_expr) + result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp); + else + result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp); + + /* Nom de la fonction effectivement appelée */ + + if (!func->is_expr) + { + callable = find_macro(pp, func->name); + + if (callable == NULL) + callable = func->name; + + } + else callable = NULL; + + if (last && callable == NULL) + { + fprintf(stderr, "Error: expected function to store '%s'.\n", func->dest); + return false; + } + + /* Dernier niveau : la variable de destination est imposée ! */ + if (last) + { + /* Si l'on doit manipuler une propriété d'instructon... */ + if (internal) + result = checked_call_instr_func(callable, func->args, fd, bits, list, pp); + + /* Si on doit constituer un opérande à ajouter... */ + else + { + if (strchr(callable, '(') == NULL) + dprintf(fd, "\t\top = %s(", callable); + else + dprintf(fd, "\t\top = %s", callable); + + result &= define_arg_list(func->args, fd, bits, list); + + dprintf(fd, ");\n"); + + } + + } + + /* On constitue une variable intermédiaire, dont on peut conserver le nom ! */ + else + { + dprintf(fd, "\t\tval_%s = ", func->dest); + + if (func->is_expr) + result &= define_arg_expr(func->expr, fd, bits, list); + + else + { + dprintf(fd, "%s(", callable); + + result = define_arg_list(func->args, fd, bits, list); + + dprintf(fd, ")"); + + } + + dprintf(fd, ";\n"); + + } + + func->defined = result; + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ENSEMBLES DE CONVERSIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouvelle liste vierge de fonctions de conversion. * +* * +* Retour : Nouvelle structure prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_list *create_conv_list(void) +{ + conv_list *result; /* Définition vierge à renvoyer*/ + + result = (conv_list *)calloc(1, sizeof(conv_list)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : list = ensemble de fonctions de conversion à supprimer. * +* * +* Description : Supprime de la mémoire une de fonctions de conversion. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_conv_list(conv_list *list) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < list->func_count; i++) + delete_conv_func(list->functions[i]); + + if (list->functions != NULL) + free(list->functions); + + free(list); + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de fonctions de conversion à compléter. * +* func = nom de la fonction assurant le calcul de valeur. * +* * +* Description : Enregistre une function de conversion du brut à l'utile. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void register_conversion(conv_list *list, conv_func *func) +{ + list->functions = (conv_func **)realloc(list->functions, ++list->func_count * sizeof(conv_func *)); + + list->functions[list->func_count - 1] = func; + +} + + +/****************************************************************************** +* * +* Paramètres : list = liste de fonctions de conversion à consulter. * +* name = désignation humaine du champ à retrouver. * +* * +* Description : Recherche un résultat précis dans une liste de fonctions. * +* * +* Retour : Structure associée au résulat trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +conv_func *find_named_conv_in_list(const conv_list *list, const char *name) +{ + conv_func *result; /* Fonction à retourner */ + size_t i; /* Boucle de parcours */ + const char *dest; /* Nom de variable existante */ + + result = NULL; + + for (i = 0; i < list->func_count && result == NULL; i++) + { + dest = get_conv_dest_name(list->functions[i]); + + if (strcmp(dest, name) == 0) + result = list->functions[i]; + + } + + return result; + +} |