diff options
Diffstat (limited to 'src/arch/arm/v7/arm.c')
-rw-r--r-- | src/arch/arm/v7/arm.c | 121 |
1 files changed, 119 insertions, 2 deletions
diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c index 5295ef8..b7d4ff1 100644 --- a/src/arch/arm/v7/arm.c +++ b/src/arch/arm/v7/arm.c @@ -39,6 +39,8 @@ static GArchInstruction *process_armv7_data_processing_and_miscellaneous_instruc /* Désassemble une instruction ARMv7 de données de registre. */ static GArchInstruction *process_armv7_data_processing_register(uint32_t); +/* Désassemble une instruction ARMv7 de données ou autre. */ +static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_transfer(uint32_t); @@ -47,7 +49,7 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t); #define process_armv7_load_store_word_and_unsigned_byte(raw) NULL #define process_armv7_load_store_word_and_unsigned_byte(raw) NULL #define process_armv7_media_instructions(raw) NULL -#define process_armv7_branch_branch_with_link_and_block_data_transfer(raw) NULL +//#define process_armv7_branch_branch_with_link_and_block_data_transfer(raw) NULL #define process_armv7_coprocessor_instructions_and_Supervisor_call(raw) NULL #define process_armv7_unconditional_instructions(raw) NULL @@ -93,6 +95,26 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t); #define armv7_read_instr_mvn_register(raw) NULL +// process_armv7_branch_branch_with_link_and_block_data_transfer + +#define armv7_read_instr_stmda_stmed(raw) NULL +#define armv7_read_instr_ldmda_ldmfa(raw) NULL +#define armv7_read_instr_stm_stmia_stmea(raw) NULL +#define armv7_read_instr_ldm_ldmia_ldmfd_arm(raw) NULL +#define armv7_read_instr_ldm_ldmia_ldmfd_arm(raw) NULL +#define armv7_read_instr_pop_arm(raw) NULL +#define armv7_read_instr_stmdb_stmfd(raw) NULL +#define armv7_read_instr_stmdb_stmfd(raw) NULL +#define armv7_read_instr_push(raw) NULL +#define armv7_read_instr_ldmdb_ldmea(raw) NULL +#define armv7_read_instr_stmib_stmfa(raw) NULL +#define armv7_read_instr_ldmib_ldmed(raw) NULL +#define armv7_read_instr_stm_user_registers(raw) NULL +#define armv7_read_instr_ldm_user_registers(raw) NULL +#define armv7_read_instr_ldm_exception_return(raw) NULL +#define armv7_read_instr_b(raw) NULL +//#define armv7_read_instr_bl_blx_immediate(raw) NULL + @@ -127,7 +149,6 @@ GArchInstruction *process_armv7_instruction_set_encoding(uint32_t raw) op1 = (raw >> 25) & 0x7; op = (raw >> 4) & 0x1; - if (cond != b1111) { if ((op1 & b110) == b000) @@ -403,3 +424,99 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t raw) + + + + + + +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 de données ou autre. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_transfer(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t op; /* Champ 'op' à retrouver */ + uint32_t rn; /* Champ 'rn' à retrouver */ + uint32_t r; /* Champ 'r' à retrouver */ + + /** + * Suit les directives de : + * § A5.5 Branch, branch with link, and block data transferr + */ + + result = NULL; + + op = (raw >> 20) & 0x3f; + rn = (raw >> 16) & 0xf; + r = (raw >> 15) & 0x1; + + if ((op & b111101) == b000000) + result = armv7_read_instr_stmda_stmed(raw); + + else if ((op & b111101) == b000001) + result = armv7_read_instr_ldmda_ldmfa(raw); + + else if ((op & b111101) == b001000) + result = armv7_read_instr_stm_stmia_stmea(raw); + + else if (op == b001001) + result = armv7_read_instr_ldm_ldmia_ldmfd_arm(raw); + + else if (op == b001011) + { + if (rn != b1101) + result = armv7_read_instr_ldm_ldmia_ldmfd_arm(raw); + else /* if (rn == b1101) */ + result = armv7_read_instr_pop_arm(raw); + } + + else if (op == b010000) + result = armv7_read_instr_stmdb_stmfd(raw); + + else if (op == b010010) + { + if (rn != b1101) + result = armv7_read_instr_stmdb_stmfd(raw); + else /* if (rn == b1101) */ + result = armv7_read_instr_push(raw); + } + + else if ((op & b111101) == b010001) + result = armv7_read_instr_ldmdb_ldmea(raw); + + else if ((op & b111101) == b011000) + result = armv7_read_instr_stmib_stmfa(raw); + + else if ((op & b111101) == b011001) + result = armv7_read_instr_ldmib_ldmed(raw); + + else if ((op & b100101) == b000100) + result = armv7_read_instr_stm_user_registers(raw); + + else if ((op & b100101) == b000101) + { + if (r == b0) + result = armv7_read_instr_ldm_user_registers(raw); + else /* if (r == b1) */ + result = armv7_read_instr_ldm_exception_return(raw); + } + + else if ((op & b110000) == b100000) + result = armv7_read_instr_b(raw); + + else if ((op & b110000) == b110000) + result = armv7_read_instr_bl_blx_immediate(raw); + + return result; + +} |