/* Chrysalide - Outil d'analyse de fichiers binaires * raccess.c - suivi des accès aux registres * * Copyright (C) 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 "raccess.h" #include #include #include /* Description d'une liste d'accès à des registres (instance) */ struct _GRAccessList { GObject parent; /* A laisser en premier */ reg_access *accesses; /* Liste des accès */ size_t count; /* Taille de cette liste */ }; /* Description d'une liste d'accès à des registres (classe) */ struct _GRAccessListClass { GObjectClass parent; /* A laisser en premier */ }; /* Initialise la classe des listes d'accès aux registres. */ static void g_raccess_list_class_init(GRAccessListClass *); /* Initialise une liste d'accès aux registres. */ static void g_raccess_list_init(GRAccessList *); /* Supprime toutes les références externes. */ static void g_raccess_list_dispose(GRAccessList *); /* Procède à la libération totale de la mémoire. */ static void g_raccess_list_finalize(GRAccessList *); /* Indique le type défini pour une liste d'accès à des registres. */ G_DEFINE_TYPE(GRAccessList, g_raccess_list, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : class = classe à initialiser. * * * * Description : Initialise la classe des listes d'accès aux registres. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_raccess_list_class_init(GRAccessListClass *class) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(class); object->dispose = (GObjectFinalizeFunc/* ! */)g_raccess_list_dispose; object->finalize = (GObjectFinalizeFunc)g_raccess_list_finalize; } /****************************************************************************** * * * Paramètres : list = instance à initialiser. * * * * Description : Initialise une liste d'accès aux registres. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_raccess_list_init(GRAccessList *list) { } /****************************************************************************** * * * Paramètres : block = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_raccess_list_dispose(GRAccessList *list) { size_t i; /* Boucle de parcours */ for (i = 0; i < list->count; i++) g_object_unref(G_OBJECT(list->accesses[i].reg)); if (list->accesses != NULL) free(list->accesses); G_OBJECT_CLASS(g_raccess_list_parent_class)->dispose(G_OBJECT(list)); } /****************************************************************************** * * * Paramètres : block = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_raccess_list_finalize(GRAccessList *list) { G_OBJECT_CLASS(g_raccess_list_parent_class)->finalize(G_OBJECT(list)); } /****************************************************************************** * * * Paramètres : - * * * * Description : Crée une liste d'accès à des registres. * * * * Retour : Adresse de la structure mise en place. * * * * Remarques : - * * * ******************************************************************************/ GRAccessList *g_raccess_list_new(void) { GRAccessList *result; /* Liste à retourner */ result = g_object_new(G_TYPE_RACCESS_LIST, NULL); return result; } /****************************************************************************** * * * Paramètres : list = liste des accès à venir grossir. * * src = liste dont les accès sont à reprendre. * * * * Description : Intègre une liste d'accès à des registres dans une autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_raccess_list_merge(GRAccessList *list, const GRAccessList *src) { size_t count; /* Taille d'un parcours */ size_t i; /* Boucle de parcours */ reg_access *access; /* Accès à un registre */ count = g_raccess_list_count(src); for (i = 0; i < count; i++) { access = g_raccess_list_get(src, i); if (g_raccess_list_find(list, access->reg) == NULL) g_raccess_list_add(list, access); } } /****************************************************************************** * * * Paramètres : a = premier opérande à consulter. * * b = second opérande à consulter. * * * * Description : Compare un accès registre avec un autre. * * * * Retour : Bilan de la comparaison. * * * * Remarques : - * * * ******************************************************************************/ int compare_reg_accesses(const reg_access *a, const reg_access *b) { return g_arch_register_compare(a->reg, b->reg); } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à consulter. * * reg = registre matériel à rechercher. * * * * Description : Recherche des informations existantes sur un registre. * * * * Retour : Bilan de la recherche. * * * * Remarques : - * * * ******************************************************************************/ reg_access *g_raccess_list_find(const GRAccessList *list, GArchRegister *reg) { reg_access *result; /* Trouaille à retourner */ result = bsearch((reg_access []) { { .reg = reg } }, list->accesses, list->count, sizeof(reg_access), (__compar_fn_t)compare_reg_accesses); return result; } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à mettre à jour. * * template = patron de l'accès à intégrer. * * * * Description : Recherche des informations existantes sur un registre. * * * * Retour : Bilan de la recherche. * * * * Remarques : - * * * ******************************************************************************/ void g_raccess_list_add(GRAccessList *list, const reg_access *template) { g_object_ref(G_OBJECT(template->reg)); list->accesses = (reg_access *)realloc(list->accesses, ++list->count * sizeof(reg_access)); list->accesses[list->count - 1] = *template; qsort(list->accesses, list->count, sizeof(reg_access), (__compar_fn_t)compare_reg_accesses); } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à consulter. * * * * Description : Dénombre les accès aux registres comptabilisés. * * * * Retour : Quantité d'accès pris en compte. * * * * Remarques : - * * * ******************************************************************************/ size_t g_raccess_list_count(const GRAccessList *list) { return list->count; } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à consulter. * * index = indice de l'accès recherché. * * * * Description : Fournit un accès donné de la liste. * * * * Retour : Accès à un registre. * * * * Remarques : - * * * ******************************************************************************/ reg_access *g_raccess_list_get(const GRAccessList *list, size_t index) { reg_access *result; /* Accès à renvoyer */ if (index >= list->count) result = NULL; else result = &list->accesses[index]; return result; } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à mettre à jour. * * access = accès visé par la procédure. * * * * Description : Retire un accès donné de la liste. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_raccess_list_delete(GRAccessList *list, reg_access *access) { size_t index; /* Indice correspondant */ if (list->count > 0) { index = (access - list->accesses) / sizeof(reg_access); g_raccess_list_delete_by_index(list, index); } } /****************************************************************************** * * * Paramètres : list = ensemble d'accès à mettre à jour. * * index = indice de l'accès visé par la procédure. * * * * Description : Retire un accès donné de la liste. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_raccess_list_delete_by_index(GRAccessList *list, size_t index) { if (index >= list->count) return; if ((index + 1) < list->count) memmove(&list->accesses[index], &list->accesses[index + 1], (list->count - index - 1) * sizeof(reg_access)); list->count--; if (list->count == 0) { free(list->accesses); list->accesses = NULL; } else list->accesses = (reg_access *)realloc(list->accesses, list->count * sizeof(reg_access)); }