/* Chrysalide - Outil d'analyse de fichiers binaires * helpers.c - aide à la mise en place des opérandes ARMv7 * * Copyright (C) 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 "helpers.h" #include "register.h" #include "../../register.h" #include "../../immediate.h" #include "../../../common/asm.h" /****************************************************************************** * * * Paramètres : value = valeur sur 32 bits maximum à traiter. * * topbit = valeur du bit de poids fort manipulé. * * size = taille de la valeur finale à constituer. * * * * Description : Crée un opérande de valeur immédiate avec extension de signe.* * * * Retour : Adresse de la structure mise en place. * * * * Remarques : - * * * ******************************************************************************/ GArchOperand *sign_extend_armv7_imm(uint32_t value, bool topbit, unsigned int size) { GArchOperand *result; /* Opérande à faire remonter */ unsigned int msb; /* Position du premier bit à 1 */ MemoryDataSize mds; /* Conversion de la taille */ uint32_t val4; /* Valeur sur 4 bits */ uint32_t val8; /* Valeur sur 8 bits */ uint32_t val16; /* Valeur sur 16 bits */ uint32_t val32; /* Valeur sur 32 bits */ unsigned int i; /* Boucle de parcours */ result = NULL; topbit &= msb_32(value, &msb); switch (size) { #define SIGN_EXTEND_CASE(sz) \ case sz: \ mds = MDS_ ## sz ## _BITS_SIGNED; \ val ## sz = value; \ if (topbit) \ for (i = msb + 1; i < sz; i++) \ val ## sz |= (1 << i); \ result = g_imm_operand_new_from_value(mds, val ## sz); \ break; SIGN_EXTEND_CASE(4); SIGN_EXTEND_CASE(8); SIGN_EXTEND_CASE(16); SIGN_EXTEND_CASE(32); } return result; } /****************************************************************************** * * * Paramètres : index = indice du registre correspondant. * * * * Description : Crée un opérande représentant un registre ARMv7. * * * * Retour : Adresse de la structure mise en place. * * * * Remarques : - * * * ******************************************************************************/ GArchOperand *translate_armv7_register(uint8_t index) { GArchOperand *result; /* Opérande à faire remonter */ GArmV7Register *reg; /* Register à représenter */ reg = g_armv7_register_new(index); if (reg == NULL) result = NULL; else result = g_register_operand_new(G_ARCH_REGISTER(reg)); return result; }