/* Chrysalide - Outil d'analyse de fichiers binaires * limit.c - détermination des bornes des routines * * Copyright (C) 2012-2013 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 Foobar. If not, see . */ #include "limit.h" /* Recherche la zone correspond à une adresse donnée. */ static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *); /****************************************************************************** * * * Paramètres : ranges = liste de zones offrant une exécution et disponibles.* * count = taille de cette liste. * * * * Description : Recherche la zone correspond à une adresse donnée. * * * * Retour : Zone trouvée ou NULL si aucune ne correspond. * * * * Remarques : - * * * ******************************************************************************/ static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t count, const vmpa2t *addr) { const mrange_t *result; /* Zone à retourner */ size_t i; /* Boucle de parcours */ result = NULL; for (i = 0; i < count && result == NULL; i++) if (mrange_contains_addr(&ranges[i], addr)) result = &ranges[i]; return result; } /****************************************************************************** * * * Paramètres : proc = ensemble d'instructions désassemblées. * * routines = prototypes existants à insérer. * * count = quantité de ces prototypes. * * begin = point de départ du parcours de liste. * * end = point d'arrivée exclu du parcours. * * id = identifiant du message affiché à l'utilisateur. * * * * Description : S'assure qu'une routine est bien bornée. * * * * Retour : Tâche créée. * * * * Remarques : - * * * ******************************************************************************/ void compute_routine_limit(GBinRoutine *routine, GBinRoutine *prev, GArchProcessor *proc, mrange_t *exe_ranges, size_t exe_count) { const mrange_t *range; /* Emplacement courant */ vmpa2t addr; /* Adresse à conserver */ GArchInstruction *start; /* Première instruction */ phys_t diff; /* Taille définie par déduction*/ mrange_t new; /* Nouvel emplacement taillé */ range = g_binary_routine_get_range(routine); if (get_mrange_length(range) > 0) goto crl_skip; copy_vmpa(&addr, get_mrange_addr(range)); /* Marquage de la première instruction */ start = g_arch_processor_find_instr_by_address(proc, &addr); /* FIXME ? */ if (start == NULL) goto crl_skip; g_arch_instruction_set_flag(start, AIF_ROUTINE_START); g_object_unref(G_OBJECT(start)); /* Si on peut se raccrocher à la routine suivante... */ if (prev != NULL) { range = g_binary_routine_get_range(prev); diff = compute_vmpa_diff(&addr, get_mrange_addr(range)); } /* Sinon on va jusqu'à la fin de la zone ! */ else { range = find_x_range_for_addr(exe_ranges, exe_count, &addr); if (range == NULL) goto crl_skip; diff = compute_vmpa_diff(&addr, get_mrange_addr(range)); diff = get_mrange_length(range) - diff; } init_mrange(&new, &addr, diff); g_binary_routine_set_range(routine, &new); crl_skip: ; }