7 #include <capstone/capstone.h>
8 #include <capstone/riscv.h>
12 #define OPERAND(x) insn->detail->riscv.operands[x]
13 #define REGID(x) insn->detail->riscv.operands[x].reg
14 #define REG(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].reg)
15 #define IMM(x) insn->detail->riscv.operands[x].imm
16 #define MEMBASE(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].mem.base)
17 #define MEMINDEX(x) insn->detail->riscv.operands[x].mem.index
18 #define MEMDISP(x) insn->detail->riscv.operands[x].mem.disp
19 #define OPCOUNT() insn->detail->riscv.op_count
22 #define SET_VAL(op, i) \
23 if ((i) < OPCOUNT() && OPERAND(i).type == RISCV_OP_IMM) { \
24 (op)->val = OPERAND(i).imm; \
27 #define CREATE_SRC_DST_3(op) \
28 (op)->src[0] = rz_analysis_value_new(); \
29 (op)->src[1] = rz_analysis_value_new(); \
30 (op)->dst = rz_analysis_value_new();
32 #define CREATE_SRC_DST_2(op) \
33 (op)->src[0] = rz_analysis_value_new(); \
34 (op)->dst = rz_analysis_value_new();
36 #define SET_SRC_DST_3_REGS(op) \
37 CREATE_SRC_DST_3(op); \
38 (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
39 (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
40 (op)->src[1]->reg = rz_reg_get(analysis->reg, REG(2), RZ_REG_TYPE_GPR);
42 #define SET_SRC_DST_3_IMM(op) \
43 CREATE_SRC_DST_3(op); \
44 (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
45 (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
46 (op)->src[1]->imm = IMM(2);
48 #define SET_SRC_DST_2_REGS(op) \
49 CREATE_SRC_DST_2(op); \
50 (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
51 (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR);
53 #define SET_SRC_DST_3_REG_OR_IMM(op) \
54 if (OPERAND(2).type == RISCV_OP_IMM) { \
55 SET_SRC_DST_3_IMM(op); \
56 } else if (OPERAND(2).type == RISCV_OP_REG) { \
57 SET_SRC_DST_3_REGS(op); \
63 #define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&"
66 #define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr)
67 #define ES_CALL_D(addr) ES_CALL_DR("ra", addr)
70 #define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr)
71 #define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
76 #define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
78 #define ES_J(addr) addr ",SETJT,1,SETD"
80 #define ES_TRAP_DS() ""
81 #define ES_J(addr) addr ",pc,="
85 #define ES_SIGN_EXT64(arg) \
86 arg ",0x80000000,&,0,<,?{," \
87 "0xffffffff00000000," arg ",|=," \
90 #define PROTECT_ZERO() \
91 if (REG(0)[0] == 'z') { \
92 rz_strbuf_appendf(&op->esil, ","); \
95 #define ESIL_LOAD(size) \
97 rz_strbuf_appendf(&op->esil, "%s,[" size "],%s,=", \
108 pj_ka(pj,
"operands");
109 cs_riscv *
x = &insn->detail->riscv;
110 for (
i = 0;
i <
x->op_count;
i++) {
111 cs_riscv_op *
op =
x->operands +
i;
115 pj_ks(pj,
"type",
"reg");
119 pj_ks(pj,
"type",
"imm");
123 pj_ks(pj,
"type",
"mem");
124 if (
op->mem.base != RISCV_REG_INVALID) {
127 pj_kN(pj,
"disp",
op->mem.disp);
130 pj_ks(pj,
"type",
"invalid");
145 switch (insn->detail->riscv.operands[
n].type) {
146 case RISCV_OP_INVALID:
151 insn->detail->riscv.operands[
n].reg));
154 st64 x = (
st64)insn->detail->riscv.operands[
n].imm;
159 st64 disp = insn->detail->riscv.operands[
n].mem.disp;
162 (
ut64)-insn->detail->riscv.operands[
n].mem.disp,
164 insn->detail->riscv.operands[
n].mem.base));
167 (
ut64)insn->detail->riscv.operands[
n].mem.disp,
169 insn->detail->riscv.operands[
n].mem.base));
177 #define ARG(x) (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x)
180 char str[8][32] = { { 0 } };
188 for (
i = 0;
i < insn->detail->riscv.op_count &&
i < 8;
i++) {
211 if (
OPERAND(reg_num).mem.base != RISCV_REG_INVALID) {
227 op->src[0]->reg = &
reg;
258 $ rizin -
a riscv -
e cfg.bigendian=1 -
c "wx 0083001b" -
263 "opcode":
"divu zero, a0, v1",
264 "disasm":
"divu zero, a0, v1",
291 if (insn && (insn->id == RISCV_INS_SLTI || insn->id == RISCV_INS_SLTIU)) {
319 int n, ret, opsize = -1;
321 static int omode = -1;
322 static int obits = 32;
324 int mode = (analysis->
bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32;
325 if (
mode != omode || analysis->
bits != obits) {
329 obits = analysis->
bits;
345 if (n < 1 || insn->
size < 1) {
349 opsize =
op->size = insn->size;
351 case RISCV_INS_C_NOP:
354 case RISCV_INS_INVALID:
357 case RISCV_INS_C_JALR:
369 op->fail =
op->addr +
op->size;
380 opex(&
op->opex, hndl, insn);
397 const char *
p =
NULL;
398 switch (analysis->
bits) {
437 "gpr s10 .32 104 0\n"
438 "gpr s11 .32 108 0\n"
445 "gpr ft0 .64 128 0\n"
446 "gpr ft1 .64 136 0\n"
447 "gpr ft2 .64 144 0\n"
448 "gpr ft3 .64 152 0\n"
449 "gpr ft4 .64 160 0\n"
450 "gpr ft5 .64 168 0\n"
451 "gpr ft6 .64 176 0\n"
452 "gpr ft7 .64 184 0\n"
453 "gpr fs0 .64 192 0\n"
454 "gpr fs1 .64 200 0\n"
455 "gpr fa0 .64 208 0\n"
456 "gpr fa1 .64 216 0\n"
457 "gpr fa2 .64 224 0\n"
458 "gpr fa3 .64 232 0\n"
459 "gpr fa4 .64 240 0\n"
460 "gpr fa5 .64 248 0\n"
461 "gpr fa6 .64 256 0\n"
462 "gpr fa7 .64 264 0\n"
463 "gpr fs2 .64 272 0\n"
464 "gpr fs3 .64 280 0\n"
465 "gpr fs4 .64 288 0\n"
466 "gpr fs5 .64 296 0\n"
467 "gpr fs6 .64 304 0\n"
468 "gpr fs7 .64 312 0\n"
469 "gpr fs8 .64 320 0\n"
470 "gpr fs9 .64 328 0\n"
471 "gpr fs10 .64 336 0\n"
472 "gpr fs11 .64 344 0\n"
473 "gpr ft8 .64 352 0\n"
474 "gpr ft9 .64 360 0\n"
475 "gpr ft10 .64 368 0\n"
476 "gpr ft11 .64 376 0\n"
477 "gpr fcsr .32 384 0\n"
483 "flg frm .3 3077 0\n";
524 "gpr s10 .64 208 0\n"
525 "gpr s11 .64 216 0\n"
531 "gpr ft0 .64 256 0\n"
532 "gpr ft1 .64 264 0\n"
533 "gpr ft2 .64 272 0\n"
534 "gpr ft3 .64 280 0\n"
535 "gpr ft4 .64 288 0\n"
536 "gpr ft5 .64 296 0\n"
537 "gpr ft6 .64 304 0\n"
538 "gpr ft7 .64 312 0\n"
539 "gpr fs0 .64 320 0\n"
540 "gpr fs1 .64 328 0\n"
541 "gpr fa0 .64 336 0\n"
542 "gpr fa1 .64 344 0\n"
543 "gpr fa2 .64 352 0\n"
544 "gpr fa3 .64 360 0\n"
545 "gpr fa4 .64 368 0\n"
546 "gpr fa5 .64 376 0\n"
547 "gpr fa6 .64 384 0\n"
548 "gpr fa7 .64 392 0\n"
549 "gpr fs2 .64 400 0\n"
550 "gpr fs3 .64 408 0\n"
551 "gpr fs4 .64 416 0\n"
552 "gpr fs5 .64 424 0\n"
553 "gpr fs6 .64 432 0\n"
554 "gpr fs7 .64 440 0\n"
555 "gpr fs8 .64 448 0\n"
556 "gpr fs9 .64 456 0\n"
557 "gpr fs10 .64 464 0\n"
558 "gpr fs11 .64 472 0\n"
559 "gpr ft8 .64 480 0\n"
560 "gpr ft9 .64 488 0\n"
561 "gpr ft10 .64 496 0\n"
562 "gpr ft11 .64 504 0\n"
563 "gpr fcsr .32 512 0\n"
569 "flg frm .3 4101 0\n";
583 if (analysis->
bits == 64) {
593 .desc =
"Capstone RISCV analyzer",
603 #ifndef RZ_PLUGIN_INCORE
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
RzAnalysisPlugin rz_analysis_plugin_riscv_cs
static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num)
static char * get_reg_profile(RzAnalysis *analysis)
static void opex(RzStrBuf *buf, csh handle, cs_insn *insn)
#define SET_SRC_DST_3_REGS(op)
static const char * arg(csh *handle, cs_insn *insn, char *buf, int n)
RZ_API RzLibStruct rizin_plugin
#define SET_SRC_DST_3_IMM(op)
#define SET_SRC_DST_2_REGS(op)
static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_insn *insn)
static void set_opdir(RzAnalysisOp *op)
static int analop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static int archinfo(RzAnalysis *analysis, int q)
#define SET_SRC_DST_3_REG_OR_IMM(op)
static mcore_handle handle
@ CS_OPT_DETAIL
Break down instruction structure into details.
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define RZ_ANALYSIS_ARCHINFO_ALIGN
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
@ RZ_ANALYSIS_OP_DIR_READ
@ RZ_ANALYSIS_OP_DIR_EXEC
@ RZ_ANALYSIS_OP_DIR_WRITE
@ RZ_ANALYSIS_OP_MASK_VAL
@ RZ_ANALYSIS_OP_MASK_OPEX
@ RZ_ANALYSIS_OP_MASK_ESIL
#define RZ_ANALYSIS_OP_TYPE_MASK
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
@ RZ_ANALYSIS_OP_TYPE_SUB
@ RZ_ANALYSIS_OP_TYPE_LOAD
@ RZ_ANALYSIS_OP_TYPE_JMP
@ RZ_ANALYSIS_OP_TYPE_AND
@ RZ_ANALYSIS_OP_TYPE_UJMP
@ RZ_ANALYSIS_OP_TYPE_SAR
@ RZ_ANALYSIS_OP_TYPE_CALL
@ RZ_ANALYSIS_OP_TYPE_ADD
@ RZ_ANALYSIS_OP_TYPE_STORE
@ RZ_ANALYSIS_OP_TYPE_SHR
@ RZ_ANALYSIS_OP_TYPE_DIV
@ RZ_ANALYSIS_OP_TYPE_MOV
@ RZ_ANALYSIS_OP_TYPE_SHL
@ RZ_ANALYSIS_OP_TYPE_ILL
@ RZ_ANALYSIS_OP_TYPE_UCALL
@ RZ_ANALYSIS_OP_TYPE_RET
@ RZ_ANALYSIS_OP_TYPE_NOP
@ RZ_ANALYSIS_OP_TYPE_LEA
@ RZ_ANALYSIS_OP_TYPE_XOR
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API PJ * pj_ka(PJ *j, const char *k)
RZ_API PJ * pj_end(PJ *j)
RZ_API const char * pj_string(PJ *pj)
RZ_API void pj_free(PJ *j)
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
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 void rz_strbuf_fini(RzStrBuf *sb)
RZ_API void rz_strbuf_init(RzStrBuf *sb)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()