summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/fetch.c')
-rw-r--r--plugins/arm/v7/fetch.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/plugins/arm/v7/fetch.c b/plugins/arm/v7/fetch.c
index 20918c5..bf60d9c 100644
--- a/plugins/arm/v7/fetch.c
+++ b/plugins/arm/v7/fetch.c
@@ -35,7 +35,11 @@
#include <format/preload.h>
+#include "operands/it.h"
#include "operands/offset.h"
+#include "operands/register.h"
+#include "operands/reglist.h"
+#include "../instruction.h"
#include "../register.h"
@@ -532,3 +536,171 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
//exit(0);
}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* iset = type de jeu d'instructions courant. *
+* *
+* Description : Applique la mise à jour d'un registre après coup. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void apply_write_back(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GExeFormat *format, ArmV7InstrSet iset)
+{
+ GArchOperand *op; /* Opérande de registre */
+
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, 0);
+ assert(G_IS_ARMV7_REGISTER_OPERAND(op));
+
+ g_armv7_register_operand_write_back(G_ARMV7_REGISTER_OPERAND(op), true);
+
+ g_object_unref(G_OBJECT(op));
+
+ g_arch_instruction_unlock_operands(instr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* iset = type de jeu d'instructions courant. *
+* *
+* Description : Applique la mise à jour d'un registre après coup au besoin. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void apply_write_back_from_registers(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GExeFormat *format, ArmV7InstrSet iset)
+{
+ GArchOperand *op; /* Opérande à manipuler */
+ GArmV7RegisterOperand *regop; /* Opérande de registre */
+ GArchRegister *reg_ref; /* Registre de référence */
+ GArmV7RegListOperand *reglist; /* Opérande de liste de reg. */
+ size_t count; /* Taille de la liste */
+ bool inside; /* Intersection de registres */
+ size_t i; /* Boucle de parcours */
+ GArmV7Register *reg; /* Registre à analyser */
+
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, 0);
+ assert(G_IS_ARMV7_REGISTER_OPERAND(op));
+
+ regop = G_ARMV7_REGISTER_OPERAND(op);
+
+ reg_ref = G_ARCH_REGISTER(g_armv7_register_operand_get(regop));
+
+ op = _g_arch_instruction_get_operand(instr, 1);
+ assert(G_IS_ARMV7_REGLIST_OPERAND(op));
+
+ reglist = G_ARMV7_REGLIST_OPERAND(op);
+
+ count = g_armv7_reglist_count_registers(reglist);
+
+ inside = false;
+
+ for (i = 0; i < count && !inside; i++)
+ {
+ reg = g_armv7_reglist_operand_get_register(reglist, i);
+
+ inside = (g_arch_register_compare(reg_ref, G_ARCH_REGISTER(reg)) == 0);
+
+ }
+
+ if (!inside)
+ g_armv7_register_operand_write_back(regop, true);
+
+ g_object_unref(G_OBJECT(regop));
+ g_object_unref(G_OBJECT(reglist));
+
+ g_arch_instruction_unlock_operands(instr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* proc = représentation de l'architecture utilisée. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* iset = type de jeu d'instructions courant. *
+* *
+* Description : Construit un suffixe adapté à une instruction IT. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void build_it_instruction_suffix(GArchInstruction *instr, GArchProcessor *proc, GArmV7Context *context, GExeFormat *format, ArmV7InstrSet iset)
+{
+ GArchOperand *op; /* Opérande à manipuler */
+ GArmV7ITCondOperand *itcond; /* Opérande de l'instruction */
+ uint8_t firstcond; /* Indication sur la condition */
+ uint8_t mask; /* Masque d'application */
+ char suffix[4]; /* Suffixe à attribuer */
+
+ g_arch_instruction_lock_operands(instr);
+
+ op = _g_arch_instruction_get_operand(instr, 0);
+ assert(G_IS_ARMV7_ITCOND_OPERAND(op));
+
+ itcond = G_ARMV7_ITCOND_OPERAND(op);
+
+ firstcond = g_armv7_itcond_operand_get_firstcond(itcond);
+ mask = g_armv7_itcond_operand_get_mask(itcond);
+
+ firstcond &= 0x1;
+
+ if ((mask & 0x7) == 0x4)
+ {
+ suffix[0] = ((mask & 0x8) >> 3) == firstcond ? 't' : 'e';
+ suffix[1] = '\0';
+ }
+
+ else if ((mask & 0x3) == 0x2)
+ {
+ suffix[0] = ((mask & 0x8) >> 3) == firstcond ? 't' : 'e';
+ suffix[1] = ((mask & 0x4) >> 2) == firstcond ? 't' : 'e';
+ suffix[2] = '\0';
+ }
+
+ else if ((mask & 0x1) == 0x1)
+ {
+ suffix[0] = ((mask & 0x8) >> 3) == firstcond ? 't' : 'e';
+ suffix[1] = ((mask & 0x4) >> 2) == firstcond ? 't' : 'e';
+ suffix[2] = ((mask & 0x2) >> 1) == firstcond ? 't' : 'e';
+ suffix[3] = '\0';
+ }
+
+ else
+ suffix[0] = '\0';
+
+ if (suffix[0] != '\0')
+ g_arm_instruction_extend_keyword(G_ARM_INSTRUCTION(instr), suffix);
+
+ g_object_unref(G_OBJECT(itcond));
+
+ g_arch_instruction_unlock_operands(instr);
+
+}