/* Chrysalide - Outil d'analyse de fichiers binaires * processors.c - enregistrement et fourniture des architectures supportées * * Copyright (C) 2015 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 "processors.h" #include #include #include #include "../arch/arm/v7/core.h" #include "../arch/arm/v7/processor.h" #include "../arch/dalvik/core.h" #include "../arch/dalvik/processor.h" #include "../arch/jvm/processor.h" /* Caractéristiques d'un processeur */ typedef struct _proc_t { char *key; /* Clef pour un accès rapide */ char *name; /* Désignation humaine */ GType instance; /* Type à manipuler en interne */ init_arch_fc init; /* Phase d'intialisation */ exit_arch_fc exit; /* Phase de relâchement */ } proc_t; /* Mémorisation des types de processeurs enregistrés */ static proc_t *_processors_definitions = NULL; static size_t _processors_definitions_count = 0; /* Verrou pour des accès atomiques */ G_LOCK_DEFINE_STATIC(_pdef_access); /* Retrouve l'enregistrement correspondant à une architecture. */ static proc_t *find_processor_by_key(const char *); /****************************************************************************** * * * Paramètres : key = désignation rapide et interne d'un processeur. * * name = désignation humaine de l'architecture. * * instance = type GLib représentant le type à instancier. * * init = procédure d'initialisation de mécanismes internes.* * exit = procédure de suppression de mécanismes internes. * * * * Description : Enregistre un processeur pour une architecture donnée. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool register_processor_type(const char *key, const char *name, GType instance, init_arch_fc init, exit_arch_fc exit) { bool result; /* Bilan à retourner */ proc_t *new; /* Nouvel élément à définir */ G_LOCK(_pdef_access); new = find_processor_by_key(key); result = (new == NULL); result &= init(); if (result) { _processors_definitions = (proc_t *)realloc(_processors_definitions, ++_processors_definitions_count * sizeof(proc_t)); new = &_processors_definitions[_processors_definitions_count - 1]; new->key = strdup(key); new->name = strdup(name); new->instance = instance; new->init = init; new->exit = exit; } G_UNLOCK(_pdef_access); return result; } /****************************************************************************** * * * Paramètres : - * * * * Description : Charge les définitions de processeurs "natifs". * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool load_hard_coded_processors_definitions(void) { bool result; /* Bilan à retourner */ result = true; result &= register_processor_type("armv7", "ARM v7", G_TYPE_ARMV7_PROCESSOR, init_armv7_core, exit_armv7_core); result &= register_processor_type("dalvik", "Dalvik Virtual Machine", G_TYPE_DALVIK_PROCESSOR, init_dalvik_core, exit_dalvik_core); //result &= register_processor_type("jvm", "Java Virtual Machine", G_TYPE_JVM_PROCESSOR); return result; } /****************************************************************************** * * * Paramètres : - * * * * Description : Décharge toutes les définitions de processeurs. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void unload_processors_definitions(void) { size_t i; /* Boucle de parcours */ G_LOCK(_pdef_access); for (i = 0; i < _processors_definitions_count; i++) { free(_processors_definitions[i].key); free(_processors_definitions[i].name); } if (_processors_definitions != NULL) free(_processors_definitions); _processors_definitions = NULL; _processors_definitions_count = 0; G_UNLOCK(_pdef_access); } /****************************************************************************** * * * Paramètres : key = nom technique du processeur recherché. * * * * Description : Retrouve l'enregistrement correspondant à une architecture. * * * * Retour : Définition trouvée ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ static proc_t *find_processor_by_key(const char *key) { proc_t *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ /** * Le verrou d'accès global doit être posé ! */ result = NULL; if (key != NULL) for (i = 0; i < _processors_definitions_count; i++) if (strcmp(_processors_definitions[i].key, key) == 0) result = &_processors_definitions[i]; return result; } /****************************************************************************** * * * Paramètres : key = nom technique du processeur recherché. * * * * Description : Fournit le nom humain de l'architecture visée. * * * * Retour : Désignation humaine trouvée ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char *get_arch_processor_name(const char *key) { const char *result; /* Description à retourner */ proc_t *def; /* Définition d'architecture */ G_LOCK(_pdef_access); def = find_processor_by_key(key); if (def == NULL) result = NULL; else result = def->name; G_UNLOCK(_pdef_access); return result; } /****************************************************************************** * * * Paramètres : key = nom technique du processeur recherché. * * * * Description : Fournit le processeur d'architecture correspondant à un type.* * * * Retour : Processeur d'architecture trouvé. * * * * Remarques : - * * * ******************************************************************************/ GArchProcessor *get_arch_processor_for_type(const char *key) { GArchProcessor *result; /* Instance à retourner */ proc_t *def; /* Définition d'architecture */ G_LOCK(_pdef_access); def = find_processor_by_key(key); if (def == NULL) result = NULL; else result = g_object_new(def->instance, NULL); G_UNLOCK(_pdef_access); return result; }