/* Chrysalide - Outil d'analyse de fichiers binaires * context.c - contexte lié à l'exécution d'un processeur * * Copyright (C) 2011-2014 Cyrille Bagard * * This file is part of Chrysalide. * * 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 "context.h" #include #include #include #include "context-int.h" /* Initialise la classe des contextes de processeur. */ static void g_proc_context_class_init(GProcContextClass *); /* Initialise une instance de contexte de processeur. */ static void g_proc_context_init(GProcContext *); /* Ajoute une adresse virtuelle comme point de départ de code. */ static void _g_proc_context_push_drop_point(GProcContext *, virt_t); /* Indique le type définit par la GLib pour le contexte de processeur. */ G_DEFINE_TYPE(GProcContext, g_proc_context, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des contextes de processeur. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_proc_context_class_init(GProcContextClass *klass) { klass->push_point = (push_drop_point_fc)_g_proc_context_push_drop_point; g_signal_new("drop-point-pushed", G_TYPE_PROC_CONTEXT, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GProcContextClass, drop_point_pushed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } /****************************************************************************** * * * Paramètres : ctx = instance à initialiser. * * * * Description : Initialise une instance de contexte de processeur. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_proc_context_init(GProcContext *ctx) { ctx->drop_points = NULL; ctx->dp_allocated = 0; ctx->dp_count = 0; g_mutex_init(&ctx->dp_access); ctx->extra_symbols = NULL; ctx->esyms_count = 0; g_mutex_init(&ctx->es_access); } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à compléter. * * addr = adresse d'un nouveau point de départ à traiter. * * * * Description : Ajoute une adresse virtuelle comme point de départ de code. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void _g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr) { if (ctx->dp_count >= ctx->dp_allocated) { ctx->dp_allocated += DP_ALLOC_BLOCK; ctx->drop_points = (virt_t *)realloc(ctx->drop_points, ctx->dp_allocated * sizeof(virt_t)); } ctx->drop_points[ctx->dp_count++] = addr; } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à compléter. * * addr = adresse d'un nouveau point de départ à traiter. * * * * Description : Ajoute une adresse virtuelle comme point de départ de code. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_proc_context_push_drop_point(GProcContext *ctx, virt_t addr) { g_mutex_lock(&ctx->dp_access); G_PROC_CONTEXT_GET_CLASS(ctx)->push_point(ctx, addr); g_mutex_unlock(&ctx->dp_access); g_signal_emit_by_name(ctx, "drop-point-pushed"); } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à consulter. * * addr = adresse de mémoire virtuelle à rechercher. * * * * Description : Précise si une adresse donnée figure comme point de départ. * * * * Retour : true si l'adresse est connue en interne, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_proc_context_has_addr_as_drop_points(GProcContext *ctx, virt_t addr) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours */ result = false; g_mutex_lock(&ctx->dp_access); for (i = 0; i < ctx->dp_count && !result; i++) result = (ctx->drop_points[i] == addr); g_mutex_unlock(&ctx->dp_access); return result; } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à compléter. * * virt = adresse d'un point de départ de code à traiter. * * * * Description : Fournit une adresse virtuelle comme point de départ de code. * * * * Retour : true si une adresse a pu être dépilée, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_proc_context_pop_drop_point(GProcContext *ctx, virt_t *virt) { bool result; /* Bilan d'accès à retourner */ g_mutex_lock(&ctx->dp_access); if (ctx->dp_count > 0) { result = true; *virt = ctx->drop_points[0]; if (ctx->dp_count > 1) memmove(&ctx->drop_points[0], &ctx->drop_points[1], (ctx->dp_count - 1) * sizeof(virt_t)); ctx->dp_count--; } else result = false; g_mutex_unlock(&ctx->dp_access); return result; } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à compléter. * * addr = adresse d'un nouveau symbole à traiter. * * * * Description : Empile une adresse de nouveau symbole à prendre en compte. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_proc_context_push_new_symbol_at(GProcContext *ctx, const vmpa2t *addr) { g_mutex_lock(&ctx->es_access); ctx->extra_symbols = (vmpa2t *)realloc(ctx->extra_symbols, ++ctx->esyms_count * sizeof(vmpa2t)); copy_vmpa(&ctx->extra_symbols[ctx->esyms_count - 1], addr); g_mutex_unlock(&ctx->es_access); } /****************************************************************************** * * * Paramètres : ctx = contexte de désassemblage à compléter. * * addr = adresse d'un nouveau symbole à traiter. * * * * Description : Dépile une adresse de nouveau symbole à prendre en compte. * * * * Retour : true si un symbole était bien encore en stock, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool g_proc_context_pop_new_symbol_at(GProcContext *ctx, vmpa2t *addr) { bool result; /* Bilan à retourner */ g_mutex_lock(&ctx->es_access); result = (ctx->esyms_count > 0); if (result) { ctx->esyms_count--; copy_vmpa(addr, &ctx->extra_symbols[ctx->esyms_count]); } g_mutex_unlock(&ctx->es_access); return result; }