/* OpenIDA - Outil d'analyse de fichiers binaires * immediate.c - opérandes représentant des valeurs numériques * * Copyright (C) 2009 Cyrille Bagard * * This file is part of OpenIDA. * * 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 "immediate.h" #include #include #include "operand-int.h" /* Définition d'un opérande de valeur numérique (instance) */ struct _GImmOperand { GArchOperand parent; /* Instance parente */ AsmOperandSize size; /* Taille de l'opérande */ /** * Note : dans le cas d'une valeur signée, * signed_imm contient la valeur lue/donnée, et * unsigned_imm la valeur humainement lisible (ie. positive). */ union { uint8_t val8; /* Valeur sur 8 bits */ uint16_t val16; /* Valeur sur 16 bits */ uint32_t val32; /* Valeur sur 32 bits */ uint64_t val64; /* Valeur sur 64 bits */ } unsigned_imm; union { uint8_t val8; /* Valeur sur 8 bits */ uint16_t val16; /* Valeur sur 16 bits */ uint32_t val32; /* Valeur sur 32 bits */ uint64_t val64; /* Valeur sur 64 bits */ } signed_imm; }; /* Définition d'un opérande de valeur numérique (classe) */ struct _GImmOperandClass { GArchOperandClass parent; /* Classe parente */ }; /* Initialise la classe des lignes de descriptions initiales. */ static void g_imm_operand_class_init(GImmOperandClass *); /* Initialise la classe des lignes de descriptions initiales. */ static void g_imm_operand_init(GImmOperand *); /* Traduit un opérande en version humainement lisible. */ static char *g_imm_operand_get_text(const GImmOperand *, const exe_format *, AsmSyntax); /* Indique le type défini pour un opérande de valeur numérique. */ G_DEFINE_TYPE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des lignes de descriptions initiales. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_imm_operand_class_init(GImmOperandClass *klass) { } /****************************************************************************** * * * Paramètres : operand = instance à initialiser. * * * * Description : Initialise la classe des lignes de descriptions initiales. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_imm_operand_init(GImmOperand *operand) { GArchOperand *parent; /* Instance parente */ parent = G_ARCH_OPERAND(operand); parent->get_text = (get_operand_text_fc)g_imm_operand_get_text; } /****************************************************************************** * * * Paramètres : size = taille de l'opérande souhaitée. * * data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale des données à analyser. * * endian = ordre des bits dans la source. * * * * Description : Crée un opérande réprésentant une valeur numérique. * * * * Retour : Instruction mise en place. * * * * Remarques : - * * * ******************************************************************************/ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, SourceEndian endian) { GImmOperand *result; /* Instruction à retourner */ result = g_object_new(G_TYPE_IMM_OPERAND, NULL); result->size = size; switch (size) { case AOS_8_BITS_UNSIGNED: if (!read_u8(&result->unsigned_imm.val8, data, pos, len, endian)) goto gionfd_error; break; } return G_ARCH_OPERAND(result); gionfd_error: /* TODO : free */ return NULL; } /****************************************************************************** * * * Paramètres : operand = opérande à traiter. * * format = format du binaire manipulé. * * syntax = type de représentation demandée. * * * * Description : Traduit un opérande en version humainement lisible. * * * * Retour : Chaîne de caractères à libérer de la mémoire. * * * * Remarques : - * * * ******************************************************************************/ static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format *format, AsmSyntax syntax) { char *result; /* Chaîne à retourner */ result = (char *)calloc(19, sizeof(char)); switch (syntax) { case ASX_INTEL: switch (operand->size) { case MDS_UNDEFINED: snprintf(result, 19, "$0x???"); break; case AOS_8_BITS_UNSIGNED: case AOS_8_BITS_SIGNED: snprintf(result, 19, "0x%hhx", operand->unsigned_imm.val8); break; case AOS_16_BITS_UNSIGNED: case AOS_16_BITS_SIGNED: snprintf(result, 19, "0x%hx", operand->unsigned_imm.val16); break; case AOS_32_BITS_UNSIGNED: case AOS_32_BITS_SIGNED: snprintf(result, 19, "0x%x", operand->unsigned_imm.val32); break; case AOS_64_BITS_UNSIGNED: case AOS_64_BITS_SIGNED: snprintf(result, 19, "0x%llx", operand->unsigned_imm.val64); break; } break; case ASX_ATT: switch (operand->size) { case MDS_UNDEFINED: snprintf(result, 19, "$0x???"); break; case AOS_8_BITS_UNSIGNED: case AOS_8_BITS_SIGNED: snprintf(result, 19, "$0x%hhx", operand->unsigned_imm.val8); break; case AOS_16_BITS_UNSIGNED: case AOS_16_BITS_SIGNED: snprintf(result, 19, "$0x%hx", operand->unsigned_imm.val16); break; case AOS_32_BITS_UNSIGNED: case AOS_32_BITS_SIGNED: snprintf(result, 19, "$0x%x", operand->unsigned_imm.val32); break; case AOS_64_BITS_UNSIGNED: case AOS_64_BITS_SIGNED: snprintf(result, 19, "$0x%llx", operand->unsigned_imm.val64); break; } break; } return result; }