/* OpenIDA - Outil d'analyse de fichiers binaires * prototype.c - manipulation des prototypes de fonctions et de variables * * Copyright (C) 2008 Cyrille Bagard * * This file is part of OpenIDA. * * OpenIDA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * OpenIDA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "prototype.h" #include #include #include "../common/extstr.h" /* Représentation générique de routine (instance) */ struct _GBinRoutine { GObject parent; /* A laisser en premier */ vmpa_t addr; /* Position physique/mémoire */ off_t size; /* Taille du code associé */ RoutineType type; /* Type de routine */ variable *ret_type; /* Type retourné */ char *name; /* Désignation humaine */ variable **args_types; /* Types d'arguments */ size_t args_count; /* Nombre d'arguments */ }; /* Représentation générique de routine (classe) */ struct _GBinRoutineClass { GObjectClass parent; /* A laisser en premier */ }; /* Initialise la classe des représentation de routine. */ static void g_bin_routine_class_init(GBinRoutineClass *); /* Initialise une instance représentation de routine. */ static void g_bin_routine_init(GBinRoutine *); /* Indique le type définit pour une représentation de routine. */ G_DEFINE_TYPE(GBinRoutine, g_bin_routine, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des représentation de routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_bin_routine_class_init(GBinRoutineClass *klass) { } /****************************************************************************** * * * Paramètres : line = instance à initialiser. * * * * Description : Initialise une instance représentation de routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_bin_routine_init(GBinRoutine *line) { } /****************************************************************************** * * * Paramètres : - * * * * Description : Crée une représentation de routine. * * * * Retour : Adresse de la structure mise en place. * * * * Remarques : - * * * ******************************************************************************/ GBinRoutine *g_binary_routine_new(void) { GBinRoutine *result; /* Structure à retourner */ result = g_object_new(G_TYPE_BIN_ROUTINE, NULL); return result; } /****************************************************************************** * * * Paramètres : routine = routine à effacer. * * * * Description : Supprime une représentation de routine de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ #if 0 /* FIXME */ void g_binary_routine_finalize(GBinRoutine *routine) { size_t i; /* Boucle de parcours */ if (routine->ret_type) delete_var(routine->ret_type); if (routine->name != NULL) free(routine->name); for (i = 0; i < routine->args_count; i++) delete_var(routine->args_types[i]); free(routine); } #endif /****************************************************************************** * * * Paramètres : a = premières informations à consulter. * * b = secondes informations à consulter. * * * * Description : Etablit la comparaison ascendante entre deux routines. * * * * Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * * * * Remarques : - * * * ******************************************************************************/ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) { int result; /* Bilan à renvoyer */ if ((*a)->addr < (*b)->addr) result = -1; else if((*a)->addr > (*b)->addr) result = 1; else result = 0; return result; } /****************************************************************************** * * * Paramètres : a = premières informations à consulter. * * b = secondes informations à consulter. * * * * Description : Etablit la comparaison descendante entre deux routines. * * * * Retour : Bilan : -1 (a < b), 0 (a == b) ou 1 (a > b). * * * * Remarques : - * * * ******************************************************************************/ int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) { int result; /* Bilan à renvoyer */ if ((*a)->addr > (*b)->addr) result = -1; else if((*a)->addr < (*b)->addr) result = 1; else result = 0; return result; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * addr = position mémoire ou physique déclarée. * * * * Description : Définit la position physique / en mémoire d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_binary_routine_set_address(GBinRoutine *routine, vmpa_t addr) { routine->addr = addr; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * * * Description : Fournit la position physique / en mémoire d'une routine. * * * * Retour : Position mémoire ou physique déclarée. * * * * Remarques : - * * * ******************************************************************************/ vmpa_t g_binary_routine_get_address(const GBinRoutine *routine) { return routine->addr; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * addr = taille du code associé. * * * * Description : Définit la taille du code d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_binary_routine_set_size(GBinRoutine *routine, off_t size) { routine->size = size; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * * * Description : Fournit la taille du code associé à une routine. * * * * Retour : Taille du code associée. * * * * Remarques : - * * * ******************************************************************************/ off_t g_binary_routine_get_size(const GBinRoutine *routine) { return routine->size; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * type = type de routine spécifié. * * * * Description : Définit le type d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) { routine->type = type; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * name = désignation humainement lisible. * * * * Description : Définit le nom humain d'une routine. * * * * Retour : - * * * * Remarques : Le nom ne doit pas ensuite être libéré par l'appelant ! * * * ******************************************************************************/ void g_binary_routine_set_name(GBinRoutine *routine, char *name) { if (routine->name != NULL) free(routine->name); routine->name = name; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * * * Description : Fournit le nom humain d'une routine. * * * * Retour : Désignation humainement lisible ou NULL si non définie. * * * * Remarques : - * * * ******************************************************************************/ const char *g_binary_routine_get_name(const GBinRoutine *routine) { return routine->name; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * var = variable représentant un type de retour. * * * * Description : Définit le type de retour d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_binary_routine_set_return_type(GBinRoutine *routine, variable *var) { if (routine->ret_type != NULL) delete_var(routine->ret_type); routine->ret_type = var; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * var = variable représentant un argument supplémentaire. * * * * Description : Ajoute un argument à une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_binary_routine_add_arg(GBinRoutine *routine, variable *var) { routine->args_count++; routine->args_types = (variable **)realloc(routine->args_types, routine->args_count * sizeof(variable *)); routine->args_types[routine->args_count - 1] = var; } /****************************************************************************** * * * Paramètres : routine = routine à consulter. * * * * Description : Décrit le prototype de la routine sous forme de caractères. * * * * Retour : Chaîne de caractères à libérer de la mémoire. * * * * Remarques : - * * * ******************************************************************************/ char *g_binary_routine_to_string(const GBinRoutine *routine) { char *result; /* Chaîne à renvoyer */ size_t i; /* Boucle de parcours */ char *typestr; /* Stockage de nom temporaire */ /* Retour de la fonction */ switch (routine->type) { case RTT_CONSTRUCTOR: result = strdup(routine->name); result = stradd(result, "::"); break; case RTT_DESTRUCTOR: result = strdup(routine->name); result = stradd(result, "::~"); break; default: /* Pour gcc */ case RTT_CLASSIC: if (routine->ret_type == NULL) result = strdup("??? "); else { result = var_to_string(routine->ret_type); result = stradd(result, " "); } break; } /* Nom de la routine */ result = stradd(result, routine->name); /* Liste des arguments */ result = stradd(result, "("); for (i = 0; i < routine->args_count; i++) { if (i > 0) result = stradd(result, ", "); typestr = var_to_string(routine->args_types[i]); result = stradd(result, typestr); free(typestr); } result = stradd(result, ")"); return result; }