diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-11-24 06:49:23 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-11-24 06:49:23 (GMT) |
commit | 96eee784837e6ed4cf9ce5f1cb2e0f8bff8bd9bf (patch) | |
tree | c7fd1108066e6359766bc18f8883b67b2b7f082f /src/arch/arm/v7 | |
parent | 2d833afa673b63a1a61e22ea2cdde59ed60b5ad1 (diff) |
Update the list of handled ARM instructions
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@423 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/arm/v7')
33 files changed, 2773 insertions, 9 deletions
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am index 3fe1394..f4b1fc9 100644 --- a/src/arch/arm/v7/Makefile.am +++ b/src/arch/arm/v7/Makefile.am @@ -6,6 +6,7 @@ libarcharmv7_la_SOURCES = \ helpers.h helpers.c \ instruction.h instruction.c \ processor.h processor.c \ + pseudo.h pseudo.c \ register.h register.c libarcharmv7_la_LIBADD = \ diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c index b7d4ff1..fb1dc3f 100644 --- a/src/arch/arm/v7/arm.c +++ b/src/arch/arm/v7/arm.c @@ -39,6 +39,12 @@ 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 de immédiate. */ +static GArchInstruction *process_armv7_data_processing_immediate(uint32_t); + +/* Désassemble une instruction ARMv7 liées aux multiplications. */ +static GArchInstruction *process_armv7_multiply_and_multiply_accumulate(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); @@ -60,11 +66,11 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr #define process_armv7_extra_load_store_instructions(raw) NULL #define process_armv7_miscellaneous_instructions(raw) NULL #define process_armv7_halfword_multiply_and_multiply_accumulate(raw) NULL -#define process_armv7_multiply_and_multiply_accumulate(raw) NULL +//#define process_armv7_multiply_and_multiply_accumulate(raw) NULL #define process_armv7_synchronization_primitives(raw) NULL #define process_armv7_extra_load_store_instructions_unprivileged(raw) NULL #define process_armv7_extra_load_store_instructions(raw) NULL -#define process_armv7_data_processing_immediate(raw) NULL +//#define process_armv7_data_processing_immediate(raw) NULL #define armv7_read_instr_mov_immediate(raw) NULL #define armv7_read_instr_movt(raw) NULL #define process_armv7_msr_immediate_and_hints(raw) NULL @@ -76,7 +82,7 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr #define armv7_read_instr_eor_register(raw) NULL #define armv7_read_instr_sub_register(raw) NULL #define armv7_read_instr_rsb_register(raw) NULL -#define armv7_read_instr_add_register(raw) NULL +#define armv7_read_instr_add_register_arm(raw) NULL #define armv7_read_instr_adc_register(raw) NULL #define armv7_read_instr_sbc_register(raw) NULL #define armv7_read_instr_rsc_register(raw) NULL @@ -117,6 +123,16 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr +#define armv7_read_instr_adr(raw) NULL + + + +// ??? +#define armv7_read_instr_yield(raw) NULL +#define armv7_read_instr_bx(raw) NULL + + + /****************************************************************************** @@ -349,7 +365,7 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t raw) result = armv7_read_instr_rsb_register(raw); else if ((op & b11110) == b01000) - result = armv7_read_instr_add_register(raw); + result = armv7_read_instr_add_register_arm(raw); else if ((op & b11110) == b01010) result = armv7_read_instr_adc_register(raw); @@ -427,6 +443,183 @@ 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 de immédiate. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_data_processing_immediate(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t op; /* Champ 'op' à retrouver */ + uint32_t rn; /* Champ 'rn' à retrouver */ + + /** + * Suit les directives de : + * § A5.2.3 Data-processing (immediate) + */ + + result = NULL; + + op = (raw >> 20) & 0x1f; + rn = (raw >> 16) & 0xf; + + if ((op & b11110) == b00000) + result = armv7_read_instr_and_immediate(raw); + + else if ((op & b11110) == b00010) + result = armv7_read_instr_eor_immediate(raw); + + else if ((op & b11110) == b00100) + { + if (rn == b1111) + result = armv7_read_instr_adr(raw); + + else + result = armv7_read_instr_sub_immediate_arm(raw); + + } + + else if ((op & b11110) == b00110) + result = armv7_read_instr_rsb_immediate(raw); + + else if ((op & b11110) == b01000) + { + if (rn == b1111) + result = armv7_read_instr_adr(raw); + + else + result = armv7_read_instr_add_immediate_arm(raw); + + } + + else if ((op & b11110) == b01010) + result = armv7_read_instr_adc_immediate(raw); + + else if ((op & b11110) == b01100) + result = armv7_read_instr_sbc_immediate(raw); + + else if ((op & b11110) == b01110) + result = armv7_read_instr_rsc_immediate(raw); + + /* + else if ((op & b11110) == b10000) + result = process_armv7_data_processing_and_miscellaneous_instructions(raw); + */ + + else if (op == b10001) + result = armv7_read_instr_tst_immediate(raw); + + else if (op == b10011) + result = armv7_read_instr_teq_immediate(raw); + + else if (op == b10101) + result = armv7_read_instr_cmp_immediate(raw); + + else if (op == b10111) + result = armv7_read_instr_cmn_immediate(raw); + + else if ((op & b11110) == b11000) + result = armv7_read_instr_orr_immediate(raw); + + else if ((op & b11110) == b11010) + result = armv7_read_instr_mov_immediate(raw); + + else if ((op & b11110) == b11100) + result = armv7_read_instr_bic_immediate(raw); + + else if ((op & b11110) == b11110) + result = armv7_read_instr_mvn_immediate(raw); + + return result; + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 liées aux multiplications. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_multiply_and_multiply_accumulate(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t op; /* Champ 'op' à retrouver */ + + /** + * Suit les directives de : + * § A5.2.5 Multiply and multiply accumulate + */ + + result = NULL; + + if ((raw & 0x0f0000f0) == 0x00000090) + return NULL; + + op = (raw >> 20) & 0x1f; + + if ((op & b1110) == b0000) + result = armv7_read_instr_mul(raw); + + else if ((op & b1110) == b0010) + result = armv7_read_instr_mla(raw); + + else if (op == b0100) + result = armv7_read_instr_umaal(raw); + + else if (op == b0101) + result = NULL; /* Non défini */ + + else if (op == b0110) + result = armv7_read_instr_mls(raw); + + else if (op == b0111) + result = NULL; /* Non défini */ + + else if ((op & b1110) == b1000) + result = armv7_read_instr_umull(raw); + + else if ((op & b1110) == b1010) + result = armv7_read_instr_umlal(raw); + + else if ((op & b1110) == b1100) + result = armv7_read_instr_smull(raw); + + else if ((op & b1110) == b1110) + result = armv7_read_instr_smlal(raw); + + return result; + +} + + + + + diff --git a/src/arch/arm/v7/helpers.c b/src/arch/arm/v7/helpers.c index e7c9ad8..8acfeb5 100644 --- a/src/arch/arm/v7/helpers.c +++ b/src/arch/arm/v7/helpers.c @@ -28,6 +28,83 @@ #include "../../register.h" #include "../../immediate.h" #include "../../../common/asm.h" +#include "../../../common/bconst.h" + + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* shift = nombre de décallages visés. * +* * +* Description : Effectue une rotation vers la droit d'une valeur. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : Correspond à la pseudo fonction 'ROR_C'. * +* * +******************************************************************************/ + +GArchOperand *ror_armv7_imm(uint32_t x, unsigned int shift) +{ + GArchOperand *result; /* Opérande à faire remonter */ + uint32_t val32; /* Valeur sur 32 bits */ + + shift %= 32; + + val32 = (x >> shift) | (x << (32 - shift)); + + result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32); + + return result; + +} + + + + + + + + + + + + +#if 0 + +// Shift_C() +// ========= +(bits(N), bit) Shift_C(bits(N) value, SRType type, integer amount, bit carry_in) +assert !(type == SRType_RRX && amount != 1); +if amount == 0 then +(result, carry_out) = (value, carry_in); +else +case type of + +when SRType_LSL +(result, carry_out) = LSL_C(value, amount); + +when SRType_LSR +(result, carry_out) + +when SRType_ASR +(result, carry_out) + +when SRType_ROR +(result, carry_out) + +when SRType_RRX +(result, carry_out) += LSR_C(value, amount); += ASR_C(value, amount); += ROR_C(value, amount); += RRX_C(value, carry_in); + +#endif + + + @@ -87,6 +164,73 @@ GArchOperand *sign_extend_armv7_imm(uint32_t value, bool topbit, unsigned int si /****************************************************************************** * * +* Paramètres : value = valeur sur 32 bits maximum à traiter. * +* * +* Description : Etend une valeur immédiate en mode 'Thumb' ARMv7. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *thumb_expand_armv7_imm(uint32_t value) +{ + GArchOperand *result; /* Opérande à faire remonter */ + uint8_t byte; /* Octet à reproduire */ + uint32_t val32; /* Valeur sur 32 bits */ + uint32_t unrotated; /* Transformation à décaller */ + + result = NULL; + + if (((value >> 10) & b11) == b00) + { + byte = value & 0xff; + + switch ((value >> 8) & b11) + { + case b00: + result = zero_extend_armv7_imm(byte, 32); + break; + + case b01: + if (byte == 0) return NULL; + val32 = byte << 16 | byte; + result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32); + break; + + case b10: + if (byte == 0) return NULL; + val32 = byte << 24 | byte << 8; + result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32); + break; + + case b11: + if (byte == 0) return NULL; + val32 = byte << 24 | byte << 16 | byte << 8 | byte; + result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32); + break; + + } + + } + else + { + unrotated = 1 << 7 | (value & 0x3f); + result = ror_armv7_imm(unrotated, (value >> 7) & 0x1f); + } + + return result; + +} + + + + + + +/****************************************************************************** +* * * Paramètres : index = indice du registre correspondant. * * * * Description : Crée un opérande représentant un registre ARMv7. * @@ -112,3 +256,49 @@ GArchOperand *translate_armv7_register(uint8_t index) return result; } + + +/****************************************************************************** +* * +* Paramètres : value = valeur sur 32 bits maximum à traiter. * +* size = taille de la valeur finale à constituer. * +* * +* Description : Réalise un simple transtypage de valeur entière. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : Correspond à la pseudo fonction 'ZeroExtend'. * +* * +******************************************************************************/ + +GArchOperand *zero_extend_armv7_imm(uint32_t value, unsigned int size) +{ + GArchOperand *result; /* Opérande à faire remonter */ + MemoryDataSize mds; /* Conversion de la taille */ + uint32_t val4; /* Valeur sur 4 bits */ + uint32_t val8; /* Valeur sur 8 bits */ + uint32_t val16; /* Valeur sur 16 bits */ + uint32_t val32; /* Valeur sur 32 bits */ + + result = NULL; + + switch (size) + { + +#define ZERO_EXTEND_CASE(sz) \ + case sz: \ + mds = MDS_ ## sz ## _BITS_UNSIGNED; \ + val ## sz = value; \ + result = g_imm_operand_new_from_value(mds, val ## sz); \ + break; + + ZERO_EXTEND_CASE(4); + ZERO_EXTEND_CASE(8); + ZERO_EXTEND_CASE(16); + ZERO_EXTEND_CASE(32); + + } + + return result; + +} diff --git a/src/arch/arm/v7/helpers.h b/src/arch/arm/v7/helpers.h index 087b2e7..66a98f6 100644 --- a/src/arch/arm/v7/helpers.h +++ b/src/arch/arm/v7/helpers.h @@ -25,20 +25,73 @@ #define _ARCH_ARM_V7_HELPERS_H -#include <stdbool.h> -#include <stdint.h> +#include <libio.h> +#include "pseudo.h" #include "../../operand.h" + + +#define ARMExpandImm_C(imm12, c) \ + ({ \ + uint32_t __val; \ + __val = armv7_arm_expand_imm_c(imm12, (bool []) { c }); \ + g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __val); \ + }) + +#define ARMExpandImm(imm12) \ + ({ \ + uint32_t __val; \ + __val = armv7_arm_expand_imm_c(imm12, NULL); \ + g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __val); \ + }) + + + + + +#define ZeroExtend(x, n, i) \ + ({ \ + MemoryDataSize __mds; \ + uint ## i ## _t __val; \ + mds = MDS_ ## sz ## _BITS_UNSIGNED; \ + __val = armv7_zero_extend(x, n, i); \ + g_imm_operand_new_from_value(__mds, __val); \ + }) + + + +#define Zeros(i) \ + ({ \ + MemoryDataSize __mds; \ + uint ## i ## _t __val; \ + mds = MDS_ ## sz ## _BITS_UNSIGNED; \ + __val = 0; \ + g_imm_operand_new_from_value(__mds, __val); \ + }) + + + + + +/* Effectue une rotation vers la droit d'une valeur. */ +GArchOperand *ror_armv7_imm(uint32_t, unsigned int); + /* Crée un opérande de valeur immédiate avec extension de signe. */ GArchOperand *sign_extend_armv7_imm(uint32_t, bool, unsigned int); +/* Etend une valeur immédiate en mode 'Thumb' ARMv7. */ +GArchOperand *thumb_expand_armv7_imm(uint32_t); + /* Crée un opérande représentant un registre ARMv7. */ GArchOperand *translate_armv7_register(uint8_t); +/* Réalise un simple transtypage de valeur entière. */ +GArchOperand *zero_extend_armv7_imm(uint32_t, unsigned int); + #endif /* _ARCH_ARM_V7_HELPERS_H */ diff --git a/src/arch/arm/v7/opcodes/Makefile.am b/src/arch/arm/v7/opcodes/Makefile.am index dc5c8d9..06a9ddd 100644 --- a/src/arch/arm/v7/opcodes/Makefile.am +++ b/src/arch/arm/v7/opcodes/Makefile.am @@ -2,9 +2,34 @@ noinst_LTLIBRARIES = libarcharmv7opcodes.la libarcharmv7opcodes_la_SOURCES = \ - bl.c \ - mov.c \ - subs.c + adc.c \ + add.c \ + and.c \ + bic.c \ + bl.c \ + bx.c \ + cmn.c \ + cmp.c \ + eor.c \ + mla.c \ + mls.c \ + mov.c \ + mul.c \ + mvn.c \ + orr.c \ + rsb.c \ + rsc.c \ + sbc.c \ + smlal.c \ + smull.c \ + sub.c \ + subs.c \ + teq.c \ + tst.c \ + umaal.c \ + umlal.c \ + umull.c \ + yield.c libarcharmv7opcodes_la_LIBADD = diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index d576782..629cf1a 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -21,8 +21,33 @@ D2C_MACROS = \ -M SignExtend=sign_extend_armv7_imm ARMV7_DEFS = \ + adc_A881.d \ + add_A885.d \ + and_A8813.d \ + bic_A8821.d \ bl_A8825.d \ + bx_A8827.d \ + cmn_A8834.d \ + cmp_A8837.d \ + eor_A8846.d \ + mla_A88100.d \ + mls_A88101.d \ mov_A88104.d \ + mul_A88114.d \ + mvn_A88115.d \ + orr_A88122.d \ + rsb_A88152.d \ + rsc_A88155.d \ + sbc_A88161.d \ + smlal_A88178.d \ + smull_A88189.d \ + sub_A88222.d \ + teq_A88237.d \ + tst_A88240.d \ + umaal_A88255.d \ + umlal_A88256.d \ + umull_A88257.d \ + yield_A88426.d \ subs_B9320.d diff --git a/src/arch/arm/v7/opdefs/adc_A881.d b/src/arch/arm/v7/opdefs/adc_A881.d new file mode 100644 index 0000000..ff37ea0 --- /dev/null +++ b/src/arch/arm/v7/opdefs/adc_A881.d @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title ADC (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 1 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm(i:imm3:imm8) + + } + + @rules { + + //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 0 1 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/add_A885.d b/src/arch/arm/v7/opdefs/add_A885.d new file mode 100644 index 0000000..bacddc8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A885.d @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title ADD (immediate, ARM) + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 0 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rn == '1111') && (S == '0')) ; see ADR + //if (Rn == '1101') ; see ADD (SP plus immediate) + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + + } + +} diff --git a/src/arch/arm/v7/opdefs/and_A8813.d b/src/arch/arm/v7/opdefs/and_A8813.d new file mode 100644 index 0000000..f0a1740 --- /dev/null +++ b/src/arch/arm/v7/opdefs/and_A8813.d @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title AND (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see TST (immediate) + //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 0 0 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/bic_A8821.d b/src/arch/arm/v7/opdefs/bic_A8821.d new file mode 100644 index 0000000..6f5bd46 --- /dev/null +++ b/src/arch/arm/v7/opdefs/bic_A8821.d @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title BIC (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 1 1 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d new file mode 100644 index 0000000..5acf969 --- /dev/null +++ b/src/arch/arm/v7/opdefs/bx_A8827.d @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title BX + +@encoding(T1) { + + + @half 0 1 0 0 0 1 1 1 0 Rm(4) 0 0 0 + + @syntax <Rm> + + @conv { + + Rm = Register(Rm) + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 Rm(4) + + @syntax {c} <Rm> + + @conv { + + c = Condition(cond) + Rm = Register(Rm) + + } + +} diff --git a/src/arch/arm/v7/opdefs/cmn_A8834.d b/src/arch/arm/v7/opdefs/cmn_A8834.d new file mode 100644 index 0000000..ff403f3 --- /dev/null +++ b/src/arch/arm/v7/opdefs/cmn_A8834.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title CMN (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 1 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) + + @syntax <Rn> <const> + + @conv { + + Rn = Register(Rn) + const = ThumbExpandImm(i:imm3:imm8) + + } + + @rules { + + if (Rn == '1111') ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 0 1 1 1 Rn(4) 0 0 0 0 imm12(12) + + @syntax {c} <Rn> <const> + + @conv { + + c = Condition(cond) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + +} diff --git a/src/arch/arm/v7/opdefs/cmp_A8837.d b/src/arch/arm/v7/opdefs/cmp_A8837.d new file mode 100644 index 0000000..24587df --- /dev/null +++ b/src/arch/arm/v7/opdefs/cmp_A8837.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title CMP (immediate) + +@encoding(T1) { + + @half 0 0 1 0 1 Rn(3) imm8(8) + + @syntax <Rn> <const> + + @conv { + + Rn = Register(Rn) + const = ZeroExtend(imm8, 8, 32) + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 0 i(1) 0 1 1 0 1 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) + + @syntax <Rn> <const> + + @conv { + + Rn = Register(Rn) + const = ThumbExpandImm(i:imm3:imm8) + + } + + @rules { + + if (Rn == '1111') ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 0 1 0 1 Rn(4) 0 0 0 0 imm12(12) + + @syntax {c} <Rn> <const> + + @conv { + + c = Condition(cond) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + +} diff --git a/src/arch/arm/v7/opdefs/eor_A8846.d b/src/arch/arm/v7/opdefs/eor_A8846.d new file mode 100644 index 0000000..2c71098 --- /dev/null +++ b/src/arch/arm/v7/opdefs/eor_A8846.d @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title EOR (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 1 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see TST (immediate) + //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 0 0 1 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/mla_A88100.d b/src/arch/arm/v7/opdefs/mla_A88100.d new file mode 100644 index 0000000..2683e3a --- /dev/null +++ b/src/arch/arm/v7/opdefs/mla_A88100.d @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title MLA + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 0 Rm(4) + + @syntax <Rd> <Rn> <Rm> <Ra> + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + Ra = Register(Ra) + + } + + @rules { + + //if (Ra == '1111') ; see MUL + //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 0 0 1 S(1) Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <Rd> <Rn> <Rm> <Ra> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + Ra = Register(Ra) + + } + + @rules { + + //if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE + + } + +} diff --git a/src/arch/arm/v7/opdefs/mls_A88101.d b/src/arch/arm/v7/opdefs/mls_A88101.d new file mode 100644 index 0000000..3d55f00 --- /dev/null +++ b/src/arch/arm/v7/opdefs/mls_A88101.d @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title MLS + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 1 Rm(4) + + @syntax <Rd> <Rn> <Rm> <Ra> + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + Ra = Register(Ra) + + } + + @rules { + + //if d IN {13,15} || n IN {13,15} || m IN {13,15} || a IN {13,15} then UNPREDICTABLE + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 0 1 1 0 Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {c} <Rd> <Rn> <Rm> <Ra> + + @conv { + + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + Ra = Register(Ra) + + } + + @rules { + + //if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/mul_A88114.d b/src/arch/arm/v7/opdefs/mul_A88114.d new file mode 100644 index 0000000..ca75e25 --- /dev/null +++ b/src/arch/arm/v7/opdefs/mul_A88114.d @@ -0,0 +1,85 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title MUL + +@encoding(T1) { + + @half 0 1 0 0 0 0 1 1 0 1 Rn(3) Rdm(3) + + @syntax <Rdm> <Rn> <Rdm> + + @conv { + + Rdm = Register(Rdm) + Rn = Register(Rn) + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <Rd> <Rn> <Rm> + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 0 0 0 S(1) Rd(4) 0 0 0 0 Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <Rd> <Rn> <Rm> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/mvn_A88115.d b/src/arch/arm/v7/opdefs/mvn_A88115.d new file mode 100644 index 0000000..32e96b3 --- /dev/null +++ b/src/arch/arm/v7/opdefs/mvn_A88115.d @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title MVN (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 1 1 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if (d IN {13,15}) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 1 1 1 S(1) 0 0 0 0 Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + const = ARMExpandImm_C(imm12, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/orr_A88122.d b/src/arch/arm/v7/opdefs/orr_A88122.d new file mode 100644 index 0000000..937c902 --- /dev/null +++ b/src/arch/arm/v7/opdefs/orr_A88122.d @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title ORR (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + if (Rn == '1111') ; see MOV (immediate) + //if ((d IN {13,15}) || (n == 13)) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 1 0 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/rsb_A88152.d b/src/arch/arm/v7/opdefs/rsb_A88152.d new file mode 100644 index 0000000..320d62e --- /dev/null +++ b/src/arch/arm/v7/opdefs/rsb_A88152.d @@ -0,0 +1,87 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title RSB (immediate) + +@encoding(T1) { + + @half 0 1 0 0 0 0 1 0 0 1 Rn(3) Rd(3) + + @syntax <Rd> <Rn> <zero> + + @conv { + + Rd = Register(Rd) + Rn = Register(Rn) + zero = Zeros(32) + + } + +} + +@encoding(T2) { + + @word 1 1 1 1 0 i(1) 0 1 1 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm(i:imm3:imm8) + + } + + @rules { + + //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 0 1 1 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/rsc_A88155.d b/src/arch/arm/v7/opdefs/rsc_A88155.d new file mode 100644 index 0000000..440f224 --- /dev/null +++ b/src/arch/arm/v7/opdefs/rsc_A88155.d @@ -0,0 +1,48 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title RSC (immediate) + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 1 1 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/sbc_A88161.d b/src/arch/arm/v7/opdefs/sbc_A88161.d new file mode 100644 index 0000000..517ea01 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sbc_A88161.d @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title SBC (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 1 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax {S} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + Rd = Register(Rd) + Rn = Register(Rn) + const = ThumbExpandImm(i:imm3:imm8) + + } + + @rules { + + //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 0 1 1 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + } + +} diff --git a/src/arch/arm/v7/opdefs/smlal_A88178.d b/src/arch/arm/v7/opdefs/smlal_A88178.d new file mode 100644 index 0000000..a3a36aa --- /dev/null +++ b/src/arch/arm/v7/opdefs/smlal_A88178.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title SMLAL + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 1 1 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) + + @syntax <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 1 1 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/smull_A88189.d b/src/arch/arm/v7/opdefs/smull_A88189.d new file mode 100644 index 0000000..15fc195 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smull_A88189.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title SMULL + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 1 0 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) + + @syntax <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 1 1 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/sub_A88222.d b/src/arch/arm/v7/opdefs/sub_A88222.d new file mode 100644 index 0000000..5564a07 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sub_A88222.d @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title SUB (immediate, ARM) + +@encoding(A1) { + + @word cond(4) 0 0 1 0 0 1 0 S(1) Rn(4) Rd(4) imm12(12) + + @syntax {S} {c} <Rd> <Rn> <const> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + Rd = Register(Rd) + Rn = Register(Rn) + const = ARMExpandImm(imm12) + + } + + @rules { + + //if ((Rn == '1111') && (S == '0')) ; see ADR + //if (Rn == '1101') ; see SUB (SP minus immediate) + //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + + + } + +} diff --git a/src/arch/arm/v7/opdefs/teq_A88237.d b/src/arch/arm/v7/opdefs/teq_A88237.d new file mode 100644 index 0000000..96ac2cb --- /dev/null +++ b/src/arch/arm/v7/opdefs/teq_A88237.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title TEQ (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 1 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) + + @syntax <Rn> <const> + + @conv { + + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if (n IN {13,15}) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 0 0 1 1 Rn(4) 0 0 0 0 imm12(12) + + @syntax {c} <Rn> <const> + + @conv { + + c = Condition(cond) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + +} diff --git a/src/arch/arm/v7/opdefs/tst_A88240.d b/src/arch/arm/v7/opdefs/tst_A88240.d new file mode 100644 index 0000000..9d4a8f9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/tst_A88240.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title TST (immediate) + +@encoding(T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) + + @syntax <Rn> <const> + + @conv { + + Rn = Register(Rn) + const = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + //if (n IN {13,15}) ; unpredictable + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 0 0 0 1 Rn(4) 0 0 0 0 imm12(12) + + @syntax {c} <Rn> <const> + + @conv { + + c = Condition(cond) + Rn = Register(Rn) + const = ARMExpandImm_C(imm12, 0) + + } + +} diff --git a/src/arch/arm/v7/opdefs/umaal_A88255.d b/src/arch/arm/v7/opdefs/umaal_A88255.d new file mode 100644 index 0000000..404f56f --- /dev/null +++ b/src/arch/arm/v7/opdefs/umaal_A88255.d @@ -0,0 +1,73 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title UMAAL + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 1 1 0 Rm(4) + + @syntax <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 0 1 0 0 RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {c} <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + c = Condition(cond) + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/umlal_A88256.d b/src/arch/arm/v7/opdefs/umlal_A88256.d new file mode 100644 index 0000000..fc17078 --- /dev/null +++ b/src/arch/arm/v7/opdefs/umlal_A88256.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title UMLAL + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) + + @syntax <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 1 0 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/umull_A88257.d b/src/arch/arm/v7/opdefs/umull_A88257.d new file mode 100644 index 0000000..ffed80b --- /dev/null +++ b/src/arch/arm/v7/opdefs/umull_A88257.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title UMULL + +@encoding(T1) { + + @word 1 1 1 1 1 0 1 1 1 0 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) + + @syntax <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} + +@encoding(A1) { + + @word cond(4) 0 0 0 0 1 0 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + + @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + + @conv { + + S = SetFlags(S) + c = Condition(cond) + RdLo = Register(RdLo) + RdHi = Register(RdHi) + Rn = Register(Rn) + Rm = Register(Rm) + + } + + @rules { + + //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; + //if dHi == dLo then UNPREDICTABLE; + + } + +} diff --git a/src/arch/arm/v7/opdefs/yield_A88426.d b/src/arch/arm/v7/opdefs/yield_A88426.d new file mode 100644 index 0000000..6de27d1 --- /dev/null +++ b/src/arch/arm/v7/opdefs/yield_A88426.d @@ -0,0 +1,50 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 <http://www.gnu.org/licenses/>. + */ + + +@title YIELD + +@encoding(T1) { + + @half 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 0 + +} + +@encoding(T2) { + + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 + +} + +@encoding(A1) { + + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 + + @syntax {c} + + @conv { + + c = Condition(cond) + + } + +} diff --git a/src/arch/arm/v7/pseudo.c b/src/arch/arm/v7/pseudo.c new file mode 100644 index 0000000..4736309 --- /dev/null +++ b/src/arch/arm/v7/pseudo.c @@ -0,0 +1,464 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pseudo.c - implémentation des pseudo-fonctions de spécification + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#include "pseudo.h" + + +#include <assert.h> +#include <libio.h> + + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* carry = retenue enventuelle à constituer. [OUT] * +* * +* Description : Traduit la fonction 'LSL_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_lsl_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +{ + assert(n <= 32); + assert(shift > 0); + + if (carry != NULL) + *carry = x & (1 << (n - 1)); + + return x << shift; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* * +* Description : Traduit la fonction 'LSL'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_lsl(uint32_t x, unsigned int n, unsigned int shift) +{ + uint32_t result; /* Valeur finale à retourner */ + + if (shift == 0) + result = x; + + else + result = armv7_lsl_c(x, n, shift, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* carry = retenue enventuelle à constituer. [OUT] * +* * +* Description : Traduit la fonction 'LSR_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_lsr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +{ + assert(n <= 32); + assert(shift > 0); + + if (carry != NULL) + *carry = x & (1 << (shift - 1)); + + return x >> shift; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* * +* Description : Traduit la fonction 'LSR'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_lsr(uint32_t x, unsigned int n, unsigned int shift) +{ + uint32_t result; /* Valeur finale à retourner */ + + if (shift == 0) + result = x; + + else + result = armv7_lsr_c(x, n, shift, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* carry = retenue enventuelle à constituer. [OUT] * +* * +* Description : Traduit la fonction 'ASR_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_asr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +{ + assert(n <= 32); + assert(shift > 0); + + if (carry != NULL) + *carry = x & (1 << (shift - 1)); + + return ((int32_t)x) >> shift; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* * +* Description : Traduit la fonction 'ASR'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_asr(uint32_t x, unsigned int n, unsigned int shift) +{ + uint32_t result; /* Valeur finale à retourner */ + + if (shift == 0) + result = x; + + else + result = armv7_asr_c(x, n, shift, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* carry = retenue enventuelle à constituer. [OUT] * +* * +* Description : Traduit la fonction 'ROR_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_ror_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +{ + uint32_t result; /* Valeur finale à retourner */ + + assert(n <= 32); + assert(shift > 0); + + result = (x >> shift) | (x << (32 - shift)); + + if (carry != NULL) + *carry = result & (1 << (n - 1)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* shift = nombre de décallages visés. * +* * +* Description : Traduit la fonction 'ROR'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_ror(uint32_t x, unsigned int n, unsigned int shift) +{ + uint32_t result; /* Valeur finale à retourner */ + + if (shift == 0) + result = x; + + else + result = armv7_ror_c(x, n, shift, NULL); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* carry = retenue enventuelle à utiliser puis constituer. [OUT]* +* * +* Description : Traduit la fonction 'RRX_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_rrx_c(uint32_t x, unsigned int n, bool *carry) +{ + uint32_t result; /* Valeur finale à retourner */ + bool new_c; /* Nouvelle retenue à retenir */ + + assert(carry != NULL); + + new_c = x & 0x1; + + result = (*carry ? 1 : 0) << (n - 1) | x >> 1; + + *carry = new_c; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* carry = retenue enventuelle à utiliser. * +* * +* Description : Traduit la fonction 'RRX'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_rrx(uint32_t x, unsigned int n, bool carry) +{ + return armv7_rrx_c(x, n, &carry); + +} + + +/****************************************************************************** +* * +* Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * +* carry = retenue enventuelle à utiliser / constituer. [OUT] * +* * +* Description : Traduit la fonction 'ARMExpandImm_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_arm_expand_imm_c(uint32_t imm12, bool *carry) +{ + uint32_t result; /* Valeur finale à retourner */ + uint32_t unrotated; /* Transformation à décaller */ + + /** + * Selon les spécifications, x contient toujours 12 bits utiles seulement. + */ + + unrotated = armv7_zero_extend(imm12 & 0xff, 8, 32); + + result = armv7_shift(unrotated, 32, SRType_ROR, 2 * ((imm12 >> 8) & 0xf), carry); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * +* carry = retenue enventuelle à utiliser / constituer. [OUT] * +* * +* Description : Traduit la fonction 'ARMExpandImm'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_arm_expand_imm(uint32_t imm12) +{ + return armv7_arm_expand_imm_c(imm12, (bool []) { false /* FIXME : APSR.C */ }); + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* type = type d'opération à mener. * +* amount = quantité liée à l'opération à mener. * +* carry = retenue enventuelle à utiliser / constituer. [OUT] * +* * +* Description : Traduit la fonction 'Shift_C'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool *carry) +{ + uint32_t result; /* Valeur finale à retourner */ + + assert(!(type == SRType_RRX && amount != 1)); + + if (amount == 0) return x; + + result = 0; /* Pour GCC... */ + + switch (type) + { + case SRType_LSL: + result = armv7_lsl_c(x, n, amount, carry); + break; + + case SRType_LSR: + result = armv7_lsr_c(x, n, amount, carry); + break; + + case SRType_ASR: + result = armv7_asr_c(x, n, amount, carry); + break; + + case SRType_ROR: + result = armv7_ror_c(x, n, amount, carry); + break; + + case SRType_RRX: + result = armv7_rrx_c(x, n, carry); + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* type = type d'opération à mener. * +* amount = quantité liée à l'opération à mener. * +* carry = retenue enventuelle à utiliser. * +* * +* Description : Traduit la fonction 'Shift'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_shift(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool carry) +{ + return armv7_shift_c(x, n, type, amount, &carry); + +} + + +/****************************************************************************** +* * +* Paramètres : x = valeur sur 32 bits maximum à traiter. * +* n = nombre de bits à prendre en compte. * +* i = taille finale à obtenir. * +* * +* Description : Traduit la fonction 'ZeroExtend'. * +* * +* Retour : Nouvelle valeur calculée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t armv7_zero_extend(uint32_t x, unsigned int n, unsigned int i) +{ + return x; + +} diff --git a/src/arch/arm/v7/pseudo.h b/src/arch/arm/v7/pseudo.h new file mode 100644 index 0000000..e46c3fc --- /dev/null +++ b/src/arch/arm/v7/pseudo.h @@ -0,0 +1,117 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pseudo.h - prototypes pour l'implémentation des pseudo-fonctions de spécification + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_PSEUDO_H +#define _ARCH_ARM_V7_PSEUDO_H + + +#include <stdbool.h> +#include <stdint.h> + + + +/** + * § A2.2.1 - Integer arithmetic + */ + + +/* Traduit la fonction 'LSL_C'. */ +uint32_t armv7_lsl_c(uint32_t, unsigned int, unsigned int, bool *); + +/* Traduit la fonction 'LSL'. */ +uint32_t armv7_lsl(uint32_t, unsigned int, unsigned int); + +/* Traduit la fonction 'LSR_C'. */ +uint32_t armv7_lsr_c(uint32_t, unsigned int, unsigned int, bool *); + +/* Traduit la fonction 'LSR'. */ +uint32_t armv7_lsr(uint32_t, unsigned int, unsigned int); + +/* Traduit la fonction 'ASR_C'. */ +uint32_t armv7_asr_c(uint32_t, unsigned int, unsigned int, bool *); + +/* Traduit la fonction 'ASR'. */ +uint32_t armv7_asr(uint32_t, unsigned int, unsigned int); + +/* Traduit la fonction 'ROR_C'. */ +uint32_t armv7_ror_c(uint32_t, unsigned int, unsigned int, bool *); + +/* Traduit la fonction 'ROR'. */ +uint32_t armv7_ror(uint32_t, unsigned int, unsigned int); + +/* Traduit la fonction 'RRX_C'. */ +uint32_t armv7_rrx_c(uint32_t, unsigned int, bool *); + +/* Traduit la fonction 'RRX'. */ +uint32_t armv7_rrx(uint32_t, unsigned int, bool); + + + +/** + * § A5.2.4 - Modified immediate constants in ARM instructions + */ + + +/* Traduit la fonction 'ARMExpandImm_C'. */ +uint32_t armv7_arm_expand_imm_c(uint32_t, bool *); + +/* Traduit la fonction 'ARMExpandImm'. */ +uint32_t armv7_arm_expand_imm(uint32_t); + + + +/** + * § A8.4.3 - Pseudocode details of instruction-specified shifts and rotates + */ + + +typedef enum _SRType +{ + SRType_LSL, + SRType_LSR, + SRType_ASR, + SRType_ROR, + SRType_RRX + +} SRType; + + +/* Traduit la fonction 'Shift_C'. */ +uint32_t armv7_shift_c(uint32_t, unsigned int, SRType, unsigned int, bool *); + +/* Traduit la fonction 'Shift'. */ +uint32_t armv7_shift(uint32_t, unsigned int, SRType, unsigned int, bool); + + + +/** + * § P.5.3 - Bitstring manipulation + */ + + +/* Traduit la fonction 'ZeroExtend'. */ +uint32_t armv7_zero_extend(uint32_t, unsigned int, unsigned int); + + + +#endif /* _ARCH_ARM_V7_PSEUDO_H */ |