diff options
Diffstat (limited to 'src/arch/arm/v7/link.c')
-rw-r--r-- | src/arch/arm/v7/link.c | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c index c1f83ac..da5e30e 100644 --- a/src/arch/arm/v7/link.c +++ b/src/arch/arm/v7/link.c @@ -28,6 +28,9 @@ #include <operands/offset.h> +#include "../register.h" + + /****************************************************************************** * * @@ -56,7 +59,25 @@ void handle_links_with_instruction_b_with_orig(GArchInstruction *instr, GArmV7Co pc = get_virt_addr(get_mrange_addr(range)); - pc += get_mrange_length(range); + + + + switch (iset) + { + case AV7IS_ARM: + pc += 8; + break; + case AV7IS_THUMB: + pc += 4; + break; + default: + assert(0); + break; + } + + + + //pc += get_mrange_length(range); op = g_arch_instruction_get_operand(instr, 0); @@ -197,6 +218,68 @@ void handle_links_with_instruction_blx_with_dest(GArchInstruction *instr, GArmV7 * 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_bx_with_orig(GArchInstruction *instr, GArmV7Context *context, GBinFormat *format, ArmV7InstrSet iset) +{ + GArchOperand *op; /* Opérande numérique en place */ + GArmRegister *reg; /* Registre matériel manipulé */ + const mrange_t *range; /* Emplacementt d'instruction */ + virt_t pc; /* Position dans l'exécution */ + + op = g_arch_instruction_get_operand(instr, 0); + assert(G_IS_REGISTER_OPERAND(op)); + + reg = G_ARM_REGISTER(g_register_operand_get_register(G_REGISTER_OPERAND(op))); + + /** + * On ne sait agir qu'avec le seul contenu facilement prédictible : pc ! + */ + + if (g_arm_register_get_index(reg) != 15 /* pc */) + return; + + /** + * On bascule alors le mode de décodage à cette adresse... + */ + + range = g_arch_instruction_get_range(instr); + + pc = get_virt_addr(get_mrange_addr(range)); + + switch (iset) + { + case AV7IS_ARM: + pc += 8; + //g_armv7_context_define_encoding(context, + g_armv7_context_push_drop_point_ext(context, pc, AV7IS_THUMB); + break; + case AV7IS_THUMB: + pc += 4; + //g_armv7_context_define_encoding(context, + g_armv7_context_push_drop_point_ext(context, pc, AV7IS_ARM); + break; + default: + assert(0); + break; + } + +} + + +/****************************************************************************** +* * +* 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. * * * @@ -342,6 +425,11 @@ void handle_links_with_instruction_ldr_literal_with_orig(GArchInstruction *instr //g_imm_operand_set_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, target); + + if (target < 0x8000) return; + + + new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target); g_arch_instruction_replace_operand(instr, new, op); |