5 #include <capstone/capstone.h>
10 #define REG(x) rz_str_get_null(cs_reg_name(*handle, insn->detail->arm.operands[x].reg))
11 #define MEMBASE(x) rz_str_get_null(cs_reg_name(*handle, insn->detail->arm.operands[x].mem.base))
12 #define MEMINDEX(x) rz_str_get_null(cs_reg_name(*handle, insn->detail->arm.operands[x].mem.index))
15 const char *E_OP_SR =
">>";
16 const char *E_OP_SL =
"<<";
17 const char *E_OP_RR =
">>>";
18 const char *E_OP_ASR =
">>>>";
19 const char *E_OP_VOID =
"";
46 #define DECODE_SHIFT(x) decode_shift(insn->detail->arm.operands[x].shift.type)
50 unsigned int reg = insn->detail->arm.operands[
n].reg;
60 #define REGSIZE32(x) regsize32(insn, x)
64 const char *close_cond[2];
66 close_cond[1] =
",}\0";
133 return close_cond[close_type];
138 switch (insn->detail->arm.operands[
n].type) {
144 insn->detail->arm.operands[
n].reg)),
149 insn->detail->arm.operands[
n].reg)));
164 sprintf(
buf,
"%lf", insn->detail->arm.operands[
n].fp);
172 #define ARG(x) arg(a, handle, insn, str[x], x)
174 #define MATH32(opchar) arm32math(a, op, addr, buf, len, handle, insn, pcdelta, str, opchar, 0)
175 #define MATH32_NEG(opchar) arm32math(a, op, addr, buf, len, handle, insn, pcdelta, str, opchar, 1)
176 #define MATH32AS(opchar) arm32mathaddsub(a, op, addr, buf, len, handle, insn, pcdelta, str, opchar)
178 static void arm32math(
RzAnalysis *
a,
RzAnalysisOp *
op,
ut64 addr,
const ut8 *
buf,
int len,
csh *
handle, cs_insn *insn,
int pcdelta,
char (*
str)[32],
const char *opchar,
int negate) {
182 bool rotate_imm =
OPCOUNT() > 3;
194 if (!strcmp(op2,
"pc")) {
205 if (!strcmp(op1,
"pc")) {
206 rz_strbuf_appendf(&
op->esil,
",%d,$$,+,%s,0xffffffff,&,%s,=", pcdelta, opchar,
dest);
211 rz_strbuf_appendf(&
op->esil,
",%s,%s,0xffffffff,&,%s,=", op1, opchar,
dest);
219 bool noflags =
false;
220 if (!strcmp(
dst,
"pc")) {
231 rz_strbuf_appendf(&
op->esil,
"%s,%s,%s,0xffffffff,&,%s,=",
src,
dst, opchar,
dst);
235 rz_strbuf_appendf(&
op->esil,
",$z,zf,:=,%s,cf,:=,vf,=,0,nf,=",
236 (!strcmp(opchar,
"+") ?
"30,$c,31,$c,^,31,$c" :
"30,$c,31,$c,^,32,$b"));
241 const char *postfix =
NULL;
244 int pcdelta = (thumb ? 4 : 8);
246 int str_ldr_bytes = 4;
247 unsigned int width = 0;
255 rz_strbuf_appendf(&
op->esil,
"%s,!,?{,32,%s,=,BREAK,},0,%s,=,%s,%s,<<,0x80000000,&,!,?{,1,%s,+=,11,GOTO,}",
REG(1),
REG(0),
REG(0),
REG(0),
REG(1),
REG(0));
298 rz_strbuf_appendf(&
op->esil,
"cf,%s,+=,%s,%s,+,%s,+=",
ARG(0),
ARG(2),
ARG(1),
ARG(0));
313 rz_strbuf_appendf(&
op->esil,
"cf,%s,-=,%s,%s,+,%s,-=",
ARG(0),
ARG(2),
ARG(1),
ARG(0));
332 if (insn->detail->arm.update_flags) {
334 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},",
ARG(1),
ARG(0),
ARG(1));
336 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},",
ARG(2),
ARG(1),
ARG(2));
342 if (insn->detail->arm.update_flags) {
344 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,32,-,%s,>>,cf,:=,},",
ARG(1),
ARG(1),
ARG(0));
346 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,32,-,%s,>>,cf,:=,},",
ARG(2),
ARG(2),
ARG(1));
363 20,
sp,-=,
lr,
r7,
r6,
r5,
r4,5,
sp,=[*]
366 4 * insn->detail->arm.op_count);
367 for (
i = insn->detail->arm.op_count;
i > 0;
i--) {
371 insn->detail->arm.op_count);
378 int offset = direction > 0 ? -1 : -insn->detail->arm.op_count;
382 for (
i = 1;
i < insn->detail->arm.op_count;
i++) {
386 if (insn->detail->arm.writeback ==
true) {
388 direction * (insn->detail->arm.op_count - 1) * 4,
ARG(0));
395 for (
i = 1;
i < insn->detail->arm.op_count;
i++) {
401 if (insn->detail->arm.writeback) {
408 for (
i = insn->detail->arm.op_count - 1;
i > 0;
i--) {
419 for (
i = 1;
i < insn->detail->arm.op_count;
i++) {
425 if (insn->detail->arm.writeback) {
432 for (
i = insn->detail->arm.op_count - 1;
i > 0;
i--) {
442 if (insn->detail->arm.update_flags) {
444 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},",
ARG(1),
ARG(0),
ARG(1));
446 rz_strbuf_appendf(&
op->esil,
"%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},",
ARG(2),
ARG(1),
ARG(2));
464 for (
i = insn->detail->arm.op_count;
i > 0;
i--) {
468 insn->detail->arm.op_count);
470 4 * insn->detail->arm.op_count);
477 int offset = direction > 0 ? -1 : -insn->detail->arm.op_count;
481 for (
i = 1;
i < insn->detail->arm.op_count;
i++) {
482 rz_strbuf_appendf(&
op->esil,
"%s,%d,+,[4],%s,=,",
ARG(0), (
i +
offset) * 4,
REG(
i));
484 if (insn->detail->arm.writeback) {
486 direction * (insn->detail->arm.op_count - 1) * 4,
ARG(0));
500 rz_strbuf_appendf(&
op->esil,
"%d,$$,+,%s,+,0xfffffffc,&,%s,=",
543 char sign = disp >= 0 ?
'+' :
'-';
544 disp = disp >= 0 ? disp : -disp;
546 REG(0), disp,
MEMBASE(1), sign, str_ldr_bytes);
547 if (insn->detail->arm.writeback) {
556 rz_strbuf_appendf(&
op->esil,
"%s,%s,%d,%s,<<,+,0xffffffff,&,=[%d]",
558 if (insn->detail->arm.writeback) {
564 rz_strbuf_appendf(&
op->esil,
"%s,%s,%d,%s,>>,+,0xffffffff,&,=[%d]",
566 if (insn->detail->arm.writeback) {
572 rz_strbuf_appendf(&
op->esil,
"%s,%s,%d,%s,>>>>,+,0xffffffff,&,=[%d]",
574 if (insn->detail->arm.writeback) {
580 rz_strbuf_appendf(&
op->esil,
"%s,%s,%d,%s,>>>,+,0xffffffff,&,=[%d]",
582 if (insn->detail->arm.writeback) {
597 if (insn->detail->arm.writeback) {
613 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,%d,%s,<<,+,%s,=",
617 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>,+,%s,=",
621 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>>,+,%s,=",
625 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>,+,%s,=",
640 if (
ISREG(1) && str_ldr_bytes == 8) {
643 char sign = disp >= 0 ?
'+' :
'-';
644 disp = disp >= 0 ? disp : -disp;
645 rz_strbuf_appendf(&
op->esil,
"%s,%d,%s,%c,0xffffffff,&,=[4],%s,4,%d,+,%s,%c,0xffffffff,&,=[4]",
647 if (insn->detail->arm.writeback) {
655 rz_strbuf_appendf(&
op->esil,
"%s,%s,%s,+,0xffffffff,&,=[4],%s,4,%s,+,%s,+,0xffffffff,&,=[4]",
657 if (insn->detail->arm.writeback) {
667 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%d,%s,+=,",
674 rz_strbuf_appendf(&
op->esil,
"%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%s,%s,+=",
686 const char *
pc =
"$$";
690 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",2,2,%s,%d,+,>>,<<,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
696 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",%s,-,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
699 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
705 const char *
pc =
"$$";
710 rz_strbuf_appendf(&
op->esil,
"%s,2,2,%d,%s,+,>>,<<,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
713 rz_strbuf_appendf(&
op->esil,
"2,2,%d,%s,+,>>,<<,%d,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
719 rz_strbuf_appendf(&
op->esil,
"%s,%s,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
722 rz_strbuf_appendf(&
op->esil,
"%d,%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
725 if (insn->detail->arm.writeback) {
751 rz_strbuf_appendf(&
op->esil,
"%s,%d,%s,<<,+,0xffffffff,&,[1],0x%x,&,%s,=",
760 if (insn->detail->arm.writeback) {
772 "15,%s,>>,1,&,?{,15,-1,<<,%s,0xffff,&,|,%s,:=,}{,%s,0xffff,%s,:=,}",
777 "7,%s,>>,1,&,?{,7,-1,<<,%s,0xff,&,|,%s,:=,}{,%s,0xff,&,%s,:=,}",
808 const char *
pc =
"$$";
812 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",2,2,%s,>>,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
818 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",%s,-,0xffffffff,&,[4],0x%x,&,%s,=",
821 rz_strbuf_appendf(&
op->esil,
"0x%" PFMT64x ",%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
827 const char *
pc =
"$$";
830 rz_strbuf_appendf(&
op->esil,
"2,2,%d,%s,+,>>,<<,%d,%s,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
833 rz_strbuf_appendf(&
op->esil,
"2,2,%d,%s,+,>>,<<,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
839 rz_strbuf_appendf(&
op->esil,
"2,2,%d,%s,+,>>,<<,%d,+,0xffffffff,&,[4],0x%x,&,%s,=",
844 rz_strbuf_appendf(&
op->esil,
"%s,%d,%s,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
847 rz_strbuf_appendf(&
op->esil,
"%s,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
850 rz_strbuf_appendf(&
op->esil,
"%d,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
853 if (insn->detail->arm.writeback) {
869 msr_flags = insn->detail->arm.operands[0].reg >> 4;
883 rz_strbuf_appendf(&
op->esil,
"DUP,!,SWAP,&,%s,SWAP,cpsr,&,|,cpsr,=",
REG(1));
886 if (
IMM(3) > 0 &&
IMM(3) <= 32 -
IMM(2)) {
887 rz_strbuf_appendf(&
op->esil,
"%d,%s,%d,%" PFMT64u ",<<,&,>>,%s,=",
905 rz_strbuf_appendf(&
op->esil,
"%s,0xffffffff,^,%s,&,%s,=",
ARG(2),
ARG(1),
ARG(0));
909 rz_strbuf_appendf(&
op->esil,
"32,%s,%s,*,>>,%s,+,0xffffffff,&,%s,=",
913 rz_strbuf_appendf(&
op->esil,
"32,0x80000000,%s,%s,*,+,>>,%s,+,0xffffffff,&,%s,=",
917 rz_strbuf_appendf(&
op->esil,
"32,%s,%s,*,DUP,0xffffffff,&,%s,=,>>,%s,=",
921 rz_strbuf_appendf(&
op->esil,
"%s,%s,*,%s,-,0xffffffff,&,%s,=",
925 rz_strbuf_appendf(&
op->esil,
"%s,%s,*,%s,+,0xffffffff,&,%s,=",
938 rz_strbuf_setf(&
op->esil,
"%" PFMT64u ",%s,&,%" PFMT64u ",%" PFMT64u ",%s,&,<<,|,0xffffffff,&,%s,=",
955 const char *
r0 =
REG(0);
956 const char *
r1 =
REG(1);
958 "24,0xff,%s,&,<<,%s,=,"
959 "16,0xff,8,%s,>>,&,<<,%s,|=,"
960 "8,0xff,16,%s,>>,&,<<,%s,|=,"
961 "0xff,24,%s,>>,&,%s,|=,",
966 const char *
r0 =
REG(0);
967 const char *
r1 =
REG(1);
969 "8,0xff00ff00,%s,&,>>,%s,=,"
970 "8,0x00ff00ff,%s,&,<<,%s,|=,",
975 const char *
r0 =
REG(0);
976 const char *
r1 =
REG(1);
978 "8,0xff00,%s,&,>>,%s,=,"
979 "8,0x00ff,%s,&,<<,%s,|=,"
987 rz_strbuf_appendf(&
op->esil,
"%s,%s,+,0xffffffff,&,DUP,[1],1,SWAP,<<,+,pc,+=",
991 rz_strbuf_appendf(&
op->esil,
"%s,%d,%s,<<,+,0xffffffff,&,[2],1,SWAP,<<,pc,+=",
999 if (insn->detail->arm.update_flags) {
1002 rz_strbuf_appendf(&
op->esil,
",$z,zf,:=,31,$s,nf,:=,32,$b,!,cf,:=,31,$o,vf,:=");
1010 rz_strbuf_appendf(&
op->esil,
",$z,zf,:=,31,$s,nf,:=,31,$c,cf,:=,31,$o,vf,:=");
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
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 const char * rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type)
static void arm32math(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn, int pcdelta, char(*str)[32], const char *opchar, int negate)
static unsigned int regsize32(cs_insn *insn, int n)
static void arm32mathaddsub(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn, int pcdelta, char(*str)[32], const char *opchar)
static const char * decode_shift(arm_shifter shift)
#define MATH32_NEG(opchar)
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
static mcore_handle handle
arm_shifter
ARM shift type.
@ ARM_SFT_ROR_REG
shift with register
@ ARM_SFT_ASR
shift with immediate const
@ ARM_SFT_LSR_REG
shift with register
@ ARM_SFT_LSL_REG
shift with register
@ ARM_SFT_ROR
shift with immediate const
@ ARM_SFT_LSL
shift with immediate const
@ ARM_SFT_RRX_REG
shift with register
@ ARM_SFT_LSR
shift with immediate const
@ ARM_SFT_RRX
shift with immediate const
@ ARM_SFT_ASR_REG
shift with register
@ ARM_OP_IMM
= CS_OP_IMM (Immediate operand).
@ ARM_OP_REG
= CS_OP_REG (Register operand).
@ ARM_OP_MEM
= CS_OP_MEM (Memory operand).
@ ARM_OP_FP
= CS_OP_FP (Floating-Point operand).
@ ARM_CC_GT
Greater than Greater than.
@ ARM_CC_LE
Less than or equal <, ==, or unordered.
@ ARM_CC_AL
Always (unconditional) Always (unconditional)
@ ARM_CC_HI
Unsigned higher Greater than, or unordered.
@ ARM_CC_VC
No overflow Not unordered.
@ ARM_CC_LS
Unsigned lower or same Less than or equal.
@ ARM_CC_GE
Greater than or equal Greater than or equal.
@ ARM_CC_VS
Overflow Unordered.
@ ARM_CC_PL
Plus, positive or zero >, ==, or unordered.
@ ARM_CC_NE
Not equal Not equal, or unordered.
@ ARM_CC_LO
Carry clear Less than.
@ ARM_CC_LT
Less than Less than, or unordered.
@ ARM_CC_HS
Carry set >, ==, or unordered.
@ ARM_CC_MI
Minus, negative Less than.
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
@ RZ_ANALYSIS_OP_FAMILY_THREAD
#define rz_return_val_if_fail(expr, val)
static ut64 rz_num_bitmask(ut8 width)
Get the 64-bit value that has exactly its width lowest bits set to 1. e.g. rz_num_bitmask(2) == 0b11 ...
static const char * rz_str_get_null(const char *str)
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()