diff options
Diffstat (limited to 'src/arch/arm')
| -rw-r--r-- | src/arch/arm/v7/helpers.h | 23 | ||||
| -rw-r--r-- | src/arch/arm/v7/opcodes/Makefile.am | 15 | ||||
| -rw-r--r-- | src/arch/arm/v7/opcodes/opcodes_tmp_arm.h | 1 | ||||
| -rw-r--r-- | src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h | 5 | ||||
| -rw-r--r-- | src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h | 4 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/Makefile.am | 5 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/ldrb_A8867.d | 121 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/nop_A88119.d | 50 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/pop_A88131.d | 87 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/push_A88133.d | 128 | ||||
| -rw-r--r-- | src/arch/arm/v7/opdefs/strb_A88206.d | 116 | ||||
| -rw-r--r-- | src/arch/arm/v7/operands/Makefile.am | 1 | ||||
| -rw-r--r-- | src/arch/arm/v7/operands/reglist.c | 325 | ||||
| -rw-r--r-- | src/arch/arm/v7/operands/reglist.h | 72 | 
14 files changed, 943 insertions, 10 deletions
diff --git a/src/arch/arm/v7/helpers.h b/src/arch/arm/v7/helpers.h index fee5aea..919611e 100644 --- a/src/arch/arm/v7/helpers.h +++ b/src/arch/arm/v7/helpers.h @@ -31,6 +31,7 @@  #include "pseudo.h"  #include "operands/maccess.h"  #include "operands/offset.h" +#include "operands/reglist.h"  #include "operands/shift.h"  #include "../../operand.h" @@ -188,8 +189,30 @@ return shift_t; +/** + * Glue purement interne pour les listes de registres. + */ + +#define RegistersList(mask)                                                             \ +    ({                                                                                  \ +        GArchOperand *__result;                                                         \ +        __result = g_armv7_reglist_operand_new();                                       \ +        if (!g_armv7_reglist_load_registers(G_ARMV7_REGLIST_OPERAND(__result), mask))   \ +        {                                                                               \ +            g_object_unref(G_OBJECT(__result));                                         \ +            __result = NULL;                                                            \ +        }                                                                               \ +        __result;                                                                       \ +    }) +#define ListFromRegister(reg)                                                           \ +    ({                                                                                  \ +        GArchOperand *__result;                                                         \ +        __result = g_armv7_reglist_operand_new();                                       \ +        g_armv7_reglist_add_register(G_ARMV7_REGLIST_OPERAND(__result), reg);           \ +        __result;                                                                       \ +    }) diff --git a/src/arch/arm/v7/opcodes/Makefile.am b/src/arch/arm/v7/opcodes/Makefile.am index be437b9..0bff196 100644 --- a/src/arch/arm/v7/opcodes/Makefile.am +++ b/src/arch/arm/v7/opcodes/Makefile.am @@ -15,19 +15,24 @@ libarcharmv7opcodes_la_SOURCES = 		\  	arm_cmp.c		\  	arm_eor.c		\  	arm_ldr.c		\ +	arm_ldrb.c		\  	arm_lsl.c		\  	arm_mla.c		\  	arm_mls.c		\  	arm_mov.c		\  	arm_mul.c		\  	arm_mvn.c		\ +	arm_nop.c		\  	arm_orr.c		\ +	arm_pop.c		\ +	arm_push.c		\  	arm_rsb.c		\  	arm_rsc.c		\  	arm_sbc.c		\  	arm_smlal.c		\  	arm_smull.c		\  	arm_str.c		\ +	arm_strb.c		\  	arm_sub.c		\  	arm_subs.c		\  	arm_teq.c		\ @@ -48,19 +53,24 @@ libarcharmv7opcodes_la_SOURCES = 		\  	thumb_16_cmp.c		\  	thumb_16_eor.c		\  	thumb_16_ldr.c		\ +	thumb_16_ldrb.c		\  	thumb_16_lsl.c		\  	thumb_16_mla.c		\  	thumb_16_mls.c		\  	thumb_16_mov.c		\  	thumb_16_mul.c		\  	thumb_16_mvn.c		\ +	thumb_16_nop.c		\  	thumb_16_orr.c		\ +	thumb_16_pop.c		\ +	thumb_16_push.c		\  	thumb_16_rsb.c		\  	thumb_16_rsc.c		\  	thumb_16_sbc.c		\  	thumb_16_smlal.c		\  	thumb_16_smull.c		\  	thumb_16_str.c		\ +	thumb_16_strb.c		\  	thumb_16_sub.c		\  	thumb_16_subs.c		\  	thumb_16_teq.c		\ @@ -81,19 +91,24 @@ libarcharmv7opcodes_la_SOURCES = 		\  	thumb_32_cmp.c		\  	thumb_32_eor.c		\  	thumb_32_ldr.c		\ +	thumb_32_ldrb.c		\  	thumb_32_lsl.c		\  	thumb_32_mla.c		\  	thumb_32_mls.c		\  	thumb_32_mov.c		\  	thumb_32_mul.c		\  	thumb_32_mvn.c		\ +	thumb_32_nop.c		\  	thumb_32_orr.c		\ +	thumb_32_pop.c		\ +	thumb_32_push.c		\  	thumb_32_rsb.c		\  	thumb_32_rsc.c		\  	thumb_32_sbc.c		\  	thumb_32_smlal.c		\  	thumb_32_smull.c		\  	thumb_32_str.c		\ +	thumb_32_strb.c		\  	thumb_32_sub.c		\  	thumb_32_subs.c		\  	thumb_32_teq.c		\ diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h index 1cd3e24..612b45e 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h @@ -11,7 +11,6 @@  #define armv7_read_arm_instr_lsr_immediate(r) NULL  #define armv7_read_arm_instr_movt(r) NULL  #define armv7_read_arm_instr_pop_arm(r) NULL -#define armv7_read_arm_instr_push(r) NULL  #define armv7_read_arm_instr_ror_immediate(r) NULL  #define armv7_read_arm_instr_rrx(r) NULL  #define armv7_read_arm_instr_stmda_stmed(r) NULL diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h index f9ef7d9..fe67305 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h @@ -17,7 +17,6 @@  #define armv7_read_thumb_16_instr_eor_register(r) NULL  #define armv7_read_thumb_16_instr_it(r) NULL  #define armv7_read_thumb_16_instr_ldm_ldmia_ldmfd_thumb(r) NULL -#define armv7_read_thumb_16_instr_ldrb_immediate_thumb(r) NULL  #define armv7_read_thumb_16_instr_ldrb_register(r) NULL  #define armv7_read_thumb_16_instr_ldrh_immediate_thumb(r) NULL  #define armv7_read_thumb_16_instr_ldrh_register(r) NULL @@ -28,10 +27,7 @@  #define armv7_read_thumb_16_instr_lsr_register(r) NULL  #define armv7_read_thumb_16_instr_mul(r) NULL  #define armv7_read_thumb_16_instr_mvn_register(r) NULL -#define armv7_read_thumb_16_instr_nop(r) NULL  #define armv7_read_thumb_16_instr_orr_register(r) NULL -#define armv7_read_thumb_16_instr_pop_thumb(r) NULL -#define armv7_read_thumb_16_instr_push(r) NULL  #define armv7_read_thumb_16_instr_rev(r) NULL  #define armv7_read_thumb_16_instr_rev16(r) NULL  #define armv7_read_thumb_16_instr_revsh(r) NULL @@ -41,7 +37,6 @@  #define armv7_read_thumb_16_instr_setend(r) NULL  #define armv7_read_thumb_16_instr_sev(r) NULL  #define armv7_read_thumb_16_instr_stm_stmia_stmea(r) NULL -#define armv7_read_thumb_16_instr_strb_immediate_thumb(r) NULL  #define armv7_read_thumb_16_instr_strb_register(r) NULL  #define armv7_read_thumb_16_instr_strh_immediate_thumb(r) NULL  #define armv7_read_thumb_16_instr_strh_register(r) NULL diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h index 966d6a2..1f0abb9 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h @@ -28,12 +28,9 @@  #define armv7_read_thumb_32_instr_mrs_banked_register(r) NULL  #define armv7_read_thumb_32_instr_msr_banked_register(r) NULL  #define armv7_read_thumb_32_instr_msr_register(r) NULL -#define armv7_read_thumb_32_instr_nop(r) NULL  #define armv7_read_thumb_32_instr_orn_immediate(r) NULL  #define armv7_read_thumb_32_instr_orn_register(r) NULL  #define armv7_read_thumb_32_instr_pkh(r) NULL -#define armv7_read_thumb_32_instr_pop_thumb(r) NULL -#define armv7_read_thumb_32_instr_push(r) NULL  #define armv7_read_thumb_32_instr_qadd(r) NULL  #define armv7_read_thumb_32_instr_qdadd(r) NULL  #define armv7_read_thumb_32_instr_qdsub(r) NULL @@ -86,7 +83,6 @@  #define armv7_read_thumb_32_instr_ssub8(r) NULL  #define armv7_read_thumb_32_instr_stmdb_stmfd(r) NULL  #define armv7_read_thumb_32_instr_stm_stmia_stmea(r) NULL -#define armv7_read_thumb_32_instr_strb_immediate_thumb(r) NULL  #define armv7_read_thumb_32_instr_strb_register(r) NULL  #define armv7_read_thumb_32_instr_strbt(r) NULL  #define armv7_read_thumb_32_instr_strh_immediate_thumb(r) NULL diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 948c9da..a24e706 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -44,6 +44,7 @@ ARMV7_DEFS = 							\  	ldr_A8862.d							\  	ldr_A8864.d							\  	ldr_A8865.d							\ +	ldrb_A8867.d						\  	lsl_A8894.d							\  	mla_A88100.d						\  	mls_A88101.d						\ @@ -53,8 +54,11 @@ ARMV7_DEFS = 							\  	mul_A88114.d						\  	mvn_A88115.d						\  	mvn_A88116.d						\ +	nop_A88119.d						\  	orr_A88122.d						\  	orr_A88123.d						\ +	pop_A88131.d						\ +	push_A88133.d						\  	rsb_A88152.d						\  	rsb_A88153.d						\  	rsc_A88155.d						\ @@ -64,6 +68,7 @@ ARMV7_DEFS = 							\  	smlal_A88178.d						\  	smull_A88189.d						\  	str_A88203.d						\ +	strb_A88206.d						\  	sub_A88222.d						\  	sub_A88223.d						\  	teq_A88237.d						\ diff --git a/src/arch/arm/v7/opdefs/ldrb_A8867.d b/src/arch/arm/v7/opdefs/ldrb_A8867.d new file mode 100644 index 0000000..8097fd0 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrb_A8867.d @@ -0,0 +1,121 @@ + +/* 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 LDRB (immediate, Thumb) + +@encoding(t1) { + +    @half 0 1 1 1 1 imm5(5) Rn(3) Rt(3) + +    @syntax <Rgt>, <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm5, 5, 32) +        access = MakeMemoryAccess(Rgn, imm32, 1, 0) + +    } + +} + +@encoding(T2) { + +    @word 1 1 1 1 1 0 0 0 1 0 0 1 Rn(4) Rt(4) imm12(12) + +    @syntax "ldrb.W" <Rgt>, <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm12, 12, 32) +        access = MakeMemoryAccess(Rgn, imm32, 1, 0) + +    } + +    @rules { + +        //if Rt == '1111' then SEE PLD; +        //if Rn == '1111' then SEE LDRB (literal); +        //if t == 13 then UNPREDICTABLE; + +    } + +} + +@encoding(T31) { + +    @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) + +    @syntax <Rgt> <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm8, 8, 32); +        access = MakeMemoryAccess(Rgn, imm32, U, W) + +    } + +    @rules { + +        //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); +        //if Rn == '1111' then SEE LDRB (literal); +        //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; + +    } + +} + +@encoding(T32) { + +    @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + +    @syntax <Rgt> <base> <offset> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm8, 8, 32); +        base = MakeMemoryNotIndexed(Rgn, W) +        offset = MakeAccessOffset(U, imm32) + +    } + +    @rules { + +        //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); +        //if Rn == '1111' then SEE LDRB (literal); +        //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; + +    } + +} diff --git a/src/arch/arm/v7/opdefs/nop_A88119.d b/src/arch/arm/v7/opdefs/nop_A88119.d new file mode 100644 index 0000000..d47c346 --- /dev/null +++ b/src/arch/arm/v7/opdefs/nop_A88119.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 NOP + +@encoding(t1) { + +    @half 1 0 1 1 1 1 1 1 0 0 0 0 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 0 + +} + +@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 0 + +    @syntax {c} + +    @conv { + +        c = Condition(cond) + +    } + +} diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d new file mode 100644 index 0000000..329b705 --- /dev/null +++ b/src/arch/arm/v7/opdefs/pop_A88131.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 POP (Thumb) + +@encoding(t1) { + +    @half 1 0 1 1 1 1 0 P(1) register_list(8) + +    @syntax <registers> + +    @conv { + +        registers = RegistersList(P:'0000000':register_list) + +    } + +    @rules { + +        //if BitCount(registers) < 1 then UNPREDICTABLE; +        //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +    } + +} + +@encoding(T2) { + +    @word 1 1 1 0 1 0 0 0 1 0 1 1 1 1 0 1 P(1) M(1) 0 register_list(13) + +    @syntax "push.W" <registers> + +    @conv { + +        registers = RegistersList(P:M:'0':register_list) + +    } + +    @rules { + +        //if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; +        //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + +    } + +} + +@encoding(T3) { + +    @word 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 Rt(4) 1 0 1 1 0 0 0 0 0 1 0 0 + +    @syntax "push.W" <registers> + +    @conv { + +        Rgt = Register(Rt) +        registers = ListFromRegister(Rgt) + +    } + +    @rules { + +        //if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; + +    } + +} diff --git a/src/arch/arm/v7/opdefs/push_A88133.d b/src/arch/arm/v7/opdefs/push_A88133.d new file mode 100644 index 0000000..0526a56 --- /dev/null +++ b/src/arch/arm/v7/opdefs/push_A88133.d @@ -0,0 +1,128 @@ + +/* 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 PUSH + +@encoding(t1) { + +    @half 1 0 1 1 0 1 0 M(1) register_list(8) + +    @syntax <registers> + +    @conv { + +        registers = RegistersList('0':M:'000000':register_list) + +    } + +    @rules { + +        //if BitCount(registers) < 1 then UNPREDICTABLE; + +    } + +} + +@encoding(T2) { + +    @word 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 1 0 M(1) 0 register_list(13) + +    @syntax "push.W" <registers> + +    @conv { + +        registers = RegistersList('0':M:'0':register_list) + +    } + +    @rules { + +        //if BitCount(registers) < 2 then UNPREDICTABLE; + +    } + +} + +@encoding(T3) { + +    @word 1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 Rt(4) 1 1 0 1 0 0 0 0 0 1 0 0 + +    @syntax "push.W" <registers> + +    @conv { + +        Rgt = Register(Rt) +        registers = ListFromRegister(Rgt) + +    } + +    @rules { + +        //if t IN {13,15} then UNPREDICTABLE + +    } + +} + +@encoding(A1) { + +    @word cond(4) 1 0 0 1 0 0 1 0 1 1 0 1 register_list(16) + +    @syntax {c} <registers> + +    @conv { + +        c = Condition(cond) +        registers = RegistersList(register_list) + +    } + +    @rules { + +        //if BitCount(register_list) < 2 then SEE STMDB / STMFD; + +    } + +} + +@encoding(A2) { + +    @word cond(4) 0 1 0 1 0 0 1 0 1 1 0 1 Rt(4) 0 0 0 0 0 0 0 0 0 1 0 0 + +    @syntax {c} <registers> + +    @conv { + +        c = Condition(cond) +        Rgt = Register(Rt) +        registers = ListFromRegister(Rgt) + +    } + +    @rules { + +        //if t == 13 then UNPREDICTABLE; + +    } + +} diff --git a/src/arch/arm/v7/opdefs/strb_A88206.d b/src/arch/arm/v7/opdefs/strb_A88206.d new file mode 100644 index 0000000..4799f61 --- /dev/null +++ b/src/arch/arm/v7/opdefs/strb_A88206.d @@ -0,0 +1,116 @@ + +/* 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 STRB (immediate, Thumb) + +@encoding(t1) { + +    @half 0 1 1 1 0 imm5(5) Rn(3) Rt(3) + +    @syntax <Rgt>, <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm5, 5, 32) +        access = MakeMemoryAccess(Rgn, imm32, 1, 0) + +    } + +} + +@encoding(T2) { + +    @word 1 1 1 1 1 0 0 0 1 0 0 0 Rn(4) Rt(4) imm12(12) + +    @syntax "strb.W" <Rgt>, <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm12, 12, 32) +        access = MakeMemoryAccess(Rgn, imm32, 1, 0) + +    } + +    @rules { + +        //if Rn == '1111' then UNDEFINED; +        //if t IN {13,15} then UNPREDICTABLE; + +    } + +} + +@encoding(T31) { + +    @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) + +    @syntax <Rgt> <access> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm8, 8, 32); +        access = MakeMemoryAccess(Rgn, imm32, U, W) + +    } + +    @rules { + +        //if P == '1' && U == '1' && W == '0' then SEE STRBT; +        //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; +        //if t IN {13,15} || (wback && n == t) then UNPREDICTABLE; + +    } + +} + +@encoding(T32) { + +    @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + +    @syntax <Rgt> <base> <offset> + +    @conv { + +        Rgt = Register(Rt) +        Rgn = Register(Rn) +        imm32 = ZeroExtend(imm8, 8, 32); +        base = MakeMemoryNotIndexed(Rgn, W) +        offset = MakeAccessOffset(U, imm32) + +    } + +    @rules { + +        //if P == '1' && U == '1' && W == '0' then SEE STRBT; +        //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; +        //if t IN {13,15} || (wback && n == t) then UNPREDICTABLE; + +    } + +} diff --git a/src/arch/arm/v7/operands/Makefile.am b/src/arch/arm/v7/operands/Makefile.am index 8733bfe..32648c9 100644 --- a/src/arch/arm/v7/operands/Makefile.am +++ b/src/arch/arm/v7/operands/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libarcharmv7operands.la  libarcharmv7operands_la_SOURCES = 		\  	maccess.h maccess.c					\  	offset.h offset.c					\ +	reglist.h reglist.c					\  	shift.h shift.c  libarcharmv7operands_la_LIBADD = diff --git a/src/arch/arm/v7/operands/reglist.c b/src/arch/arm/v7/operands/reglist.c new file mode 100644 index 0000000..a54d148 --- /dev/null +++ b/src/arch/arm/v7/operands/reglist.c @@ -0,0 +1,325 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * reglist.c - accès à la mémorie à partir d'un registre et d'un décallage + * + * 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 "reglist.h" + + +#include <assert.h> +#include <malloc.h> + + +#include "../../../operand-int.h" +#include "../../../register.h" + + + +/* Définition d'un opérande listant une série de registres ARM (instance) */ +struct _GArmV7RegListOperand +{ +    GArchOperand parent;                    /* Instance parente            */ + +    GArmV7Register **registers;             /* Liste de registres intégrés */ +    size_t count;                           /* Taille de cette liste       */ + +}; + + +/* Définition d'un opérande listant une série de registres ARM (classe) */ +struct _GArmV7RegListOperandClass +{ +    GArchOperandClass parent;               /* Classe parente              */ + +}; + + +/* Initialise la classe des listes de registres ARM. */ +static void g_armv7_reglist_operand_class_init(GArmV7RegListOperandClass *); + +/* Initialise une instance de liste de registres ARM. */ +static void g_armv7_reglist_operand_init(GArmV7RegListOperand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *, GBufferLine *, AsmSyntax); + + + +/* Indique le type défini par la GLib pour une liste de registres ARM. */ +G_DEFINE_TYPE(GArmV7RegListOperand, g_armv7_reglist_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des listes de registres ARM.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_armv7_reglist_operand_class_init(GArmV7RegListOperandClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GArchOperandClass *operand;             /* Version de classe parente   */ + +    object = G_OBJECT_CLASS(klass); +    operand = G_ARCH_OPERAND_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_reglist_operand_dispose; +    object->finalize = (GObjectFinalizeFunc)g_armv7_reglist_operand_finalize; + +    operand->print = (operand_print_fc)g_armv7_reglist_operand_print; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise une instance de liste de registres ARM.           * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_armv7_reglist_operand_init(GArmV7RegListOperand *operand) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_armv7_reglist_operand_dispose(GArmV7RegListOperand *operand) +{ +    size_t i;                               /* Boucle de parcours          */ + +    for (i = 0; i < operand->count; i++) +        g_object_unref(G_OBJECT(operand->registers[i])); + +    G_OBJECT_CLASS(g_armv7_reglist_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_armv7_reglist_operand_finalize(GArmV7RegListOperand *operand) +{ +    if (operand->registers != NULL) +        free(operand->registers); + +    G_OBJECT_CLASS(g_armv7_reglist_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Crée une liste vierge de registres ARM.                      * +*                                                                             * +*  Retour      : Opérande mis en place.                                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchOperand *g_armv7_reglist_operand_new(void) +{ +    GArmV7RegListOperand *result;             /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_ARMV7_REGLIST_OPERAND, NULL); + +    return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à traiter.                                * +*                line    = ligne tampon où imprimer l'opérande donné.         * +*                syntax  = type de représentation demandée.                   * +*                                                                             * +*  Description : Traduit un opérande en version humainement lisible.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_armv7_reglist_operand_print(const GArmV7RegListOperand *operand, GBufferLine *line, AsmSyntax syntax) +{ +    size_t i;                               /* Boucle de parcours          */ + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY, "{", 1, RTT_HOOK); + +    for (i = 0; i < operand->count; i++) +    { +        if (i > 0) +        { +            g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); +            g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); +        } + +        g_arch_register_print(G_ARCH_REGISTER(operand->registers[i]), line, syntax); + +    } + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY, "}", 1, RTT_HOOK); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand  = liste de registres à compléter.                   * +*                selected = masque de bits pour les registres à intégrer.     * +*                                                                             * +*  Description : Remplit une liste de registres de registres ARM.             * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool g_armv7_reglist_load_registers(GArmV7RegListOperand *operand, uint32_t selected) +{ +    uint8_t i;                              /* Boucle de parcours          */ +    GArmV7Register *reg;                    /* Nouveau registre à intégrer */ + +    for (i = 18; i < 32; i++) +        if (selected & (1 << i)) return false; + +    for (i = 0; i < 18; i++) +    { +        if ((selected & (1 << i)) == 0) continue; + +        reg = g_armv7_register_new(i); +        g_armv7_reglist_add_register(operand, reg); + +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = liste de registres à compléter.                    * +*                reg     = nouveau registre à intégrer.                       * +*                                                                             * +*  Description : Ajoute un registre à une liste de registres ARM.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_armv7_reglist_add_register(GArmV7RegListOperand *operand, GArmV7Register *reg) +{ +    operand->registers = (GArmV7Register **)realloc(operand->registers, +                                                    ++operand->count * sizeof(GArmV7Register *)); + +    operand->registers[operand->count - 1] = reg; + +} + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à consulter.                              * +*                                                                             * +*  Description : Compte le nombre de registres ARM composant la liste.        * +*                                                                             * +*  Retour      : Nombre positif ou nul.                                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +size_t g_armv7_reglist_count_registers(const GArmV7RegListOperand *operand) +{ +    return operand->count; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand = opérande à consulter.                              * +*                index   = indice de l'élément à fournier.                    * +*                                                                             * +*  Description : Founit un élément donné d'une liste de registres ARM.        * +*                                                                             * +*  Retour      : Registre intégré à la liste manipulée.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArmV7Register *g_armv7_reglist_operand_get_register(const GArmV7RegListOperand *operand, size_t index) +{ +    assert(index < operand->count); + +    return operand->registers[index]; + +} diff --git a/src/arch/arm/v7/operands/reglist.h b/src/arch/arm/v7/operands/reglist.h new file mode 100644 index 0000000..cf0b9c0 --- /dev/null +++ b/src/arch/arm/v7/operands/reglist.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * reglist.h - prototypes pour les accès à la mémorie à partir d'un registre et d'un décallage + * + * 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_OPERANDS_REGLIST_H +#define _ARCH_ARM_V7_OPERANDS_REGLIST_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "../register.h" +#include "../../../operand.h" + + + +#define G_TYPE_ARMV7_REGLIST_OPERAND                  g_armv7_reglist_operand_get_type() +#define G_ARMV7_REGLIST_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_reglist_operand_get_type(), GArmV7RegListOperand)) +#define G_IS_ARMV7_REGLIST_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_reglist_operand_get_type())) +#define G_ARMV7_REGLIST_OPERAND_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) +#define G_IS_ARMV7_REGLIST_OPERAND_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_REGLIST_OPERAND)) +#define G_ARMV7_REGLIST_OPERAND_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_REGLIST_OPERAND, GArmV7RegListOperandClass)) + + +/* Définition d'un opérande listant une série de registres ARM (instance) */ +typedef struct _GArmV7RegListOperand GArmV7RegListOperand; + +/* Définition d'un opérande listant une série de registres ARM (classe) */ +typedef struct _GArmV7RegListOperandClass GArmV7RegListOperandClass; + + +/* Indique le type défini par la GLib pour une liste de registres ARM. */ +GType g_armv7_reglist_operand_get_type(void); + +/* Crée une liste vierge de registres ARM. */ +GArchOperand *g_armv7_reglist_operand_new(void); + +/* Remplit une liste de registres de registres ARM. */ +bool g_armv7_reglist_load_registers(GArmV7RegListOperand *, uint32_t); + +/* Ajoute un registre à une liste de registres ARM. */ +void g_armv7_reglist_add_register(GArmV7RegListOperand *, GArmV7Register *); + +/* Compte le nombre de registres ARM composant la liste. */ +size_t g_armv7_reglist_count_registers(const GArmV7RegListOperand *); + +/* Founit un élément donné d'une liste de registres ARM. */ +GArmV7Register *g_armv7_reglist_operand_get_register(const GArmV7RegListOperand *, size_t ); + + + +#endif  /* _ARCH_ARM_V7_OPERANDS_REGLIST_H */  | 
