/* Chrysalide - Outil d'analyse de fichiers binaires
* pseudo.c - définition des pseudo-registres
*
* Copyright (C) 2010-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 "pseudo.h"
#include
#include
#include
#include "../expression-int.h"
/* Définition d'un pseudo-registre (instance) */
struct _GPseudoRegister
{
GDecExpression parent; /* A laisser en premier */
PseudoRegUsage usage; /* Type d'utilisation attendue */
char *name; /* Désignation générale */
size_t index; /* Position dans l'ensemble */
GBinVariable *var; /* Variable plus précise */
};
/* Définition d'un pseudo-registre (classe) */
struct _GPseudoRegisterClass
{
GDecExpressionClass parent; /* A laisser en premier */
};
/* Initialise la classe des pseudo-registres. */
static void g_pseudo_register_class_init(GPseudoRegisterClass *);
/* Initialise une instance de pseudo-registre. */
static void g_pseudo_register_init(GPseudoRegister *);
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_pseudo_register_print(const GPseudoRegister *, GCodeBuffer *, GBufferLine *, GLangOutput *);
/* Indique le type défini pour un pseudo-registre. */
G_DEFINE_TYPE(GPseudoRegister, g_pseudo_register, G_TYPE_DEC_EXPRESSION);
/******************************************************************************
* *
* Paramètres : klass = classe à initialiser. *
* *
* Description : Initialise la classe des pseudo-registres. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_pseudo_register_class_init(GPseudoRegisterClass *klass)
{
}
/******************************************************************************
* *
* Paramètres : reg = instance à initialiser. *
* *
* Description : Initialise une instance de pseudo-registre. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_pseudo_register_init(GPseudoRegister *reg)
{
GDecInstruction *instr; /* Autre version de l'objet */
instr = G_DEC_INSTRUCTION(reg);
instr->print = (dec_instr_print_fc)g_pseudo_register_print;
}
/******************************************************************************
* *
* Paramètres : usage = précision quant à l'usage du pseudo-registre à créer.*
* *
* Description : Assigne le contenu d'une expression dans une autre. *
* *
* Retour : Pseudo-registre mis en place. *
* *
* Remarques : - *
* *
******************************************************************************/
GDecInstruction *g_pseudo_register_new(PseudoRegUsage usage)
{
GPseudoRegister *result; /* Pseudo-registre à renvoyer */
result = g_object_new(G_TYPE_PSEUDO_REGISTER, NULL);
result->usage = usage;
return G_DEC_INSTRUCTION(result);
}
/******************************************************************************
* *
* Paramètres : reg = pseudo-registre à venir consulter. *
* *
* Description : Indique l'usage attendu du pseudo-registre consulté. *
* *
* Retour : Utilité du pseudo-registre en place. *
* *
* Remarques : - *
* *
******************************************************************************/
PseudoRegUsage g_pseudo_register_get_usage(const GPseudoRegister *reg)
{
return reg->usage;
}
/******************************************************************************
* *
* Paramètres : reg = expression à transcrire en version humaine. *
* buffer = tampon où doit se réaliser l'insertion. *
* line = ligne d'impression prête à emploi ou NULL. *
* output = langage de programmation de sortie. *
* *
* Description : Imprime pour l'écran un version humaine d'une expression. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static GBufferLine *g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)
{
char label[32];
char *name;
if (reg->var != NULL)
{
name = g_binary_variable_to_string(reg->var, true);
g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, name, strlen(name), RTT_RAW, NULL);
free(name);
}
else
{
snprintf(label, 32, "%s%zu", reg->name, reg->index);
g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, label, strlen(label), RTT_RAW, NULL);
}
return line;
}
/******************************************************************************
* *
* Paramètres : reg = expression représentant un pseudo-registre à traiter. *
* name = désignation générale à associer au pseudo-registre. *
* *
* Description : Définit un nom général pour un pseudo-registre donné. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_pseudo_register_set_basename(GPseudoRegister *reg, const char *name)
{
reg->name = strdup(name);
}
/******************************************************************************
* *
* Paramètres : reg = expression représentant un pseudo-registre à traiter.*
* index = indice à associer au pseudo-registre. *
* *
* Description : Définit un indice unique pour un pseudo-registre donné. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_pseudo_register_set_index(GPseudoRegister *reg, size_t index)
{
reg->index = index;
}
/******************************************************************************
* *
* Paramètres : reg = expression représentant un pseudo-registre à traiter. *
* var = indications supplémentaire quant à la variable. *
* *
* Description : Précise le nom et le type de la variable. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_pseudo_register_set_variable(GPseudoRegister *reg, GBinVariable *var)
{
reg->var = var;
}