summaryrefslogtreecommitdiff
path: root/src/arch/arm/v7
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/v7')
-rw-r--r--src/arch/arm/v7/context.c48
-rw-r--r--src/arch/arm/v7/context.h15
-rw-r--r--src/arch/arm/v7/link.c242
-rw-r--r--src/arch/arm/v7/link.h33
-rw-r--r--src/arch/arm/v7/opdefs/Makefile.am1
-rw-r--r--src/arch/arm/v7/opdefs/b_A8818.d45
-rw-r--r--src/arch/arm/v7/opdefs/bl_A8825.d32
-rw-r--r--src/arch/arm/v7/opdefs/blx_A8826.d2
-rw-r--r--src/arch/arm/v7/opdefs/bx_A8827.d12
-rw-r--r--src/arch/arm/v7/opdefs/cbnz_A8829.d14
-rw-r--r--src/arch/arm/v7/opdefs/ldr_A8862.d3
-rw-r--r--src/arch/arm/v7/opdefs/ldr_A8863.d2
-rw-r--r--src/arch/arm/v7/opdefs/ldr_A8864.d32
-rw-r--r--src/arch/arm/v7/opdefs/ldr_A8865.d1
-rw-r--r--src/arch/arm/v7/opdefs/ldrb_A8867.d3
-rw-r--r--src/arch/arm/v7/post.c189
-rw-r--r--src/arch/arm/v7/post.h9
-rw-r--r--src/arch/arm/v7/processor.c7
18 files changed, 678 insertions, 12 deletions
diff --git a/src/arch/arm/v7/context.c b/src/arch/arm/v7/context.c
index 41ffd29..c29794d 100644
--- a/src/arch/arm/v7/context.c
+++ b/src/arch/arm/v7/context.c
@@ -24,6 +24,9 @@
#include "context.h"
+#include <assert.h>
+
+
#include "../context-int.h"
@@ -208,7 +211,7 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr)
{
- printf("PUSH v7 !!\n");
+ printf("PUSH v7 !! 0x%08x\n", addr);
@@ -224,6 +227,47 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr)
}
+/******************************************************************************
+* *
+* Paramètres : ctx = contexte de désassemblage à compléter. *
+* addr = adresse d'un nouveau point de départ à traiter. *
+* *
+* Description : Ajoute une adresse virtuelle comme point de départ de code. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker)
+{
+
+
+ printf("PUSH v7 !! 0x%08x\n", (unsigned int)addr);
+
+
+
+ if (addr & 0x1)
+ {
+ addr -= 0x1;
+ assert(marker == AV7IS_THUMB);
+ }
+
+
+ g_armv7_context_define_encoding(ctx, addr, marker);
+
+ G_PROC_CONTEXT_CLASS(g_armv7_context_parent_class)->push_point(G_PROC_CONTEXT(ctx), addr);
+
+}
+
+
+
+
+
+
+
+
/******************************************************************************
@@ -242,6 +286,8 @@ static void g_armv7_context_push_drop_point(GArmV7Context *ctx, virt_t addr)
void g_armv7_context_define_encoding(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker)
{
+ printf(" --encoding-- @ 0x%08llx -> %d\n", (unsigned long long)addr, (int)marker);
+
_g_arm_context_define_encoding(G_ARM_CONTEXT(ctx), addr, marker);
}
diff --git a/src/arch/arm/v7/context.h b/src/arch/arm/v7/context.h
index 65b5302..a4d99d6 100644
--- a/src/arch/arm/v7/context.h
+++ b/src/arch/arm/v7/context.h
@@ -79,4 +79,19 @@ ArmV7InstrSet g_armv7_context_find_encoding(GArmV7Context *, virt_t);
+
+
+
+
+
+
+
+
+void g_armv7_context_push_drop_point_ext(GArmV7Context *ctx, virt_t addr, ArmV7InstrSet marker);
+
+
+
+
+
+
#endif /* _ARCH_ARM_V7_CONTEXT_H */
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
index fff0944..c1f83ac 100644
--- a/src/arch/arm/v7/link.c
+++ b/src/arch/arm/v7/link.c
@@ -25,6 +25,7 @@
#include <assert.h>
+#include <operands/offset.h>
@@ -43,6 +44,54 @@
* *
******************************************************************************/
+void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+ const mrange_t *range; /* Emplacementt d'instruction */
+ virt_t pc; /* Position dans l'exécution */
+ GArchOperand *op; /* Opérande numérique en place */
+ int32_t offset; /* Décallage encodé en dur */
+ virt_t target; /* Adresse virtuelle visée */
+
+ range = g_arch_instruction_get_range(instr);
+
+ pc = get_virt_addr(get_mrange_addr(range));
+
+ pc += get_mrange_length(range);
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
+ g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+ else assert(0);
+
+ printf("1... 0x%x (0x%x) + 0x%x\n",
+ (unsigned int)get_virt_addr(get_mrange_addr(range)),
+ (unsigned int)pc, (unsigned int)offset);
+
+ target = pc + offset;
+
+ //g_armv7_context_define_encoding(context, target, iset);
+ g_armv7_context_push_drop_point_ext(context, target, iset);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* 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 à faire suivre. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
{
const mrange_t *range; /* Emplacementt d'instruction */
@@ -69,9 +118,18 @@ void handle_links_with_instruction_bl_with_orig(GArchInstruction *instr, GArmV7C
if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+ else assert(0);
+
+ printf("2... 0x%x (0x%x) + 0x%x\n",
+ (unsigned int)get_virt_addr(get_mrange_addr(range)),
+ (unsigned int)pc, (unsigned int)offset);
+
+
+
target = pc + offset;
- g_armv7_context_define_encoding(context, target, iset);
+ //g_armv7_context_define_encoding(context, target, iset);
+ g_armv7_context_push_drop_point_ext(context, target, iset);
}
@@ -118,8 +176,188 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7
if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_SIGNED, &offset))
g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+ else assert(0);
+
+ printf("3... 0x%x (0x%x) + 0x%x\n",
+ (unsigned int)get_virt_addr(get_mrange_addr(range)),
+ (unsigned int)pc, (unsigned int)offset);
+
+
+
target = pc + offset;
- g_armv7_context_define_encoding(context, target, iset);
+ //g_armv7_context_define_encoding(context, target, iset);
+ g_armv7_context_push_drop_point_ext(context, target, iset);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = acès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_links_with_instruction_cb_n_z(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format)
+{
+ const mrange_t *range; /* Emplacementt d'instruction */
+ virt_t pc; /* Position dans l'exécution */
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t offset; /* Décallage encodé en dur */
+ virt_t target; /* Adresse virtuelle visée */
+
+ range = g_arch_instruction_get_range(instr);
+
+ pc = get_virt_addr(get_mrange_addr(range));
+
+
+ printf("PC :: 0x%08x\n", (unsigned int)pc);
+
+
+ /**
+ * En mode Thumb, pc a pour valeur l'adresse courante plus 4.
+ */
+
+ pc += 4;
+
+ op = g_arch_instruction_get_operand(instr, 1);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset))
+ g_imm_operand_set_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, pc + offset);
+
+ else assert(0);
+
+ target = pc + offset;
+
+ //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
+ g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* 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 à inverser. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset)
+{
+ const mrange_t *range; /* Emplacementt d'instruction */
+ phys_t phys_pc; /* Position dans l'exécution */
+ GArchOperand *op; /* Opérande de surcouche */
+ GArchOperand *sub_op; /* Opérande numérique en place */
+
+
+ uint32_t offset; /* Décallage encodé en dur */
+ bool ret; /* Bilan d'une récupération */
+
+
+ off_t val_offset; /* Position de valeur à lire */
+
+
+
+ off_t length; /* Taille des données à lire */
+ const bin_t *data; /* Données binaires à lire */
+
+
+ uint32_t target; /* Adresse virtuelle visée */
+ GArchOperand *new; /* Instruction de ciblage */
+
+ /* Récupération de l'adresse visée par le chargement */
+
+ range = g_arch_instruction_get_range(instr);
+
+ phys_pc = get_phy_addr(get_mrange_addr(range));
+
+ phys_pc &= ~3;
+ //phys_pc = (phys_pc + 3) & ~3;
+
+ printf(">>>>>>> @pc @ 0x%08x\n", (unsigned int)phys_pc);
+
+
+ switch (iset)
+ {
+ case AV7IS_ARM:
+ phys_pc += 8;
+ break;
+ case AV7IS_THUMB:
+ phys_pc += 4;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ op = g_arch_instruction_get_operand(instr, 1);
+ assert(G_IS_ARMV7_OFFSET_OPERAND(op));
+
+ sub_op = g_armv7_offset_operand_get_value(G_ARMV7_OFFSET_OPERAND(op));
+
+ ret = g_imm_operand_get_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, &offset);
+ if (!ret)
+ {
+ assert(0);
+ return;
+ }
+
+ /* Lecture de la valeur vers laquelle renvoyer */
+
+ if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op)))
+ val_offset = phys_pc + offset;
+ else
+ val_offset = phys_pc - offset;
+
+
+ data = g_binary_format_get_content(format, &length);
+
+
+ printf(">>>>>>> @reading @ 0x%08x (0x%x)\n", (unsigned int)val_offset, offset);
+
+
+ ret = read_u32(&target, data, &val_offset, length, SRE_LITTLE /* FIXME */);
+ if (!ret) return;
+
+
+ printf(">>>>>>> @got target :: 0x%08x\n", (unsigned int)target);
+
+
+ //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target);
+
+
+ new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
+ g_arch_instruction_replace_operand(instr, new, op);
+
+
+
+
+ //exit(0);
+
+
+
+ //target = pc + offset;
+
+ //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
+ g_armv7_context_push_drop_point_ext(context, target, AV7IS_THUMB);
+
+
+ //exit(0);
}
diff --git a/src/arch/arm/v7/link.h b/src/arch/arm/v7/link.h
index ef71bd6..87bef54 100644
--- a/src/arch/arm/v7/link.h
+++ b/src/arch/arm/v7/link.h
@@ -32,6 +32,21 @@
/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_instruction_b_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void handle_links_with_instruction_b_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_THUMB);
+}
+
+static inline void handle_links_with_instruction_b_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ handle_links_with_instruction_b_with_orig(ins, ctx, fmt, AV7IS_ARM);
+}
+
+
+/* Complète un désassemblage accompli pour une instruction. */
void handle_links_with_instruction_bl_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
@@ -61,5 +76,23 @@ static inline void handle_links_with_instruction_blx_from_thumb(GArchInstruction
}
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_instruction_cb_n_z(GArchInstruction *, GArmV7Context *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *, GArmV7Context *, GBinFormat *, ArmV7InstrSet);
+
+
+static inline void handle_links_with_instruction_ldr_literal_from_arm(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_ARM);
+}
+
+static inline void handle_links_with_instruction_ldr_literal_from_thumb(GArchInstruction *ins, GArmV7Context *ctx, GBinFormat *fmt)
+{
+ handle_links_with_instruction_ldr_literal_with_orig(ins, ctx, fmt, AV7IS_THUMB);
+}
+
+
#endif /* _ARCH_ARM_V7_LINK_H */
diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am
index 0966e2e..fa42230 100644
--- a/src/arch/arm/v7/opdefs/Makefile.am
+++ b/src/arch/arm/v7/opdefs/Makefile.am
@@ -16,6 +16,7 @@ D2C_ENCODINGS = \
-e T=thumb_32_
D2C_MACROS = \
+ -M DefineAsReturn=g_arch_instruction_define_as_return \
-M SetFlags=g_armv7_instruction_define_setflags \
-M Condition=g_arm_instruction_set_cond \
-M Register=translate_armv7_register \
diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d
index 50600d4..5d696a3 100644
--- a/src/arch/arm/v7/opdefs/b_A8818.d
+++ b/src/arch/arm/v7/opdefs/b_A8818.d
@@ -36,10 +36,18 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_b_from_thumb
+ post = post_process_branch_instructions
+
+ }
+
@rules {
//if cond == '1110' then UNDEFINED;
//if cond == '1111' then SEE SVC;
+ call DefineAsReturn(1)
}
@@ -57,9 +65,17 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_b_from_thumb
+ post = post_process_branch_instructions
+
+ }
+
@rules {
//if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ call DefineAsReturn(1)
}
@@ -78,10 +94,18 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_b_from_thumb
+ post = post_process_branch_instructions
+
+ }
+
@rules {
//if cond<3:1> == '111' then SEE "Related encodings";
//if InITBlock() then UNPREDICTABLE;
+ call DefineAsReturn(1)
}
@@ -101,9 +125,17 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_b_from_thumb
+ post = post_process_branch_instructions
+
+ }
+
@rules {
//if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ call DefineAsReturn(1)
}
@@ -122,4 +154,17 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_b_from_arm
+ post = post_process_branch_instructions
+
+ }
+
+ @rules {
+
+ call DefineAsReturn(1)
+
+ }
+
}
diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d
index 96c782f..c5de31e 100644
--- a/src/arch/arm/v7/opdefs/bl_A8825.d
+++ b/src/arch/arm/v7/opdefs/bl_A8825.d
@@ -40,7 +40,13 @@
@hooks {
link = handle_links_with_instruction_bl_from_thumb
- post = post_process_branch_instructions
+ post = post_process_branch_and_link_instructions
+
+ }
+
+ @rules {
+
+ //call DefineAsReturn(1)
}
@@ -63,7 +69,13 @@
@hooks {
link = handle_links_with_instruction_blx_from_thumb
- post = post_process_branch_instructions
+ post = post_process_branch_and_link_instructions
+
+ }
+
+ @rules {
+
+ //call DefineAsReturn(1)
}
@@ -84,7 +96,13 @@
@hooks {
link = handle_links_with_instruction_bl_from_arm
- post = post_process_branch_instructions
+ post = post_process_branch_and_link_instructions
+
+ }
+
+ @rules {
+
+ //call DefineAsReturn(1)
}
@@ -105,7 +123,13 @@
@hooks {
link = handle_links_with_instruction_blx_from_arm
- post = post_process_branch_instructions
+ post = post_process_branch_and_link_instructions
+
+ }
+
+ @rules {
+
+ //call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/blx_A8826.d b/src/arch/arm/v7/opdefs/blx_A8826.d
index 178515a..12c55ad 100644
--- a/src/arch/arm/v7/opdefs/blx_A8826.d
+++ b/src/arch/arm/v7/opdefs/blx_A8826.d
@@ -39,6 +39,7 @@
//if m == 15 then UNPREDICTABLE;
//if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ //call DefineAsReturn(1)
}
@@ -60,6 +61,7 @@
@rules {
//if m == 15 then UNPREDICTABLE;
+ //call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d
index 45ccfd5..b8ab6f8 100644
--- a/src/arch/arm/v7/opdefs/bx_A8827.d
+++ b/src/arch/arm/v7/opdefs/bx_A8827.d
@@ -36,6 +36,12 @@
}
+ @rules {
+
+ call DefineAsReturn(1)
+
+ }
+
}
@encoding(A1) {
@@ -51,4 +57,10 @@
}
+ @rules {
+
+ call DefineAsReturn(1)
+
+ }
+
}
diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cbnz_A8829.d
index 9ecf141..93a8d1f 100644
--- a/src/arch/arm/v7/opdefs/cbnz_A8829.d
+++ b/src/arch/arm/v7/opdefs/cbnz_A8829.d
@@ -36,6 +36,13 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_cb_n_z
+ post = post_process_comp_and_branch_instructions
+
+ }
+
}
@encoding(t12) {
@@ -51,4 +58,11 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_cb_n_z
+ post = post_process_comp_and_branch_instructions
+
+ }
+
}
diff --git a/src/arch/arm/v7/opdefs/ldr_A8862.d b/src/arch/arm/v7/opdefs/ldr_A8862.d
index 7799fce..ecb530b 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8862.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8862.d
@@ -76,6 +76,7 @@
//if Rn == '1111' then SEE LDR (literal);
//if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -103,6 +104,7 @@
//if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
//if P == '0' && W == '0' then UNDEFINED;
//if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -131,6 +133,7 @@
//if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
//if P == '0' && W == '0' then UNDEFINED;
//if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/ldr_A8863.d b/src/arch/arm/v7/opdefs/ldr_A8863.d
index 2526671..0158c3d 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8863.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8863.d
@@ -46,6 +46,7 @@
//t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
//index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
//if wback && n == t then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -75,6 +76,7 @@
//t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
//index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
//if wback && n == t then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d
index acb6f94..3fbc0e3 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8864.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8864.d
@@ -37,6 +37,13 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_ldr_literal_from_thumb
+ post = post_process_ldr_instructions
+
+ }
+
}
@encoding(T2) {
@@ -53,9 +60,17 @@
}
+ @hooks {
+
+ link = handle_links_with_instruction_ldr_literal_from_thumb
+ post = post_process_ldr_instructions
+
+ }
+
@rules {
//if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -65,14 +80,29 @@
@word cond(4) 0 1 0 1 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12)
- @syntax <Rgt> <label>
+ @syntax {c} <Rgt> <label>
@conv {
+ c = Condition(cond)
Rgt = Register(Rt)
imm32 = ZeroExtend(imm12, 12, 32)
label = MakeAccessOffset(U, imm32)
}
+ @hooks {
+
+ link = handle_links_with_instruction_ldr_literal_from_arm
+ post = post_process_ldr_instructions
+
+ }
+
+ @rules {
+
+ //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
+
+ }
+
}
diff --git a/src/arch/arm/v7/opdefs/ldr_A8865.d b/src/arch/arm/v7/opdefs/ldr_A8865.d
index 11a8932..56a09fb 100644
--- a/src/arch/arm/v7/opdefs/ldr_A8865.d
+++ b/src/arch/arm/v7/opdefs/ldr_A8865.d
@@ -67,6 +67,7 @@
//if Rn == '1111' then SEE LDR (literal);
//if m IN {13,15} then UNPREDICTABLE;
//if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/opdefs/ldrb_A8867.d b/src/arch/arm/v7/opdefs/ldrb_A8867.d
index 8097fd0..52a50cb 100644
--- a/src/arch/arm/v7/opdefs/ldrb_A8867.d
+++ b/src/arch/arm/v7/opdefs/ldrb_A8867.d
@@ -60,6 +60,7 @@
//if Rt == '1111' then SEE PLD;
//if Rn == '1111' then SEE LDRB (literal);
//if t == 13 then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -87,6 +88,7 @@
//if P == '1' && U == '1' && W == '0' then SEE LDRBT;
//if P == '0' && W == '0' then UNDEFINED;
//if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
@@ -115,6 +117,7 @@
//if P == '1' && U == '1' && W == '0' then SEE LDRBT;
//if P == '0' && W == '0' then UNDEFINED;
//if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE;
+ if (Rt == '1111'); call DefineAsReturn(1)
}
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index f85fc91..8895740 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -89,3 +89,192 @@ void post_process_branch_instructions(GArchInstruction *instr, GProcContext *con
}
}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = accès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void post_process_branch_and_link_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t addr; /* Adresse visée par le saut */
+ GArchOperand *new; /* Instruction de ciblage */
+ vmpa2t target;
+ mrange_t trange;
+ VMPA_BUFFER(loc);
+ char name[5 + VMPA_MAX_LEN];
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ op = g_arch_instruction_get_operand(instr, 0);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+ {
+ new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
+
+ if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+ {
+ init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
+ init_mrange(&trange, &target, 0);
+
+ vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
+ snprintf(name, sizeof(name), "sub_%s", loc + 2);
+
+ routine = g_binary_routine_new();
+ g_binary_routine_set_name(routine, strdup(name));
+ //routine = try_to_demangle_routine(name);
+
+ g_binary_routine_set_range(routine, &trange);
+
+ symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+
+
+ g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+
+ }
+
+ g_arch_instruction_replace_operand(instr, new, op);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = accès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void post_process_comp_and_branch_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t addr; /* Adresse visée par le saut */
+ GArchOperand *new; /* Instruction de ciblage */
+ vmpa2t target;
+ mrange_t trange;
+ VMPA_BUFFER(loc);
+ char name[5 + VMPA_MAX_LEN];
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ op = g_arch_instruction_get_operand(instr, 1);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+ {
+ new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
+
+ if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+ {
+ init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
+ init_mrange(&trange, &target, 0);
+
+ vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
+ snprintf(name, sizeof(name), "loc_%s", loc + 2);
+
+ routine = g_binary_routine_new();
+ g_binary_routine_set_name(routine, strdup(name));
+ //routine = try_to_demangle_routine(name);
+
+ g_binary_routine_set_range(routine, &trange);
+
+ symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+
+
+ g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+
+ }
+
+ g_arch_instruction_replace_operand(instr, new, op);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction ARMv7 à traiter. *
+* context = contexte associé à la phase de désassemblage. *
+* format = accès aux données du binaire d'origine. *
+* *
+* Description : Complète un désassemblage accompli pour une instruction. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void post_process_ldr_instructions(GArchInstruction *instr, GProcContext *context, GBinFormat *format)
+{
+ GArchOperand *op; /* Opérande numérique en place */
+ uint32_t addr; /* Adresse visée par le saut */
+ GArchOperand *new; /* Instruction de ciblage */
+ vmpa2t target;
+ mrange_t trange;
+ VMPA_BUFFER(loc);
+ char name[5 + VMPA_MAX_LEN];
+ GBinRoutine *routine; /* Nouvelle routine trouvée */
+ GBinSymbol *symbol; /* Nouveau symbole construit */
+
+ op = g_arch_instruction_get_operand(instr, 1);
+
+ if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr))
+ {
+ new = g_target_operand_new(MDS_32_BITS_UNSIGNED, addr);
+
+ if (!g_target_operand_resolve(G_TARGET_OPERAND(new), format))
+ {
+ init_vmpa(&target, VMPA_NO_PHYSICAL, addr);
+ init_mrange(&trange, &target, 0);
+
+ vmpa2_virt_to_string(&target, MDS_32_BITS, loc, NULL);
+ snprintf(name, sizeof(name), "loc_%s", loc + 2);
+
+ routine = g_binary_routine_new();
+ g_binary_routine_set_name(routine, strdup(name));
+ //routine = try_to_demangle_routine(name);
+
+ g_binary_routine_set_range(routine, &trange);
+
+ symbol = g_binary_symbol_new(STP_ROUTINE, NULL, ~0);
+ g_binary_symbol_attach_routine(symbol, routine);
+ g_binary_format_add_symbol(G_BIN_FORMAT(format), symbol);
+
+
+
+ g_target_operand_resolve(G_TARGET_OPERAND(new), format);
+
+ }
+
+ g_arch_instruction_replace_operand(instr, new, op);
+
+ }
+
+}
diff --git a/src/arch/arm/v7/post.h b/src/arch/arm/v7/post.h
index dec51b2..79dcaa8 100644
--- a/src/arch/arm/v7/post.h
+++ b/src/arch/arm/v7/post.h
@@ -33,6 +33,15 @@
/* Complète un désassemblage accompli pour une instruction. */
void post_process_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+/* Complète un désassemblage accompli pour une instruction. */
+void post_process_branch_and_link_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void post_process_comp_and_branch_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+
+/* Complète un désassemblage accompli pour une instruction. */
+void post_process_ldr_instructions(GArchInstruction *, GProcContext *, GBinFormat *);
+
#endif /* _ARCH_ARM_V7_POST_H */
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c
index d83c36d..3464214 100644
--- a/src/arch/arm/v7/processor.c
+++ b/src/arch/arm/v7/processor.c
@@ -231,8 +231,7 @@ static GArmV7Context *g_armv7_processor_get_context(const GArmV7Processor *proc)
* Remarques : - *
* *
******************************************************************************/
-#include "link.h"
-#include "post.h"
+
static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *proc, GArmV7Context *ctx, const bin_t *data, vmpa2t *pos, phys_t end)
{
GArchInstruction *result; /* Instruction à renvoyer */
@@ -297,11 +296,11 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr
if (result != NULL)
advance_vmpa(pos, diff);
-
+ /*
else
result = g_raw_instruction_new_array(data, MDS_32_BITS, 1, pos, end,
G_ARCH_PROCESSOR(proc)->endianness);
-
+ */
return result;
}