/* Chrysalide - Outil d'analyse de fichiers binaires
* symbol.c - gestion des symboles dans un binaire
*
* Copyright (C) 2009-2012 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 "symbol.h"
#include
#include
/* Symbole d'exécutable (instance) */
struct _GBinSymbol
{
GObject parent; /* A laisser en premier */
SymbolType type; /* Type du symbole */
const char *name; /* Désignation du symbole */
vmpa_t address; /* Adresse du symbole */
char *alt; /* Nom alternatif */
union
{
GArchInstruction *instr; /* Instruction correspondante */
GBinRoutine *routine; /* Compléments pour fonction */
} extra;
GDbComment *comment; /* Eventuel commentaire lié */
};
/* Symbole d'exécutable (classe) */
struct _GBinSymbolClass
{
GObjectClass parent; /* A laisser en premier */
};
/* Initialise la classe des symboles d'exécutables. */
static void g_binary_symbol_class_init(GBinSymbolClass *);
/* Initialise une instance de symbole d'exécutable. */
static void g_binary_symbol_init(GBinSymbol *);
/* Indique le type défini pour un symbole d'exécutable. */
G_DEFINE_TYPE(GBinSymbol, g_binary_symbol, G_TYPE_OBJECT);
/******************************************************************************
* *
* Paramètres : klass = classe à initialiser. *
* *
* Description : Initialise la classe des symboles d'exécutables. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_symbol_class_init(GBinSymbolClass *klass)
{
}
/******************************************************************************
* *
* Paramètres : symbol = instance à initialiser. *
* *
* Description : Initialise une instance de symbole d'exécutable. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_binary_symbol_init(GBinSymbol *symbol)
{
}
/******************************************************************************
* *
* Paramètres : type = type de symbole à créer. *
* name = désignation humaine du symbole. *
* address = adresse associée au symbole. *
* *
* Description : Crée un nouveau symbole d'exécutable. *
* *
* Retour : Adresse de l'instance mise en place ou NULL en cas d'échec. *
* *
* Remarques : - *
* *
******************************************************************************/
GBinSymbol *g_binary_symbol_new(SymbolType type, const char *name, vmpa_t address)
{
GBinSymbol *result; /* Nouveau symbole à renvoyer */
result = g_object_new(G_TYPE_BIN_SYMBOL, NULL);
result->type = type;
result->name = name;
result->address = address;
return result;
}
/******************************************************************************
* *
* Paramètres : a = premier symbole à analyser. *
* b = second symbole à analyser. *
* *
* Description : Compare deux symboles d'exécutable selon leurs propriétés. *
* *
* Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). *
* *
* Remarques : - *
* *
******************************************************************************/
int g_binary_symbol_cmp(const GBinSymbol **a, const GBinSymbol **b)
{
int result; /* Bilan à retourner */
const mrange_t *ra; /* Emplacement du symbole A */
const mrange_t *rb; /* Emplacement du symbole B */
const vmpa2t *aa; /* Adresse du symbole A */
const vmpa2t *ab; /* Adresse du symbole B */
ra = g_binary_symbol_get_range(*a);
rb = g_binary_symbol_get_range(*b);
if (ra == NULL && rb == NULL)
result = 0;
else if (ra != NULL && rb == NULL)
result = 1;
else if (ra == NULL && rb != NULL)
result = -1;
else
{
aa = get_mrange_addr(ra);
ab = get_mrange_addr(rb);
result = aa->virtual < ab->virtual ? -1 : (aa->virtual > ab->virtual ? 1 : 0);
///result = cmp_mrange(ra, rb);
//printf(" ?? 0x%08lx vs 0x%08lx -> %d\n", aa->virtual, ab->virtual, result);
}
return result;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit le type du symbole. *
* *
* Retour : Type de symbole représenté. *
* *
* Remarques : - *
* *
******************************************************************************/
SymbolType g_binary_symbol_get_target_type(const GBinSymbol *symbol)
{
return symbol->type;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit la description humaine du symbole. *
* *
* Retour : Nom du symbole sous forme de chaîne de caractères. *
* *
* Remarques : - *
* *
******************************************************************************/
const char *g_binary_symbol_to_string(const GBinSymbol *symbol)
{
const char *result; /* Désignation à retourner */
switch (symbol->type)
{
case STP_ROUTINE:
case STP_ENTRY_POINT:
result = g_binary_routine_get_name(symbol->extra.routine);
break;
default:
result = (symbol->alt != NULL ? symbol->alt : symbol->name);
break;
}
return result;
}
vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol)
{
return 0;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit un étiquette pour viser un symbole. *
* *
* Retour : Chaîne de caractères renvoyant au symbole. *
* *
* Remarques : - *
* *
******************************************************************************/
const char *g_binary_symbol_get_label(const GBinSymbol *symbol)
{
const char *result; /* Etiquette à retourner */
result = NULL;
switch (symbol->type)
{
case STP_ROUTINE:
case STP_ENTRY_POINT:
result = g_binary_routine_get_name(symbol->extra.routine);
break;
default:
result = NULL;
break;
}
return result;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir mettre à jour. *
* full = adresse dont la définition est complète. *
* *
* Description : Raffine la définition de l'emplacement d'un symbole. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_symbol_fix_range(GBinSymbol *symbol, const vmpa2t *full)
{
GArchInstruction *instr; /* Instruction associée */
mrange_t range; /* Plage à manipuler */
GBinRoutine *routine; /* Routine associée */
switch (symbol->type)
{
case STP_DATA:
instr = g_binary_symbol_get_instruction(symbol);
copy_mrange(&range, g_arch_instruction_get_range(instr));
assert(cmp_vmpa(get_mrange_addr(&range), full) == 0);
copy_vmpa(get_mrange_addr(&range), full);
g_arch_instruction_set_range(instr, &range);
break;
case STP_ROUTINE:
case STP_ENTRY_POINT:
routine = g_binary_symbol_get_routine(symbol);
copy_mrange(&range, g_binary_routine_get_range(routine));
assert(cmp_vmpa(get_mrange_addr(&range), full) == 0);
copy_vmpa(get_mrange_addr(&range), full);
g_binary_routine_set_range(routine, &range);
break;
default:
break;
}
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit l'emplacement où se situe un symbole. *
* *
* Retour : Zone mémoire couverte par le symbole. *
* *
* Remarques : - *
* *
******************************************************************************/
const mrange_t *g_binary_symbol_get_range(const GBinSymbol *symbol)
{
const mrange_t *result; /* Plage à retourner */
result = NULL;
switch (symbol->type)
{
case STP_DATA:
result = g_arch_instruction_get_range(symbol->extra.instr);
break;
case STP_ROUTINE:
case STP_ENTRY_POINT:
result = g_binary_routine_get_range(symbol->extra.routine);
break;
default:
result = NULL;
break;
}
return result;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* alt = désignation humaine alternative à favoriser. *
* *
* Description : Définit un autre nom pour le symbole. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_symbol_set_alt_name(GBinSymbol *symbol, char *alt)
{
symbol->alt = alt;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* routine = prototype de la fonction représentée. *
* *
* Description : Attache la routine associée au symbole. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_symbol_attach_routine(GBinSymbol *symbol, GBinRoutine *routine)
{
symbol->extra.routine = routine;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir manipuler. *
* instr = représentation du symbole associé. *
* *
* Description : Attache l'instruction associée au symbole. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_symbol_attach_instruction(GBinSymbol *symbol, GArchInstruction *instr)
{
symbol->type = STP_DATA;
symbol->extra.instr = instr;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit l'éventuelle routine associée au symbole. *
* *
* Retour : - *
* *
* Remarques : Il n'y a pas de transfert de propriété ici ! *
* *
******************************************************************************/
GBinRoutine *g_binary_symbol_get_routine(const GBinSymbol *symbol)
{
return symbol->extra.routine;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit l'éventuelle instruction associée au symbole. *
* *
* Retour : - *
* *
* Remarques : Il n'y a pas de transfert de propriété ici ! *
* *
******************************************************************************/
GArchInstruction *g_binary_symbol_get_instruction(const GBinSymbol *symbol)
{
return symbol->extra.instr;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir manipuler. *
* comment = commentaire construit à propos du symbole. *
* *
* Description : Ajoute un commentaire facultatif au symbole. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_binary_symbol_set_comment(GBinSymbol *symbol, GDbComment *comment)
{
symbol->comment = comment;
}
/******************************************************************************
* *
* Paramètres : symbol = symbole à venir consulter. *
* *
* Description : Fournit l'éventuel commentaire associé au symbole. *
* *
* Retour : - *
* *
* Remarques : Il n'y a pas de transfert de propriété ici ! *
* *
******************************************************************************/
GDbComment *g_binary_symbol_get_comment(const GBinSymbol *symbol)
{
return symbol->comment;
}