9 #include "../../asm/arch/riscv/riscv-opc.c"
10 #include "../../asm/arch/riscv/riscv.h"
11 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
12 #define RISCVARGSMAX (8)
13 #define RISCVARGSIZE (64)
14 #define RISCVARGN(x) ((x)->arg[(x)->num++])
25 #define is_any(...) _is_any(o->name, __VA_ARGS__, NULL)
31 cur = va_arg(va,
char *);
35 if (!strcmp(
str, cur)) {
44 static void arg_p2(
char *
buf,
unsigned long val,
const char *
const *array,
size_t size) {
45 const char *
s =
val >=
size || array[
val] ? array[
val] :
"unknown";
53 #define OP_HASH_IDX(i) ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP))
258 const char *csr_name =
NULL;
261 #define DECLARE_CSR(name, num) \
265 #include "../../asm/arch/riscv/riscv-opc.h"
288 if (
n >=
args->num || !strcmp(
args->arg[
n],
"zero")) {
295 const int no_alias = 1;
298 int xlen = analysis->
bits;
305 }
else if (
len >=
sizeof(
ut16)) {
341 if (!strncmp(
"c.", o->
name, 2)) {
345 #define ARG(x) (arg_n(&args, (x)))
347 if (!strcmp(
name,
"nop")) {
351 else if (!strncmp(
name,
"addi16sp", 8)) {
357 }
else if (!strncmp(
name,
"addiw", 5)) {
366 }
else if (!strncmp(
name,
"addw", 4)) {
371 }
else if (!strncmp(
name,
"add", 3)) {
378 }
else if (!strncmp(
name,
"subw", 4)) {
383 }
else if (!strncmp(
name,
"sub", 3)) {
390 }
else if (!strncmp(
name,
"mulw", 4)) {
395 }
else if (!strncmp(
name,
"mul", 3)) {
397 }
else if (!strncmp(
name,
"div", 3)) {
399 }
else if (!strncmp(
name,
"rem", 3)) {
401 }
else if (!strncmp(
name,
"xor", 3)) {
403 }
else if (!strncmp(
name,
"or", 2)) {
405 }
else if (!strncmp(
name,
"and", 3)) {
407 }
else if (!strcmp(
name,
"auipc")) {
409 }
else if (!strncmp(
name,
"sll", 3)) {
411 if (
name[3] ==
'w' || !strncmp(
name,
"slliw", 5)) {
414 }
else if (!strcmp(
name,
"srlw") || !strcmp(
name,
"srliw")) {
415 esilprintf(
op,
"%s,0xffffffff,%s,&,>>,%s,=",
ARG(2),
ARG(1),
ARG(0));
416 }
else if (!strncmp(
name,
"srl", 3)) {
418 }
else if (!strcmp(
name,
"sraiw")) {
421 }
else if (!strncmp(
name,
"sra", 3)) {
425 else if (!strcmp(
name,
"mv")) {
427 }
else if (!strcmp(
name,
"li")) {
429 }
else if (!strcmp(
name,
"lui")) {
431 if (analysis->
bits == 64) {
437 else if (!strncmp(
name,
"csrrw", 5)) {
439 esilprintf(
op,
"%s,0,+,%s,%s,=,%s,=",
ARG(1),
ARG(2),
ARG(1),
ARG(0));
440 }
else if (!strncmp(
name,
"csrrs", 5)) {
442 esilprintf(
op,
"%s,0,+,%s,%s,|=,%s,=",
ARG(1),
ARG(2),
ARG(1),
ARG(0));
443 }
else if (!strncmp(
name,
"csrrc", 5)) {
445 esilprintf(
op,
"%s,0,+,%s,1,+,0,-,%s,&=,%s,=",
ARG(1),
ARG(1),
ARG(2),
ARG(0));
448 else if (!strcmp(
name,
"sd") || !strcmp(
name,
"sdsp")) {
450 }
else if (!strcmp(
name,
"sw") || !strcmp(
name,
"swsp")) {
452 }
else if (!strcmp(
name,
"sh") || !strcmp(
name,
"shsp")) {
454 }
else if (!strcmp(
name,
"sb") || !strcmp(
name,
"sbsp")) {
456 }
else if (!strcmp(
name,
"fsq") || !strcmp(
name,
"fsqsp")) {
458 }
else if (!strcmp(
name,
"fsd") || !strcmp(
name,
"fsdsp")) {
460 }
else if (!strcmp(
name,
"fsw") || !strcmp(
name,
"fswsp")) {
462 }
else if (!strcmp(
name,
"fsh") || !strcmp(
name,
"fshsp")) {
464 }
else if (!strcmp(
name,
"fsb") || !strcmp(
name,
"fsbsp")) {
468 else if (!strcmp(
name,
"ld") || !strcmp(
name,
"ldsp")) {
470 }
else if (!strcmp(
name,
"lw") || !strcmp(
name,
"lwu") || !strcmp(
name,
"lwsp")) {
472 if ((analysis->
bits == 64) && strcmp(
name,
"lwu")) {
475 }
else if (!strcmp(
name,
"lh") || !strcmp(
name,
"lhu") || !strcmp(
name,
"lhsp")) {
477 if (strcmp(
name,
"lwu")) {
480 }
else if (!strcmp(
name,
"lb") || !strcmp(
name,
"lbu") || !strcmp(
name,
"lbsp")) {
482 if (strcmp(
name,
"lbu")) {
485 }
else if (!strcmp(
name,
"flq") || !strcmp(
name,
"flqsp")) {
487 }
else if (!strcmp(
name,
"fld") || !strcmp(
name,
"fldsp")) {
489 }
else if (!strcmp(
name,
"flw") || !strcmp(
name,
"flwsp")) {
491 }
else if (!strcmp(
name,
"flh") || !strcmp(
name,
"flhsp")) {
493 }
else if (!strcmp(
name,
"flb") || !strcmp(
name,
"flbsp")) {
497 else if (!strcmp(
name,
"jalr")) {
498 if (strcmp(
ARG(0),
"0")) {
499 esilprintf(
op,
"%s,%s,+,pc,=,%d,$$,+,%s,=",
ARG(2),
ARG(1),
op->size,
ARG(0));
503 }
else if (!strcmp(
name,
"jal")) {
504 if (strcmp(
ARG(0),
"0")) {
506 esilprintf(
op,
"%d,$$,+,ra,=,%s,pc,=",
op->size,
ARG(0));
508 esilprintf(
op,
"%d,$$,+,%s,=,%s,pc,=",
op->size,
ARG(0),
ARG(1));
513 }
else if (!strcmp(
name,
"jr") || !strcmp(
name,
"j")) {
515 }
else if (!strcmp(
name,
"ecall") || !strcmp(
name,
"ebreak")) {
519 else if (!strcmp(
name,
"beq")) {
520 esilprintf(
op,
"%s,%s,==,$z,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
521 }
else if (!strcmp(
name,
"bne")) {
522 esilprintf(
op,
"%s,%s,==,$z,!,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
523 }
else if (!strcmp(
name,
"ble") || !strcmp(
name,
"bleu")) {
524 esilprintf(
op,
"%s,%s,<=,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
525 }
else if (!strcmp(
name,
"blt") || !strcmp(
name,
"bltu")) {
526 esilprintf(
op,
"%s,%s,<,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
527 }
else if (!strcmp(
name,
"bge") || !strcmp(
name,
"bgeu")) {
528 esilprintf(
op,
"%s,%s,>=,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
529 }
else if (!strcmp(
name,
"bgt") || !strcmp(
name,
"bgtu")) {
530 esilprintf(
op,
"%s,%s,>,?{,%s,pc,=,},",
ARG(1),
ARG(0),
ARG(2));
531 }
else if (!strcmp(
name,
"beqz")) {
532 esilprintf(
op,
"%s,0,==,$z,?{,%s,pc,=,},",
ARG(0),
ARG(1));
533 }
else if (!strcmp(
name,
"bnez")) {
534 esilprintf(
op,
"%s,0,==,$z,!,?{,%s,pc,=,},",
ARG(0),
ARG(1));
535 }
else if (!strcmp(
name,
"blez")) {
536 esilprintf(
op,
"%s,0,<=,?{,%s,pc,=,},",
ARG(0),
ARG(1));
537 }
else if (!strcmp(
name,
"bltz")) {
538 esilprintf(
op,
"%s,0,<,?{,%s,pc,=,},",
ARG(0),
ARG(1));
539 }
else if (!strcmp(
name,
"bgez")) {
540 esilprintf(
op,
"%s,0,>=,?{,%s,pc,=,},",
ARG(0),
ARG(1));
541 }
else if (!strcmp(
name,
"bgtz")) {
542 esilprintf(
op,
"%s,0,>,?{,%s,pc,=,},",
ARG(0),
ARG(1));
543 }
else if (!strncmp(
name,
"seq", 3)) {
545 }
else if (!strncmp(
name,
"sne", 3)) {
547 }
else if (!strncmp(
name,
"sle", 3)) {
549 }
else if (!strncmp(
name,
"slt", 3)) {
551 }
else if (!strncmp(
name,
"sge", 3)) {
553 }
else if (!strncmp(
name,
"sgt", 3)) {
566 }
else if (
is_any(
"c.jal")) {
570 }
else if (
is_any(
"jr")) {
572 }
else if (
is_any(
"c.j",
"jump")) {
575 }
else if (
is_any(
"jalr")) {
582 }
else if (
is_any(
"c.ret")) {
584 }
else if (
is_any(
"c.jalr")) {
586 }
else if (
is_any(
"c.jr")) {
588 }
else if (
is_any(
"beqz",
"beq",
"blez",
"bgez",
"ble",
589 "bleu",
"bge",
"bgeu",
"bltz",
"bgtz",
"blt",
"bltu",
590 "bgt",
"bgtu",
"bnez",
"bne")) {
594 }
else if (
is_any(
"c.beqz",
"c.bnez")) {
599 }
else if (
is_any(
"c.addi",
"c.addiw")) {
602 }
else if (
is_any(
"addi",
"addiw")) {
605 }
else if (
is_any(
"c.addi4spn")) {
608 }
else if (
is_any(
"c.addi16sp")) {
611 }
else if (
is_any(
"addw",
"add",
"c.addw",
"c.add")) {
613 }
else if (
is_any(
"auipc")) {
616 }
else if (
is_any(
"c.mv",
"csrrw",
"csrrc",
"csrrs")) {
618 }
else if (
is_any(
"subi",
"subw",
"sub",
"c.sub",
"c.subw")) {
620 }
else if (
is_any(
"xori",
"xor",
"c.xor")) {
622 }
else if (
is_any(
"andi",
"and",
"c.andi",
"c.and")) {
624 }
else if (
is_any(
"ori",
"or",
"c.or")) {
626 }
else if (
is_any(
"not")) {
628 }
else if (
is_any(
"c.nop")) {
630 }
else if (
is_any(
"mul",
"mulh",
"mulhu",
"mulhsu",
"mulw")) {
632 }
else if (
is_any(
"div",
"divu",
"divw",
"divuw")) {
634 }
else if (
is_any(
"sll",
"slli",
"sllw",
"slliw",
"c.slli")) {
636 }
else if (
is_any(
"srl",
"srlw",
"srliw",
"c.srli")) {
638 }
else if (
is_any(
"sra",
"srai",
"sraiw",
"c.srai")) {
641 }
else if (
is_any(
"sd",
"sb",
"sh",
"sw",
"c.sd",
"c.sw",
642 "c.swsp",
"c.sdsp")) {
644 }
else if (
is_any(
"ld",
"lw",
"lwu",
"lb",
"lbu",
"lh",
645 "lhu",
"la",
"lla",
"c.ld",
"c.lw",
"c.lwsp")) {
647 }
else if (
is_any(
"lui")) {
650 }
else if (
is_any(
"c.lui")) {
653 }
else if (
is_any(
"li")) {
656 }
else if (
is_any(
"c.li")) {
664 int dst_idx = 0, src_idx;
668 *(
char *)
comma++ = 0;
669 if (strchr(
comma,
'(')) {
676 comma = strtok(argf,
",");
698 for (
i = 0; src_idx <
args.num;
i++, src_idx++) {
720 const char *
p =
NULL;
721 switch (analysis->
bits) {
768 "gpr s10 .32 104 0\n"
769 "gpr s11 .32 108 0\n"
776 "fpu ft0 .64 128 0\n"
777 "fpu ft1 .64 136 0\n"
778 "fpu ft2 .64 144 0\n"
779 "fpu ft3 .64 152 0\n"
780 "fpu ft4 .64 160 0\n"
781 "fpu ft5 .64 168 0\n"
782 "fpu ft6 .64 176 0\n"
783 "fpu ft7 .64 184 0\n"
784 "fpu fs0 .64 192 0\n"
785 "fpu fs1 .64 200 0\n"
786 "fpu fa0 .64 208 0\n"
787 "fpu fa1 .64 216 0\n"
788 "fpu fa2 .64 224 0\n"
789 "fpu fa3 .64 232 0\n"
790 "fpu fa4 .64 240 0\n"
791 "fpu fa5 .64 248 0\n"
792 "fpu fa6 .64 256 0\n"
793 "fpu fa7 .64 264 0\n"
794 "fpu fs2 .64 272 0\n"
795 "fpu fs3 .64 280 0\n"
796 "fpu fs4 .64 288 0\n"
797 "fpu fs5 .64 296 0\n"
798 "fpu fs6 .64 304 0\n"
799 "fpu fs7 .64 312 0\n"
800 "fpu fs8 .64 320 0\n"
801 "fpu fs9 .64 328 0\n"
802 "fpu fs10 .64 336 0\n"
803 "fpu fs11 .64 344 0\n"
804 "fpu ft8 .64 352 0\n"
805 "fpu ft9 .64 360 0\n"
806 "fpu ft10 .64 368 0\n"
807 "fpu ft11 .64 376 0\n"
808 "fpu fcsr .32 384 0\n"
814 "flg frm .3 3077 0\n";
863 "gpr s10 .64 208 0\n"
864 "gpr s11 .64 216 0\n"
870 "fpu ft0 .64 256 0\n"
871 "fpu ft1 .64 264 0\n"
872 "fpu ft2 .64 272 0\n"
873 "fpu ft3 .64 280 0\n"
874 "fpu ft4 .64 288 0\n"
875 "fpu ft5 .64 296 0\n"
876 "fpu ft6 .64 304 0\n"
877 "fpu ft7 .64 312 0\n"
878 "fpu fs0 .64 320 0\n"
879 "fpu fs1 .64 328 0\n"
880 "fpu fa0 .64 336 0\n"
881 "fpu fa1 .64 344 0\n"
882 "fpu fa2 .64 352 0\n"
883 "fpu fa3 .64 360 0\n"
884 "fpu fa4 .64 368 0\n"
885 "fpu fa5 .64 376 0\n"
886 "fpu fa6 .64 384 0\n"
887 "fpu fa7 .64 392 0\n"
888 "fpu fs2 .64 400 0\n"
889 "fpu fs3 .64 408 0\n"
890 "fpu fs4 .64 416 0\n"
891 "fpu fs5 .64 424 0\n"
892 "fpu fs6 .64 432 0\n"
893 "fpu fs7 .64 440 0\n"
894 "fpu fs8 .64 448 0\n"
895 "fpu fs9 .64 456 0\n"
896 "fpu fs10 .64 464 0\n"
897 "fpu fs11 .64 472 0\n"
898 "fpu ft8 .64 480 0\n"
899 "fpu ft9 .64 488 0\n"
900 "fpu ft10 .64 496 0\n"
901 "fpu ft11 .64 504 0\n"
902 "fpu fcsr .32 512 0\n"
908 "flg frm .3 4101 0\n";
924 .desc =
"RISC-V analysis plugin",
934 #ifndef RZ_PLUGIN_INCORE
static const char * arg_n(riscv_args_t *args, int n)
static const char *const * riscv_fpr_names
static char * get_reg_profile(RzAnalysis *analysis)
static int riscv_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
static int archinfo(RzAnalysis *a, int q)
RzAnalysisPlugin rz_analysis_plugin_riscv
RZ_API RzLibStruct rizin_plugin
static bool _is_any(const char *str,...)
static const char *const * riscv_gpr_names
static void get_insn_args(riscv_args_t *args, const char *d, insn_t l, uint64_t pc)
struct riscv_args riscv_args_t
static struct riscv_opcode * get_opcode(insn_t word)
static void arg_p2(char *buf, unsigned long val, const char *const *array, size_t size)
RZ_API void Ht_() free(HtName_(Ht) *ht)
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")
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
static const char *const riscv_gpr_names_abi[NGPR]
static const char *const riscv_fpr_names_abi[NFPR]
static struct riscv_opcode * riscv_opcodes
#define EXTRACT_RVC_LD_IMM(x)
#define EXTRACT_RVC_J_IMM(x)
#define EXTRACT_RVC_LDSP_IMM(x)
#define EXTRACT_SBTYPE_IMM(x)
#define EXTRACT_STYPE_IMM(x)
#define EXTRACT_RVC_IMM(x)
#define EXTRACT_RVC_SWSP_IMM(x)
#define EXTRACT_UTYPE_IMM(x)
#define RISCV_BIGIMM_REACH
#define EXTRACT_RVC_SDSP_IMM(x)
static const char *const riscv_rm[8]
#define EXTRACT_RVC_LWSP_IMM(x)
#define EXTRACT_UJTYPE_IMM(x)
#define EXTRACT_RVC_B_IMM(x)
#define EXTRACT_ITYPE_IMM(x)
#define EXTRACT_OPERAND(FIELD, INSN)
#define EXTRACT_RVC_SIMM3(x)
#define EXTRACT_RVC_ADDI4SPN_IMM(x)
#define EXTRACT_RVC_ADDI16SP_IMM(x)
#define EXTRACT_RVC_LW_IMM(x)
static const char *const riscv_pred_succ[16]
#define esilprintf(op, fmt,...)
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
@ RZ_ANALYSIS_OP_MASK_DISASM
@ RZ_ANALYSIS_OP_MASK_VAL
@ RZ_ANALYSIS_OP_TYPE_SUB
@ RZ_ANALYSIS_OP_TYPE_LOAD
@ RZ_ANALYSIS_OP_TYPE_UNK
@ RZ_ANALYSIS_OP_TYPE_MUL
@ RZ_ANALYSIS_OP_TYPE_JMP
@ RZ_ANALYSIS_OP_TYPE_AND
@ 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_CJMP
@ 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_NOT
@ RZ_ANALYSIS_OP_TYPE_RET
@ RZ_ANALYSIS_OP_TYPE_NOP
@ RZ_ANALYSIS_OP_TYPE_XOR
static ut64 rz_read_ble64(const void *src, bool big_endian)
static ut16 rz_read_ble16(const void *src, bool big_endian)
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
RZ_API const char * rz_str_rchr(const char *base, const char *p, int ch)
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
int(* match_func)(const struct riscv_opcode *op, insn_t word)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()