Improvements on the arm64.v35/cs plugins ##esil

* fix arm.v35 conditional sets, cs arm64e ESIL, add q0-31 aliases
* add default to prevent warnings
This commit is contained in:
aemmitt-ns 2021-11-12 10:37:02 -05:00 committed by GitHub
parent 93f4ec40de
commit bd901a3861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 289 additions and 16 deletions

View File

@ -881,6 +881,7 @@ static int regsize64(cs_insn *insn, int n) {
#define REGBITS64(x) 8*regsize64 (insn, x)
#define REGBITS32(x) 8*regsize32 (insn, x)
#define SET_FLAGS() r_strbuf_appendf (&op->esil, ",$z,zf,:=,%d,$s,nf,:=,%d,$c,cf,:=,%d,$o,vf,:=", REGBITS64 (0) - 1, REGBITS64 (0), REGBITS64 (0) -1);
static int vector_size(cs_arm64_op *op) {
#if CS_API_MAJOR == 4
@ -1097,7 +1098,8 @@ static ut64 shifted_imm64(csh *handle, cs_insn *insn, int n, int sz) {
cs_arm64_op op = INSOP64 (n);
int sft = op.shift.value;
switch (op.shift.type) {
case ARM64_SFT_MSL: // idk what this is
case ARM64_SFT_MSL:
return (IMM64 (n) << sft) | ((1 << sft) - 1);
case ARM64_SFT_LSL:
return IMM64 (n) << sft;
case ARM64_SFT_LSR:
@ -1328,7 +1330,6 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
break;
case ARM64_INS_ADD:
case ARM64_INS_ADC: // Add with carry.
//case ARM64_INS_ADCS: // Add with carry.
OPCALL("+");
break;
case ARM64_INS_SUB:
@ -1360,9 +1361,43 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
case ARM64_INS_AND:
OPCALL("&");
break;
case ARM64_INS_NAND:
OPCALL_NEG("&");
break;
case ARM64_INS_ORR:
OPCALL("|");
break;
#if CS_API_MAJOR > 4
case ARM64_INS_ADDS:
case ARM64_INS_ADCS:
OPCALL("+");
SET_FLAGS();
break;
case ARM64_INS_SUBS:
OPCALL("-");
SET_FLAGS();
break;
case ARM64_INS_ANDS:
OPCALL("&");
SET_FLAGS();
break;
case ARM64_INS_NANDS:
OPCALL_NEG("&");
SET_FLAGS();
break;
case ARM64_INS_ORRS:
OPCALL("|");
SET_FLAGS();
break;
case ARM64_INS_EORS:
OPCALL("^");
SET_FLAGS();
break;
case ARM64_INS_ORNS:
OPCALL_NEG("|");
SET_FLAGS();
break;
#endif
case ARM64_INS_EOR:
OPCALL("^");
break;
@ -1504,6 +1539,27 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
VEC64_DST_APPEND(&op->esil, 0, -1);
r_strbuf_appendf (&op->esil, ",=");
break;
case ARM64_INS_FRINTA:
case ARM64_INS_FRINTI:
case ARM64_INS_FRINTN:
case ARM64_INS_FRINTX:
case ARM64_INS_FRINTZ:
case ARM64_INS_FRINTP:
case ARM64_INS_FRINTM:
{
char* rounder = "ROUND";
if (insn->id == ARM64_INS_FRINTM) {
rounder = "FLOOR";
} else if (insn->id == ARM64_INS_FRINTP) {
rounder = "CEIL";
}
r_strbuf_setf (&op->esil, "%d,DUP,", REGBITS64 (1));
ARG64_APPEND(&op->esil, 1);
r_strbuf_appendf (&op->esil, ",F2D,%s,D2F,", rounder);
VEC64_DST_APPEND(&op->esil, 0, -1);
r_strbuf_appendf (&op->esil, ",=");
break;
}
case ARM64_INS_FABS:
r_strbuf_setf (&op->esil, "%d,DUP,%s,F2D,DUP,0,I2D,F<,?{,-F,},D2F,%s,=",
REGBITS64 (1), REG64 (1), REG64 (0));
@ -1568,6 +1624,12 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
/* TODO: support WZR XZR to specify 32, 64bit op */
OPCALL("/");
break;
#if CS_API_MAJOR > 4
case ARM64_INS_BRAA:
case ARM64_INS_BRAAZ:
case ARM64_INS_BRAB:
case ARM64_INS_BRABZ:
#endif
case ARM64_INS_BR:
r_strbuf_setf (&op->esil, "%s,pc,=", REG64 (0));
break;
@ -1578,6 +1640,12 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
case ARM64_INS_BL:
r_strbuf_setf (&op->esil, "pc,lr,=,%"PFMT64d",pc,=", IMM64 (0));
break;
#if CS_API_MAJOR > 4
case ARM64_INS_BLRAA:
case ARM64_INS_BLRAAZ:
case ARM64_INS_BLRAB:
case ARM64_INS_BLRABZ:
#endif
case ARM64_INS_BLR:
r_strbuf_setf (&op->esil, "pc,lr,=,%s,pc,=", REG64 (0));
break;
@ -2181,6 +2249,12 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l
case ARM64_INS_UXTH:
r_strbuf_setf (&op->esil, "%s,0xffff,&,%s,=", REG64 (1), REG64 (0));
break;
#if CS_API_MAJOR > 4
case ARM64_INS_RETAA:
case ARM64_INS_RETAB:
case ARM64_INS_ERETAA:
case ARM64_INS_ERETAB:
#endif
case ARM64_INS_RET:
r_strbuf_setf (&op->esil, "lr,pc,=");
break;

View File

@ -322,6 +322,111 @@ static char *get_reg_profile(RAnal *anal) {
"fpu v30h .64 776 0\n"
"fpu v31h .64 792 0\n"
// this sucks but q* is a valid alias
// for the vector registers in arm64
/* 128 bit vector */
"fpu q0 .128 288 0\n"
"fpu q1 .128 304 0\n"
"fpu q2 .128 320 0\n"
"fpu q3 .128 336 0\n"
"fpu q4 .128 352 0\n"
"fpu q5 .128 368 0\n"
"fpu q6 .128 384 0\n"
"fpu q7 .128 400 0\n"
"fpu q8 .128 416 0\n"
"fpu q9 .128 432 0\n"
"fpu q10 .128 448 0\n"
"fpu q11 .128 464 0\n"
"fpu q12 .128 480 0\n"
"fpu q13 .128 496 0\n"
"fpu q14 .128 512 0\n"
"fpu q15 .128 528 0\n"
"fpu q16 .128 544 0\n"
"fpu q17 .128 560 0\n"
"fpu q18 .128 576 0\n"
"fpu q19 .128 592 0\n"
"fpu q20 .128 608 0\n"
"fpu q21 .128 624 0\n"
"fpu q22 .128 640 0\n"
"fpu q23 .128 656 0\n"
"fpu q24 .128 672 0\n"
"fpu q25 .128 688 0\n"
"fpu q26 .128 704 0\n"
"fpu q27 .128 720 0\n"
"fpu q28 .128 736 0\n"
"fpu q29 .128 752 0\n"
"fpu q30 .128 768 0\n"
"fpu q31 .128 784 0\n"
/* 64bit double */
"fpu q0l .64 288 0\n"
"fpu q1l .64 304 0\n"
"fpu q2l .64 320 0\n"
"fpu q3l .64 336 0\n"
"fpu q4l .64 352 0\n"
"fpu q5l .64 368 0\n"
"fpu q6l .64 384 0\n"
"fpu q7l .64 400 0\n"
"fpu q8l .64 416 0\n"
"fpu q9l .64 432 0\n"
"fpu q10l .64 448 0\n"
"fpu q11l .64 464 0\n"
"fpu q12l .64 480 0\n"
"fpu q13l .64 496 0\n"
"fpu q14l .64 512 0\n"
"fpu q15l .64 528 0\n"
"fpu q16l .64 544 0\n"
"fpu q17l .64 560 0\n"
"fpu q18l .64 576 0\n"
"fpu q19l .64 592 0\n"
"fpu q20l .64 608 0\n"
"fpu q21l .64 624 0\n"
"fpu q22l .64 640 0\n"
"fpu q23l .64 656 0\n"
"fpu q24l .64 672 0\n"
"fpu q25l .64 688 0\n"
"fpu q26l .64 704 0\n"
"fpu q27l .64 720 0\n"
"fpu q28l .64 736 0\n"
"fpu q29l .64 752 0\n"
"fpu q30l .64 768 0\n"
"fpu q31l .64 784 0\n"
/* 128 bit qector high 64 */
"fpu q0h .64 296 0\n"
"fpu q1h .64 312 0\n"
"fpu q2h .64 328 0\n"
"fpu q3h .64 344 0\n"
"fpu q4h .64 360 0\n"
"fpu q5h .64 376 0\n"
"fpu q6h .64 392 0\n"
"fpu q7h .64 408 0\n"
"fpu q8h .64 424 0\n"
"fpu q9h .64 440 0\n"
"fpu q10h .64 456 0\n"
"fpu q11h .64 472 0\n"
"fpu q12h .64 488 0\n"
"fpu q13h .64 504 0\n"
"fpu q14h .64 520 0\n"
"fpu q15h .64 536 0\n"
"fpu q16h .64 552 0\n"
"fpu q17h .64 568 0\n"
"fpu q18h .64 584 0\n"
"fpu q19h .64 600 0\n"
"fpu q20h .64 616 0\n"
"fpu q21h .64 632 0\n"
"fpu q22h .64 648 0\n"
"fpu q23h .64 664 0\n"
"fpu q24h .64 680 0\n"
"fpu q25h .64 696 0\n"
"fpu q26h .64 712 0\n"
"fpu q27h .64 728 0\n"
"fpu q28h .64 744 0\n"
"fpu q29h .64 760 0\n"
"fpu q30h .64 776 0\n"
"fpu q31h .64 792 0\n"
/* foo */
"gpr fp .64 232 0\n" // fp = x29
"gpr lr .64 240 0\n" // lr = x30

View File

@ -501,7 +501,8 @@ static ut64 shifted_imm64(Instruction *insn, int n, int sz) {
InstructionOperand op = INSOP64 (n);
int sft = op.shiftValue;
switch (op.shiftType) {
case ShiftType_MSL: // idk what this is
case ShiftType_MSL:
return (GETIMM64 (n) << sft) | ((1 << sft) - 1);
case ShiftType_LSL:
return GETIMM64 (n) << sft;
case ShiftType_LSR:
@ -1409,6 +1410,7 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
r_strbuf_setf (&op->esil, ",");
break;
case ARM64_MOV:
case ARM64_MOVI:
case ARM64_FMOV:
{
if (0) {
@ -1489,6 +1491,31 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
VEC64_DST_APPEND(&op->esil, 0, -1);
r_strbuf_appendf (&op->esil, ",=");
break;
case ARM64_FRINTA:
case ARM64_FRINTI:
case ARM64_FRINTN:
case ARM64_FRINTX:
case ARM64_FRINTZ:
case ARM64_FRINTP:
case ARM64_FRINTM:
case ARM64_FRINT32X:
case ARM64_FRINT32Z:
case ARM64_FRINT64X:
case ARM64_FRINT64Z:
{
char* rounder = "ROUND";
if (insn->operation == ARM64_FRINTM) {
rounder = "FLOOR";
} else if (insn->operation == ARM64_FRINTP) {
rounder = "CEIL";
}
r_strbuf_setf (&op->esil, "%d,DUP,", REGBITS64 (1));
ARG64_APPEND(&op->esil, 1);
r_strbuf_appendf (&op->esil, ",F2D,%s,D2F,", rounder);
VEC64_DST_APPEND(&op->esil, 0, -1);
r_strbuf_appendf (&op->esil, ",=");
break;
}
case ARM64_FABS:
r_strbuf_setf (&op->esil, "%d,DUP,%s,F2D,DUP,0,I2D,F<,?{,-F,},D2F,%s,=",
REGBITS64 (1), REG64 (1), REG64 (0));
@ -1497,11 +1524,17 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
r_strbuf_setf (&op->esil, "%d,DUP,%s,F2D,-F,D2F,%s,=",
REGBITS64 (1), REG64 (1), REG64 (0));
break;
case ARM64_FSQRT:
r_strbuf_setf (&op->esil, "%d,DUP,%s,F2D,SQRT,D2F,%s,=",
REGBITS64 (1), REG64 (1), REG64 (0));
break;
case ARM64_FMINNM:
case ARM64_FMIN:
r_strbuf_setf (&op->esil, "%d,%s,F2D,%d,%s,F2D,F<,?{,%s,}{,%s,},%s,=",
REGBITS64 (2), REG64 (2),
REGBITS64 (1), REG64 (1), REG64 (1), REG64 (2), REG64 (0));
break;
case ARM64_FMAXNM:
case ARM64_FMAX:
r_strbuf_setf (&op->esil, "%d,%s,F2D,%d,%s,F2D,F<,!,?{,%s,}{,%s,},%s,=",
REGBITS64 (2), REG64 (2),
@ -1693,6 +1726,11 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
case ARM64_LDUR:
case ARM64_LDURB:
case ARM64_LDURH:
case ARM64_LDTR:
case ARM64_LDTRB:
case ARM64_LDTRH:
case ARM64_LDTRSB:
case ARM64_LDTRSH:
case ARM64_LDR:
case ARM64_LDRB:
case ARM64_LDXR:
@ -1712,6 +1750,8 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
case ARM64_LDAXRB:
case ARM64_LDXRB:
case ARM64_LDURB:
case ARM64_LDTRB:
case ARM64_LDTRSB:
size = 1;
break;
case ARM64_LDRH:
@ -1719,9 +1759,12 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
case ARM64_LDXRH:
case ARM64_LDAXRH:
case ARM64_LDURH:
case ARM64_LDTRH:
case ARM64_LDTRSH:
size = 2;
break;
case ARM64_LDRSW:
case ARM64_LDTRSW:
case ARM64_LDURSW:
size = 4;
break;
@ -1897,39 +1940,67 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
if (insn->operation == ARM64_CCMP || insn->operation == ARM64_CCMN) {
r_strbuf_appendf (&op->esil, ",");
//arm_prefix_cond(op, insn->detail->arm64.cc);
v35arm_prefix_cond(op, insn->operands[3].cond);
r_strbuf_appendf (&op->esil, "}{,pstate,1,28,1,<<,-,&,28,%"PFMT64u",<<,|,pstate,:=", GETIMM64 (2));
}
break;
case ARM64_FCSEL:
case ARM64_CSEL: // csel Wd, Wn, Wm --> Wd := (cond) ? Wn : Wm
if ISCOND64(3) {
// XXX arm_prefix_cond (op, insn->operands[3].cond);
v35arm_prefix_cond (op, insn->operands[3].cond);
}
r_strbuf_appendf (&op->esil, "%s,}{,%s,},%s,=", REG64 (1), REG64 (2), REG64 (0));
postfix = "";
break;
case ARM64_CSET: // cset Wd --> Wd := (cond) ? 1 : 0
if ISCOND64(1) {
// XXX arm_prefix_cond (op, insn->operands[1].cond);
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "1,}{,0,},%s,=", REG64 (0));
postfix = "";
break;
case ARM64_CSETM: // cset Wd --> Wd := (cond) ? 1 : 0
if ISCOND64(1) {
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "-1,}{,0,},%s,=", REG64 (0));
postfix = "";
break;
case ARM64_CINC: // cinc Wd, Wn --> Wd := (cond) ? (Wn+1) : Wn
if ISCOND64(1) {
// XXX arm_prefix_cond (op, insn->operands[1].cond);
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "1,%s,+,}{,%s,},%s,=", REG64 (1), REG64 (1), REG64 (0));
postfix = "";
break;
case ARM64_CSINC: // csinc Wd, Wn, Wm --> Wd := (cond) ? Wn : (Wm+1)
if ISCOND64(1) {
// XXX arm_prefix_cond (op, insn->operands[1].cond);
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "%s,}{,1,%s,+,},%s,=", REG64 (1), REG64 (2), REG64 (0));
postfix = "";
break;
case ARM64_CINV:
if ISCOND64(1) {
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "-1,%s,^,}{,%s,},%s,=", REG64 (1), REG64 (1), REG64 (0));
postfix = "";
break;
case ARM64_CSINV: // csinc Wd, Wn, Wm --> Wd := (cond) ? Wn : (Wm+1)
if ISCOND64(1) {
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "%s,}{,-1,%s,^,},%s,=", REG64 (1), REG64 (2), REG64 (0));
postfix = "";
break;
case ARM64_CNEG:
if ISCOND64(1) {
v35arm_prefix_cond (op, insn->operands[1].cond);
}
r_strbuf_appendf (&op->esil, "-1,%s,*,}{,%s,},%s,=", REG64 (1), REG64 (1), REG64 (0));
postfix = "";
break;
case ARM64_STXRB:
case ARM64_STXRH:
case ARM64_STXR:
@ -1949,13 +2020,29 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
case ARM64_STUR:
case ARM64_STURB:
case ARM64_STURH:
case ARM64_STTR:
case ARM64_STTRH:
case ARM64_STTRB:
case ARM64_STR: // str x6, [x6,0xf90]
{
int size = REGSIZE64 (0);
if (insn->operation == ARM64_STRB || insn->operation == ARM64_STURB) {
size = 1;
} else if (insn->operation == ARM64_STRH || insn->operation == ARM64_STURH) {
size = 2;
switch (insn->operation) {
case ARM64_STRB:
case ARM64_STURB:
case ARM64_STTRB:
{
size = 1;
break;
}
case ARM64_STRH:
case ARM64_STURH:
case ARM64_STTRH:
{
size = 2;
break;
}
default:
break;
}
if (ISMEM64 (1)) {
if (HASMEMINDEX64 (1)) {
@ -2094,6 +2181,7 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
}
break;
}
case ARM64_LDNP:
case ARM64_LDP: // ldp x29, x30, [sp], 0x10
{
int disp = (int)MEMDISP64 (2);
@ -2128,10 +2216,10 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
abs, MEMBASE64 (2), sign);
} else {
r_strbuf_setf (&op->esil,
"%s,%"PFMT64u",%c,[%d],%s,=,"
"%s,%"PFMT64u",%c,%d,%c,[%d],%s,=",
MEMBASE64 (2), abs, sign, size, REG64 (0),
MEMBASE64 (2), abs, sign, size, sign, size, REG64 (1));
"%"PFMT64d",%s,%c,[%d],%s,=,"
"%d,%"PFMT64d",%s,%c,+,[%d],%s,=",
abs, MEMBASE64 (2), sign, size, REG64 (0),
size, abs, MEMBASE64 (2), sign, size, REG64 (1));
}
break;
}
@ -2312,10 +2400,16 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
GETIMM64 (2), REG64 (1), GETIMM64 (2) , (ut64)bitmask_by_width[index], REG64 (0));
}
break;
case ARM64_NGC:
case ARM64_NEG:
ARG64_APPEND (&op->esil, 1);
r_strbuf_appendf (&op->esil, ",0,-,%s,=", REG64 (0));
break;
case ARM64_NGCS:
case ARM64_NEGS:
ARG64_APPEND (&op->esil, 1);
r_strbuf_appendf (&op->esil, ",0,-,%s,=", REG64 (0));
SET_FLAGS();
break;
case ARM64_SVC:
r_strbuf_setf (&op->esil, "%" PFMT64u ",$", GETIMM64 (0));