/* 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" /* Variable représentant un prototype de routine */ struct _bin_routine { uint64_t offset; /* Position physique/mémoire */ 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 */ }; /****************************************************************************** * * * Paramètres : - * * * * Description : Crée une représentation de routine. * * * * Retour : Adresse de la structure mise en place. * * * * Remarques : - * * * ******************************************************************************/ bin_routine *create_binary_routine(void) { bin_routine *result; /* Structure à retourner */ result = (bin_routine *)calloc(1, sizeof(bin_routine)); return result; } /****************************************************************************** * * * Paramètres : routine = routine à effacer. * * * * Description : Supprime une représentation de routine de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void delete_binary_routine(bin_routine *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); } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * offset = position mémoire ou physique déclarée. * * * * Description : Définit la position physique / en mémoire d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void set_binary_routine_offset(bin_routine *routine, uint64_t offset) { routine->offset = offset; } /****************************************************************************** * * * 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 : - * * * ******************************************************************************/ uint64_t get_binary_routine_offset(const bin_routine *routine) { return routine->offset; } /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * * type = type de routine spécifié. * * * * Description : Définit le type d'une routine. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void set_binary_routine_type(bin_routine *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 set_binary_routine_name(bin_routine *routine, char *name) { if (routine->name != NULL) free(routine->name); routine->name = 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 set_binary_routine_return_type(bin_routine *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 add_arg_to_binary_routine(bin_routine *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 *routine_to_string(const bin_routine *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; }