mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-07 05:41:43 +00:00
Improve analysis of compressed instructions and update instruction format (#17115)
This commit is contained in:
parent
5124bef434
commit
521db221f4
@ -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) {
|
||||
|
@ -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 },
|
||||
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user