/* OpenIDA - Outil d'analyse de fichiers binaires * addressing.c - prise en compte des modes d'adressage ARM v4/5/6 * * Copyright (C) 2013 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 "addressing.h" #include "encoding.h" #include "register.h" #include "operands/content.h" #include "operands/register.h" /****************************************************************************** * * * Paramètres : instr = instruction à compléter. * * data = mot de données contenant les indications. * * format = format du binaire manipulé. * * * * Description : Charge les opérandes selon le mode d'adressage § A5.2.1. * * * * Retour : true si le décodage s'est bien déroulé. * * * * Remarques : - * * * ******************************************************************************/ bool build_v456_operands_with_load_immediate_offset(GArmV456Instruction *instr, uint32_t data, const GExeFormat *format) { uint8_t rd_index; /* Indice du registre Rd */ GArmV456Register *rd_reg; /* Registre Rd en place */ GArchOperand *op; /* Opérande à ajouter */ uint8_t rn_index; /* Indice du registre Rn */ GArmV456Register *rn_reg; /* Registre Rn en place */ uint16_t value; /* Valeur de décallage */ GImmOperand *offset; /* Opérande de décallage */ bool add; /* Utilisation du décallage */ /* Destination */ rd_index = ARM_V456_REG_RD(data); rd_reg = g_armv456_register_new(rd_index); op = g_armv456_register_operand_new_from_existing(rd_reg); g_arch_instruction_attach_extra_operand(G_ARCH_INSTRUCTION(instr), op); /* Source */ rn_index = ARM_V456_REG_RN(data); rn_reg = g_armv456_register_new(rn_index); value = ARM_V456_ADDR_MODE(data); offset = G_IMM_OPERAND(g_imm_operand_new_from_value(MDS_16_BITS_UNSIGNED, value)); add = (data & ARM_V456_BIT_U); op = g_armv456_content_operand_new(rn_reg, offset, add); g_arch_instruction_attach_extra_operand(G_ARCH_INSTRUCTION(instr), op); return true; }