/* 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. * * 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 "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; }