Improve analysis of compressed instructions and update instruction format (#17115)

This commit is contained in:
Sylvain Pelissier 2020-06-22 10:12:50 +02:00 committed by GitHub
parent 5124bef434
commit 521db221f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 20 deletions

View File

@ -105,7 +105,7 @@ static void get_insn_args(riscv_args_t *args, const char *d, insn_t l, uint64_t
snprintf (RISCVARGN(args), RISCVARGSIZE , "%s",
riscv_gpr_names[EXTRACT_OPERAND (CRS2S, l) + 8]);
break;
case 'U': /* RS1, constrained to equal RD */
case 'U': /* RS1, constrained to equal RD in CI format*/
snprintf (RISCVARGN(args), RISCVARGSIZE , "%s", riscv_gpr_names[rd]);
break;
case 'c': /* RS1, constrained to equal sp */
@ -400,13 +400,13 @@ static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
} else if (!strncmp (name, "and", 3)) {
esilprintf (op, "%s,%s,&,%s,=", ARG (2), ARG (1), ARG (0));
} else if (!strcmp (name, "auipc")) {
esilprintf (op, "%s,pc,+,%s,=", ARG (1), ARG (0));
esilprintf (op, "%s,$$,+,%s,=", ARG (1), ARG (0));
} else if (!strncmp (name, "sll", 3)) {
esilprintf (op, "%s,%s,<<,%s,=", ARG (2), ARG (1), ARG (0));
} else if (!strncmp (name, "srl", 3)) {
esilprintf (op, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0));
} else if (!strncmp (name, "sra", 3)) {
esilprintf (op, "%s,%s,>>,%s,=", ARG (2), ARG (1), ARG (0));
esilprintf (op, "%s,%s,>>>>,%s,=", ARG (2), ARG (1), ARG (0));
}
// assigns
else if (!strcmp (name, "mv")) {
@ -560,6 +560,8 @@ static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
// decide whether it's ret or call
int rd = (word >> OP_SH_RD) & OP_MASK_RD;
op->type = (rd == 0) ? R_ANAL_OP_TYPE_RET: R_ANAL_OP_TYPE_UCALL;
} else if (is_any ("c.jalr")) {
op->type = R_ANAL_OP_TYPE_UCALL;
} else if (is_any ("c.jr")) {
op->type = R_ANAL_OP_TYPE_RET;
} else if (is_any ("beqz", "beq", "blez", "bgez", "ble",
@ -567,10 +569,14 @@ static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
"bgt", "bgtu", "bnez", "bne")) {
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = EXTRACT_SBTYPE_IMM (word) + addr;
op->fail = addr + 4;
op->fail = addr + op->size;
} else if (is_any ("c.beqz", "c.bnez")) {
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = EXTRACT_RVC_B_IMM (word) + addr;
op->fail = addr + op->size;
// math
} else if (is_any ("addi", "addw", "addiw", "add", "auipc", "c.addi",
"c.addw", "c.add")) {
"c.addw", "c.add", "c.addi4spn", "c.addi16sp")) {
op->type = R_ANAL_OP_TYPE_ADD;
} else if (is_any ("c.mv")) {
op->type = R_ANAL_OP_TYPE_MOV;
@ -590,12 +596,19 @@ static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
op->type = R_ANAL_OP_TYPE_MUL;
} else if (is_any ("div", "divu", "divw", "divuw")) {
op->type = R_ANAL_OP_TYPE_DIV;
} else if (is_any ("slli", "c.slli")) {
op->type = R_ANAL_OP_TYPE_SHL;
} else if (is_any ("srl", "c.srli")) {
op->type = R_ANAL_OP_TYPE_SHR;
} else if (is_any ("sra", "srai", "c.srai")) {
op->type = R_ANAL_OP_TYPE_SAR;
// memory
} else if (is_any ("sd", "sb", "sh", "sw", "c.sd", "c.sw")) {
} else if (is_any ("sd", "sb", "sh", "sw", "c.sd", "c.sw",
"c.swsp")) {
op->type = R_ANAL_OP_TYPE_STORE;
} else if (is_any ("ld", "lw", "lwu", "lui", "li",
"lb", "lbu", "lh", "lhu", "la", "lla", "c.ld",
"c.lw", "c.li")) {
"c.lw", "c.lwsp", "c.li", "c.lui")) {
op->type = R_ANAL_OP_TYPE_LOAD;
}
if (mask & R_ANAL_OP_MASK_VAL && args.num) {

View File

@ -114,7 +114,7 @@ static int match_c_lui(const struct riscv_opcode *op, insn_t insn)
static const struct riscv_opcode riscv_builtin_opcodes[] =
{
/* name, isa, operands, match, mask, match_func, pinfo. */
{"unimp", "C", "", 0, 0xffffU, match_opcode, 0 },
{"illegal", "C", "", 0, 0xffffU, match_opcode, 0 },
{"unimp", "I", "", MATCH_CSRRW | (CSR_CYCLE << OP_SH_CSR), 0xffffffffU, match_opcode, 0 }, /* csrw cycle, x0 */
{"ebreak", "C", "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
{"ebreak", "I", "", MATCH_EBREAK, MASK_EBREAK, match_opcode, 0 },
@ -617,18 +617,18 @@ static const struct riscv_opcode riscv_builtin_opcodes[] =
{"c.li", "C", "d,Cj", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, 0 },
{"c.addi4spn","C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, 0 },
{"c.addi16sp","C", "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, 0 },
{"c.addi", "C", "d,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, 0 },
{"c.add", "C", "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 },
{"c.sub", "C", "Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
{"c.and", "C", "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
{"c.or", "C", "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
{"c.xor", "C", "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
{"c.slli", "C", "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, 0 },
{"c.srli", "C", "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
{"c.srai", "C", "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
{"c.andi", "C", "Cs,Cj", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
{"c.addiw", "64C", "d,Cj", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
{"c.addw", "64C", "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },
{"c.addi", "C", "d,Cj,CU", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, 0 },
{"c.add", "C", "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 },
{"c.sub", "C", "Cs,Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
{"c.and", "C", "Cs,Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
{"c.or", "C", "Cs,Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
{"c.xor", "C", "Cs,Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
{"c.slli", "C", "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, 0 },
{"c.srli", "C", "Cs,Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
{"c.srai", "C", "Cs,Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
{"c.andi", "C", "Cs,Cj,Cs", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
{"c.addiw", "64C", "d,Cj,CU", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
{"c.addw", "64C", "Cs,Ct,Cs", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },
{"c.subw", "64C", "Cs,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 },
{"c.ldsp", "64C", "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, 0 },
{"c.ld", "64C", "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, 0 },

View File

@ -24,4 +24,21 @@ EXPECT=<<EOF
| 0x00000006 aa85 mv a1, a0
`-> 0x00000008 8146 li a3, 0
EOF
RUN
NAME=branch with compress instruction
FILE=-
CMDS=<<EOF
e asm.arch=riscv
e asm.bits=32
wx 11c182809d06f5fe
pd 5
EOF
EXPECT=<<EOF
,=< 0x00000000 11c1 beqz a0, 0x4
.--> 0x00000002 8280 ret
:`-> 0x00000004 9d06 addi a3, a3, 7
`==< 0x00000006 f5fe bnez a3, 0x2
0x00000008 0000 illegal
EOF
RUN

View File

@ -13,6 +13,23 @@ EXPECT=<<EOF
EOF
RUN
NAME=RISC-V ESIL for arithmetic compressed instructions
FILE=malloc://1024
CMDS=<<EOF
e asm.arch=riscv
e asm.bits=32
wx ad668d067d562206d18e1186158e
aei
7aes
ar a2
ar a3
EOF
EXPECT=<<EOF
0x000000ed
0xffffff03
EOF
RUN
NAME=RISC-V ESIL for jump instructions
FILE=malloc://1024
CMDS=<<EOF