From b2c7443132d34f644313e92096645e6b63b0201d Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 19 Jun 2023 11:31:54 -0500 Subject: [PATCH 01/53] [REVERT ME] Add auto-sync Capstone --- meson_options.txt | 2 +- subprojects/capstone-auto-sync-arm.wrap | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 subprojects/capstone-auto-sync-arm.wrap diff --git a/meson_options.txt b/meson_options.txt index a8b86abfc1a..42d2c6460b7 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -20,7 +20,7 @@ option('rizin_bindings', type: 'string', value: '', description: 'Path where riz option('checks_level', type: 'integer', value: 9999, description: 'Value between 0 and 3 to enable different level of assert (see RZ_CHECKS_LEVEL). By default its value depends on buildtype (2 on debug, 1 on release).') option('use_sys_capstone', type: 'feature', value: 'disabled') -option('use_capstone_version', type: 'combo', choices: ['v3', 'v4', 'v5', 'next'], value: 'next', description: 'Specify which version of capstone to use') +option('use_capstone_version', type: 'combo', choices: ['v3', 'v4', 'v5', 'next', 'auto-sync-arm'], value: 'auto-sync-arm', description: 'Specify which version of capstone to use') option('use_sys_magic', type: 'feature', value: 'disabled') option('use_sys_libzip', type: 'feature', value: 'disabled') option('use_sys_libzip_openssl', type: 'boolean', value: false, description: 'Whether to use or not system openssl dependency to build libzip') diff --git a/subprojects/capstone-auto-sync-arm.wrap b/subprojects/capstone-auto-sync-arm.wrap new file mode 100644 index 00000000000..518a7c6bf20 --- /dev/null +++ b/subprojects/capstone-auto-sync-arm.wrap @@ -0,0 +1,5 @@ +[wrap-git] +url = https://github.com/Rot127/capstone.git +revision = auto-sync +directory = capstone-auto-sync-arm +depth = 1 From 4032495f5280e0308f9feccbdf23798f2ef72a22 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 19 Jun 2023 11:32:23 -0500 Subject: [PATCH 02/53] Fix ARM identifiers and API changes. --- librz/analysis/arch/arm/arm_accessors32.h | 2 +- librz/analysis/arch/arm/arm_esil32.c | 64 +++++++------- librz/analysis/arch/arm/arm_il32.c | 52 ++++++----- librz/analysis/p/analysis_arm_cs.c | 103 ++++++++-------------- librz/asm/p/asm_arm_cs.c | 44 +-------- 5 files changed, 97 insertions(+), 168 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 6b9127e9a4d..cf6e88c44e3 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -38,6 +38,6 @@ SHIFTTYPE(x) == ARM_SFT_RRX_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value -#define ISWRITEBACK32() insn->detail->arm.writeback +#define ISWRITEBACK32() insn->detail->writeback #define ISPREINDEX32() (((OPCOUNT() == 2) && (ISMEM(1)) && (ISWRITEBACK32())) || ((OPCOUNT() == 3) && (ISMEM(2)) && (ISWRITEBACK32()))) #define ISPOSTINDEX32() (((OPCOUNT() == 3) && (ISIMM(2) || ISREG(2)) && (ISWRITEBACK32())) || ((OPCOUNT() == 4) && (ISIMM(3) || ISREG(3)) && (ISWRITEBACK32()))) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 385d39f04c1..e171222298b 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -66,65 +66,65 @@ RZ_IPI const char *rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type) { close_cond[1] = ",}"; int close_type = 0; switch (cond_type) { - case ARM_CC_EQ: + case ARMCC_EQ: close_type = 1; rz_strbuf_setf(&op->esil, "zf,?{,"); break; - case ARM_CC_NE: + case ARMCC_NE: close_type = 1; rz_strbuf_setf(&op->esil, "zf,!,?{,"); break; - case ARM_CC_HS: + case ARMCC_HS: close_type = 1; rz_strbuf_setf(&op->esil, "cf,?{,"); break; - case ARM_CC_LO: + case ARMCC_LO: close_type = 1; rz_strbuf_setf(&op->esil, "cf,!,?{,"); break; - case ARM_CC_MI: + case ARMCC_MI: close_type = 1; rz_strbuf_setf(&op->esil, "nf,?{,"); break; - case ARM_CC_PL: + case ARMCC_PL: close_type = 1; rz_strbuf_setf(&op->esil, "nf,!,?{,"); break; - case ARM_CC_VS: + case ARMCC_VS: close_type = 1; rz_strbuf_setf(&op->esil, "vf,?{,"); break; - case ARM_CC_VC: + case ARMCC_VC: close_type = 1; rz_strbuf_setf(&op->esil, "vf,!,?{,"); break; - case ARM_CC_HI: + case ARMCC_HI: close_type = 1; rz_strbuf_setf(&op->esil, "cf,zf,!,&,?{,"); break; - case ARM_CC_LS: + case ARMCC_LS: close_type = 1; rz_strbuf_setf(&op->esil, "cf,!,zf,|,?{,"); break; - case ARM_CC_GE: + case ARMCC_GE: close_type = 1; rz_strbuf_setf(&op->esil, "nf,vf,^,!,?{,"); break; - case ARM_CC_LT: + case ARMCC_LT: close_type = 1; rz_strbuf_setf(&op->esil, "nf,vf,^,?{,"); break; - case ARM_CC_GT: + case ARMCC_GT: // zf == 0 && nf == vf close_type = 1; rz_strbuf_setf(&op->esil, "zf,!,nf,vf,^,!,&,?{,"); break; - case ARM_CC_LE: + case ARMCC_LE: // zf == 1 || nf != vf close_type = 1; rz_strbuf_setf(&op->esil, "zf,nf,vf,^,|,?{,"); break; - case ARM_CC_AL: + case ARMCC_AL: // always executed break; default: @@ -391,7 +391,7 @@ PUSH { r4, r5, r6, r7, lr } rz_strbuf_appendf(&op->esil, "%s,%s,%d,+,=[4],", REG(i), ARG(0), (i + offset) * 4); } - if (insn->detail->arm.writeback == true) { // writeback, reg should be incremented + if (insn->detail->writeback == true) { // writeback, reg should be incremented rz_strbuf_appendf(&op->esil, "%d,%s,+=,", direction * (insn->detail->arm.op_count - 1) * 4, ARG(0)); } @@ -406,7 +406,7 @@ PUSH { r4, r5, r6, r7, lr } width += REGSIZE32(i); } // increment if writeback - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, "%d,%s,+=,", width, ARG(0)); } break; @@ -430,7 +430,7 @@ PUSH { r4, r5, r6, r7, lr } width += REGSIZE32(i); } // increment if writeback - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, "%d,%s,+=,", width, ARG(0)); } break; @@ -489,7 +489,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= for (i = 1; i < insn->detail->arm.op_count; i++) { rz_strbuf_appendf(&op->esil, "%s,%d,+,[4],%s,=,", ARG(0), (i + offset) * 4, REG(i)); } - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, "%d,%s,+=,", direction * (insn->detail->arm.op_count - 1) * 4, ARG(0)); } @@ -552,7 +552,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= disp = disp >= 0 ? disp : -disp; rz_strbuf_appendf(&op->esil, "%s,0x%x,%s,%c,0xffffffff,&,=[%d]", REG(0), disp, MEMBASE(1), sign, str_ldr_bytes); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%d,%s,%c,%s,=", disp, MEMBASE(1), sign, MEMBASE(1)); } @@ -563,7 +563,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_SFT_LSL: rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,<<,+,0xffffffff,&,=[%d]", REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes); - if (insn->detail->arm.writeback) { // e.g. 'str r2, [r3, r1, lsl 4]!' + if (insn->detail->writeback) { // e.g. 'str r2, [r3, r1, lsl 4]!' rz_strbuf_appendf(&op->esil, ",%s,%d,%s,<<,+,%s,=", MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); } @@ -571,7 +571,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_SFT_LSR: rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>,+,0xffffffff,&,=[%d]", REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>,+,%s,=", MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); } @@ -579,7 +579,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_SFT_ASR: rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>>>,+,0xffffffff,&,=[%d]", REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>>>,+,%s,=", MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); } @@ -587,7 +587,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_SFT_ROR: rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>>,+,0xffffffff,&,=[%d]", REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>>,+,%s,=", MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); } @@ -602,7 +602,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= } else { // No shift rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,0xffffffff,&,=[%d]", REG(0), MEMINDEX(1), MEMBASE(1), str_ldr_bytes); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%s,%s,+,%s,=", MEMINDEX(1), MEMBASE(1), MEMBASE(1)); } @@ -651,7 +651,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= disp = disp >= 0 ? disp : -disp; rz_strbuf_appendf(&op->esil, "%s,%d,%s,%c,0xffffffff,&,=[4],%s,4,%d,+,%s,%c,0xffffffff,&,=[4]", REG(0), disp, MEMBASE(2), sign, REG(1), disp, MEMBASE(2), sign); - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%d,%s,%c,%s,=", disp, MEMBASE(2), sign, MEMBASE(2)); } @@ -659,10 +659,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= if (ISSHIFTED(2)) { // it seems strd does not support SHIFT which is good, but have a check nonetheless } else { - rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,=[4],%s,4,%s,+,0xffffffff,&,=[4]", - REG(0), MEMBASE(2), REG(1), MEMBASE(2)); + const char sign = ISMEMINDEXSUB(2) ? '-' : '+'; + rz_strbuf_appendf(&op->esil, "%s,%s,%s,%c,0xffffffff,&,=[4],%s,4,%s,+,%s,%c,0xffffffff,&,=[4]", + REG(0), MEMINDEX(2), MEMBASE(2), sign, REG(1), MEMINDEX(2), MEMBASE(2), sign); if (insn->detail->arm.writeback) { - const char sign = ISMEMINDEXSUB(2) ? '-' : '+'; rz_strbuf_appendf(&op->esil, ",%s,%s,%c=", MEMINDEX(2), MEMBASE(2), sign); } @@ -730,7 +730,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", MEMDISP(2), MEMBASE(2), REG(0), REG(1)); } - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { if (ISPOSTINDEX32()) { if (ISIMM(3)) { rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", @@ -765,7 +765,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%s,%d,+,[1],%s,=", MEMBASE(1), MEMDISP(1), REG(0)); } - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { if (ISIMM(2)) { rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", MEMBASE(1), IMM(2), MEMBASE(1)); @@ -858,7 +858,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,[4],0x%x,&,%s,=", MEMDISP(1), MEMBASE(1), mask, REG(0)); } - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { if (ISIMM(2)) { rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", MEMBASE(1), IMM(2), MEMBASE(1)); diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 00d7ccf602f..8bea27e57ff 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -283,37 +283,37 @@ static RzILOpEffect *write_reg(arm_reg reg, RZ_OWN RZ_NONNULL RzILOpBitVector *v * IL for arm condition * unconditional is returned as NULL (rather than true), for simpler code */ -static RZ_NULLABLE RzILOpBool *cond(arm_cc c) { +static RZ_NULLABLE RzILOpBool *cond(ARMCC_CondCodes c) { switch (c) { - case ARM_CC_EQ: + case ARMCC_EQ: return VARG("zf"); - case ARM_CC_NE: + case ARMCC_NE: return INV(VARG("zf")); - case ARM_CC_HS: + case ARMCC_HS: return VARG("cf"); - case ARM_CC_LO: + case ARMCC_LO: return INV(VARG("cf")); - case ARM_CC_MI: + case ARMCC_MI: return VARG("nf"); - case ARM_CC_PL: + case ARMCC_PL: return INV(VARG("nf")); - case ARM_CC_VS: + case ARMCC_VS: return VARG("vf"); - case ARM_CC_VC: + case ARMCC_VC: return INV(VARG("vf")); - case ARM_CC_HI: + case ARMCC_HI: return AND(VARG("cf"), INV(VARG("zf"))); - case ARM_CC_LS: + case ARMCC_LS: return OR(INV(VARG("cf")), VARG("zf")); - case ARM_CC_GE: + case ARMCC_GE: return INV(XOR(VARG("nf"), VARG("vf"))); - case ARM_CC_LT: + case ARMCC_LT: return XOR(VARG("nf"), VARG("vf")); - case ARM_CC_GT: + case ARMCC_GT: return AND(INV(VARG("zf")), INV(XOR(VARG("nf"), VARG("vf")))); - case ARM_CC_LE: + case ARMCC_LE: return OR(VARG("zf"), XOR(VARG("nf"), VARG("vf"))); - case ARM_CC_AL: + case ARMCC_AL: default: return NULL; } @@ -806,7 +806,7 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { if (!addr) { return NULL; } - bool writeback = insn->detail->arm.writeback; + bool writeback = insn->detail->writeback; if (ISIMM(mem_idx + 1)) { // capstone incorrectly sets writeback to false for e.g. 0400b1e4 ldrt r0, [r1], 4 writeback = true; @@ -895,7 +895,7 @@ static RzILOpEffect *str(cs_insn *insn, bool is_thumb) { if (!addr) { return NULL; } - bool writeback = insn->detail->arm.writeback; + bool writeback = insn->detail->writeback; if (ISIMM(mem_idx + 1)) { // capstone incorrectly sets writeback to false for e.g. 04b0ade4 strt fp, [sp], 4 writeback = true; @@ -1199,7 +1199,7 @@ static RzILOpEffect *stm(cs_insn *insn, bool is_thumb) { size_t op_first; arm_reg ptr_reg; bool writeback; - if (insn->id == ARM_INS_PUSH || insn->id == ARM_INS_VPUSH) { + if (insn->id == ARM_INS_PUSH) { op_first = 0; ptr_reg = ARM_REG_SP; writeback = true; @@ -1209,7 +1209,7 @@ static RzILOpEffect *stm(cs_insn *insn, bool is_thumb) { } op_first = 1; ptr_reg = REGID(0); - writeback = insn->detail->arm.writeback; + writeback = insn->detail->writeback; } size_t op_count = OPCOUNT() - op_first; if (!op_count) { @@ -1220,9 +1220,9 @@ static RzILOpEffect *stm(cs_insn *insn, bool is_thumb) { return NULL; } bool decrement = insn->id == ARM_INS_STMDA || insn->id == ARM_INS_STMDB || insn->id == ARM_INS_PUSH || - insn->id == ARM_INS_VSTMDB || insn->id == ARM_INS_VPUSH; + insn->id == ARM_INS_VSTMDB; bool before = insn->id == ARM_INS_STMDB || insn->id == ARM_INS_PUSH || insn->id == ARM_INS_VSTMDB || - insn->id == ARM_INS_STMIB || insn->id == ARM_INS_VPUSH; + insn->id == ARM_INS_STMIB; ut32 regsize = reg_bits(REGID(op_first)) / 8; RzILOpEffect *eff = NULL; // build up in reverse order so the result recurses in the second arg of seq (for tail-call optimization) @@ -1260,7 +1260,7 @@ static RzILOpEffect *ldm(cs_insn *insn, bool is_thumb) { size_t op_first; arm_reg ptr_reg; bool writeback; - if (insn->id == ARM_INS_POP || insn->id == ARM_INS_VPOP) { + if (insn->id == ARM_INS_POP) { op_first = 0; ptr_reg = ARM_REG_SP; writeback = true; @@ -1270,7 +1270,7 @@ static RzILOpEffect *ldm(cs_insn *insn, bool is_thumb) { } op_first = 1; ptr_reg = REGID(0); - writeback = insn->detail->arm.writeback; + writeback = insn->detail->writeback; } size_t op_count = OPCOUNT() - op_first; if (!op_count) { @@ -1879,7 +1879,7 @@ static RzILOpEffect *rfe(cs_insn *insn, bool is_thumb) { RzILOpEffect *wb = NULL; bool wordhigher = insn->id == ARM_INS_RFEDA || insn->id == ARM_INS_RFEIB; bool increment = insn->id == ARM_INS_RFEIA || insn->id == ARM_INS_RFEIB; - if (insn->detail->arm.writeback) { + if (insn->detail->writeback) { wb = write_reg(REGID(0), increment ? ADD(DUP(base), U32(8)) : SUB(DUP(base), U32(8))); if (!wb) { @@ -4312,11 +4312,9 @@ static RzILOpEffect *il_unconditional(csh *handle, cs_insn *insn, bool is_thumb) // Advanced SIMD and Floating-point case ARM_INS_VSTMIA: case ARM_INS_VSTMDB: - case ARM_INS_VPUSH: return stm(insn, is_thumb); case ARM_INS_VLDMIA: case ARM_INS_VLDMDB: - case ARM_INS_VPOP: return ldm(insn, is_thumb); #if CS_API_MAJOR > 4 case ARM_INS_VMOVL: diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 95ca7bde18f..9c4f4d39412 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -129,41 +129,6 @@ static const char *vector_data_type_name(arm_vectordata_type type) { } } -static const char *cc_name(arm_cc cc) { - switch (cc) { - case ARM_CC_EQ: // Equal Equal - return "eq"; - case ARM_CC_NE: // Not equal Not equal, or unordered - return "ne"; - case ARM_CC_HS: // Carry set >, ==, or unordered - return "hs"; - case ARM_CC_LO: // Carry clear Less than - return "lo"; - case ARM_CC_MI: // Minus, negative Less than - return "mi"; - case ARM_CC_PL: // Plus, positive or zero >, ==, or unordered - return "pl"; - case ARM_CC_VS: // Overflow Unordered - return "vs"; - case ARM_CC_VC: // No overflow Not unordered - return "vc"; - case ARM_CC_HI: // Unsigned higher Greater than, or unordered - return "hi"; - case ARM_CC_LS: // Unsigned lower or same Less than or equal - return "ls"; - case ARM_CC_GE: // Greater than or equal Greater than or equal - return "ge"; - case ARM_CC_LT: // Less than Less than, or unordered - return "lt"; - case ARM_CC_GT: // Greater than Greater than - return "gt"; - case ARM_CC_LE: // Less than or equal <, ==, or unordered - return "le"; - default: - return ""; - } -} - static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { int i; PJ *pj = pj_new(); @@ -273,7 +238,7 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { if (x->update_flags) { pj_kb(pj, "update_flags", true); } - if (x->writeback) { + if (insn->detail->writeback) { pj_kb(pj, "writeback", true); } if (x->vector_size) { @@ -288,10 +253,10 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { if (x->cps_flag != ARM_CPSFLAG_INVALID) { pj_ki(pj, "cps_flag", x->cps_flag); } - if (x->cc != ARM_CC_INVALID && x->cc != ARM_CC_AL) { - pj_ks(pj, "cc", cc_name(x->cc)); + if (x->cc != ARMCC_UNDEF && x->cc != ARMCC_AL) { + pj_ks(pj, "cc", ARMCondCodeToString(x->cc)); } - if (x->mem_barrier != ARM_MB_INVALID) { + if (x->mem_barrier != ARM_MB_RESERVED_0) { pj_ki(pj, "mem_barrier", x->mem_barrier - 1); } pj_end(pj); @@ -550,24 +515,24 @@ static void opex64(RzStrBuf *buf, csh handle, cs_insn *insn) { } static int cond_cs2r2(int cc) { - if (cc == ARM_CC_AL || cc < 0) { + if (cc == ARMCC_AL || cc < 0) { cc = RZ_TYPE_COND_AL; } else { switch (cc) { - case ARM_CC_EQ: cc = RZ_TYPE_COND_EQ; break; - case ARM_CC_NE: cc = RZ_TYPE_COND_NE; break; - case ARM_CC_HS: cc = RZ_TYPE_COND_HS; break; - case ARM_CC_LO: cc = RZ_TYPE_COND_LO; break; - case ARM_CC_MI: cc = RZ_TYPE_COND_MI; break; - case ARM_CC_PL: cc = RZ_TYPE_COND_PL; break; - case ARM_CC_VS: cc = RZ_TYPE_COND_VS; break; - case ARM_CC_VC: cc = RZ_TYPE_COND_VC; break; - case ARM_CC_HI: cc = RZ_TYPE_COND_HI; break; - case ARM_CC_LS: cc = RZ_TYPE_COND_LS; break; - case ARM_CC_GE: cc = RZ_TYPE_COND_GE; break; - case ARM_CC_LT: cc = RZ_TYPE_COND_LT; break; - case ARM_CC_GT: cc = RZ_TYPE_COND_GT; break; - case ARM_CC_LE: cc = RZ_TYPE_COND_LE; break; + case ARMCC_EQ: cc = RZ_TYPE_COND_EQ; break; + case ARMCC_NE: cc = RZ_TYPE_COND_NE; break; + case ARMCC_HS: cc = RZ_TYPE_COND_HS; break; + case ARMCC_LO: cc = RZ_TYPE_COND_LO; break; + case ARMCC_MI: cc = RZ_TYPE_COND_MI; break; + case ARMCC_PL: cc = RZ_TYPE_COND_PL; break; + case ARMCC_VS: cc = RZ_TYPE_COND_VS; break; + case ARMCC_VC: cc = RZ_TYPE_COND_VC; break; + case ARMCC_HI: cc = RZ_TYPE_COND_HI; break; + case ARMCC_LS: cc = RZ_TYPE_COND_LS; break; + case ARMCC_GE: cc = RZ_TYPE_COND_GE; break; + case ARMCC_LT: cc = RZ_TYPE_COND_LT; break; + case ARMCC_GT: cc = RZ_TYPE_COND_GT; break; + case ARMCC_LE: cc = RZ_TYPE_COND_LE; break; } } return cc; @@ -902,7 +867,7 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { } if (REGID(0) == ARM_REG_PC) { op->type = RZ_ANALYSIS_OP_TYPE_UJMP; - if (insn->detail->arm.cc != ARM_CC_AL) { + if (insn->detail->arm.cc != ARMCC_AL) { // op->type = RZ_ANALYSIS_OP_TYPE_MCJMP; op->type = RZ_ANALYSIS_OP_TYPE_UCJMP; } @@ -1028,21 +993,22 @@ static void anop32(RzAnalysis *a, csh handle, RzAnalysisOp *op, cs_insn *insn, b } op->cycles = 1; /* grab family */ - if (cs_insn_group(handle, insn, ARM_GRP_CRYPTO)) { + if (cs_insn_group(handle, insn, ARM_FEATURE_HasAES)) { op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; - } else if (cs_insn_group(handle, insn, ARM_GRP_CRC)) { + } else if (cs_insn_group(handle, insn, ARM_FEATURE_HasCRC)) { op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; #if CS_API_MAJOR >= 4 } else if (cs_insn_group(handle, insn, ARM_GRP_PRIVILEGE)) { op->family = RZ_ANALYSIS_OP_FAMILY_PRIV; - } else if (cs_insn_group(handle, insn, ARM_GRP_VIRTUALIZATION)) { + } else if (cs_insn_group(handle, insn, ARM_FEATURE_HasVirtualization)) { op->family = RZ_ANALYSIS_OP_FAMILY_VIRT; #endif - } else if (cs_insn_group(handle, insn, ARM_GRP_NEON)) { + } else if (cs_insn_group(handle, insn, ARM_FEATURE_HasNEON)) { op->family = RZ_ANALYSIS_OP_FAMILY_MMX; - } else if (cs_insn_group(handle, insn, ARM_GRP_FPARMV8)) { + } else if (cs_insn_group(handle, insn, ARM_FEATURE_HasFPARMv8)) { op->family = RZ_ANALYSIS_OP_FAMILY_FPU; - } else if (cs_insn_group(handle, insn, ARM_GRP_THUMB2DSP)) { + } else if (cs_insn_group(handle, insn, ARM_FEATURE_HasDSP) && + cs_insn_group(handle, insn, ARM_FEATURE_HasDSP)) { op->family = RZ_ANALYSIS_OP_FAMILY_MMX; } else { op->family = RZ_ANALYSIS_OP_FAMILY_CPU; @@ -1113,7 +1079,7 @@ jmp $$ + 4 + ( [delta] * 2 ) for (i = 0; i < insn->detail->arm.op_count; i++) { if (insn->detail->arm.operands[i].type == ARM_OP_REG && insn->detail->arm.operands[i].reg == ARM_REG_PC) { - if (insn->detail->arm.cc == ARM_CC_AL) { + if (insn->detail->arm.cc == ARMCC_AL) { op->type = RZ_ANALYSIS_OP_TYPE_RET; } else { op->type = RZ_ANALYSIS_OP_TYPE_CRET; @@ -1158,7 +1124,7 @@ jmp $$ + 4 + ( [delta] * 2 ) op->type = RZ_ANALYSIS_OP_TYPE_ADD; if (REGID(0) == ARM_REG_PC) { op->type = RZ_ANALYSIS_OP_TYPE_UJMP; - if (REGID(1) == ARM_REG_PC && insn->detail->arm.cc != ARM_CC_AL) { + if (REGID(1) == ARM_REG_PC && insn->detail->arm.cc != ARMCC_AL) { // op->type = RZ_ANALYSIS_OP_TYPE_RCJMP; op->type = RZ_ANALYSIS_OP_TYPE_UCJMP; op->fail = addr + op->size; @@ -1341,7 +1307,7 @@ jmp $$ + 4 + ( [delta] * 2 ) op->disp = MEMDISP(1); if (REGID(0) == ARM_REG_PC) { op->type = RZ_ANALYSIS_OP_TYPE_UJMP; - if (insn->detail->arm.cc != ARM_CC_AL) { + if (insn->detail->arm.cc != ARMCC_AL) { // op->type = RZ_ANALYSIS_OP_TYPE_MCJMP; op->type = RZ_ANALYSIS_OP_TYPE_UCJMP; } @@ -1364,7 +1330,7 @@ jmp $$ + 4 + ( [delta] * 2 ) } else if (REGBASE(1) == ARM_REG_PC) { op->ptr = (addr & ~3LL) + (thumb ? 4 : 8) + MEMDISP(1); op->refptr = 4; - if (REGID(0) == ARM_REG_PC && insn->detail->arm.cc != ARM_CC_AL) { + if (REGID(0) == ARM_REG_PC && insn->detail->arm.cc != ARMCC_AL) { // op->type = RZ_ANALYSIS_OP_TYPE_MCJMP; op->type = RZ_ANALYSIS_OP_TYPE_UCJMP; op->fail = addr + op->size; @@ -1417,10 +1383,10 @@ jmp $$ + 4 + ( [delta] * 2 ) case ARM_INS_B: /* b.cc label */ op->cycles = 4; - if (insn->detail->arm.cc == ARM_CC_INVALID) { + if (insn->detail->arm.cc == ARMCC_UNDEF) { op->type = RZ_ANALYSIS_OP_TYPE_ILL; op->fail = addr + op->size; - } else if (insn->detail->arm.cc == ARM_CC_AL) { + } else if (insn->detail->arm.cc == ARMCC_AL) { op->type = RZ_ANALYSIS_OP_TYPE_JMP; op->fail = UT64_MAX; } else { @@ -1491,7 +1457,7 @@ jmp $$ + 4 + ( [delta] * 2 ) if (thumb && rz_arm_it_apply_cond(&ctx->it, insn)) { op->mnemonic = rz_str_newf("%s%s%s%s", rz_analysis_optype_to_string(op->type), - cc_name(insn->detail->arm.cc), + ARMCondCodeToString(insn->detail->arm.cc), insn->op_str[0] ? " " : "", insn->op_str); op->cond = (RzTypeCond)insn->detail->arm.cc; @@ -1775,6 +1741,7 @@ static int analysis_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *bu } else { patch_capstone_bugs(insn, a->bits, a->big_endian); if (mask & RZ_ANALYSIS_OP_MASK_DISASM) { + // TODO Remove after Capstone auto-sync update. op->mnemonic = rz_str_newf("%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", diff --git a/librz/asm/p/asm_arm_cs.c b/librz/asm/p/asm_arm_cs.c index de5bac5e9d1..b944a5822f8 100644 --- a/librz/asm/p/asm_arm_cs.c +++ b/librz/asm/p/asm_arm_cs.c @@ -27,10 +27,9 @@ static bool check_features(RzAsm *a, cs_insn *insn) { for (i = 0; i < insn->detail->groups_count; i++) { int id = insn->detail->groups[i]; switch (id) { - case ARM_GRP_ARM: - case ARM_GRP_THUMB: - case ARM_GRP_THUMB1ONLY: - case ARM_GRP_THUMB2: + case ARM_FEATURE_IsARM: + case ARM_FEATURE_IsThumb: + case ARM_FEATURE_IsThumb2: continue; default: if (id < 128) { @@ -48,41 +47,6 @@ static bool check_features(RzAsm *a, cs_insn *insn) { return true; } -static const char *cc_name(arm_cc cc) { - switch (cc) { - case ARM_CC_EQ: // Equal Equal - return "eq"; - case ARM_CC_NE: // Not equal Not equal, or unordered - return "ne"; - case ARM_CC_HS: // Carry set >, ==, or unordered - return "hs"; - case ARM_CC_LO: // Carry clear Less than - return "lo"; - case ARM_CC_MI: // Minus, negative Less than - return "mi"; - case ARM_CC_PL: // Plus, positive or zero >, ==, or unordered - return "pl"; - case ARM_CC_VS: // Overflow Unordered - return "vs"; - case ARM_CC_VC: // No overflow Not unordered - return "vc"; - case ARM_CC_HI: // Unsigned higher Greater than, or unordered - return "hi"; - case ARM_CC_LS: // Unsigned lower or same Less than or equal - return "ls"; - case ARM_CC_GE: // Greater than or equal Greater than or equal - return "ge"; - case ARM_CC_LT: // Less than Less than, or unordered - return "lt"; - case ARM_CC_GT: // Greater than Greater than - return "gt"; - case ARM_CC_LE: // Less than or equal <, ==, or unordered - return "le"; - default: - return ""; - } -} - static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { ArmCSContext *ctx = (ArmCSContext *)a->plugin_data; @@ -162,7 +126,7 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { if (thumb && rz_arm_it_apply_cond(&ctx->it, insn)) { char *tmpstr = rz_str_newf("%s%s", cs_insn_name(ctx->cd, insn->id), - cc_name(insn->detail->arm.cc)); + ARMCondCodeToString(insn->detail->arm.cc)); rz_str_cpy(insn->mnemonic, tmpstr); free(tmpstr); } From d163d6768ac72c7b7c252c90874bd2bf28caf1b0 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 19 Jun 2023 12:02:21 -0500 Subject: [PATCH 03/53] Add auto-sync packagefile --- subprojects/capstone-auto-sync-arm.wrap | 1 + .../capstone-auto-sync-arm/meson.build | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 subprojects/packagefiles/capstone-auto-sync-arm/meson.build diff --git a/subprojects/capstone-auto-sync-arm.wrap b/subprojects/capstone-auto-sync-arm.wrap index 518a7c6bf20..9c4c98946d2 100644 --- a/subprojects/capstone-auto-sync-arm.wrap +++ b/subprojects/capstone-auto-sync-arm.wrap @@ -3,3 +3,4 @@ url = https://github.com/Rot127/capstone.git revision = auto-sync directory = capstone-auto-sync-arm depth = 1 +patch_directory = capstone-auto-sync-arm diff --git a/subprojects/packagefiles/capstone-auto-sync-arm/meson.build b/subprojects/packagefiles/capstone-auto-sync-arm/meson.build new file mode 100644 index 00000000000..708fcfdc470 --- /dev/null +++ b/subprojects/packagefiles/capstone-auto-sync-arm/meson.build @@ -0,0 +1,98 @@ +project('capstone', 'c', version: '5.0', meson_version: '>=0.55.0') + +cs_files = [ + 'arch/AArch64/AArch64BaseInfo.c', + 'arch/AArch64/AArch64Disassembler.c', + 'arch/AArch64/AArch64InstPrinter.c', + 'arch/AArch64/AArch64Mapping.c', + 'arch/AArch64/AArch64Module.c', + 'arch/ARM/ARMBaseInfo.c', + 'arch/ARM/ARMDisassemblerExtension.c', + 'arch/ARM/ARMDisassembler.c', + 'arch/ARM/ARMInstPrinter.c', + 'arch/ARM/ARMMapping.c', + 'arch/ARM/ARMModule.c', + 'arch/M680X/M680XDisassembler.c', + 'arch/M680X/M680XInstPrinter.c', + 'arch/M680X/M680XModule.c', + 'arch/M68K/M68KDisassembler.c', + 'arch/M68K/M68KInstPrinter.c', + 'arch/M68K/M68KModule.c', + 'arch/Mips/MipsDisassembler.c', + 'arch/Mips/MipsInstPrinter.c', + 'arch/Mips/MipsMapping.c', + 'arch/Mips/MipsModule.c', + 'arch/PowerPC/PPCDisassembler.c', + 'arch/PowerPC/PPCInstPrinter.c', + 'arch/PowerPC/PPCMapping.c', + 'arch/PowerPC/PPCModule.c', + 'arch/Sparc/SparcDisassembler.c', + 'arch/Sparc/SparcInstPrinter.c', + 'arch/Sparc/SparcMapping.c', + 'arch/Sparc/SparcModule.c', + 'arch/SystemZ/SystemZDisassembler.c', + 'arch/SystemZ/SystemZInstPrinter.c', + 'arch/SystemZ/SystemZMapping.c', + 'arch/SystemZ/SystemZMCTargetDesc.c', + 'arch/SystemZ/SystemZModule.c', + 'arch/TMS320C64x/TMS320C64xDisassembler.c', + 'arch/TMS320C64x/TMS320C64xInstPrinter.c', + 'arch/TMS320C64x/TMS320C64xMapping.c', + 'arch/TMS320C64x/TMS320C64xModule.c', + 'arch/X86/X86ATTInstPrinter.c', + 'arch/X86/X86Disassembler.c', + 'arch/X86/X86DisassemblerDecoder.c', + 'arch/X86/X86IntelInstPrinter.c', + 'arch/X86/X86Mapping.c', + 'arch/X86/X86Module.c', + 'arch/X86/X86InstPrinterCommon.c', + 'arch/XCore/XCoreDisassembler.c', + 'arch/XCore/XCoreInstPrinter.c', + 'arch/XCore/XCoreMapping.c', + 'arch/XCore/XCoreModule.c', + 'arch/TriCore/TriCoreDisassembler.c', + 'arch/TriCore/TriCoreInstPrinter.c', + 'arch/TriCore/TriCoreMapping.c', + 'arch/TriCore/TriCoreModule.c', + 'cs.c', + 'Mapping.c', + 'MCInst.c', + 'MCInstrDesc.c', + 'MCInstPrinter.c', + 'MCRegisterInfo.c', + 'SStream.c', + 'Mapping.c', + 'utils.c', +] + +capstone_includes = [include_directories('include'), include_directories('include/capstone')] + +libcapstone_c_args = [ + '-DCAPSTONE_X86_ATT_DISABLE_NO', + '-DCAPSTONE_X86_REDUCE_NO', + '-DCAPSTONE_USE_SYS_DYN_MEM', + '-DCAPSTONE_DIET_NO', + '-DCAPSTONE_HAS_ARM', + '-DCAPSTONE_HAS_ARM64', + '-DCAPSTONE_HAS_M68K', + '-DCAPSTONE_HAS_M680X', + '-DCAPSTONE_HAS_MIPS', + '-DCAPSTONE_HAS_POWERPC', + '-DCAPSTONE_HAS_SPARC', + '-DCAPSTONE_HAS_SYSZ', + '-DCAPSTONE_HAS_X86', + '-DCAPSTONE_HAS_XCORE', + '-DCAPSTONE_HAS_TMS320C64X', + '-DCAPSTONE_HAS_TRICORE', +] + +libcapstone = library('capstone', cs_files, + c_args: libcapstone_c_args, + include_directories: capstone_includes, + implicit_include_directories: false +) + +capstone_dep = declare_dependency( + link_with: libcapstone, + include_directories: capstone_includes +) From 931474efd14c22af21e6ff558809b16b2ca1c24b Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 19 Jun 2023 12:17:47 -0500 Subject: [PATCH 04/53] Rename registers --- librz/analysis/arch/arm/arm_il32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 8bea27e57ff..35d79cef1bb 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -1506,13 +1506,13 @@ static RzILOpEffect *msr(cs_insn *insn, bool is_thumb) { bool update_f = false; bool update_s = false; switch (dst->reg) { - case ARM_SYSREG_APSR_NZCVQ: + case ARM_MCLASSSYSREG_APSR_NZCVQ: update_f = true; break; - case ARM_SYSREG_APSR_G: + case ARM_MCLASSSYSREG_APSR_G: update_s = true; break; - case ARM_SYSREG_APSR_NZCVQG: + case ARM_MCLASSSYSREG_APSR_NZCVQG: update_f = true; update_s = true; break; From 5511a7b469b8190420fc65dad24ccf95540c9cda Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 21 Jun 2023 10:04:32 -0500 Subject: [PATCH 05/53] Set option for CS register alias. --- librz/analysis/p/analysis_arm_cs.c | 1 + librz/asm/p/asm_arm_cs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 9c4f4d39412..af6dd27bc5c 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -1722,6 +1722,7 @@ static int analysis_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *bu if (ctx->handle == 0) { ret = (a->bits == 64) ? cs_open(CS_ARCH_ARM64, mode, &ctx->handle) : cs_open(CS_ARCH_ARM, mode, &ctx->handle); cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_CS_REG_ALIAS); if (ret != CS_ERR_OK) { ctx->handle = 0; return -1; diff --git a/librz/asm/p/asm_arm_cs.c b/librz/asm/p/asm_arm_cs.c index b944a5822f8..59e427e61af 100644 --- a/librz/asm/p/asm_arm_cs.c +++ b/librz/asm/p/asm_arm_cs.c @@ -92,6 +92,7 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { } } cs_option(ctx->cd, CS_OPT_SYNTAX, (a->syntax == RZ_ASM_SYNTAX_REGNUM) ? CS_OPT_SYNTAX_NOREGNAME : CS_OPT_SYNTAX_DEFAULT); + cs_option(ctx->cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_CS_REG_ALIAS); cs_option(ctx->cd, CS_OPT_DETAIL, (a->features && *a->features) ? CS_OPT_ON : CS_OPT_OFF); cs_option(ctx->cd, CS_OPT_DETAIL, CS_OPT_ON); if (!buf) { From e4017f855a10ec493276326d8851e27a3b451290 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 21 Jun 2023 11:43:05 -0500 Subject: [PATCH 06/53] Fix: Shift amounts are always decimal. --- test/db/asm/arm_32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index 8f8e683fcfd..90fa1542c83 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -464,7 +464,7 @@ d "ror r2, r7, r3" 7723a0e1 0x0 (set r2 (| (>> (var r7) (cast 5 false (var r3)) d "rors r2, r7, r3" 7723b0e1 0x0 (seq (set cf_tmp (ite (is_zero (cast 5 false (var r3))) (var cf) (msb (<< (var r7) (~- (cast 5 false (var r3))) false)))) (set r2 (| (>> (var r7) (cast 5 false (var r3)) false) (<< (var r7) (~- (cast 5 false (var r3))) false))) (set cf (var cf_tmp)) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) d "rrx r2, r3" 6320a0e1 0x0 (set r2 (>> (var r3) (bv 5 0x1) (var cf))) d "rrxs r2, r3" 6320b0e1 0x0 (seq (set cf_tmp (lsb (var r3))) (set r2 (>> (var r3) (bv 5 0x1) (var cf))) (set cf (var cf_tmp)) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) -d "lsr r1, r3, 0x1f" a31fa0e1 0x0 (set r1 (>> (var r3) (bv 5 0x1f) false)) +d "lsr r1, r3, 32" a31fa0e1 0x0 (set r1 (>> (var r3) (bv 5 0x1f) false)) d "mvn r1, 0x90000000" 0912e0e3 0x0 (set r1 (~ (bv 32 0x90000000))) d "mvns r1, 0x90000000" 0912f0e3 0x0 (seq (set cf_tmp true) (set r1 (~ (bv 32 0x90000000))) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) ad "tst r1, r2" 020011e1 0x0 (seq (set zf (is_zero (& (var r1) (var r2)))) (set nf (msb (& (var r1) (var r2))))) From aea3728c961f0656f95abac8b7e98c403dcd9472 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 26 Jun 2023 00:02:14 -0500 Subject: [PATCH 07/53] Remove code which handles fixed CS issue. --- librz/analysis/arch/arm/arm_il32.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 35d79cef1bb..a4800886ba0 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -807,10 +807,7 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { return NULL; } bool writeback = insn->detail->writeback; - if (ISIMM(mem_idx + 1)) { - // capstone incorrectly sets writeback to false for e.g. 0400b1e4 ldrt r0, [r1], 4 - writeback = true; - } + RzILOpEffect *writeback_eff = NULL; bool writeback_post = false; if (writeback) { @@ -896,10 +893,6 @@ static RzILOpEffect *str(cs_insn *insn, bool is_thumb) { return NULL; } bool writeback = insn->detail->writeback; - if (ISIMM(mem_idx + 1)) { - // capstone incorrectly sets writeback to false for e.g. 04b0ade4 strt fp, [sp], 4 - writeback = true; - } RzILOpEffect *writeback_eff = NULL; bool writeback_post = false; if (writeback) { From c8b98c8dba94f5f8ead43e0b6071fc6a0297cec9 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 26 Jun 2023 00:02:58 -0500 Subject: [PATCH 08/53] Use mem disp which is a member of the member operand. --- librz/analysis/arch/arm/arm_il32.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index a4800886ba0..61d733999fe 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -812,13 +812,10 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { bool writeback_post = false; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - if (ISIMM(mem_idx + 1)) { - // "ldr r0, [r1], 4" is treated as an extra operand after the mem - addr = insn->detail->arm.operands[mem_idx + 1].subtracted - ? SUB(addr, ARG(mem_idx + 1)) - : ADD(addr, ARG(mem_idx + 1)); - writeback_post = true; - } + addr = insn->detail->arm.operands[mem_idx].subtracted + ? SUB(addr, ARG(mem_idx)) + : ADD(addr, ARG(mem_idx)); + writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { // 'ldrb r0, [pc, 0x104]!' (0401ffe5) for example is unpredictable. write_reg will return NULL for pc. @@ -897,13 +894,10 @@ static RzILOpEffect *str(cs_insn *insn, bool is_thumb) { bool writeback_post = false; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - if (ISIMM(mem_idx + 1)) { - // "str r0, [r1], 4" is treated as an extra operand after the mem - addr = insn->detail->arm.operands[mem_idx + 1].subtracted - ? SUB(addr, ARG(mem_idx + 1)) - : ADD(addr, ARG(mem_idx + 1)); - writeback_post = true; - } + addr = insn->detail->arm.operands[mem_idx].subtracted + ? SUB(addr, ARG(mem_idx)) + : ADD(addr, ARG(mem_idx)); + writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { return NULL; From 6c224cc57000c16acdece83e97eed0dc8459b26e Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 26 Jun 2023 00:29:30 -0500 Subject: [PATCH 09/53] Get register and imm memory disponent. --- librz/analysis/arch/arm/arm_accessors32.h | 1 + librz/analysis/arch/arm/arm_il32.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index cf6e88c44e3..096ba3e635a 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -18,6 +18,7 @@ #define HASMEMINDEX(x) (insn->detail->arm.operands[x].mem.index != ARM_REG_INVALID) #define ISMEMINDEXSUB(x) insn->detail->arm.operands[x].subtracted #define MEMDISP(x) insn->detail->arm.operands[x].mem.disp +#define MEMDISP_BV(x) (HASMEMINDEX(x) ? REG_VAL(insn->detail->arm.operands[x].mem.index) : U32(MEMDISP(x))) #define ISIMM(x) (insn->detail->arm.operands[x].type == ARM_OP_IMM || insn->detail->arm.operands[x].type == ARM_OP_FP) #define ISREG(x) (insn->detail->arm.operands[x].type == ARM_OP_REG) #define ISMEM(x) (insn->detail->arm.operands[x].type == ARM_OP_MEM) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 61d733999fe..63322f84056 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -813,8 +813,8 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; addr = insn->detail->arm.operands[mem_idx].subtracted - ? SUB(addr, ARG(mem_idx)) - : ADD(addr, ARG(mem_idx)); + ? SUB(addr, MEMDISP_BV(mem_idx)) + : ADD(addr, MEMDISP_BV(mem_idx)); writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { From a239afcd3a8a25ca63290ccad9bdb7e0d1c8daa1 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 29 Jun 2023 05:45:36 -0500 Subject: [PATCH 10/53] Remove duplicate extension --- librz/analysis/arch/arm/arm_il32.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 63322f84056..e0516ca6fb4 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -812,9 +812,6 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { bool writeback_post = false; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - addr = insn->detail->arm.operands[mem_idx].subtracted - ? SUB(addr, MEMDISP_BV(mem_idx)) - : ADD(addr, MEMDISP_BV(mem_idx)); writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { @@ -894,9 +891,6 @@ static RzILOpEffect *str(cs_insn *insn, bool is_thumb) { bool writeback_post = false; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - addr = insn->detail->arm.operands[mem_idx].subtracted - ? SUB(addr, ARG(mem_idx)) - : ADD(addr, ARG(mem_idx)); writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { From 280582eb18a0641561f6aecb40f19a281a890a0e Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 29 Jun 2023 08:54:36 -0500 Subject: [PATCH 11/53] Check for subtracted flag. --- librz/analysis/arch/arm/arm_il32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index e0516ca6fb4..73183d2ce62 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -527,10 +527,10 @@ static RzILOpBitVector *arg(cs_insn *insn, bool is_thumb, int n, RZ_NULLABLE RzI case ARM_OP_MEM: { RzILOpBitVector *addr = MEMBASE(n); int disp = MEMDISP(n); - if (disp > 0) { + if (disp != 0 && !op->subtracted) { addr = ADD(addr, U32(disp)); - } else if (disp < 0) { - addr = SUB(addr, U32(-disp)); + } else if (disp != 0 && op->subtracted) { + addr = SUB(addr, U32(disp)); } return arg_mem(addr, &insn->detail->arm.operands[n], carry_out); } From 14d2717961b1f91eb9c7e5f5b0261b537471c1eb Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 1 Jul 2023 13:24:38 -0500 Subject: [PATCH 12/53] Determine post writeback by CS em operand flag. --- librz/analysis/arch/arm/arm_il32.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 73183d2ce62..1592d7d649c 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -809,10 +809,9 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { bool writeback = insn->detail->writeback; RzILOpEffect *writeback_eff = NULL; - bool writeback_post = false; + bool writeback_post = insn->detail->arm.post_index; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { // 'ldrb r0, [pc, 0x104]!' (0401ffe5) for example is unpredictable. write_reg will return NULL for pc. @@ -888,10 +887,9 @@ static RzILOpEffect *str(cs_insn *insn, bool is_thumb) { } bool writeback = insn->detail->writeback; RzILOpEffect *writeback_eff = NULL; - bool writeback_post = false; + bool writeback_post = insn->detail->arm.post_index; if (writeback) { arm_reg base = insn->detail->arm.operands[mem_idx].mem.base; - writeback_post = true; writeback_eff = write_reg(base, addr); if (!writeback_eff) { return NULL; From 26c5e96b2345bf267c36922b874525f85603fab5 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sun, 2 Jul 2023 06:37:13 -0500 Subject: [PATCH 13/53] Add VPOP and VPUSH again. --- librz/analysis/arch/arm/arm_il32.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 1592d7d649c..0ae5a0ba017 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -1178,7 +1178,7 @@ static RzILOpEffect *stm(cs_insn *insn, bool is_thumb) { size_t op_first; arm_reg ptr_reg; bool writeback; - if (insn->id == ARM_INS_PUSH) { + if (insn->id == ARM_INS_PUSH || insn->id == ARM_INS_VPUSH) { op_first = 0; ptr_reg = ARM_REG_SP; writeback = true; @@ -1199,9 +1199,9 @@ static RzILOpEffect *stm(cs_insn *insn, bool is_thumb) { return NULL; } bool decrement = insn->id == ARM_INS_STMDA || insn->id == ARM_INS_STMDB || insn->id == ARM_INS_PUSH || - insn->id == ARM_INS_VSTMDB; + insn->id == ARM_INS_VSTMDB || insn->id == ARM_INS_VPUSH; bool before = insn->id == ARM_INS_STMDB || insn->id == ARM_INS_PUSH || insn->id == ARM_INS_VSTMDB || - insn->id == ARM_INS_STMIB; + insn->id == ARM_INS_STMIB || insn->id == ARM_INS_VPUSH; ut32 regsize = reg_bits(REGID(op_first)) / 8; RzILOpEffect *eff = NULL; // build up in reverse order so the result recurses in the second arg of seq (for tail-call optimization) @@ -1239,7 +1239,7 @@ static RzILOpEffect *ldm(cs_insn *insn, bool is_thumb) { size_t op_first; arm_reg ptr_reg; bool writeback; - if (insn->id == ARM_INS_POP) { + if (insn->id == ARM_INS_POP || insn->id == ARM_INS_VPOP) { op_first = 0; ptr_reg = ARM_REG_SP; writeback = true; @@ -4130,9 +4130,11 @@ static RzILOpEffect *il_unconditional(csh *handle, cs_insn *insn, bool is_thumb) case ARM_INS_STMDA: case ARM_INS_STMDB: case ARM_INS_PUSH: + case ARM_INS_VPUSH: case ARM_INS_STMIB: return stm(insn, is_thumb); case ARM_INS_POP: + case ARM_INS_VPOP: case ARM_INS_LDM: case ARM_INS_LDMDA: case ARM_INS_LDMDB: From 3de62b124f26ecc63d0cdc03de6c14acb3841fa4 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 3 Jul 2023 07:27:15 -0500 Subject: [PATCH 14/53] Check for subtracted flag if disp is added to PC --- librz/analysis/arch/arm/arm_il32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 0ae5a0ba017..686f996185a 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -799,7 +799,8 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { cs_arm_op *memop = &insn->detail->arm.operands[mem_idx]; if (memop->mem.base == ARM_REG_PC) { // LDR (literal) is different in the sense that it aligns the pc value: - addr = arg_mem(U32(PCALIGN(insn->address, is_thumb) + MEMDISP(mem_idx)), memop, NULL); + int32_t mem_disp = memop->subtracted ? -MEMDISP(mem_idx) : MEMDISP(mem_idx); + addr = arg_mem(U32(PCALIGN(insn->address, is_thumb) + mem_disp), memop, NULL); } else { addr = ARG(mem_idx); } From 648e81887175405e163117fc439cd65917a10790 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 3 Jul 2023 07:38:34 -0500 Subject: [PATCH 15/53] Fix hex <-> decimal tests and off by one --- test/db/asm/arm_32 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index 90fa1542c83..d4e1dd28266 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -142,8 +142,8 @@ d "andeq r0, r0, 1" 01000002 d "andeq r3, r5, 0x80000000" 02310502 d "andne r3, r3, r2" 02300310 d "andne ip, ip, r7" 07c00c10 -d "asreq r0, ip, 0x1f" cc0fa001 -d "asrne r0, r4, 0x1f" c40fa011 +d "asreq r0, ip, 31" cc0fa001 +d "asrne r0, r4, 31" c40fa011 d "beq 8" 0000000a 0x0 (branch (var zf) (jmp (bv 32 0x8)) nop) d "biceq r3, r3, 7" 0730c303 d "blne 0x1900" 3E06001B @@ -182,7 +182,7 @@ d "ldrdne r2, r3, [r3, ip]" dc208311 d "ldreq r0, [fp, -0xb4]" b4001b05 d "ldrheq r0, [r3, r0]" b0009301 d "lslne r1, r1, 2" 0111a011 -d "lsreq r0, r0, 0x10" 2008a001 +d "lsreq r0, r0, 16" 2008a001 d "lsrne r0, r0, 9" a004a011 d "mlaeq r7, r5, r7, r0" 95072700 d "mlane r3, r1, r3, r2" 91232310 @@ -464,7 +464,7 @@ d "ror r2, r7, r3" 7723a0e1 0x0 (set r2 (| (>> (var r7) (cast 5 false (var r3)) d "rors r2, r7, r3" 7723b0e1 0x0 (seq (set cf_tmp (ite (is_zero (cast 5 false (var r3))) (var cf) (msb (<< (var r7) (~- (cast 5 false (var r3))) false)))) (set r2 (| (>> (var r7) (cast 5 false (var r3)) false) (<< (var r7) (~- (cast 5 false (var r3))) false))) (set cf (var cf_tmp)) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) d "rrx r2, r3" 6320a0e1 0x0 (set r2 (>> (var r3) (bv 5 0x1) (var cf))) d "rrxs r2, r3" 6320b0e1 0x0 (seq (set cf_tmp (lsb (var r3))) (set r2 (>> (var r3) (bv 5 0x1) (var cf))) (set cf (var cf_tmp)) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) -d "lsr r1, r3, 32" a31fa0e1 0x0 (set r1 (>> (var r3) (bv 5 0x1f) false)) +d "lsr r1, r3, 31" a31fa0e1 0x0 (set r1 (>> (var r3) (bv 5 0x1f) false)) d "mvn r1, 0x90000000" 0912e0e3 0x0 (set r1 (~ (bv 32 0x90000000))) d "mvns r1, 0x90000000" 0912f0e3 0x0 (seq (set cf_tmp true) (set r1 (~ (bv 32 0x90000000))) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) ad "tst r1, r2" 020011e1 0x0 (seq (set zf (is_zero (& (var r1) (var r2)))) (set nf (msb (& (var r1) (var r2))))) From 61f059e8babfc925b68826f9cb326c3c32949531 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 3 Jul 2023 09:23:59 -0500 Subject: [PATCH 16/53] Print immediates ins signed form as LLVM does. --- test/db/asm/arm_16 | 14 +++++++------- test/db/asm/arm_32 | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/test/db/asm/arm_16 b/test/db/asm/arm_16 index be3ff449294..8a39c97bcff 100755 --- a/test/db/asm/arm_16 +++ b/test/db/asm/arm_16 @@ -21,7 +21,7 @@ a "sub ip, 0x33" acf1330c a "sub r8, 0xf9" a8f1f908 ad "adc r0, r1, 0x7b" 41f17b00 0x0 (set r0 (+ (+ (var r1) (bv 32 0x7b)) (ite (var cf) (bv 32 0x1) (bv 32 0x0)))) ad "adc r0, r1, 0xaf00af" 41f1af10 -ad "adc r0, r1, -0x47ff4800" 41f1b820 # -0xb800b800 +ad "adc r0, r1, 0xb800b800" 41f1b820 ad "adc r0, r1, 0x26262626" 41f12630 ad "adc r0, r1, 0x8f0000" 41f50f00 ad "adc r0, r1, 0x1360000" 41f19b70 @@ -99,7 +99,7 @@ d "adds r6, r2, 5" 561d 0x0 (seq (set a (var r2)) (set b (bv 32 0x5)) (set r6 (+ a "add r6, r2, 5" 561d d "adds r7, 0xc3" c337 a "add r7, 0xc3" c337 -d "add.w sb, ip, -0x4dff4e00" 0cf1b229 # 0xb200b200 +d "add.w sb, ip, 0xb200b200" 0cf1b229 a "add r9, r12, -0x4dff4e00" 0cf1b229 # 0xb200b200 ad "add.w r1, r3, 0x2c" 03f12c01 d "adds.w sb, r2, 0x250000" 12f51419 @@ -237,7 +237,7 @@ d "cmn.w r1, r3, asr 30" 11eba37f 0x0 (seq (set a (var r1)) (set b (>> (var r3) a "cmn r1, r3, asr 30" 11eba37f ad "cmn.w r2, r5" 12eb050f ad "cmp r3, 0x73" 732b 0x0 (seq (set a (var r3)) (set b (bv 32 0x73)) (set res (- (var a) (var b))) (set cf (ule (var b) (var a))) (set vf (&& (^^ (msb (var a)) (msb (var b))) (^^ (msb (var a)) (msb (var res))))) (set zf (is_zero (var res))) (set nf (msb (var res)))) -d "cmp.w r8, -0x54545455" b8f1ab3f 0x0 (seq (set a (var r8)) (set b (bv 32 0xabababab)) (set res (- (var a) (var b))) (set cf (ule (var b) (var a))) (set vf (&& (^^ (msb (var a)) (msb (var b))) (^^ (msb (var a)) (msb (var res))))) (set zf (is_zero (var res))) (set nf (msb (var res)))) +d "cmp.w r8, 0xabababab" b8f1ab3f 0x0 (seq (set a (var r8)) (set b (bv 32 0xabababab)) (set res (- (var a) (var b))) (set cf (ule (var b) (var a))) (set vf (&& (^^ (msb (var a)) (msb (var b))) (^^ (msb (var a)) (msb (var res))))) (set zf (is_zero (var res))) (set nf (msb (var res)))) a "cmp r8, -0x54545455" b8f1ab3f # 0xabababab ad "cmp.w r6, 0x23" b6f1230f ad "cmp r3, r4" a342 @@ -455,7 +455,7 @@ d "mls r6, sl, r2, r5" 0afb1256 a "mls r6, r10, r2, r5" 0afb1256 d "movs r6, 0x26" 2626 0x0 (seq (set r6 (bv 32 0x26)) (set zf (is_zero (var r6))) (set nf (msb (var r6)))) a "mov r6, 0x26" 2626 -d "mov.w r7, -0x4dff4e00" 4ff0b227 # 0xb200b200 +d "mov.w r7, 0xb200b200" 4ff0b227 a "mov r7, 0xb200b200" 4ff0b227 d "movs.w fp, 0x130000" 5ff4981b a "movs r11, 0x00130000" 5ff4981b @@ -510,7 +510,7 @@ a "mvn r10, r3, lsr 17" 6fea534a ad "mvn.w r1, r2" 6fea0201 ad "nop" 00bf ad "nop.w" aff30080 -d "orn r6, sl, -0x54545455" 6af0ab36 # 0xabababab +d "orn r6, sl, 0xabababab" 6af0ab36 a "orn r6, r10, 0xabababab" 6af0ab36 d "orns r2, r3, 0x12800" 73f49432 0x0 (seq (set r2 (| (var r3) (~ (bv 32 0x12800)))) (set cf false) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) a "orns r2, r3, 0x00012800" 73f49432 @@ -665,7 +665,7 @@ d "rsbs r6, r6, 0" 7642 a "rsb r6, 0" 7642 d "rsb.w sb, r2, 0x16" c2f11609 a "rsb r9, r2, 0x16" c2f11609 -d "rsbs.w r7, sb, -0x54ff5500" d9f1ab27 # 0xab00ab00 +d "rsbs.w r7, sb, 0xab00ab00" d9f1ab27 a "rsbs r7, r9, 0xab00ab00" d9f1ab27 ad "rsb.w r2, r3, 0" c3f10002 ad "rsbs.w r3, r5, 0" d5f10003 @@ -691,7 +691,7 @@ d "sbc r7, r2, 0xf30000" 62f57307 a "sbc r7, r2, 0x00f30000" 62f57307 d "sbc r1, r1, 0xfb" 61f1fb01 a "sbc r1, 0xfb" 61f1fb01 -d "sbcs r2, r5, -0x54ff5500" 75f1ab22 # 0xab00ab00 +d "sbcs r2, r5, 0xab00ab00" 75f1ab22 a "sbcs r2, r5, 0xab00ab00" 75f1ab22 d "sbcs r2, r5" aa41 a "sbc r2, r5" aa41 diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index d4e1dd28266..6320cd5829c 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -139,7 +139,7 @@ d "sbc r6, r6, 0xc" 0c60c6e2 0x0 (set r6 (- (- (var r6) (bv 32 0xc)) (ite (var c d "sbc r6, r7, r5" 0560c7e0 0x0 (set r6 (- (- (var r7) (var r5)) (ite (var cf) (bv 32 0x0) (bv 32 0x1)))) d "sbcs r6, r7, r5" 0560d7e0 0x0 (seq (set a (var r7)) (set b (var r5)) (set r6 (- (- (var r7) (var r5)) (ite (var cf) (bv 32 0x0) (bv 32 0x1)))) (set cf (msb (+ (+ (cast 33 false (var a)) (cast 33 false (~ (var b)))) (ite (var cf) (bv 33 0x1) (bv 33 0x0))))) (set vf (&& (^^ (msb (var a)) (msb (var b))) (^^ (msb (var a)) (msb (var r6))))) (set zf (is_zero (var r6))) (set nf (msb (var r6)))) d "andeq r0, r0, 1" 01000002 -d "andeq r3, r5, 0x80000000" 02310502 +d "andeq r3, r5, -0x80000000" 02310502 d "andne r3, r3, r2" 02300310 d "andne ip, ip, r7" 07c00c10 d "asreq r0, ip, 31" cc0fa001 @@ -190,10 +190,10 @@ d "moveq r0, sl" 0a00a001 d "movne r0, sb" 0900a011 d "mulne r3, r3, r0" 93000310 d "mvneq r0, 0x15" 1500e003 -d "mvneq r0, 0x80000000" 0201e003 +d "mvneq r0, -0x80000000" 0201e003 d "orreq r5, r5, r3" 03508501 d "orreq r6, r6, r2, lsr 1" a2608601 -d "orreq r3, r3, 0x80000000" 02318303 +d "orreq r3, r3, -0x80000000" 02318303 d "orrne r0, r0, r1, lsl ip" 110c8011 d "orrne r1, r1, r3" 03108111 d "popeq {pc}" 04f09d04 @@ -235,7 +235,7 @@ d "movs r1, 0, 2" 0011b0e3 0x0 (seq (set cf_tmp false) (set r1 (bv 32 0x0)) (set d "movs r1, 1, 30" 011fb0e3 0x0 (seq (set cf_tmp false) (set r1 (bv 32 0x4)) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) d "movs r1, 4" 0410b0e3 0x0 (seq (set r1 (bv 32 0x4)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) d "movs r1, 0x40000000" 0111b0e3 0x0 (seq (set cf_tmp false) (set r1 (bv 32 0x40000000)) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) -d "movs r1, 0x80000000" 0211b0e3 0x0 (seq (set cf_tmp true) (set r1 (bv 32 0x80000000)) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) +d "movs r1, -0x80000000" 0211b0e3 0x0 (seq (set cf_tmp true) (set r1 (bv 32 0x80000000)) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) ad "movs r0, 0x2a" 2a00b0e3 0x0 (seq (set r0 (bv 32 0x2a)) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) ad "mov pc, 0x2a" 2af0a0e3 0x0 (jmp (bv 32 0x2a)) ad "movs pc, 0x2a" 2af0b0e3 @@ -392,10 +392,10 @@ d "eor r4, r3, 3" 034023e2 0x0 (set r4 (^ (var r3) (bv 32 0x3))) d "eors r4, r3, 3" 034033e2 0x0 (seq (set r4 (^ (var r3) (bv 32 0x3))) (set zf (is_zero (var r4))) (set nf (msb (var r4)))) d "eors r4, r3, 0x30000" 034833e2 0x0 (seq (set r4 (^ (var r3) (bv 32 0x30000))) (set cf false) (set zf (is_zero (var r4))) (set nf (msb (var r4)))) d "eors r3, r3, 0x30000" 033833e2 0x0 (seq (set r3 (^ (var r3) (bv 32 0x30000))) (set cf false) (set zf (is_zero (var r3))) (set nf (msb (var r3)))) -d "eors r3, r3, 0x80000000" 023133e2 0x0 (seq (set r3 (^ (var r3) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r3))) (set nf (msb (var r3)))) +d "eors r3, r3, -0x80000000" 023133e2 0x0 (seq (set r3 (^ (var r3) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r3))) (set nf (msb (var r3)))) d "and r0, r1, r2" 020001e0 0x0 (set r0 (& (var r1) (var r2))) -d "ands r0, r1, 0x80000000" 020111e2 0x0 (seq (set r0 (& (var r1) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) -d "ands r0, r0, 0x80000000" 020110e2 0x0 (seq (set r0 (& (var r0) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) +d "ands r0, r1, -0x80000000" 020111e2 0x0 (seq (set r0 (& (var r1) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) +d "ands r0, r0, -0x80000000" 020110e2 0x0 (seq (set r0 (& (var r0) (bv 32 0x80000000))) (set cf true) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) d "ands r0, r1, 0x42" 420011e2 0x0 (seq (set r0 (& (var r1) (bv 32 0x42))) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) d "orr r0, r1, 0x42" 420081e3 0x0 (set r0 (| (var r1) (bv 32 0x42))) d "orrs r0, r1, 0x42" 420091e3 0x0 (seq (set r0 (| (var r1) (bv 32 0x42))) (set zf (is_zero (var r0))) (set nf (msb (var r0)))) @@ -465,13 +465,13 @@ d "rors r2, r7, r3" 7723b0e1 0x0 (seq (set cf_tmp (ite (is_zero (cast 5 false (v d "rrx r2, r3" 6320a0e1 0x0 (set r2 (>> (var r3) (bv 5 0x1) (var cf))) d "rrxs r2, r3" 6320b0e1 0x0 (seq (set cf_tmp (lsb (var r3))) (set r2 (>> (var r3) (bv 5 0x1) (var cf))) (set cf (var cf_tmp)) (set zf (is_zero (var r2))) (set nf (msb (var r2)))) d "lsr r1, r3, 31" a31fa0e1 0x0 (set r1 (>> (var r3) (bv 5 0x1f) false)) -d "mvn r1, 0x90000000" 0912e0e3 0x0 (set r1 (~ (bv 32 0x90000000))) -d "mvns r1, 0x90000000" 0912f0e3 0x0 (seq (set cf_tmp true) (set r1 (~ (bv 32 0x90000000))) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) +d "mvn r1, -0x70000000" 0912e0e3 0x0 (set r1 (~ (bv 32 0x90000000))) +d "mvns r1, -0x70000000" 0912f0e3 0x0 (seq (set cf_tmp true) (set r1 (~ (bv 32 0x90000000))) (set cf (var cf_tmp)) (set zf (is_zero (var r1))) (set nf (msb (var r1)))) ad "tst r1, r2" 020011e1 0x0 (seq (set zf (is_zero (& (var r1) (var r2)))) (set nf (msb (& (var r1) (var r2))))) ad "tst ip, r3" 03001ce1 0x0 (seq (set zf (is_zero (& (var r12) (var r3)))) (set nf (msb (& (var r12) (var r3))))) d "tst r0, r1, ror 16" 610810e1 0x0 (seq (set cf (ite (is_zero (bv 5 0x10)) (var cf) (msb (<< (var r1) (~- (bv 5 0x10)) false)))) (set zf (is_zero (& (var r0) (| (>> (var r1) (bv 5 0x10) false) (<< (var r1) (~- (bv 5 0x10)) false))))) (set nf (msb (& (var r0) (| (>> (var r1) (bv 5 0x10) false) (<< (var r1) (~- (bv 5 0x10)) false)))))) d "teq r1, r2" 020031e1 0x0 (seq (set zf (is_zero (| (var r1) (var r2)))) (set nf (msb (| (var r1) (var r2))))) -d "teq r1, 0x80000000" 020131e3 0x0 (seq (set cf true) (set zf (is_zero (| (var r1) (bv 32 0x80000000)))) (set nf (msb (| (var r1) (bv 32 0x80000000))))) +d "teq r1, -0x80000000" 020131e3 0x0 (seq (set cf true) (set zf (is_zero (| (var r1) (bv 32 0x80000000)))) (set nf (msb (| (var r1) (bv 32 0x80000000))))) ad "clz r3, r2" 123f6fe1 0x0 (seq (set v (var r2)) (set i (bv 32 0x20)) (repeat (! (is_zero (var v))) (seq (set v (>> (var v) (bv 5 0x1) false)) (set i (- (var i) (bv 32 0x1))))) (set r3 (var i))) ad "svc 0" 000000ef 0x0 (goto svc) ad "bfc r3, 3, 5" 9f31c7e7 0x0 (set r3 (& (var r3) (bv 32 0xffffff07))) From c55f1b1cc9c0dd0ea94a6f854269a7934c5bbb68 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 3 Jul 2023 09:56:58 -0500 Subject: [PATCH 17/53] Fix tests wit equivalent results --- test/db/asm/arm_16 | 10 +++++----- test/db/asm/arm_32 | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/db/asm/arm_16 b/test/db/asm/arm_16 index 8a39c97bcff..87e6e008d41 100755 --- a/test/db/asm/arm_16 +++ b/test/db/asm/arm_16 @@ -87,13 +87,13 @@ ad "adr r6, 0x360" d8a6 0x0 (set r6 (bv 32 0x364)) d "adr r6, 0x360" d8a6 0x1000 (set r6 (bv 32 0x1364)) d "adr r6, 0x360" d8a6 0x1002 (set r6 (bv 32 0x1364)) d "adr r6, 0x360" d8a6 0x1004 (set r6 (bv 32 0x1368)) -d "subw r8, pc, 0xec7" aff6c768 0x1000 (set r8 (bv 32 0x13d)) +d "adr.w r8, -0xec7" aff6c768 0x1000 (set r8 (bv 32 0x13d)) a "adr r8, -0xec7" aff6c768 -d "subw r2, pc, 0x10" aff21002 0x1000 (set r2 (bv 32 0xff4)) +d "adr.w r2, -0x10" aff21002 0x1000 (set r2 (bv 32 0xff4)) a "adr.w r2, -0x10" aff21002 -d "addw r8, pc, 0xa23" 0ff62328 0x1000 (set r8 (bv 32 0x1a27)) +d "adr.w r8, 0xa23" 0ff62328 0x1000 (set r8 (bv 32 0x1a27)) a "adr r8, 0xa23" 0ff62328 -d "addw r3, pc, 0x24" 0ff22403 0x1000 (set r3 (bv 32 0x1028)) +d "adr.w r3, 0x24" 0ff22403 0x1000 (set r3 (bv 32 0x1028)) a "adr.w r3, 0x24" 0ff22403 d "adds r6, r2, 5" 561d 0x0 (seq (set a (var r2)) (set b (bv 32 0x5)) (set r6 (+ (var r2) (bv 32 0x5))) (set cf (msb (+ (cast 33 false (var a)) (cast 33 false (var b))))) (set vf (&& (! (^^ (msb (var a)) (msb (var b)))) (^^ (msb (var a)) (msb (var r6))))) (set zf (is_zero (var r6))) (set nf (msb (var r6)))) a "add r6, r2, 5" 561d @@ -1144,5 +1144,5 @@ ad "wfi.w" aff30380 ad "yield" 10bf ad "yield.w" aff30180 d "add r1, pc" 7944 0x3ffd70ca (set r1 (+ (var r1) (bv 32 0x3ffd70ce))) -d "subw r5, pc, 0x27" aff22705 0x1000 (set r5 (bv 32 0xfdd)) +d "adr.w r5, -0x27" aff22705 0x1000 (set r5 (bv 32 0xfdd)) d "addw ip, ip, 0x604" 0cf2046c 0x0 (set r12 (+ (var r12) (bv 32 0x604))) diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index 6320cd5829c..bb743ef35c1 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -196,7 +196,7 @@ d "orreq r6, r6, r2, lsr 1" a2608601 d "orreq r3, r3, -0x80000000" 02318303 d "orrne r0, r0, r1, lsl ip" 110c8011 d "orrne r1, r1, r3" 03108111 -d "popeq {pc}" 04f09d04 +d "ldreq pc, [sp], 4" 04f09d04 d "popeq {r4, pc}" 1080bd08 d "popeq {r4, r5, pc}" 3080bd08 d "popeq {r3, r4, r5, pc}" 3880bd08 @@ -338,16 +338,16 @@ d "ldr r0, [r1, r4, ror 5]" e40291e7 0x0 (set r0 (loadw 0 32 (+ (var r1) (| (>> d "ldr r0, [r1, r4, rrx]" 640091e7 0x0 (set r0 (loadw 0 32 (+ (var r1) (>> (var r4) (bv 5 0x1) (var cf))))) d "ldrb r2, [r3]" 0020d3e5 0x0 (set r2 (cast 32 false (load 0 (var r3)))) d "ldrsb r2, [r3]" d020d3e1 0x0 (set r2 (cast 32 (msb (load 0 (var r3))) (load 0 (var r3)))) -d "ldrsbt r2, [r3], 0" d020f3e0 0x0 (seq (set r2 (cast 32 (msb (load 0 (var r3))) (load 0 (var r3)))) (set r3 (+ (var r3) (bv 32 0x0)))) +d "ldrsbt r2, [r3], 0" d020f3e0 0x0 (seq (set r2 (cast 32 (msb (load 0 (var r3))) (load 0 (var r3)))) (set r3 (var r3))) d "ldrh r0, [r1]" b000d1e1 0x0 (set r0 (cast 32 false (loadw 0 16 (var r1)))) d "ldrsh r4, [r2]" f040d2e1 0x0 (set r4 (cast 32 (msb (loadw 0 16 (var r2))) (loadw 0 16 (var r2)))) -d "ldrsht r4, [r2], 0" f040f2e0 0x0 (seq (set r4 (cast 32 (msb (loadw 0 16 (var r2))) (loadw 0 16 (var r2)))) (set r2 (+ (var r2) (bv 32 0x0)))) +d "ldrsht r4, [r2], 0" f040f2e0 0x0 (seq (set r4 (cast 32 (msb (loadw 0 16 (var r2))) (loadw 0 16 (var r2)))) (set r2 (var r2))) d "ldr r6, [pc, 0x48]" 48609fe5 0x10660 (set r6 (loadw 0 32 (bv 32 0x106b0))) d "ldr r2, [pc, -0x10]" 10201fe5 0x1000 (set r2 (loadw 0 32 (bv 32 0xff8))) d "ldr sb, [pc, r3]" 03909fe7 0x1000 (set r9 (loadw 0 32 (+ (bv 32 0x1008) (var r3)))) d "ldr r2, [fp, -0x10]!" 10203be5 0x0 (seq (set r11 (- (var r11) (bv 32 0x10))) (set r2 (loadw 0 32 (var r11)))) d "ldr r0, [r1], 4" 040091e4 0x0 (seq (set r0 (loadw 0 32 (var r1))) (set r1 (+ (var r1) (bv 32 0x4)))) -d "ldrt r0, [r1], 0" 0000b1e4 0x0 (seq (set r0 (loadw 0 32 (var r1))) (set r1 (+ (var r1) (bv 32 0x0)))) +d "ldrt r0, [r1], 0" 0000b1e4 0x0 (seq (set r0 (loadw 0 32 (var r1))) (set r1 (var r1))) d "ldrt r0, [r1], 4" 0400b1e4 0x0 (seq (set r0 (loadw 0 32 (var r1))) (set r1 (+ (var r1) (bv 32 0x4)))) d "ldrbt r0, [r1], 4" 0400f1e4 0x0 (seq (set r0 (cast 32 false (load 0 (var r1)))) (set r1 (+ (var r1) (bv 32 0x4)))) d "ldrht r0, [r1], 4" b400f1e0 0x0 (seq (set r0 (cast 32 false (loadw 0 16 (var r1)))) (set r1 (+ (var r1) (bv 32 0x4)))) @@ -439,7 +439,7 @@ d "stmib r0, {r1, r3, r4}" 1a0080e9 0x0 (seq (storew 0 (+ (var r0) (bv 32 0x4)) d "stmib r0!, {r1, r3, r4}" 1a00a0e9 0x0 (seq (storew 0 (+ (var r0) (bv 32 0x4)) (var r1)) (storew 0 (+ (var r0) (bv 32 0x8)) (var r3)) (storew 0 (+ (var r0) (bv 32 0xc)) (var r4)) (set r0 (+ (var r0) (bv 32 0xc)))) d "stmdb r0, {r1, r3, r4}" 1a0000e9 0x0 (seq (storew 0 (- (var r0) (bv 32 0xc)) (var r1)) (storew 0 (- (var r0) (bv 32 0x8)) (var r3)) (storew 0 (- (var r0) (bv 32 0x4)) (var r4))) d "stmdb r0!, {r1, r3, r4}" 1a0020e9 0x0 (seq (storew 0 (- (var r0) (bv 32 0xc)) (var r1)) (storew 0 (- (var r0) (bv 32 0x8)) (var r3)) (storew 0 (- (var r0) (bv 32 0x4)) (var r4)) (set r0 (- (var r0) (bv 32 0xc)))) -d "pop {fp}" 04b09de4 0x0 (seq (set base (var sp)) (set r11 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set sp (+ (var base) (bv 32 0x4)))) +d "ldr fp, [sp], 4" 04b09de4 0x0 (seq (set r11 (loadw 0 32 (var sp))) (set sp (+ (var sp) (bv 32 0x4)))) d "pop {r3, pc}" 0880bde8 0x0 (seq (set base (var sp)) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set tgt (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set sp (+ (var base) (bv 32 0x8))) (jmp (var tgt))) d "ldm r0, {r1, r3, r4}" 1a0090e8 0x0 (seq (set base (var r0)) (set r1 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set r4 (loadw 0 32 (+ (var base) (bv 32 0x8))))) d "ldm r0!, {r1, r3, r4}" 1a00b0e8 0x0 (seq (set base (var r0)) (set r1 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set r4 (loadw 0 32 (+ (var base) (bv 32 0x8)))) (set r0 (+ (var base) (bv 32 0xc)))) From fd082175195877512b61dd3ea9b51cb81d8b2c06 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Tue, 4 Jul 2023 05:36:21 -0500 Subject: [PATCH 18/53] Revert use of subtracted flag and move it into the macro --- librz/analysis/arch/arm/arm_accessors32.h | 2 +- librz/analysis/arch/arm/arm_il32.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 096ba3e635a..63ef2468161 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -17,7 +17,7 @@ // s/index/base|reg/ #define HASMEMINDEX(x) (insn->detail->arm.operands[x].mem.index != ARM_REG_INVALID) #define ISMEMINDEXSUB(x) insn->detail->arm.operands[x].subtracted -#define MEMDISP(x) insn->detail->arm.operands[x].mem.disp +#define MEMDISP(x) (ISMEMINDEXSUB(x) ? -insn->detail->arm.operands[x].mem.disp : insn->detail->arm.operands[x].mem.disp) #define MEMDISP_BV(x) (HASMEMINDEX(x) ? REG_VAL(insn->detail->arm.operands[x].mem.index) : U32(MEMDISP(x))) #define ISIMM(x) (insn->detail->arm.operands[x].type == ARM_OP_IMM || insn->detail->arm.operands[x].type == ARM_OP_FP) #define ISREG(x) (insn->detail->arm.operands[x].type == ARM_OP_REG) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 686f996185a..56f859ac138 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -527,10 +527,10 @@ static RzILOpBitVector *arg(cs_insn *insn, bool is_thumb, int n, RZ_NULLABLE RzI case ARM_OP_MEM: { RzILOpBitVector *addr = MEMBASE(n); int disp = MEMDISP(n); - if (disp != 0 && !op->subtracted) { + if (disp > 0) { addr = ADD(addr, U32(disp)); - } else if (disp != 0 && op->subtracted) { - addr = SUB(addr, U32(disp)); + } else if (disp < 0) { + addr = SUB(addr, U32(-disp)); } return arg_mem(addr, &insn->detail->arm.operands[n], carry_out); } @@ -799,8 +799,7 @@ static RzILOpEffect *ldr(cs_insn *insn, bool is_thumb) { cs_arm_op *memop = &insn->detail->arm.operands[mem_idx]; if (memop->mem.base == ARM_REG_PC) { // LDR (literal) is different in the sense that it aligns the pc value: - int32_t mem_disp = memop->subtracted ? -MEMDISP(mem_idx) : MEMDISP(mem_idx); - addr = arg_mem(U32(PCALIGN(insn->address, is_thumb) + mem_disp), memop, NULL); + addr = arg_mem(U32(PCALIGN(insn->address, is_thumb) + MEMDISP(mem_idx)), memop, NULL); } else { addr = ARG(mem_idx); } From 2b87d56332f638ddc6a2cd12e555d43b390155db Mon Sep 17 00:00:00 2001 From: Rot127 Date: Tue, 4 Jul 2023 13:58:50 -0500 Subject: [PATCH 19/53] Check for VPT blocks. --- librz/asm/arch/arm/arm_it.c | 2 +- librz/asm/p/asm_arm_cs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/librz/asm/arch/arm/arm_it.c b/librz/asm/arch/arm/arm_it.c index f764723c26f..564032510f7 100644 --- a/librz/asm/arch/arm/arm_it.c +++ b/librz/asm/arch/arm/arm_it.c @@ -52,7 +52,7 @@ RZ_API void rz_arm_it_update_block(RzArmITContext *ctx, cs_insn *insn) { cond.cond = insn->detail->arm.cc; break; case 0x65: //'e' - cond.cond = (insn->detail->arm.cc % 2) ? insn->detail->arm.cc + 1 : insn->detail->arm.cc - 1; + cond.cond = ARMCC_getOppositeCondition(insn->detail->arm.cc); break; default: break; diff --git a/librz/asm/p/asm_arm_cs.c b/librz/asm/p/asm_arm_cs.c index 59e427e61af..8aa682513d4 100644 --- a/librz/asm/p/asm_arm_cs.c +++ b/librz/asm/p/asm_arm_cs.c @@ -119,7 +119,7 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { } if (op && !op->size) { op->size = insn->size; - if (insn->id == ARM_INS_IT) { + if (insn->id == ARM_INS_IT || insn->id == ARM_INS_VPT) { rz_arm_it_update_block(&ctx->it, insn); } else { rz_arm_it_update_nonblock(&ctx->it, insn); From 94d9b5bdd225d49b634f36f644ad4396fa595f93 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 5 Jul 2023 12:30:16 -0500 Subject: [PATCH 20/53] Fix more incorrect usages of mem disponents --- librz/analysis/arch/arm/arm_accessors32.h | 5 +-- librz/analysis/arch/arm/arm_esil32.c | 41 ++++++----------------- 2 files changed, 13 insertions(+), 33 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 63ef2468161..9caf6406e1e 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -39,6 +39,7 @@ SHIFTTYPE(x) == ARM_SFT_RRX_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value +#define ISPOSTINDEX() insn->detail->arm.post_index #define ISWRITEBACK32() insn->detail->writeback -#define ISPREINDEX32() (((OPCOUNT() == 2) && (ISMEM(1)) && (ISWRITEBACK32())) || ((OPCOUNT() == 3) && (ISMEM(2)) && (ISWRITEBACK32()))) -#define ISPOSTINDEX32() (((OPCOUNT() == 3) && (ISIMM(2) || ISREG(2)) && (ISWRITEBACK32())) || ((OPCOUNT() == 4) && (ISIMM(3) || ISREG(3)) && (ISWRITEBACK32()))) +#define ISPREINDEX32() (((OPCOUNT() == 2) && (ISMEM(1)) && (ISWRITEBACK32()) && (!ISPOSTINDEX())) || \ + ((OPCOUNT() == 3) && (ISMEM(2)) && (ISWRITEBACK32()) && (!ISPOSTINDEX()))) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index e171222298b..5e868f1e0b6 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -670,20 +670,6 @@ r6,r5,r4,3,sp,[*],12,sp,+= } } } - if (OPCOUNT() == 4) { // e.g. 'strd r2, r3, [r4], 4' or 'strd r2, r3, [r4], r5' - if (ISIMM(3)) { // e.g. 'strd r2, r3, [r4], 4' - rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%d,%s,+=,", - REG(0), MEMBASE(2), str_ldr_bytes, REG(1), MEMBASE(2), str_ldr_bytes, IMM(3), MEMBASE(2)); - } - if (ISREG(3)) { // e.g. 'strd r2, r3, [r4], r5' - if (ISSHIFTED(3)) { - // same as above - } else { - rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%s,%s,+=", - REG(0), MEMBASE(2), str_ldr_bytes, REG(1), MEMBASE(2), str_ldr_bytes, REG(3), MEMBASE(2)); - } - } - } break; case ARM_INS_TST: rz_strbuf_appendf(&op->esil, "0,%s,%s,&,==", ARG(1), ARG(0)); @@ -731,10 +717,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= MEMDISP(2), MEMBASE(2), REG(0), REG(1)); } if (insn->detail->writeback) { - if (ISPOSTINDEX32()) { - if (ISIMM(3)) { + if (ISPOSTINDEX()) { + if (!HASMEMINDEX(2)) { rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", - MEMBASE(2), IMM(3), MEMBASE(2)); + MEMBASE(2), MEMDISP(2), MEMBASE(2)); } else { const char op_index = ISMEMINDEXSUB(3) ? '-' : '+'; rz_strbuf_appendf(&op->esil, ",%s,%s,%c,%s,=", @@ -766,13 +752,8 @@ r6,r5,r4,3,sp,[*],12,sp,+= MEMBASE(1), MEMDISP(1), REG(0)); } if (insn->detail->writeback) { - if (ISIMM(2)) { - rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", - MEMBASE(1), IMM(2), MEMBASE(1)); - } else { - rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", - MEMBASE(1), MEMDISP(1), MEMBASE(1)); - } + rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", + MEMBASE(1), MEMDISP(1), MEMBASE(1)); } break; case ARM_INS_SXTH: @@ -854,18 +835,16 @@ r6,r5,r4,3,sp,[*],12,sp,+= } else if (HASMEMINDEX(1)) { // e.g. `ldr r2, [r3, r1]` rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,[4],0x%x,&,%s,=", MEMINDEX(1), MEMBASE(1), mask, REG(0)); + } else if (ISPOSTINDEX()) { + rz_strbuf_appendf(&op->esil, "%s,0xffffffff,&,[4],0x%x,&,%s,=", + MEMBASE(1), mask, REG(0)); } else { rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,[4],0x%x,&,%s,=", MEMDISP(1), MEMBASE(1), mask, REG(0)); } if (insn->detail->writeback) { - if (ISIMM(2)) { - rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", - MEMBASE(1), IMM(2), MEMBASE(1)); - } else { - rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", - MEMBASE(1), MEMDISP(1), MEMBASE(1)); - } + rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", + MEMBASE(1), MEMDISP(1), MEMBASE(1)); } } } From 36d6e2a117bc93e4046ea80aa97b02caa2094bf6 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 5 Jul 2023 13:09:38 -0500 Subject: [PATCH 21/53] Fix restoring of condition codes. --- librz/asm/arch/arm/arm_it.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/librz/asm/arch/arm/arm_it.c b/librz/asm/arch/arm/arm_it.c index 564032510f7..9c326c20a1f 100644 --- a/librz/asm/arch/arm/arm_it.c +++ b/librz/asm/arch/arm/arm_it.c @@ -13,6 +13,7 @@ typedef union arm_cs_itcond_t { struct { ut32 cond; ///< arm_cc ut8 off; ///< offset of this instruction from the it, for back-referencing to the ArmCSITBlock + ut8 vpt; ///< >0 if it is a VCC condition. 0 otherwise. }; ut64 packed; ///< for putting into HtUU } ArmCSITCond; @@ -32,7 +33,8 @@ RZ_API void rz_arm_it_context_fini(RzArmITContext *ctx) { * \p insn must be ARM_INS_IT */ RZ_API void rz_arm_it_update_block(RzArmITContext *ctx, cs_insn *insn) { - rz_return_if_fail(ctx && insn && insn->id == ARM_INS_IT); + rz_return_if_fail(ctx && insn && (insn->id == ARM_INS_IT || insn->id == ARM_INS_VPT)); + bool is_vpt = insn->id == ARM_INS_VPT; bool found; ht_uu_find(ctx->ht_itblock, insn->address, &found); if (found) { @@ -49,14 +51,21 @@ RZ_API void rz_arm_it_update_block(RzArmITContext *ctx, cs_insn *insn) { cond.off = block.off[i - 1] = 2 * i; switch (insn->mnemonic[i]) { case 0x74: //'t' - cond.cond = insn->detail->arm.cc; + cond.cond = is_vpt ? insn->detail->arm.vcc : insn->detail->arm.cc; break; case 0x65: //'e' - cond.cond = ARMCC_getOppositeCondition(insn->detail->arm.cc); + if (is_vpt) { + cond.cond = insn->detail->arm.vcc; + } else if (insn->detail->arm.cc == ARMCC_AL) { + cond.cond = ARMCC_AL; + } else { + cond.cond = ARMCC_getOppositeCondition(insn->detail->arm.cc); + } break; default: break; } + cond.vpt = is_vpt ? 1 : 0; RZ_STATIC_ASSERT(sizeof(cond) == sizeof(cond.packed)); ht_uu_update(ctx->ht_itcond, insn->address + cond.off, cond.packed); } @@ -91,7 +100,11 @@ RZ_API bool rz_arm_it_apply_cond(RzArmITContext *ctx, cs_insn *insn) { if (!found) { return false; } - insn->detail->arm.cc = cond.cond; + if (cond.vpt) { + insn->detail->arm.vcc = cond.cond; + } else { + insn->detail->arm.cc = cond.cond; + } insn->detail->arm.update_flags = 0; // Readjust if we detected that the previous assumption of all-2-byte instructions in From a73e9258972399c821d472f3500f943316907832 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 5 Jul 2023 16:56:34 -0500 Subject: [PATCH 22/53] Test for shifting via registers. --- librz/analysis/arch/arm/arm_accessors32.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 9caf6406e1e..ec45d03a745 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -31,12 +31,12 @@ #define LSHIFT(x) 0 #define LSHIFT2(x) 0 #endif -#define OPCOUNT() insn->detail->arm.op_count -#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) -#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type +#define OPCOUNT() insn->detail->arm.op_count +#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) +#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type #define SHIFTTYPEREG(x) (SHIFTTYPE(x) == ARM_SFT_ASR_REG || SHIFTTYPE(x) == ARM_SFT_LSL_REG || \ - SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ - SHIFTTYPE(x) == ARM_SFT_RRX_REG) + SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ + SHIFTTYPE(x) == ARM_SFT_RRX_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value #define ISPOSTINDEX() insn->detail->arm.post_index From d78a5bded14ece0f370ad4c40c20c9426f2f84f5 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 5 Jul 2023 16:57:21 -0500 Subject: [PATCH 23/53] Fix: mem index is no longer its own operand. --- librz/analysis/arch/arm/arm_esil32.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 5e868f1e0b6..2999d6ae0c6 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -545,7 +545,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= default: str_ldr_bytes = 4; } - if (OPCOUNT() == 2) { + if (!ISPOSTINDEX()) { if (ISMEM(1) && !HASMEMINDEX(1)) { int disp = MEMDISP(1); char sign = disp >= 0 ? '+' : '-'; @@ -609,28 +609,28 @@ r6,r5,r4,3,sp,[*],12,sp,+= } } } - if (OPCOUNT() == 3) { // e.g. 'str r2, [r3], 4 - if (ISIMM(2) && str_ldr_bytes != 8) { // e.g. 'str r2, [r3], 4 + if (ISPOSTINDEX()) { // e.g. 'str r2, [r3], 4 + if (!HASMEMINDEX(1)) { // e.g. 'str r2, [r3], 4 rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=", REG(0), MEMBASE(1), str_ldr_bytes, IMM(2), MEMBASE(1)); - } else if (str_ldr_bytes != 8) { + } else { // e.g. 'str r2, [r3], r1 if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4' switch (SHIFTTYPE(2)) { case ARM_SFT_LSL: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,<<,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_LSR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_ASR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_ROR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_RRX: // TODO @@ -641,7 +641,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= } } else { // No shift rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%s,+=", - REG(0), MEMBASE(1), str_ldr_bytes, REG(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMINDEX(1), MEMBASE(1)); } } if (ISREG(1) && str_ldr_bytes == 8) { // e.g. 'strd r2, r3, [r4]', normally should be the only case for ISREG(1). From 1fef4faf591d7e8ffae436bf5ffd3c8ce941ad1d Mon Sep 17 00:00:00 2001 From: Rot127 Date: Wed, 5 Jul 2023 17:01:33 -0500 Subject: [PATCH 24/53] Update ids for new ones --- test/db/analysis/arm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/db/analysis/arm b/test/db/analysis/arm index 39ab6e034ac..c1bd150ec29 100644 --- a/test/db/analysis/arm +++ b/test/db/analysis/arm @@ -912,7 +912,7 @@ pseudo: push (r3, lr) mnemonic: push mask: ffffffff prefix: 0 -id: 128 +id: 635 bytes: 08402de9 refptr: 0 size: 4 @@ -934,7 +934,7 @@ mnemonic: add description: add two values mask: ffff prefix: 0 -id: 2 +id: 31 bytes: 00af refptr: 0 size: 2 From 119f8715624a747c305491aef6229280e80eb7b0 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 6 Jul 2023 10:47:18 -0500 Subject: [PATCH 25/53] Fix another memdisp post_index bug --- librz/analysis/arch/arm/arm_esil32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 2999d6ae0c6..792727f6352 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -612,7 +612,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= if (ISPOSTINDEX()) { // e.g. 'str r2, [r3], 4 if (!HASMEMINDEX(1)) { // e.g. 'str r2, [r3], 4 rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=", - REG(0), MEMBASE(1), str_ldr_bytes, IMM(2), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMDISP(1), MEMBASE(1)); } else { // e.g. 'str r2, [r3], r1 if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4' switch (SHIFTTYPE(2)) { From 725755e0eaa165f8bc768d08874bc72daac26e36 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 6 Jul 2023 10:48:27 -0500 Subject: [PATCH 26/53] Formatting --- librz/analysis/arch/arm/arm_accessors32.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index ec45d03a745..4a4b472e9b6 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -31,15 +31,15 @@ #define LSHIFT(x) 0 #define LSHIFT2(x) 0 #endif -#define OPCOUNT() insn->detail->arm.op_count -#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) -#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type +#define OPCOUNT() insn->detail->arm.op_count +#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) +#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type #define SHIFTTYPEREG(x) (SHIFTTYPE(x) == ARM_SFT_ASR_REG || SHIFTTYPE(x) == ARM_SFT_LSL_REG || \ - SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ - SHIFTTYPE(x) == ARM_SFT_RRX_REG) + SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ + SHIFTTYPE(x) == ARM_SFT_RRX_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value #define ISPOSTINDEX() insn->detail->arm.post_index #define ISWRITEBACK32() insn->detail->writeback #define ISPREINDEX32() (((OPCOUNT() == 2) && (ISMEM(1)) && (ISWRITEBACK32()) && (!ISPOSTINDEX())) || \ - ((OPCOUNT() == 3) && (ISMEM(2)) && (ISWRITEBACK32()) && (!ISPOSTINDEX()))) + ((OPCOUNT() == 3) && (ISMEM(2)) && (ISWRITEBACK32()) && (!ISPOSTINDEX()))) From d97aa4b14cf10fbd226af6514ab7e370e55b24f2 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 6 Jul 2023 11:23:19 -0500 Subject: [PATCH 27/53] Another post_index --- librz/analysis/arch/arm/arm_esil32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 792727f6352..10f7e829068 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -749,7 +749,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= MEMINDEX(1), MEMBASE(1), REG(0)); } else { rz_strbuf_appendf(&op->esil, "%s,%d,+,[1],%s,=", - MEMBASE(1), MEMDISP(1), REG(0)); + MEMBASE(1), ISPOSTINDEX() ? 0 : MEMDISP(1), REG(0)); } if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", From bc08e6331f82bcf081f7a37bf0c36ef2c1da012b Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 6 Jul 2023 13:32:29 -0500 Subject: [PATCH 28/53] Fix 8 byte stores. --- librz/analysis/arch/arm/arm_esil32.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 10f7e829068..3ee33078ab9 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -610,10 +610,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= } } if (ISPOSTINDEX()) { // e.g. 'str r2, [r3], 4 - if (!HASMEMINDEX(1)) { // e.g. 'str r2, [r3], 4 + if (!HASMEMINDEX(1) && (str_ldr_bytes != 8)) { // e.g. 'str r2, [r3], 4 rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=", REG(0), MEMBASE(1), str_ldr_bytes, MEMDISP(1), MEMBASE(1)); - } else { // e.g. 'str r2, [r3], r1 + } else if (str_ldr_bytes != 8) { // e.g. 'str r2, [r3], r1 if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4' switch (SHIFTTYPE(2)) { case ARM_SFT_LSL: @@ -643,8 +643,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%s,+=", REG(0), MEMBASE(1), str_ldr_bytes, MEMINDEX(1), MEMBASE(1)); } - } - if (ISREG(1) && str_ldr_bytes == 8) { // e.g. 'strd r2, r3, [r4]', normally should be the only case for ISREG(1). + } else if (ISREG(1) && str_ldr_bytes == 8) { // e.g. 'strd r2, r3, [r4]', normally should be the only case for ISREG(1). if (!HASMEMINDEX(2)) { int disp = MEMDISP(2); char sign = disp >= 0 ? '+' : '-'; @@ -659,10 +658,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= if (ISSHIFTED(2)) { // it seems strd does not support SHIFT which is good, but have a check nonetheless } else { - const char sign = ISMEMINDEXSUB(2) ? '-' : '+'; - rz_strbuf_appendf(&op->esil, "%s,%s,%s,%c,0xffffffff,&,=[4],%s,4,%s,+,%s,%c,0xffffffff,&,=[4]", - REG(0), MEMINDEX(2), MEMBASE(2), sign, REG(1), MEMINDEX(2), MEMBASE(2), sign); - if (insn->detail->arm.writeback) { + rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[4],%s,4,%s,+,0xffffffff,&,=[4]", + REG(0), MEMBASE(2), REG(1), MEMBASE(2)); + if (insn->detail->writeback) { + const char sign = ISMEMINDEXSUB(2) ? '-' : '+'; rz_strbuf_appendf(&op->esil, ",%s,%s,%c=", MEMINDEX(2), MEMBASE(2), sign); } From 2a4cf01503aaf0f2dede4149e43a9005645287cd Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 6 Jul 2023 13:33:30 -0500 Subject: [PATCH 29/53] Add flag checking for MOV with shifts. --- librz/analysis/arch/arm/arm_esil32.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 3ee33078ab9..24dfd29b162 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -995,6 +995,22 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_INS_CMN: rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=,31,$c,cf,:=,31,$o,vf,:="); break; + case ARM_INS_MOV: + switch (SHIFTTYPE(1)) { + default: + break; + case ARM_SFT_LSL: + case ARM_SFT_LSL_REG: + rz_strbuf_appendf(&op->esil, ",%s,!,!,?{,%s,32,-,%s,>>,cf,:=,}", ARG(1), ARG(1), ARG(0)); + break; + case ARM_SFT_LSR: + case ARM_SFT_LSR_REG: + case ARM_SFT_ASR: + case ARM_SFT_ASR_REG: + rz_strbuf_appendf(&op->esil, ",%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,}", ARG(1), ARG(0), ARG(1)); + break; + } + // fallthrough default: rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:="); } From 6d6a0486df03fd53584b1a8869cf47771202c71c Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 20 Jul 2023 09:34:09 -0500 Subject: [PATCH 30/53] Revert "[REVERT ME] Add auto-sync Capstone" This reverts commit b86eb6dc6c1c8046307f27593cce13cb89d301df. --- meson_options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson_options.txt b/meson_options.txt index 42d2c6460b7..a8b86abfc1a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -20,7 +20,7 @@ option('rizin_bindings', type: 'string', value: '', description: 'Path where riz option('checks_level', type: 'integer', value: 9999, description: 'Value between 0 and 3 to enable different level of assert (see RZ_CHECKS_LEVEL). By default its value depends on buildtype (2 on debug, 1 on release).') option('use_sys_capstone', type: 'feature', value: 'disabled') -option('use_capstone_version', type: 'combo', choices: ['v3', 'v4', 'v5', 'next', 'auto-sync-arm'], value: 'auto-sync-arm', description: 'Specify which version of capstone to use') +option('use_capstone_version', type: 'combo', choices: ['v3', 'v4', 'v5', 'next'], value: 'next', description: 'Specify which version of capstone to use') option('use_sys_magic', type: 'feature', value: 'disabled') option('use_sys_libzip', type: 'feature', value: 'disabled') option('use_sys_libzip_openssl', type: 'boolean', value: false, description: 'Whether to use or not system openssl dependency to build libzip') From be4260164392fd055efe9520f5eef302cea472d5 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 20 Jul 2023 09:46:07 -0500 Subject: [PATCH 31/53] Remove capstone-auto-sync subproject and replace with next --- subprojects/capstone-auto-sync-arm.wrap | 6 -- subprojects/capstone-next.wrap | 2 +- .../capstone-auto-sync-arm/meson.build | 98 ------------------- .../packagefiles/capstone-next/meson.build | 5 +- 4 files changed, 5 insertions(+), 106 deletions(-) delete mode 100644 subprojects/capstone-auto-sync-arm.wrap delete mode 100644 subprojects/packagefiles/capstone-auto-sync-arm/meson.build diff --git a/subprojects/capstone-auto-sync-arm.wrap b/subprojects/capstone-auto-sync-arm.wrap deleted file mode 100644 index 9c4c98946d2..00000000000 --- a/subprojects/capstone-auto-sync-arm.wrap +++ /dev/null @@ -1,6 +0,0 @@ -[wrap-git] -url = https://github.com/Rot127/capstone.git -revision = auto-sync -directory = capstone-auto-sync-arm -depth = 1 -patch_directory = capstone-auto-sync-arm diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index ca2a1e47cf0..196aca72591 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,5 +1,5 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = 097c04d9413c59a58b00d4d1c8d5dc0ac158ffaa +revision = 0daa5044b8904d55e7628f3528d588c1354cd275 directory = capstone-next patch_directory = capstone-next diff --git a/subprojects/packagefiles/capstone-auto-sync-arm/meson.build b/subprojects/packagefiles/capstone-auto-sync-arm/meson.build deleted file mode 100644 index 708fcfdc470..00000000000 --- a/subprojects/packagefiles/capstone-auto-sync-arm/meson.build +++ /dev/null @@ -1,98 +0,0 @@ -project('capstone', 'c', version: '5.0', meson_version: '>=0.55.0') - -cs_files = [ - 'arch/AArch64/AArch64BaseInfo.c', - 'arch/AArch64/AArch64Disassembler.c', - 'arch/AArch64/AArch64InstPrinter.c', - 'arch/AArch64/AArch64Mapping.c', - 'arch/AArch64/AArch64Module.c', - 'arch/ARM/ARMBaseInfo.c', - 'arch/ARM/ARMDisassemblerExtension.c', - 'arch/ARM/ARMDisassembler.c', - 'arch/ARM/ARMInstPrinter.c', - 'arch/ARM/ARMMapping.c', - 'arch/ARM/ARMModule.c', - 'arch/M680X/M680XDisassembler.c', - 'arch/M680X/M680XInstPrinter.c', - 'arch/M680X/M680XModule.c', - 'arch/M68K/M68KDisassembler.c', - 'arch/M68K/M68KInstPrinter.c', - 'arch/M68K/M68KModule.c', - 'arch/Mips/MipsDisassembler.c', - 'arch/Mips/MipsInstPrinter.c', - 'arch/Mips/MipsMapping.c', - 'arch/Mips/MipsModule.c', - 'arch/PowerPC/PPCDisassembler.c', - 'arch/PowerPC/PPCInstPrinter.c', - 'arch/PowerPC/PPCMapping.c', - 'arch/PowerPC/PPCModule.c', - 'arch/Sparc/SparcDisassembler.c', - 'arch/Sparc/SparcInstPrinter.c', - 'arch/Sparc/SparcMapping.c', - 'arch/Sparc/SparcModule.c', - 'arch/SystemZ/SystemZDisassembler.c', - 'arch/SystemZ/SystemZInstPrinter.c', - 'arch/SystemZ/SystemZMapping.c', - 'arch/SystemZ/SystemZMCTargetDesc.c', - 'arch/SystemZ/SystemZModule.c', - 'arch/TMS320C64x/TMS320C64xDisassembler.c', - 'arch/TMS320C64x/TMS320C64xInstPrinter.c', - 'arch/TMS320C64x/TMS320C64xMapping.c', - 'arch/TMS320C64x/TMS320C64xModule.c', - 'arch/X86/X86ATTInstPrinter.c', - 'arch/X86/X86Disassembler.c', - 'arch/X86/X86DisassemblerDecoder.c', - 'arch/X86/X86IntelInstPrinter.c', - 'arch/X86/X86Mapping.c', - 'arch/X86/X86Module.c', - 'arch/X86/X86InstPrinterCommon.c', - 'arch/XCore/XCoreDisassembler.c', - 'arch/XCore/XCoreInstPrinter.c', - 'arch/XCore/XCoreMapping.c', - 'arch/XCore/XCoreModule.c', - 'arch/TriCore/TriCoreDisassembler.c', - 'arch/TriCore/TriCoreInstPrinter.c', - 'arch/TriCore/TriCoreMapping.c', - 'arch/TriCore/TriCoreModule.c', - 'cs.c', - 'Mapping.c', - 'MCInst.c', - 'MCInstrDesc.c', - 'MCInstPrinter.c', - 'MCRegisterInfo.c', - 'SStream.c', - 'Mapping.c', - 'utils.c', -] - -capstone_includes = [include_directories('include'), include_directories('include/capstone')] - -libcapstone_c_args = [ - '-DCAPSTONE_X86_ATT_DISABLE_NO', - '-DCAPSTONE_X86_REDUCE_NO', - '-DCAPSTONE_USE_SYS_DYN_MEM', - '-DCAPSTONE_DIET_NO', - '-DCAPSTONE_HAS_ARM', - '-DCAPSTONE_HAS_ARM64', - '-DCAPSTONE_HAS_M68K', - '-DCAPSTONE_HAS_M680X', - '-DCAPSTONE_HAS_MIPS', - '-DCAPSTONE_HAS_POWERPC', - '-DCAPSTONE_HAS_SPARC', - '-DCAPSTONE_HAS_SYSZ', - '-DCAPSTONE_HAS_X86', - '-DCAPSTONE_HAS_XCORE', - '-DCAPSTONE_HAS_TMS320C64X', - '-DCAPSTONE_HAS_TRICORE', -] - -libcapstone = library('capstone', cs_files, - c_args: libcapstone_c_args, - include_directories: capstone_includes, - implicit_include_directories: false -) - -capstone_dep = declare_dependency( - link_with: libcapstone, - include_directories: capstone_includes -) diff --git a/subprojects/packagefiles/capstone-next/meson.build b/subprojects/packagefiles/capstone-next/meson.build index 647b1478dfb..93220396e68 100644 --- a/subprojects/packagefiles/capstone-next/meson.build +++ b/subprojects/packagefiles/capstone-next/meson.build @@ -6,7 +6,9 @@ cs_files = [ 'arch/AArch64/AArch64InstPrinter.c', 'arch/AArch64/AArch64Mapping.c', 'arch/AArch64/AArch64Module.c', + 'arch/ARM/ARMBaseInfo.c', 'arch/ARM/ARMDisassembler.c', + 'arch/ARM/ARMDisassemblerExtension.c', 'arch/ARM/ARMInstPrinter.c', 'arch/ARM/ARMMapping.c', 'arch/ARM/ARMModule.c', @@ -53,11 +55,12 @@ cs_files = [ 'arch/TriCore/TriCoreMapping.c', 'arch/TriCore/TriCoreModule.c', 'cs.c', + 'Mapping.c', 'MCInst.c', 'MCInstrDesc.c', + 'MCInstPrinter.c', 'MCRegisterInfo.c', 'SStream.c', - 'Mapping.c', 'utils.c', ] From 7781cec91720b6ae892364d2c11d346659a0367e Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 20 Jul 2023 10:15:09 -0500 Subject: [PATCH 32/53] Fix rebase mistakes --- librz/analysis/arch/arm/arm_il32.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 56f859ac138..594859286f5 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -2975,7 +2975,7 @@ static RzILOpEffect *vldn_multiple_elem(cs_insn *insn, bool is_thumb) { ut32 rm_idx = OPCOUNT() - 1; ut32 rn_idx; ut32 regs = 0; - bool wback = insn->detail->arm.writeback; + bool wback = insn->detail->writeback; bool use_rm_as_wback_offset = false; ut32 group_sz = insn->id - ARM_INS_VLD1 + 1; @@ -3145,7 +3145,7 @@ static RzILOpEffect *vldn_single_lane(cs_insn *insn, bool is_thumb) { return NULL; } - bool wback = insn->detail->arm.writeback; + bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); @@ -3234,7 +3234,7 @@ static RzILOpEffect *vldn_all_lane(cs_insn *insn, bool is_thumb) { return NULL; } - bool wback = insn->detail->arm.writeback; + bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); @@ -3269,7 +3269,7 @@ static RzILOpEffect *vstn_multiple_elem(cs_insn *insn, bool is_thumb) { ut32 rm_idx = OPCOUNT() - 1; ut32 rn_idx; ut32 regs = 0; - bool wback = insn->detail->arm.writeback; + bool wback = insn->detail->writeback; bool use_rm_as_wback_offset = false; ut32 group_sz = insn->id - ARM_INS_VST1 + 1; @@ -3434,7 +3434,7 @@ static RzILOpEffect *vstn_from_single_lane(cs_insn *insn, bool is_thumb) { return NULL; } - bool wback = insn->detail->arm.writeback; + bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); @@ -4018,7 +4018,6 @@ static RzILOpEffect *il_unconditional(csh *handle, cs_insn *insn, bool is_thumb) case ARM_INS_PLD: case ARM_INS_PLDW: case ARM_INS_PLI: - case ARM_INS_YIELD: // barriers/synchronization case ARM_INS_DMB: case ARM_INS_DSB: From 3c5fc456ef34e6b756ca5cdf60b86b89ea4ae126 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 20 Jul 2023 10:17:26 -0500 Subject: [PATCH 33/53] Check for NEON features. --- librz/analysis/arch/arm/arm_cs.h | 2 ++ librz/analysis/arch/arm/arm_il32.c | 32 +++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/librz/analysis/arch/arm/arm_cs.h b/librz/analysis/arch/arm/arm_cs.h index 5fc14a1e755..b5f7161e815 100644 --- a/librz/analysis/arch/arm/arm_cs.h +++ b/librz/analysis/arch/arm/arm_cs.h @@ -10,6 +10,8 @@ RZ_IPI int rz_arm_cs_analysis_op_32_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn, bool thumb); RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn); +RZ_IPI bool rz_arm_cs_is_group_member(const cs_insn *insn, arm_insn_group feature); + RZ_IPI const char *rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type); RZ_IPI RzILOpEffect *rz_arm_cs_32_il(csh *handle, cs_insn *insn, bool thumb); diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 594859286f5..9a131f9e1ab 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include #include #include "arm_cs.h" @@ -11,6 +12,27 @@ #include "arm_il_common.inc" +/** + * \brief Tests if the instruction is part of the given group. + * + * \param insn The instruction to test. + * \param group The group to test for. + * \return true The instruction is part of the group. + * \return false The instruction is not part of the group. + */ +RZ_IPI bool rz_arm_cs_is_group_member(RZ_NONNULL const cs_insn *insn, arm_insn_group group) { + rz_return_val_if_fail(insn && insn->detail, false); + uint32_t i = 0; + arm_insn_group group_it = insn->detail->groups[i]; + while (group_it) { + if (group_it == group) { + return true; + } + group_it = insn->detail->groups[++i]; + } + return false; +} + /** * All regs available as global IL variables */ @@ -3554,7 +3576,7 @@ static RzILOpEffect *try_as_int_cvt(cs_insn *insn, bool is_thumb, bool *success) bv_sz = cvt_isize(VVEC_DT(insn), &is_signed); ut32 fl_sz = rz_float_get_format_info(is_f2i ? from_fmt : to_fmt, RZ_FLOAT_INFO_TOTAL_LEN); - if (insn->detail->groups[0] != ARM_GRP_NEON) { + if (!rz_arm_cs_is_group_member(insn, ARM_FEATURE_HasNEON)) { // vfp // VCVT.F64.S32/U32
, // VCVT.F32.S32/U32 , @@ -3789,7 +3811,7 @@ static RzILOpEffect *vadd(cs_insn *insn, bool is_thumb) { RzFloatFormat fmt = dt2fmt(dt); bool is_float_vec = fmt == RZ_FLOAT_UNK ? false : true; - if (insn->detail->groups[0] != ARM_GRP_NEON) { + if (!rz_arm_cs_is_group_member(insn, ARM_FEATURE_HasNEON)) { // VFP return write_reg(REGID(0), F2BV(FADD(RZ_FLOAT_RMODE_RNE, @@ -3836,7 +3858,7 @@ static RzILOpEffect *vsub(cs_insn *insn, bool is_thumb) { RzFloatFormat fmt = dt2fmt(dt); bool is_float_vec = fmt == RZ_FLOAT_UNK ? false : true; - if (insn->detail->groups[0] != ARM_GRP_NEON) { + if (!rz_arm_cs_is_group_member(insn, ARM_FEATURE_HasNEON)) { // VFP return write_reg(REGID(0), F2BV(FSUB(RZ_FLOAT_RMODE_RNE, @@ -3881,7 +3903,7 @@ static RzILOpEffect *vmul(cs_insn *insn, bool is_thumb) { arm_vectordata_type dt = VVEC_DT(insn); RzFloatFormat fmt = dt2fmt(dt); - if (insn->detail->groups[0] != ARM_GRP_NEON) { + if (!rz_arm_cs_is_group_member(insn, ARM_FEATURE_HasNEON)) { // VFP fmul return write_reg(REGID(0), F2BV(FMUL(RZ_FLOAT_RMODE_RNE, @@ -3978,7 +4000,7 @@ static RzILOpEffect *vabs(cs_insn *insn, bool is_thumb) { return NULL; } - if (insn->detail->groups[0] == ARM_GRP_NEON) { + if (rz_arm_cs_is_group_member(insn, ARM_FEATURE_HasNEON)) { // not implement return NULL; } From d51cf41cd39d407a011df15b32c77e3c7eb67ccc Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 21 Jul 2023 09:31:36 -0500 Subject: [PATCH 34/53] Fix tests where ldr was replaced with pop --- test/db/asm/arm_32 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index bb743ef35c1..b3e554fbed0 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -196,7 +196,7 @@ d "orreq r6, r6, r2, lsr 1" a2608601 d "orreq r3, r3, -0x80000000" 02318303 d "orrne r0, r0, r1, lsl ip" 110c8011 d "orrne r1, r1, r3" 03108111 -d "ldreq pc, [sp], 4" 04f09d04 +d "popeq {pc}" 04f09d04 d "popeq {r4, pc}" 1080bd08 d "popeq {r4, r5, pc}" 3080bd08 d "popeq {r3, r4, r5, pc}" 3880bd08 @@ -439,7 +439,7 @@ d "stmib r0, {r1, r3, r4}" 1a0080e9 0x0 (seq (storew 0 (+ (var r0) (bv 32 0x4)) d "stmib r0!, {r1, r3, r4}" 1a00a0e9 0x0 (seq (storew 0 (+ (var r0) (bv 32 0x4)) (var r1)) (storew 0 (+ (var r0) (bv 32 0x8)) (var r3)) (storew 0 (+ (var r0) (bv 32 0xc)) (var r4)) (set r0 (+ (var r0) (bv 32 0xc)))) d "stmdb r0, {r1, r3, r4}" 1a0000e9 0x0 (seq (storew 0 (- (var r0) (bv 32 0xc)) (var r1)) (storew 0 (- (var r0) (bv 32 0x8)) (var r3)) (storew 0 (- (var r0) (bv 32 0x4)) (var r4))) d "stmdb r0!, {r1, r3, r4}" 1a0020e9 0x0 (seq (storew 0 (- (var r0) (bv 32 0xc)) (var r1)) (storew 0 (- (var r0) (bv 32 0x8)) (var r3)) (storew 0 (- (var r0) (bv 32 0x4)) (var r4)) (set r0 (- (var r0) (bv 32 0xc)))) -d "ldr fp, [sp], 4" 04b09de4 0x0 (seq (set r11 (loadw 0 32 (var sp))) (set sp (+ (var sp) (bv 32 0x4)))) +d "pop {fp}" 04b09de4 0x0 (seq (set base (var sp)) (set r11 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set sp (+ (var base) (bv 32 0x4)))) d "pop {r3, pc}" 0880bde8 0x0 (seq (set base (var sp)) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set tgt (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set sp (+ (var base) (bv 32 0x8))) (jmp (var tgt))) d "ldm r0, {r1, r3, r4}" 1a0090e8 0x0 (seq (set base (var r0)) (set r1 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set r4 (loadw 0 32 (+ (var base) (bv 32 0x8))))) d "ldm r0!, {r1, r3, r4}" 1a00b0e8 0x0 (seq (set base (var r0)) (set r1 (loadw 0 32 (+ (var base) (bv 32 0x0)))) (set r3 (loadw 0 32 (+ (var base) (bv 32 0x4)))) (set r4 (loadw 0 32 (+ (var base) (bv 32 0x8)))) (set r0 (+ (var base) (bv 32 0xc)))) From 7229d5a018f38d0128ea84cb933d6f797079be65 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 21 Jul 2023 09:41:23 -0500 Subject: [PATCH 35/53] Fix postindex 8byte store --- librz/analysis/arch/arm/arm_esil32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 24dfd29b162..719120052e6 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -648,8 +648,8 @@ r6,r5,r4,3,sp,[*],12,sp,+= int disp = MEMDISP(2); char sign = disp >= 0 ? '+' : '-'; disp = disp >= 0 ? disp : -disp; - rz_strbuf_appendf(&op->esil, "%s,%d,%s,%c,0xffffffff,&,=[4],%s,4,%d,+,%s,%c,0xffffffff,&,=[4]", - REG(0), disp, MEMBASE(2), sign, REG(1), disp, MEMBASE(2), sign); + rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[4],%s,4,%s,+,0xffffffff,&,=[4]", + REG(0), MEMBASE(2), REG(1), MEMBASE(2)); if (insn->detail->writeback) { rz_strbuf_appendf(&op->esil, ",%d,%s,%c,%s,=", disp, MEMBASE(2), sign, MEMBASE(2)); From cbe6366ec43672259f887d60db15d88f3d9509dc Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 21 Jul 2023 10:45:01 -0500 Subject: [PATCH 36/53] Remove unreachable code for ESIL LDR. --- librz/analysis/arch/arm/arm_esil32.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 719120052e6..8b99dfaa617 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -800,15 +800,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",2,2,%s,>>,<<,+,0xffffffff,&,[4],0x%x,&,%s,=", (ut64)MEMDISP(1), pc, mask, REG(0)); } else { - int disp = MEMDISP(1); + st64 disp = MEMDISP(1); // not refptr, because we can't grab the reg value statically op->refptr = 4; - if (disp < 0) { - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,[4],0x%x,&,%s,=", - (ut64)-disp, MEMBASE(1), mask, REG(0)); - } else { - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,+,0xffffffff,&,[4],0x%x,&,%s,=", - (ut64)disp, MEMBASE(1), mask, REG(0)); - } + rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,[4],0x%x,&,%s,=", + (ut64)-disp, MEMBASE(1), mask, REG(0)); } } else { if (ISMEM(1) && REGBASE(1) == ARM_REG_PC) { From 17ca89472a07b753858c93e527ac5009dd111aa7 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 21 Jul 2023 11:42:39 -0500 Subject: [PATCH 37/53] Fix flag check/set of mov instructions with shift. --- librz/analysis/arch/arm/arm_esil32.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 8b99dfaa617..e60ef641616 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -990,22 +990,30 @@ r6,r5,r4,3,sp,[*],12,sp,+= case ARM_INS_CMN: rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=,31,$c,cf,:=,31,$o,vf,:="); break; - case ARM_INS_MOV: + case ARM_INS_MOV: { + // Move has already set the dest register at this point. + // But mind that ARG() always includes the shift of the source register. + // If the source register is the same as the destination register it would shift the value twice. + // We need to prepend the move (already in op->esil) to the flag check. + char move_esil[64]; switch (SHIFTTYPE(1)) { default: break; case ARM_SFT_LSL: case ARM_SFT_LSL_REG: - rz_strbuf_appendf(&op->esil, ",%s,!,!,?{,%s,32,-,%s,>>,cf,:=,}", ARG(1), ARG(1), ARG(0)); + rz_strf(move_esil, "%s", rz_strbuf_drain_nofree(&op->esil)); + rz_strbuf_appendf(&op->esil, ",%s,!,!,?{,%s,32,-,%s,>>,cf,:=,},%s", ARG(1), ARG(1), ARG(0), move_esil); break; case ARM_SFT_LSR: case ARM_SFT_LSR_REG: case ARM_SFT_ASR: case ARM_SFT_ASR_REG: - rz_strbuf_appendf(&op->esil, ",%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,}", ARG(1), ARG(0), ARG(1)); + rz_strf(move_esil, "%s", rz_strbuf_drain_nofree(&op->esil)); + rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},%s", ARG(1), ARG(0), ARG(1), move_esil); break; } - // fallthrough + } + // fallthrough default: rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:="); } From 2c0d744d6bc645b0f47cea08607ecaa5b5be1c0f Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 21 Jul 2023 12:15:04 -0500 Subject: [PATCH 38/53] Check for subtracted flag of mem.disp. --- librz/analysis/p/analysis_arm_cs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index af6dd27bc5c..5fe01f499d7 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -159,7 +159,11 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { pj_ks(pj, "index", cs_reg_name(handle, op->mem.index)); } pj_ki(pj, "scale", op->mem.scale); +#if CS_API_MAJOR >= 6 + pj_ki(pj, "disp", (op->subtracted ? -op->mem.disp : op->mem.disp)); +#else pj_ki(pj, "disp", op->mem.disp); +#endif break; case ARM_OP_FP: pj_ks(pj, "type", "fp"); @@ -1585,7 +1589,11 @@ static void set_src_dst(RzAnalysisValue *val, RzReg *reg, csh *handle, cs_insn * #if CS_API_MAJOR > 3 val->mul = armop.mem.scale << armop.mem.lshift; #endif +#if CS_API_MAJOR >= 6 + val->delta = armop.subtracted ? -armop.mem.disp : armop.mem.disp; +#else val->delta = armop.mem.disp; +#endif break; case ARM_OP_IMM: val->type = RZ_ANALYSIS_VAL_IMM; From a0e905fe245c454bd3b5bb12df94c9cb404fdbc1 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 07:12:25 -0500 Subject: [PATCH 39/53] Use macro for disp access --- librz/analysis/p/analysis_arm_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 5fe01f499d7..a376dde4950 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -1590,7 +1590,7 @@ static void set_src_dst(RzAnalysisValue *val, RzReg *reg, csh *handle, cs_insn * val->mul = armop.mem.scale << armop.mem.lshift; #endif #if CS_API_MAJOR >= 6 - val->delta = armop.subtracted ? -armop.mem.disp : armop.mem.disp; + val->delta = MEMDISP(x); #else val->delta = armop.mem.disp; #endif From 7fc913cca480b4e642158afdddbc263c004a9bf2 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 08:21:09 -0500 Subject: [PATCH 40/53] Fix function variable recognition. The variable should not added if sp was only moved. --- librz/analysis/var.c | 5 +++++ test/db/analysis/vars | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/librz/analysis/var.c b/librz/analysis/var.c index 55f5cd91738..1d0eb9b7915 100644 --- a/librz/analysis/var.c +++ b/librz/analysis/var.c @@ -1171,6 +1171,11 @@ static void extract_stack_var(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzA if (*sign == '-') { addend = -addend; } + if (addend == 0 && op->direction != RZ_ANALYSIS_OP_DIR_READ && op->direction != RZ_ANALYSIS_OP_DIR_WRITE) { + // avoid creating variables for just `mov rbp, rsp`, which would otherwise detect a var at rsp+0 + // so for addend == 0, we only consider actual memory operations for now + goto beach; + } } if (!op->src[0] || !op->dst) { diff --git a/test/db/analysis/vars b/test/db/analysis/vars index 7052a1240aa..0d69048d088 100644 --- a/test/db/analysis/vars +++ b/test/db/analysis/vars @@ -427,11 +427,11 @@ afvR arg1 0x6 arg2 0x8 arg3 0xc - var_10h 0x4,0x2c + var_10h var_ch 0x18,0x22 var_eh 0x16,0x1e var_fh 0x10 - var_4h 0x2c + var_4h afvW arg1 arg2 @@ -472,7 +472,7 @@ afvW | `--> 0x00000026 00bf nop | 0x00000028 0c37 adds r7, 0xc | 0x0000002a bd46 mov sp, r7 -| 0x0000002c 5df8047b ldr r7, [sp], 4 +| 0x0000002c 5df8047b pop {r7} \ 0x00000030 7047 bx lr EOF RUN From 9c220a028fccfd71924b9a92e036eacb3112b542 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 09:35:00 -0500 Subject: [PATCH 41/53] Fix json tests --- librz/analysis/p/analysis_arm_cs.c | 4 ---- test/db/cmd/cmd_ao | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index a376dde4950..311fac768fd 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -159,11 +159,7 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { pj_ks(pj, "index", cs_reg_name(handle, op->mem.index)); } pj_ki(pj, "scale", op->mem.scale); -#if CS_API_MAJOR >= 6 - pj_ki(pj, "disp", (op->subtracted ? -op->mem.disp : op->mem.disp)); -#else pj_ki(pj, "disp", op->mem.disp); -#endif break; case ARM_OP_FP: pj_ks(pj, "type", "fp"); diff --git a/test/db/cmd/cmd_ao b/test/db/cmd/cmd_ao index dc96586a4cd..17bb690cfe6 100644 --- a/test/db/cmd/cmd_ao +++ b/test/db/cmd/cmd_ao @@ -117,7 +117,7 @@ aoj~{[0].opex} EOF EXPECT=< Date: Sat, 22 Jul 2023 09:35:29 -0500 Subject: [PATCH 42/53] Fix new id --- test/db/cmd/cmd_a_capital_o | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/db/cmd/cmd_a_capital_o b/test/db/cmd/cmd_a_capital_o index 2c650d6c06e..565bc55788b 100644 --- a/test/db/cmd/cmd_a_capital_o +++ b/test/db/cmd/cmd_a_capital_o @@ -10,6 +10,6 @@ EXPECT=<>,<<,36,+,0xffffffff,&,[4],0xffffffff,&,ip,= -[{"opcode":"ldr ip, [pc, 0x24]","disasm":"ldr ip, sym.__libc_csu_fini","pseudo":"ip = sym.__libc_csu_fini","description":"load from memory to register","mnemonic":"ldr","mask":"ffffffff","esil":"2,2,8,$$,+,>>,<<,36,+,0xffffffff,&,[4],0xffffffff,&,ip,=","rzil":{"opcode":"set","dst":"r12","src":{"opcode":"loadw","mem":0,"key":{"opcode":"bitv","bits":"0x817c","len":32},"bits":32}},"sign":false,"prefix":0,"id":83,"opex":{"operands":[{"type":"reg","value":"ip"},{"type":"mem","base":"pc","scale":1,"disp":36}]},"addr":33104,"bytes":"24c09fe5","disp":36,"ptr":33148,"size":4,"type":"load","esilcost":4,"ireg":"pc","scale":1,"refptr":4,"cycles":4,"failcycles":0,"delay":0,"stackptr":0,"family":"cpu"}] +[{"opcode":"ldr ip, [pc, 0x24]","disasm":"ldr ip, sym.__libc_csu_fini","pseudo":"ip = sym.__libc_csu_fini","description":"load from memory to register","mnemonic":"ldr","mask":"ffffffff","esil":"2,2,8,$$,+,>>,<<,36,+,0xffffffff,&,[4],0xffffffff,&,ip,=","rzil":{"opcode":"set","dst":"r12","src":{"opcode":"loadw","mem":0,"key":{"opcode":"bitv","bits":"0x817c","len":32},"bits":32}},"sign":false,"prefix":0,"id":4,"opex":{"operands":[{"type":"reg","value":"ip"},{"type":"mem","base":"pc","scale":1,"disp":36}]},"addr":33104,"bytes":"24c09fe5","disp":36,"ptr":33148,"size":4,"type":"load","esilcost":4,"ireg":"pc","scale":1,"refptr":4,"cycles":4,"failcycles":0,"delay":0,"stackptr":0,"family":"cpu"}] EOF RUN \ No newline at end of file From 8c039b43ef1a6a62d2b5d2392e19f9415a1b467e Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 10:29:26 -0500 Subject: [PATCH 43/53] Fix post-index ldrd esil instructions --- librz/analysis/arch/arm/arm_esil32.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index e60ef641616..09e5ac1f5fe 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -683,15 +683,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",2,2,%s,%d,+,>>,<<,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", (ut64)MEMDISP(2), pc, pcdelta, REG(0), REG(1)); } else { - int disp = MEMDISP(2); + int disp = ISPOSTINDEX() ? 0 : MEMDISP(2); // not refptr, because we can't grab the reg value statically op->refptr = 4; - if (disp < 0) { - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", - (ut64)-disp, MEMBASE(2), REG(0), REG(1)); - } else { - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", - (ut64)disp, MEMBASE(2), REG(0), REG(1)); - } + rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", + (ut64)-disp, MEMBASE(2), REG(0), REG(1)); } } else { if (REGBASE(2) == ARM_REG_PC) { @@ -712,8 +707,9 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%s,%s,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", MEMINDEX(2), MEMBASE(2), op_index, REG(0), REG(1)); } else { + int disp = ISPOSTINDEX() ? 0 : MEMDISP(2); rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", - MEMDISP(2), MEMBASE(2), REG(0), REG(1)); + disp, MEMBASE(2), REG(0), REG(1)); } if (insn->detail->writeback) { if (ISPOSTINDEX()) { From 75a7ff2531a135cc418b7a76940b810ad81a5394 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 11:05:51 -0500 Subject: [PATCH 44/53] Fix ARM64 tests by separating their esil condition code. --- librz/analysis/arch/arm/arm_cs.h | 3 +- librz/analysis/arch/arm/arm_esil32.c | 4 +- librz/analysis/arch/arm/arm_esil64.c | 75 +++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/librz/analysis/arch/arm/arm_cs.h b/librz/analysis/arch/arm/arm_cs.h index b5f7161e815..8bfaa543e50 100644 --- a/librz/analysis/arch/arm/arm_cs.h +++ b/librz/analysis/arch/arm/arm_cs.h @@ -12,7 +12,8 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a RZ_IPI bool rz_arm_cs_is_group_member(const cs_insn *insn, arm_insn_group feature); -RZ_IPI const char *rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type); +RZ_IPI const char *rz_arm32_cs_esil_prefix_cond(RzAnalysisOp *op, ARMCC_CondCodes cond_type); +RZ_IPI const char *rz_arm64_cs_esil_prefix_cond(RzAnalysisOp *op, arm64_cc cond_type); RZ_IPI RzILOpEffect *rz_arm_cs_32_il(csh *handle, cs_insn *insn, bool thumb); RZ_IPI RzAnalysisILConfig *rz_arm_cs_32_il_config(bool big_endian); diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 09e5ac1f5fe..d7dc40ca509 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -60,7 +60,7 @@ static unsigned int regsize32(cs_insn *insn, int n) { #define REGSIZE32(x) regsize32(insn, x) // return postfix -RZ_IPI const char *rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type) { +RZ_IPI const char *rz_arm32_cs_esil_prefix_cond(RzAnalysisOp *op, ARMCC_CondCodes cond_type) { const char *close_cond[2]; close_cond[0] = ""; close_cond[1] = ",}"; @@ -256,7 +256,7 @@ RZ_IPI int rz_arm_cs_analysis_op_32_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a rz_strbuf_init(&op->esil); rz_strbuf_set(&op->esil, ""); - postfix = rz_arm_cs_esil_prefix_cond(op, insn->detail->arm.cc); + postfix = rz_arm32_cs_esil_prefix_cond(op, insn->detail->arm.cc); switch (insn->id) { case ARM_INS_CLZ: diff --git a/librz/analysis/arch/arm/arm_esil64.c b/librz/analysis/arch/arm/arm_esil64.c index 91c5787e313..30e04b51635 100644 --- a/librz/analysis/arch/arm/arm_esil64.c +++ b/librz/analysis/arch/arm/arm_esil64.c @@ -11,6 +11,79 @@ #define MEMBASE64(x) rz_str_get_null(cs_reg_name(*handle, insn->detail->arm64.operands[x].mem.base)) #define MEMINDEX64(x) rz_str_get_null(cs_reg_name(*handle, insn->detail->arm64.operands[x].mem.index)) +RZ_IPI const char *rz_arm64_cs_esil_prefix_cond(RzAnalysisOp *op, arm64_cc cond_type) { + const char *close_cond[2]; + close_cond[0] = ""; + close_cond[1] = ",}"; + int close_type = 0; + switch (cond_type) { + case ARM64_CC_EQ: + close_type = 1; + rz_strbuf_setf(&op->esil, "zf,?{,"); + break; + case ARM64_CC_NE: + close_type = 1; + rz_strbuf_setf(&op->esil, "zf,!,?{,"); + break; + case ARM64_CC_HS: + close_type = 1; + rz_strbuf_setf(&op->esil, "cf,?{,"); + break; + case ARM64_CC_LO: + close_type = 1; + rz_strbuf_setf(&op->esil, "cf,!,?{,"); + break; + case ARM64_CC_MI: + close_type = 1; + rz_strbuf_setf(&op->esil, "nf,?{,"); + break; + case ARM64_CC_PL: + close_type = 1; + rz_strbuf_setf(&op->esil, "nf,!,?{,"); + break; + case ARM64_CC_VS: + close_type = 1; + rz_strbuf_setf(&op->esil, "vf,?{,"); + break; + case ARM64_CC_VC: + close_type = 1; + rz_strbuf_setf(&op->esil, "vf,!,?{,"); + break; + case ARM64_CC_HI: + close_type = 1; + rz_strbuf_setf(&op->esil, "cf,zf,!,&,?{,"); + break; + case ARM64_CC_LS: + close_type = 1; + rz_strbuf_setf(&op->esil, "cf,!,zf,|,?{,"); + break; + case ARM64_CC_GE: + close_type = 1; + rz_strbuf_setf(&op->esil, "nf,vf,^,!,?{,"); + break; + case ARM64_CC_LT: + close_type = 1; + rz_strbuf_setf(&op->esil, "nf,vf,^,?{,"); + break; + case ARM64_CC_GT: + // zf == 0 && nf == vf + close_type = 1; + rz_strbuf_setf(&op->esil, "zf,!,nf,vf,^,!,&,?{,"); + break; + case ARM64_CC_LE: + // zf == 1 || nf != vf + close_type = 1; + rz_strbuf_setf(&op->esil, "zf,nf,vf,^,|,?{,"); + break; + case ARM64_CC_AL: + // always executed + break; + default: + break; + } + return close_cond[close_type]; +} + static int arm64_reg_width(int reg) { switch (reg) { case ARM64_REG_W0: @@ -205,7 +278,7 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a rz_strbuf_init(&op->esil); rz_strbuf_set(&op->esil, ""); - postfix = rz_arm_cs_esil_prefix_cond(op, insn->detail->arm64.cc); + postfix = rz_arm64_cs_esil_prefix_cond(op, insn->detail->arm64.cc); switch (insn->id) { case ARM64_INS_REV: From 837dcb5634131609f4bbd7cd66696bd62d5bfe2a Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 11:48:16 -0500 Subject: [PATCH 45/53] Fix shift of post index stores --- librz/analysis/arch/arm/arm_esil32.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index d7dc40ca509..b0d5e5cfa3d 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -614,23 +614,23 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=", REG(0), MEMBASE(1), str_ldr_bytes, MEMDISP(1), MEMBASE(1)); } else if (str_ldr_bytes != 8) { // e.g. 'str r2, [r3], r1 - if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4' - switch (SHIFTTYPE(2)) { + if (ISSHIFTED(1)) { // e.g. 'str r2, [r3], r1, lsl 4' + switch (SHIFTTYPE(1)) { case ARM_SFT_LSL: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,<<,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_LSR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_ASR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_ROR: rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>,+,%s,=", - REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), MEMINDEX(1), MEMBASE(1)); + REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1)); break; case ARM_SFT_RRX: // TODO From f7d50dbb3af70e999405303fda4b3cc637bc8616 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 12:31:07 -0500 Subject: [PATCH 46/53] Fix more post index memory instructions. --- librz/analysis/arch/arm/arm_esil32.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index b0d5e5cfa3d..cf0b9052df6 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -702,10 +702,11 @@ r6,r5,r4,3,sp,[*],12,sp,+= pcdelta, pc, MEMDISP(2), REG(0), REG(1)); } } else { - if (HASMEMINDEX(2)) { // e.g. `ldrd r2, r3 [r4, r1]` + if (HASMEMINDEX(2)) { // e.g. `ldrd r2, r3 [r4, r1]` or `ldrd r2, r3 [r4], r1` const char op_index = ISMEMINDEXSUB(2) ? '-' : '+'; + const char *mem_index = ISPOSTINDEX() ? "0" : MEMINDEX(2); rz_strbuf_appendf(&op->esil, "%s,%s,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", - MEMINDEX(2), MEMBASE(2), op_index, REG(0), REG(1)); + mem_index, MEMBASE(2), op_index, REG(0), REG(1)); } else { int disp = ISPOSTINDEX() ? 0 : MEMDISP(2); rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=", @@ -717,9 +718,9 @@ r6,r5,r4,3,sp,[*],12,sp,+= rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=", MEMBASE(2), MEMDISP(2), MEMBASE(2)); } else { - const char op_index = ISMEMINDEXSUB(3) ? '-' : '+'; + const char op_index = ISMEMINDEXSUB(2) ? '-' : '+'; rz_strbuf_appendf(&op->esil, ",%s,%s,%c,%s,=", - REG(3), MEMBASE(2), op_index, MEMBASE(2)); + MEMINDEX(2), MEMBASE(2), op_index, MEMBASE(2)); } } else if (ISPREINDEX32()) { if (HASMEMINDEX(2)) { From 5afd6f8c2618761b5b5115ad22a68777de89a8db Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 22 Jul 2023 12:42:11 -0500 Subject: [PATCH 47/53] Fix invalid variable recognition. --- test/db/formats/elf/thumb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/db/formats/elf/thumb b/test/db/formats/elf/thumb index 0c85b0c267c..af682a4bfd6 100644 --- a/test/db/formats/elf/thumb +++ b/test/db/formats/elf/thumb @@ -118,7 +118,7 @@ EXPECT=< Date: Sun, 23 Jul 2023 11:00:46 -0500 Subject: [PATCH 48/53] Use https://github.com/capstone-engine/capstone/pull/2122 for better system operand support. --- librz/analysis/arch/arm/arm_accessors32.h | 1 + librz/analysis/arch/arm/arm_esil32.c | 5 ++++- librz/analysis/arch/arm/arm_il32.c | 10 +++++----- test/db/tools/rz_asm | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 4a4b472e9b6..7d3d5b06858 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -21,6 +21,7 @@ #define MEMDISP_BV(x) (HASMEMINDEX(x) ? REG_VAL(insn->detail->arm.operands[x].mem.index) : U32(MEMDISP(x))) #define ISIMM(x) (insn->detail->arm.operands[x].type == ARM_OP_IMM || insn->detail->arm.operands[x].type == ARM_OP_FP) #define ISREG(x) (insn->detail->arm.operands[x].type == ARM_OP_REG) +#define ISPSRFLAGS(x) (insn->detail->arm.operands[x].type == ARM_OP_CPSR || insn->detail->arm.operands[x].type == ARM_OP_SPSR) #define ISMEM(x) (insn->detail->arm.operands[x].type == ARM_OP_MEM) #define ISFPIMM(x) (insn->detail->arm.operands[x].type == ARM_OP_FP) diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index cf0b9052df6..507cc611928 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -844,7 +844,7 @@ r6,r5,r4,3,sp,[*],12,sp,+= // TODO: esil for MRS break; case ARM_INS_MSR: - msr_flags = insn->detail->arm.operands[0].reg >> 4; + msr_flags = insn->detail->arm.operands[0].sysop.msr_mask; rz_strbuf_appendf(&op->esil, "0,"); if (msr_flags & 1) { rz_strbuf_appendf(&op->esil, "0xFF,|,"); @@ -976,6 +976,9 @@ r6,r5,r4,3,sp,[*],12,sp,+= // many errors if (insn->detail->arm.update_flags) { switch (insn->id) { + case ARM_INS_MSR: + // Updates flags manually + break; case ARM_INS_CMP: rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=,32,$b,!,cf,:=,31,$o,vf,:="); break; diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 9a131f9e1ab..8f75449a6f6 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -1477,10 +1477,10 @@ static RzILOpEffect *mla(cs_insn *insn, bool is_thumb) { * ARM: mrs */ static RzILOpEffect *mrs(cs_insn *insn, bool is_thumb) { - if (!ISREG(0) || !ISREG(1)) { + if (!ISREG(0) || !(ISREG(1) || ISPSRFLAGS(1))) { return NULL; } - if (REGID(1) != ARM_REG_CPSR && REGID(1) != ARM_REG_SPSR && REGID(1) != ARM_REG_APSR) { + if (REGID(1) != ARM_REG_CPSR && REGID(1) != ARM_REG_SPSR && REGID(1) != ARM_REG_APSR && !ISPSRFLAGS(1)) { // only these regs supported return NULL; } @@ -1500,7 +1500,7 @@ static RzILOpEffect *mrs(cs_insn *insn, bool is_thumb) { */ static RzILOpEffect *msr(cs_insn *insn, bool is_thumb) { cs_arm_op *dst = &insn->detail->arm.operands[0]; - if (dst->type != ARM_OP_SYSREG) { + if ((dst->type != ARM_OP_SYSREG) && (dst->type != ARM_OP_CPSR) && (dst->type != ARM_OP_SPSR)) { return NULL; } // check if the reg+mask contains any of the flags we have: @@ -1518,8 +1518,8 @@ static RzILOpEffect *msr(cs_insn *insn, bool is_thumb) { update_s = true; break; default: - update_f = (dst->reg & ARM_SYSREG_CPSR_F) || (dst->reg & ARM_SYSREG_SPSR_F); - update_s = (dst->reg & ARM_SYSREG_CPSR_S) || (dst->reg & ARM_SYSREG_SPSR_S); + update_f = (dst->sysop.psr_bits & ARM_FIELD_CPSR_F) || (dst->sysop.psr_bits & ARM_FIELD_SPSR_F); + update_s = (dst->sysop.psr_bits & ARM_FIELD_CPSR_S) || (dst->sysop.psr_bits & ARM_FIELD_SPSR_S); break; } if (!update_f && !update_s) { diff --git a/test/db/tools/rz_asm b/test/db/tools/rz_asm index ce7afca77c6..b990402cbe5 100644 --- a/test/db/tools/rz_asm +++ b/test/db/tools/rz_asm @@ -395,6 +395,7 @@ EOF RUN NAME=rz-asm -A with -c and -o +BROKEN=1 FILE== CMDS=!rz-asm -a arm -b 16 -A -o 0x1000 -c cortexm 0x80f30988 EXPECT=< Date: Sun, 23 Jul 2023 11:08:52 -0500 Subject: [PATCH 49/53] Distinguish between 32 and 64bit cc check. --- librz/analysis/p/analysis_arm_cs.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 311fac768fd..1b9179d6322 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -514,7 +514,7 @@ static void opex64(RzStrBuf *buf, csh handle, cs_insn *insn) { pj_free(pj); } -static int cond_cs2r2(int cc) { +static int cond_cs2r2_32(int cc) { if (cc == ARMCC_AL || cc < 0) { cc = RZ_TYPE_COND_AL; } else { @@ -538,6 +538,30 @@ static int cond_cs2r2(int cc) { return cc; } +static int cond_cs2r2_64(int cc) { + if (cc == ARMCC_AL || cc < 0) { + cc = RZ_TYPE_COND_AL; + } else { + switch (cc) { + case ARM64_CC_EQ: cc = RZ_TYPE_COND_EQ; break; + case ARM64_CC_NE: cc = RZ_TYPE_COND_NE; break; + case ARM64_CC_HS: cc = RZ_TYPE_COND_HS; break; + case ARM64_CC_LO: cc = RZ_TYPE_COND_LO; break; + case ARM64_CC_MI: cc = RZ_TYPE_COND_MI; break; + case ARM64_CC_PL: cc = RZ_TYPE_COND_PL; break; + case ARM64_CC_VS: cc = RZ_TYPE_COND_VS; break; + case ARM64_CC_VC: cc = RZ_TYPE_COND_VC; break; + case ARM64_CC_HI: cc = RZ_TYPE_COND_HI; break; + case ARM64_CC_LS: cc = RZ_TYPE_COND_LS; break; + case ARM64_CC_GE: cc = RZ_TYPE_COND_GE; break; + case ARM64_CC_LT: cc = RZ_TYPE_COND_LT; break; + case ARM64_CC_GT: cc = RZ_TYPE_COND_GT; break; + case ARM64_CC_LE: cc = RZ_TYPE_COND_LE; break; + } + } + return cc; +} + static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { csh handle = ctx->handle; ut64 addr = op->addr; @@ -559,7 +583,7 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { op->family = RZ_ANALYSIS_OP_FAMILY_CPU; } - op->cond = cond_cs2r2(insn->detail->arm64.cc); + op->cond = cond_cs2r2_64(insn->detail->arm64.cc); if (op->cond == RZ_TYPE_COND_NV) { op->type = RZ_ANALYSIS_OP_TYPE_NOP; return; @@ -986,7 +1010,7 @@ static void anop32(RzAnalysis *a, csh handle, RzAnalysisOp *op, cs_insn *insn, b const int pcdelta = thumb ? 4 : 8; int i; - op->cond = cond_cs2r2(insn->detail->arm.cc); + op->cond = cond_cs2r2_32(insn->detail->arm.cc); if (op->cond == RZ_TYPE_COND_NV) { op->type = RZ_ANALYSIS_OP_TYPE_NOP; return; From 18dc5d7b242479d8487430f88e29b063510d91ee Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sun, 23 Jul 2023 11:26:17 -0500 Subject: [PATCH 50/53] Check for CS API version >5 --- librz/analysis/arch/ppc/ppc_il_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/librz/analysis/arch/ppc/ppc_il_ops.c b/librz/analysis/arch/ppc/ppc_il_ops.c index c74a92d982f..3bcfb74b6d7 100644 --- a/librz/analysis/arch/ppc/ppc_il_ops.c +++ b/librz/analysis/arch/ppc/ppc_il_ops.c @@ -1050,7 +1050,8 @@ static RzILOpEffect *shift_and_rotate(RZ_BORROW csh handle, RZ_BORROW cs_insn *i // C/CL/CR Clear, clear left/right // M/NM/MI Mask, AND with mask, mask insert -#if CS_API_MAJOR == 5 && CS_API_MINOR == 0 +// FIXME: With update to auto-sync ppc arch +#if CS_API_MAJOR >= 5 && CS_API_MINOR == 0 // weird bug on capstone v5.0 if (id == PPC_INS_CLRLDI && !strcmp(insn->mnemonic, "rldicl")) { id = PPC_INS_RLDICL; From 23c371c32a555d3a588547f4d735aab9f818e021 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Mon, 24 Jul 2023 02:57:22 -0500 Subject: [PATCH 51/53] Check for CS_NEXT_VERSION instead of CS_API_MAJOR. --- librz/analysis/p/analysis_arm_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 1b9179d6322..5ee9180dc42 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -1609,7 +1609,7 @@ static void set_src_dst(RzAnalysisValue *val, RzReg *reg, csh *handle, cs_insn * #if CS_API_MAJOR > 3 val->mul = armop.mem.scale << armop.mem.lshift; #endif -#if CS_API_MAJOR >= 6 +#if CS_NEXT_VERSION == 6 val->delta = MEMDISP(x); #else val->delta = armop.mem.disp; From 3341388feed1a091a9aab4c1a21cde42a7bfb6f7 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 7 Sep 2023 13:36:44 -0500 Subject: [PATCH 52/53] Fix VSTn and VLDn instructions to use corrected memory operands. --- librz/analysis/arch/arm/arm_il32.c | 115 ++++++++++++----------------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il32.c b/librz/analysis/arch/arm/arm_il32.c index 8f75449a6f6..61229b52228 100644 --- a/librz/analysis/arch/arm/arm_il32.c +++ b/librz/analysis/arch/arm/arm_il32.c @@ -257,6 +257,7 @@ static inline RzFloatFormat cvtdt2fmt(arm_vectordata_type type, bool choose_src) #define REG_VAL(id) read_reg(PC(insn->address, is_thumb), id) #define REG(n) REG_VAL(REGID(n)) #define MEMBASE(x) REG_VAL(insn->detail->arm.operands[x].mem.base) +#define MEMINDEX(x) REG_VAL(insn->detail->arm.operands[x].mem.index) #define DT_WIDTH(insn) arm_data_width(insn->detail->arm.vector_data) #define REG_WIDTH(n) reg_bits(REGID(n)) #define VVEC_SIZE(insn) insn->detail->arm.vector_size @@ -2994,25 +2995,20 @@ static RzILOpEffect *vtst(cs_insn *insn, bool is_thumb) { } static RzILOpEffect *vldn_multiple_elem(cs_insn *insn, bool is_thumb) { - ut32 rm_idx = OPCOUNT() - 1; - ut32 rn_idx; + ut32 mem_idx; ut32 regs = 0; bool wback = insn->detail->writeback; bool use_rm_as_wback_offset = false; ut32 group_sz = insn->id - ARM_INS_VLD1 + 1; // vldn {list}, [Rn], Rm - if (!ISMEM(rm_idx)) { - regs = OPCOUNT() - 2; + if (ISPOSTINDEX()) { use_rm_as_wback_offset = true; - } else { - // vldn {list}, [Rn] - rm_idx = -1; - regs = OPCOUNT() - 1; } + regs = OPCOUNT() - 1; // mem_idx - rn_idx = regs; + mem_idx = regs; // assert list_size % n == 0 // assert they were all Dn @@ -3020,11 +3016,11 @@ static RzILOpEffect *vldn_multiple_elem(cs_insn *insn, bool is_thumb) { ut32 elem_bits = VVEC_SIZE(insn); ut32 elem_bytes = elem_bits / 8; ut32 lanes = 64 / elem_bits; - ut32 addr_bits = REG_WIDTH(rn_idx); + ut32 addr_bits = REG_WIDTH(mem_idx); RzILOpEffect *wback_eff = NULL; RzILOpEffect *eff = EMPTY(); - RzILOpBitVector *addr = ARG(rn_idx); + RzILOpBitVector *addr = ISPOSTINDEX() ? MEMBASE(mem_idx) : ARG(mem_idx); for (int i = 0; i < n_groups; ++i) { for (int j = 0; j < lanes; ++j) { @@ -3083,8 +3079,8 @@ static RzILOpEffect *vldn_multiple_elem(cs_insn *insn, bool is_thumb) { // update Rn // if write_back then Rn = Rn + (if use_rm then Rm else 8 * regs) if (wback) { - RzILOpBitVector *new_offset = use_rm_as_wback_offset ? ARG(rm_idx) : UN(32, 8 * regs); - wback_eff = write_reg(REGID(rn_idx), ADD(REG(rn_idx), new_offset)); + RzILOpBitVector *new_offset = use_rm_as_wback_offset ? MEMINDEX(mem_idx) : UN(32, 8 * regs); + wback_eff = write_reg(REGBASE(mem_idx), ADD(MEMBASE(mem_idx), new_offset)); } else { wback_eff = EMPTY(); } @@ -3094,19 +3090,15 @@ static RzILOpEffect *vldn_multiple_elem(cs_insn *insn, bool is_thumb) { #if CS_API_MAJOR > 3 static RzILOpEffect *vldn_single_lane(cs_insn *insn, bool is_thumb) { - ut32 rm_idx = OPCOUNT() - 1; - ut32 rn_idx; - bool use_rm = false; + ut32 mem_idx; + bool use_rm_as_wback_offset = false; ut32 regs; // number of regs in {list} - if (!ISMEM(rm_idx)) { - use_rm = true; - regs = OPCOUNT() - 2; - } else { - rm_idx = -1; - regs = OPCOUNT() - 1; + if (ISPOSTINDEX()) { + use_rm_as_wback_offset = true; } - rn_idx = regs; + regs = OPCOUNT() - 1; + mem_idx = regs; ut32 group_sz = insn->id - ARM_INS_VLD1 + 1; if (group_sz != regs) { @@ -3115,11 +3107,11 @@ static RzILOpEffect *vldn_single_lane(cs_insn *insn, bool is_thumb) { RzILOpBitVector *data0, *data1, *data2, *data3; RzILOpEffect *eff; - RzILOpBitVector *addr = ARG(rn_idx); + RzILOpBitVector *addr = ISPOSTINDEX() ? MEMBASE(mem_idx) : ARG(mem_idx); ut32 vreg_idx = 0; ut32 elem_bits = VVEC_SIZE(insn); ut32 elem_bytes = elem_bits / 8; - ut32 addr_bits = REG_WIDTH(rn_idx); + ut32 addr_bits = REG_WIDTH(mem_idx); // vld1/vld2/vld3/vld4, max(lane_size) == 4 Bytes if (group_sz > 4 || elem_bytes > 4) { @@ -3170,8 +3162,8 @@ static RzILOpEffect *vldn_single_lane(cs_insn *insn, bool is_thumb) { bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { - RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); - wback_eff = write_reg(REGID(rn_idx), ADD(REG(rn_idx), new_offset)); + RzILOpBitVector *new_offset = use_rm_as_wback_offset ? MEMINDEX(mem_idx) : UN(32, elem_bytes * group_sz); + wback_eff = write_reg(REGID(mem_idx), ADD(MEMBASE(mem_idx), new_offset)); } else { wback_eff = EMPTY(); } @@ -3181,19 +3173,15 @@ static RzILOpEffect *vldn_single_lane(cs_insn *insn, bool is_thumb) { #endif static RzILOpEffect *vldn_all_lane(cs_insn *insn, bool is_thumb) { - ut32 rm_idx = OPCOUNT() - 1; - ut32 rn_idx; - bool use_rm = false; + ut32 mem_idx; + bool use_rm_as_wback_offset = false; ut32 regs; // number of regs in {list} - if (!ISMEM(rm_idx)) { - use_rm = true; - regs = OPCOUNT() - 2; - } else { - rm_idx = -1; - regs = OPCOUNT() - 1; + if (ISPOSTINDEX()) { + use_rm_as_wback_offset = true; } - rn_idx = regs; + regs = OPCOUNT() - 1; + mem_idx = regs; ut32 group_sz = insn->id - ARM_INS_VLD1 + 1; if (group_sz != regs) { @@ -3202,10 +3190,10 @@ static RzILOpEffect *vldn_all_lane(cs_insn *insn, bool is_thumb) { RzILOpBitVector *data0 = NULL, *data1 = NULL, *data2 = NULL, *data3 = NULL; RzILOpEffect *eff = NULL; - RzILOpBitVector *addr = ARG(rn_idx); + RzILOpBitVector *addr = ISPOSTINDEX() ? MEMBASE(mem_idx) : ARG(mem_idx); ut32 elem_bits = VVEC_SIZE(insn); ut32 elem_bytes = elem_bits / 8; - ut32 addr_bits = REG_WIDTH(rn_idx); + ut32 addr_bits = REG_WIDTH(mem_idx); // vld1/vld2/vld3/vld4, max(lane_size) == 4 Bytes if (group_sz > 4 || elem_bytes > 4) { @@ -3259,8 +3247,8 @@ static RzILOpEffect *vldn_all_lane(cs_insn *insn, bool is_thumb) { bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { - RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); - wback_eff = write_reg(REGID(rn_idx), ADD(REG(rn_idx), new_offset)); + RzILOpBitVector *new_offset = use_rm_as_wback_offset ? MEMINDEX(mem_idx) : UN(32, elem_bytes * group_sz); + wback_eff = write_reg(REGID(mem_idx), ADD(MEMBASE(mem_idx), new_offset)); } else { wback_eff = EMPTY(); } @@ -3288,25 +3276,20 @@ static RzILOpEffect *vldn(cs_insn *insn, bool is_thumb) { } static RzILOpEffect *vstn_multiple_elem(cs_insn *insn, bool is_thumb) { - ut32 rm_idx = OPCOUNT() - 1; - ut32 rn_idx; + ut32 mem_idx; ut32 regs = 0; bool wback = insn->detail->writeback; bool use_rm_as_wback_offset = false; ut32 group_sz = insn->id - ARM_INS_VST1 + 1; // vldn {list}, [Rn], Rm - if (!ISMEM(rm_idx)) { - regs = OPCOUNT() - 2; + if (ISPOSTINDEX()) { use_rm_as_wback_offset = true; - } else { - // vldn {list}, [Rn] - rm_idx = -1; - regs = OPCOUNT() - 1; } + regs = OPCOUNT() - 1; // mem_idx - rn_idx = regs; + mem_idx = regs; // assert list_size % n == 0 // assert they were all Dn @@ -3314,11 +3297,11 @@ static RzILOpEffect *vstn_multiple_elem(cs_insn *insn, bool is_thumb) { ut32 elem_bits = VVEC_SIZE(insn); ut32 elem_bytes = elem_bits / 8; ut32 lanes = 64 / elem_bits; - ut32 addr_bits = REG_WIDTH(rn_idx); + ut32 addr_bits = REG_WIDTH(mem_idx); RzILOpEffect *wback_eff = NULL; RzILOpEffect *eff = EMPTY(), *eff_ = NULL, *eff__ = NULL; - RzILOpBitVector *addr = ARG(rn_idx); + RzILOpBitVector *addr = ISPOSTINDEX() ? MEMBASE(mem_idx) : ARG(mem_idx); for (int i = 0; i < n_groups; ++i) { for (int j = 0; j < lanes; ++j) { @@ -3373,8 +3356,8 @@ static RzILOpEffect *vstn_multiple_elem(cs_insn *insn, bool is_thumb) { // update Rn // if write_back then Rn = Rn + (if use_rm then Rm else 8 * regs) if (wback) { - RzILOpBitVector *new_offset = use_rm_as_wback_offset ? ARG(rm_idx) : UN(32, 8 * regs); - wback_eff = write_reg(REGID(rn_idx), ADD(REG(rn_idx), new_offset)); + RzILOpBitVector *new_offset = use_rm_as_wback_offset ? MEMINDEX(mem_idx) : UN(32, 8 * regs); + wback_eff = write_reg(REGID(mem_idx), ADD(MEMBASE(mem_idx), new_offset)); } else { wback_eff = EMPTY(); } @@ -3384,19 +3367,15 @@ static RzILOpEffect *vstn_multiple_elem(cs_insn *insn, bool is_thumb) { #if CS_API_MAJOR > 3 static RzILOpEffect *vstn_from_single_lane(cs_insn *insn, bool is_thumb) { - ut32 rm_idx = OPCOUNT() - 1; - ut32 rn_idx; - bool use_rm = false; + ut32 mem_idx; + bool use_rm_as_wback_offset = false; ut32 regs; // number of regs in {list} - if (!ISMEM(rm_idx)) { - use_rm = true; - regs = OPCOUNT() - 2; - } else { - rm_idx = -1; - regs = OPCOUNT() - 1; + if (ISPOSTINDEX()) { + use_rm_as_wback_offset = true; } - rn_idx = regs; + regs = OPCOUNT() - 1; + mem_idx = regs; ut32 group_sz = insn->id - ARM_INS_VST1 + 1; if (group_sz != regs) { @@ -3405,11 +3384,11 @@ static RzILOpEffect *vstn_from_single_lane(cs_insn *insn, bool is_thumb) { RzILOpBitVector *data0, *data1, *data2, *data3; RzILOpEffect *eff, *eff_, *eff__; - RzILOpBitVector *addr = ARG(rn_idx); + RzILOpBitVector *addr = ISPOSTINDEX() ? MEMBASE(mem_idx) : ARG(mem_idx); ut32 vreg_idx = 0; ut32 elem_bits = VVEC_SIZE(insn); ut32 elem_bytes = elem_bits / 8; - ut32 addr_bits = REG_WIDTH(rn_idx); + ut32 addr_bits = REG_WIDTH(mem_idx); if (group_sz > 4 || elem_bytes > 4) { return NULL; @@ -3459,8 +3438,8 @@ static RzILOpEffect *vstn_from_single_lane(cs_insn *insn, bool is_thumb) { bool wback = insn->detail->writeback; RzILOpEffect *wback_eff; if (wback) { - RzILOpBitVector *new_offset = use_rm ? ARG(rm_idx) : UN(32, elem_bytes * group_sz); - wback_eff = write_reg(REGID(rn_idx), ADD(REG(rn_idx), new_offset)); + RzILOpBitVector *new_offset = use_rm_as_wback_offset ? MEMINDEX(mem_idx) : UN(32, elem_bytes * group_sz); + wback_eff = write_reg(REGID(mem_idx), ADD(MEMBASE(mem_idx), new_offset)); } else { wback_eff = EMPTY(); } From 327ef813c13a89935ef7767e670e07ec5eaf415c Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 7 Sep 2023 13:41:06 -0500 Subject: [PATCH 53/53] Fix incorrect tests with missing writeback due to missing post-index flag --- test/db/asm/arm_32 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/db/asm/arm_32 b/test/db/asm/arm_32 index b3e554fbed0..3aec5cc31a9 100644 --- a/test/db/asm/arm_32 +++ b/test/db/asm/arm_32 @@ -769,7 +769,7 @@ d "vzip.16 d2, d3" 8321b6f3 0x0 (seq (set d2 (cast 64 false (| (| (| (| (bv 128 d "vuzp.8 d0, d1" 0101b2f3 0x0 (seq (set d0 (| (| (| (| (bv 64 0x0) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x0) false))) (bv 8 0x0) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x0) false))) (bv 8 0x0) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x10) false))) (bv 8 0x8) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x10) false))) (bv 8 0x8) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x20) false))) (bv 8 0x10) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x20) false))) (bv 8 0x10) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x30) false))) (bv 8 0x18) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x30) false))) (bv 8 0x18) false) (bv 8 0x20) false)))) (set d1 (| (| (| (| (bv 64 0x0) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x8) false))) (bv 8 0x0) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x8) false))) (bv 8 0x0) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x18) false))) (bv 8 0x8) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x18) false))) (bv 8 0x8) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x28) false))) (bv 8 0x10) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x28) false))) (bv 8 0x10) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 8 false (>> (var d0) (bv 8 0x38) false))) (bv 8 0x18) false) (<< (<< (cast 64 false (cast 8 false (>> (var d1) (bv 8 0x38) false))) (bv 8 0x18) false) (bv 8 0x20) false))))) d "vuzp.8 q0, q1" 4201b2f3 0x0 (seq (set d0 (cast 64 false (| (| (| (| (| (| (| (| (bv 128 0x0) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x0) false))) (bv 8 0x0) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x0) false))) (bv 8 0x0) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x10) false))) (bv 8 0x8) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x10) false))) (bv 8 0x8) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x20) false))) (bv 8 0x10) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x20) false))) (bv 8 0x10) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x30) false))) (bv 8 0x18) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x30) false))) (bv 8 0x18) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x40) false))) (bv 8 0x20) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x40) false))) (bv 8 0x20) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x50) false))) (bv 8 0x28) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x50) false))) (bv 8 0x28) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x60) false))) (bv 8 0x30) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x60) false))) (bv 8 0x30) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x70) false))) (bv 8 0x38) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x70) false))) (bv 8 0x38) false) (bv 8 0x40) false))))) (set d1 (cast 64 false (>> (| (| (| (| (| (| (| (| (bv 128 0x0) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x0) false))) (bv 8 0x0) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x0) false))) (bv 8 0x0) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x10) false))) (bv 8 0x8) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x10) false))) (bv 8 0x8) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x20) false))) (bv 8 0x10) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x20) false))) (bv 8 0x10) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x30) false))) (bv 8 0x18) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x30) false))) (bv 8 0x18) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x40) false))) (bv 8 0x20) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x40) false))) (bv 8 0x20) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x50) false))) (bv 8 0x28) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x50) false))) (bv 8 0x28) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x60) false))) (bv 8 0x30) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x60) false))) (bv 8 0x30) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x70) false))) (bv 8 0x38) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x70) false))) (bv 8 0x38) false) (bv 8 0x40) false))) (bv 8 0x40) false))) (set d2 (cast 64 false (| (| (| (| (| (| (| (| (bv 128 0x0) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x8) false))) (bv 8 0x0) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x8) false))) (bv 8 0x0) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x18) false))) (bv 8 0x8) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x18) false))) (bv 8 0x8) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x28) false))) (bv 8 0x10) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x28) false))) (bv 8 0x10) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x38) false))) (bv 8 0x18) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x38) false))) (bv 8 0x18) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x48) false))) (bv 8 0x20) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x48) false))) (bv 8 0x20) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x58) false))) (bv 8 0x28) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x58) false))) (bv 8 0x28) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x68) false))) (bv 8 0x30) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x68) false))) (bv 8 0x30) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x78) false))) (bv 8 0x38) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x78) false))) (bv 8 0x38) false) (bv 8 0x40) false))))) (set d3 (cast 64 false (>> (| (| (| (| (| (| (| (| (bv 128 0x0) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x8) false))) (bv 8 0x0) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x8) false))) (bv 8 0x0) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x18) false))) (bv 8 0x8) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x18) false))) (bv 8 0x8) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x28) false))) (bv 8 0x10) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x28) false))) (bv 8 0x10) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x38) false))) (bv 8 0x18) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x38) false))) (bv 8 0x18) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x48) false))) (bv 8 0x20) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x48) false))) (bv 8 0x20) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x58) false))) (bv 8 0x28) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x58) false))) (bv 8 0x28) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x68) false))) (bv 8 0x30) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x68) false))) (bv 8 0x30) false) (bv 8 0x40) false))) (| (<< (cast 128 false (cast 8 false (>> (append (var d1) (var d0)) (bv 8 0x78) false))) (bv 8 0x38) false) (<< (<< (cast 128 false (cast 8 false (>> (append (var d3) (var d2)) (bv 8 0x78) false))) (bv 8 0x38) false) (bv 8 0x40) false))) (bv 8 0x40) false)))) d "vuzp.16 d2, d4" 0421b6f3 0x0 (seq (set d2 (| (| (bv 64 0x0) (| (<< (cast 64 false (cast 16 false (>> (var d2) (bv 8 0x0) false))) (bv 8 0x0) false) (<< (<< (cast 64 false (cast 16 false (>> (var d4) (bv 8 0x0) false))) (bv 8 0x0) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 16 false (>> (var d2) (bv 8 0x20) false))) (bv 8 0x10) false) (<< (<< (cast 64 false (cast 16 false (>> (var d4) (bv 8 0x20) false))) (bv 8 0x10) false) (bv 8 0x20) false)))) (set d4 (| (| (bv 64 0x0) (| (<< (cast 64 false (cast 16 false (>> (var d2) (bv 8 0x10) false))) (bv 8 0x0) false) (<< (<< (cast 64 false (cast 16 false (>> (var d4) (bv 8 0x10) false))) (bv 8 0x0) false) (bv 8 0x20) false))) (| (<< (cast 64 false (cast 16 false (>> (var d2) (bv 8 0x30) false))) (bv 8 0x10) false) (<< (<< (cast 64 false (cast 16 false (>> (var d4) (bv 8 0x30) false))) (bv 8 0x10) false) (bv 8 0x20) false))))) -d "vld1.8 {d0}, [r1], r0" 000721f4 0x0 (seq empty (set d0 (<< (cast 64 false (loadw 0 8 (var r1))) (bv 8 0x0) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (var r1) (bv 32 0x1)))) (bv 8 0x8) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) empty) +d "vld1.8 {d0}, [r1], r0" 000721f4 0x0 (seq empty (set d0 (<< (cast 64 false (loadw 0 8 (var r1))) (bv 8 0x0) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (var r1) (bv 32 0x1)))) (bv 8 0x8) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set r1 (+ (var r1) (var r0)))) d "vld1.16 {d1}, [r7]!" 4d1727f4 0x0 (seq empty (set d1 (<< (cast 64 false (loadw 0 16 (var r7))) (bv 8 0x0) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (var r7) (bv 32 0x2)))) (bv 8 0x10) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)))) (bv 8 0x20) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (bv 32 0x2)))) (bv 8 0x30) false)) (set r7 (+ (var r7) (bv 32 0x8)))) d "vld1.16 {d1}, [r7]" 4f1727f4 0x0 (seq empty (set d1 (<< (cast 64 false (loadw 0 16 (var r7))) (bv 8 0x0) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (var r7) (bv 32 0x2)))) (bv 8 0x10) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)))) (bv 8 0x20) false)) (set d1 (<< (cast 64 false (loadw 0 16 (+ (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (bv 32 0x2)))) (bv 8 0x30) false)) empty) d "vld1.32 {d1}, [r7]" 8f1727f4 0x0 (seq empty (set d1 (<< (cast 64 false (loadw 0 32 (var r7))) (bv 8 0x0) false)) (set d1 (<< (cast 64 false (loadw 0 32 (+ (var r7) (bv 32 0x4)))) (bv 8 0x20) false)) empty) @@ -786,7 +786,7 @@ d "vld1.8 {d0, d1, d2}, [r0]" 0f0620f4 0x0 (seq empty (set d0 (<< (cast 64 false d "vld2.8 {d0, d2}, [r0]" 0f0920f4 0x0 (seq empty (set d0 (<< (cast 64 false (loadw 0 8 (var r0))) (bv 8 0x0) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (var r0) (bv 32 0x1)))) (bv 8 0x0) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) empty) d "vld3.8 {d0, d1, d2}, [r0]" 0f0420f4 0x0 (seq empty (set d0 (<< (cast 64 false (loadw 0 8 (var r0))) (bv 8 0x0) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (var r0) (bv 32 0x1)))) (bv 8 0x0) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x0) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) empty) d "vld4.8 {d0, d1, d2, d3}, [r0]" 0f0020f4 0x0 (seq empty (set d0 (<< (cast 64 false (loadw 0 8 (var r0))) (bv 8 0x0) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (var r0) (bv 32 0x1)))) (bv 8 0x0) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x0) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x0) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x8) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x10) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x18) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x20) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x28) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x30) false)) (set d0 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d1 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d2 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) (set d3 (<< (cast 64 false (loadw 0 8 (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (var r0) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)))) (bv 8 0x38) false)) empty) -d "vst1.8 {d0}, [r1], r0" 000701f4 0x0 (seq empty (storew 0 (var r1) (cast 8 false (>> (var d0) (bv 8 0x0) false))) (storew 0 (+ (var r1) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x8) false))) (storew 0 (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x10) false))) (storew 0 (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x18) false))) (storew 0 (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x20) false))) (storew 0 (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x28) false))) (storew 0 (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x30) false))) (storew 0 (+ (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x38) false))) empty) +d "vst1.8 {d0}, [r1], r0" 000701f4 0x0 (seq empty (storew 0 (var r1) (cast 8 false (>> (var d0) (bv 8 0x0) false))) (storew 0 (+ (var r1) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x8) false))) (storew 0 (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x10) false))) (storew 0 (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x18) false))) (storew 0 (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x20) false))) (storew 0 (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x28) false))) (storew 0 (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x30) false))) (storew 0 (+ (+ (+ (+ (+ (+ (+ (var r1) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (bv 32 0x1)) (cast 8 false (>> (var d0) (bv 8 0x38) false))) (set r1 (+ (var r1) (var r0)))) d "vst1.16 {d1}, [r7]!" 4d1707f4 0x0 (seq empty (storew 0 (var r7) (cast 16 false (>> (var d1) (bv 8 0x0) false))) (storew 0 (+ (var r7) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x10) false))) (storew 0 (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x20) false))) (storew 0 (+ (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x30) false))) (set r7 (+ (var r7) (bv 32 0x8)))) d "vst1.16 {d1}, [r7]" 4f1707f4 0x0 (seq empty (storew 0 (var r7) (cast 16 false (>> (var d1) (bv 8 0x0) false))) (storew 0 (+ (var r7) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x10) false))) (storew 0 (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x20) false))) (storew 0 (+ (+ (+ (var r7) (bv 32 0x2)) (bv 32 0x2)) (bv 32 0x2)) (cast 16 false (>> (var d1) (bv 8 0x30) false))) empty) d "vst1.32 {d1}, [r7]" 8f1707f4 0x0 (seq empty (storew 0 (var r7) (cast 32 false (>> (var d1) (bv 8 0x0) false))) (storew 0 (+ (var r7) (bv 32 0x4)) (cast 32 false (>> (var d1) (bv 8 0x20) false))) empty)