Rizin
unix-like reverse engineering framework and cli tools
analysis_riscv.c File Reference
#include <string.h>
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_asm.h>
#include <rz_analysis.h>
#include "../../asm/arch/riscv/riscv-opc.c"
#include "../../asm/arch/riscv/riscv.h"
#include "../../asm/arch/riscv/riscv-opc.h"

Go to the source code of this file.

Classes

struct  riscv_args
 

Macros

#define ARRAY_SIZE(a)   (sizeof(a) / sizeof(*a))
 
#define RISCVARGSMAX   (8)
 
#define RISCVARGSIZE   (64)
 
#define RISCVARGN(x)   ((x)->arg[(x)->num++])
 
#define is_any(...)   _is_any(o->name, __VA_ARGS__, NULL)
 
#define OP_HASH_IDX(i)   ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP))
 
#define DECLARE_CSR(name, num)
 
#define ARG(x)   (arg_n(&args, (x)))
 

Typedefs

typedef struct riscv_args riscv_args_t
 

Functions

static bool _is_any (const char *str,...)
 
static void arg_p2 (char *buf, unsigned long val, const char *const *array, size_t size)
 
static struct riscv_opcodeget_opcode (insn_t word)
 
static void get_insn_args (riscv_args_t *args, const char *d, insn_t l, uint64_t pc)
 
static const char * arg_n (riscv_args_t *args, int n)
 
static int riscv_op (RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
 
static char * get_reg_profile (RzAnalysis *analysis)
 
static int archinfo (RzAnalysis *a, int q)
 

Variables

static bool init = false
 
static const char *constriscv_gpr_names = riscv_gpr_names_abi
 
static const char *constriscv_fpr_names = riscv_fpr_names_abi
 
RzAnalysisPlugin rz_analysis_plugin_riscv
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ ARG

#define ARG (   x)    (arg_n(&args, (x)))

◆ ARRAY_SIZE

#define ARRAY_SIZE (   a)    (sizeof(a) / sizeof(*a))

Definition at line 11 of file analysis_riscv.c.

◆ DECLARE_CSR

#define DECLARE_CSR (   name,
  num 
)
Value:
case num: \
csr_name = #name; \
break;
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
const char * name
Definition: op.c:541

◆ is_any

#define is_any (   ...)    _is_any(o->name, __VA_ARGS__, NULL)

Definition at line 25 of file analysis_riscv.c.

◆ OP_HASH_IDX

#define OP_HASH_IDX (   i)    ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP))

◆ RISCVARGN

#define RISCVARGN (   x)    ((x)->arg[(x)->num++])

Definition at line 14 of file analysis_riscv.c.

◆ RISCVARGSIZE

#define RISCVARGSIZE   (64)

Definition at line 13 of file analysis_riscv.c.

◆ RISCVARGSMAX

#define RISCVARGSMAX   (8)

Definition at line 12 of file analysis_riscv.c.

Typedef Documentation

◆ riscv_args_t

typedef struct riscv_args riscv_args_t

Function Documentation

◆ _is_any()

static bool _is_any ( const char *  str,
  ... 
)
static

Definition at line 26 of file analysis_riscv.c.

26  {
27  char *cur;
28  va_list va;
29  va_start(va, str);
30  while (true) {
31  cur = va_arg(va, char *);
32  if (!cur) {
33  break;
34  }
35  if (!strcmp(str, cur)) {
36  va_end(va);
37  return true;
38  }
39  }
40  va_end(va);
41  return false;
42 }

References cmd_descs_generate::str.

◆ archinfo()

static int archinfo ( RzAnalysis a,
int  q 
)
static

Definition at line 915 of file analysis_riscv.c.

915  {
917  return 6;
918  }
919  return 2;
920 }
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99

References RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE.

◆ arg_n()

static const char* arg_n ( riscv_args_t args,
int  n 
)
static

Definition at line 287 of file analysis_riscv.c.

287  {
288  if (n >= args->num || !strcmp(args->arg[n], "zero")) {
289  return "0";
290  }
291  return args->arg[n];
292 }
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19

References args, and n.

◆ arg_p2()

static void arg_p2 ( char *  buf,
unsigned long  val,
const char *const array,
size_t  size 
)
static

Definition at line 44 of file analysis_riscv.c.

44  {
45  const char *s = val >= size || array[val] ? array[val] : "unknown";
46  snprintf(buf, RISCVARGSIZE, "%s", s);
47 }
#define RISCVARGSIZE
ut16 val
Definition: armass64_const.h:6
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
static RzSocket * s
Definition: rtr.c:28

References RISCVARGSIZE, s, snprintf, and val.

Referenced by get_insn_args().

◆ get_insn_args()

static void get_insn_args ( riscv_args_t args,
const char *  d,
insn_t  l,
uint64_t  pc 
)
static

Definition at line 68 of file analysis_riscv.c.

68  {
69  int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1;
70  int rd = (l >> OP_SH_RD) & OP_MASK_RD;
71  uint64_t target;
72  args->num = 0;
73 
74  for (; *d != '\0' && args->num < RISCVARGSMAX; d++) {
75  switch (*d) {
76  /* Xcustom */
77  case '^':
78  switch (*++d) {
79  case 'd':
81  break;
82  case 's':
83  snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", rs1);
84  break;
85  case 't':
87  break;
88  case 'j':
89  snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", (int)EXTRACT_OPERAND(CUSTOM_IMM, l));
90  break;
91  }
92  break;
93 
94  case 'C': /* RVC */
95  switch (*++d) {
96  case 's': /* RS1 x8-x15 */
97  case 'w': /* RS1 x8-x15 */
99  riscv_gpr_names[EXTRACT_OPERAND(CRS1S, l) + 8]);
100  break;
101  case 't': /* RS2 x8-x15 */
102  case 'x': /* RS2 x8-x15 */
104  riscv_gpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]);
105  break;
106  case 'U': /* RS1, constrained to equal RD in CI format*/
108  break;
109  case 'c': /* RS1, constrained to equal sp */
111  break;
112  case 'V': /* RS2 */
114  riscv_gpr_names[EXTRACT_OPERAND(CRS2, l)]);
115  break;
116  case 'i':
118  break;
119  case 'j':
121  break;
122  case 'k':
124  break;
125  case 'l':
127  break;
128  case 'm':
130  break;
131  case 'n':
133  break;
134  case 'K':
136  break;
137  case 'L':
139  break;
140  case 'M':
142  break;
143  case 'N':
145  break;
146  case 'p':
147  target = EXTRACT_RVC_B_IMM(l) + pc;
148  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target);
149  break;
150  case 'a':
151  target = EXTRACT_RVC_J_IMM(l) + pc;
152  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target);
153  break;
154  case 'u':
156  (int)(EXTRACT_RVC_IMM(l) & (RISCV_BIGIMM_REACH - 1)));
157  break;
158  case '>':
159  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x3f);
160  break;
161  case '<':
162  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_RVC_IMM(l) & 0x1f);
163  break;
164  case 'T': /* floating-point RS2 */
166  riscv_fpr_names[EXTRACT_OPERAND(CRS2, l)]);
167  break;
168  case 'D': /* floating-point RS2 x8-x15 */
170  riscv_fpr_names[EXTRACT_OPERAND(CRS2S, l) + 8]);
171  break;
172  }
173  break;
174 
175  case ',':
176  case '(':
177  case ')':
178  case '[':
179  case ']':
180  break;
181  case '0':
182  /* Only print constant 0 if it is the last argument */
183  if (!d[1]) {
185  }
186  break;
187 
188  case 'b':
189  case 's':
191  break;
192 
193  case 't':
196  break;
197 
198  case 'u':
200  (unsigned)EXTRACT_UTYPE_IMM(l) >> RISCV_IMM_BITS);
201  break;
202 
203  case 'm':
206  break;
207 
208  case 'P':
211  break;
212 
213  case 'Q':
216  break;
217  case 'o':
218  case 'j':
220  break;
221  case 'q':
223  break;
224  case 'a':
225  target = EXTRACT_UJTYPE_IMM(l) + pc;
226  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target);
227  break;
228  case 'p':
229  target = EXTRACT_SBTYPE_IMM(l) + pc;
230  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%" PFMT64x, (ut64)target);
231  break;
232  case 'd':
234  break;
235  case 'z':
237  break;
238  case '>':
239  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_OPERAND(SHAMT, l));
240  break;
241  case '<':
242  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", (int)EXTRACT_OPERAND(SHAMTW, l));
243  break;
244  case 'S':
245  case 'U':
247  break;
248  case 'T':
250  break;
251  case 'D':
253  break;
254  case 'R':
256  break;
257  case 'E': {
258  const char *csr_name = NULL;
259  unsigned int csr = EXTRACT_OPERAND(CSR, l);
260  switch (csr) {
261 #define DECLARE_CSR(name, num) \
262  case num: \
263  csr_name = #name; \
264  break;
265 #include "../../asm/arch/riscv/riscv-opc.h"
266 #undef DECLARE_CSR
267  }
268  if (csr_name) {
269  snprintf(RISCVARGN(args), RISCVARGSIZE, "%s", csr_name);
270  } else {
271  snprintf(RISCVARGN(args), RISCVARGSIZE, "0x%x", csr);
272  }
273  break;
274  }
275  case 'Z':
276  snprintf(RISCVARGN(args), RISCVARGSIZE, "%d", rs1);
277  break;
278  default:
279  /* xgettext:c-format */
280  snprintf(RISCVARGN(args), RISCVARGSIZE, "# internal error, undefined modifier (%c)",
281  *d);
282  return;
283  }
284  }
285 }
#define rd()
#define RISCVARGN(x)
static const char *const * riscv_fpr_names
#define ARRAY_SIZE(a)
#define RISCVARGSMAX
static const char *const * riscv_gpr_names
static void arg_p2(char *buf, unsigned long val, const char *const *array, size_t size)
#define NULL
Definition: cris-opc.c:27
#define OP_MASK_RD
Definition: mips.h:84
#define OP_SH_RD
Definition: mips.h:85
#define RS2(x)
Definition: sparc.h:203
#define EXTRACT_RVC_LD_IMM(x)
Definition: riscv.h:89
#define EXTRACT_RVC_J_IMM(x)
Definition: riscv.h:101
#define EXTRACT_RVC_LDSP_IMM(x)
Definition: riscv.h:93
#define EXTRACT_SBTYPE_IMM(x)
Definition: riscv.h:71
#define EXTRACT_STYPE_IMM(x)
Definition: riscv.h:69
#define X_SP
Definition: riscv.h:241
#define EXTRACT_RVC_IMM(x)
Definition: riscv.h:77
#define EXTRACT_RVC_SWSP_IMM(x)
Definition: riscv.h:95
#define EXTRACT_UTYPE_IMM(x)
Definition: riscv.h:73
#define RISCV_BIGIMM_REACH
Definition: riscv.h:190
#define EXTRACT_RVC_SDSP_IMM(x)
Definition: riscv.h:97
static const char *const riscv_rm[8]
Definition: riscv.h:47
#define EXTRACT_RVC_LWSP_IMM(x)
Definition: riscv.h:91
#define OP_SH_RS1
Definition: riscv.h:204
#define EXTRACT_UJTYPE_IMM(x)
Definition: riscv.h:75
#define OP_MASK_RS1
Definition: riscv.h:203
#define EXTRACT_RVC_B_IMM(x)
Definition: riscv.h:99
#define EXTRACT_ITYPE_IMM(x)
Definition: riscv.h:67
#define EXTRACT_OPERAND(FIELD, INSN)
Definition: riscv.h:264
#define EXTRACT_RVC_SIMM3(x)
Definition: riscv.h:81
#define EXTRACT_RVC_ADDI4SPN_IMM(x)
Definition: riscv.h:83
#define EXTRACT_RVC_ADDI16SP_IMM(x)
Definition: riscv.h:85
#define EXTRACT_RVC_LW_IMM(x)
Definition: riscv.h:87
#define RISCV_IMM_BITS
Definition: riscv.h:187
static const char *const riscv_pred_succ[16]
Definition: riscv.h:52
#define PFMT64x
Definition: rz_types.h:393
unsigned long uint64_t
Definition: sftypes.h:28
#define d(i)
Definition: sha256.c:44
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References arg_p2(), args, ARRAY_SIZE, d, EXTRACT_ITYPE_IMM, EXTRACT_OPERAND, EXTRACT_RVC_ADDI16SP_IMM, EXTRACT_RVC_ADDI4SPN_IMM, EXTRACT_RVC_B_IMM, EXTRACT_RVC_IMM, EXTRACT_RVC_J_IMM, EXTRACT_RVC_LD_IMM, EXTRACT_RVC_LDSP_IMM, EXTRACT_RVC_LW_IMM, EXTRACT_RVC_LWSP_IMM, EXTRACT_RVC_SDSP_IMM, EXTRACT_RVC_SIMM3, EXTRACT_RVC_SWSP_IMM, EXTRACT_SBTYPE_IMM, EXTRACT_STYPE_IMM, EXTRACT_UJTYPE_IMM, EXTRACT_UTYPE_IMM, NULL, OP_MASK_RD, OP_MASK_RS1, OP_SH_RD, OP_SH_RS1, pc, PFMT64x, rd, RISCV_BIGIMM_REACH, riscv_fpr_names, riscv_gpr_names, RISCV_IMM_BITS, riscv_pred_succ, riscv_rm, RISCVARGN, RISCVARGSIZE, RISCVARGSMAX, RS2, snprintf, ut64(), and X_SP.

Referenced by riscv_op().

◆ get_opcode()

static struct riscv_opcode* get_opcode ( insn_t  word)
static

Definition at line 49 of file analysis_riscv.c.

49  {
50  struct riscv_opcode *op;
51  static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1] = { 0 };
52 
53 #define OP_HASH_IDX(i) ((i) & (riscv_insn_length(i) == 2 ? 3 : OP_MASK_OP))
54 
55  if (!init) {
56  for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++) {
57  if (!riscv_hash[OP_HASH_IDX(op->match)]) {
58  riscv_hash[OP_HASH_IDX(op->match)] = op;
59  }
60  }
61  init = true;
62  }
63 
64  return (struct riscv_opcode *)riscv_hash[OP_HASH_IDX(word)];
65 }
ut8 op
Definition: 6502dis.c:13
static bool init
#define OP_HASH_IDX(i)
#define NUMOPCODES
Definition: hppa.h:1079
#define OP_MASK_OP
Definition: mips.h:64
static struct riscv_opcode * riscv_opcodes
Definition: riscv-opc.c:685
Definition: dis.c:32

References init, NUMOPCODES, op, OP_HASH_IDX, OP_MASK_OP, and riscv_opcodes.

Referenced by riscv_op().

◆ get_reg_profile()

static char* get_reg_profile ( RzAnalysis analysis)
static

Definition at line 719 of file analysis_riscv.c.

719  {
720  const char *p = NULL;
721  switch (analysis->bits) {
722  case 32:
723  p =
724  "=PC pc\n"
725  "=A0 a0\n"
726  "=A1 a1\n"
727  "=A2 a2\n"
728  "=A3 a3\n"
729  "=A4 a4\n"
730  "=A5 a5\n"
731  "=A6 a6\n"
732  "=A7 a7\n"
733  "=R0 a0\n"
734  "=R1 a1\n"
735  "=SP sp\n" // ABI: stack pointer
736  "=LR ra\n" // ABI: return address
737  "=BP s0\n" // ABI: frame pointer
738  "=SN a7\n" // ABI: syscall numer
739  "gpr pc .32 0 0\n"
740  // RV32I regs (ABI names)
741  // From user-Level ISA Specification, section 2.1
742  // "zero" has been left out as it ignores writes and always reads as zero
743  "gpr ra .32 4 0\n" // =x1
744  "gpr sp .32 8 0\n" // =x2
745  "gpr gp .32 12 0\n" // =x3
746  "gpr tp .32 16 0\n" // =x4
747  "gpr t0 .32 20 0\n" // =x5
748  "gpr t1 .32 24 0\n" // =x6
749  "gpr t2 .32 28 0\n" // =x7
750  "gpr s0 .32 32 0\n" // =x8
751  "gpr s1 .32 36 0\n" // =x9
752  "gpr a0 .32 40 0\n" // =x10
753  "gpr a1 .32 44 0\n" // =x11
754  "gpr a2 .32 48 0\n" // =x12
755  "gpr a3 .32 52 0\n" // =x13
756  "gpr a4 .32 56 0\n" // =x14
757  "gpr a5 .32 60 0\n" // =x15
758  "gpr a6 .32 64 0\n" // =x16
759  "gpr a7 .32 68 0\n" // =x17
760  "gpr s2 .32 72 0\n" // =x18
761  "gpr s3 .32 76 0\n" // =x19
762  "gpr s4 .32 80 0\n" // =x20
763  "gpr s5 .32 84 0\n" // =x21
764  "gpr s6 .32 88 0\n" // =x22
765  "gpr s7 .32 92 0\n" // =x23
766  "gpr s8 .32 96 0\n" // =x24
767  "gpr s9 .32 100 0\n" // =x25
768  "gpr s10 .32 104 0\n" // =x26
769  "gpr s11 .32 108 0\n" // =x27
770  "gpr t3 .32 112 0\n" // =x28
771  "gpr t4 .32 116 0\n" // =x29
772  "gpr t5 .32 120 0\n" // =x30
773  "gpr t6 .32 124 0\n" // =x31
774  // RV32F/D regs (ABI names)
775  // From user-Level ISA Specification, section 8.1 and 9.1
776  "fpu ft0 .64 128 0\n" // =f0
777  "fpu ft1 .64 136 0\n" // =f1
778  "fpu ft2 .64 144 0\n" // =f2
779  "fpu ft3 .64 152 0\n" // =f3
780  "fpu ft4 .64 160 0\n" // =f4
781  "fpu ft5 .64 168 0\n" // =f5
782  "fpu ft6 .64 176 0\n" // =f6
783  "fpu ft7 .64 184 0\n" // =f7
784  "fpu fs0 .64 192 0\n" // =f8
785  "fpu fs1 .64 200 0\n" // =f9
786  "fpu fa0 .64 208 0\n" // =f10
787  "fpu fa1 .64 216 0\n" // =f11
788  "fpu fa2 .64 224 0\n" // =f12
789  "fpu fa3 .64 232 0\n" // =f13
790  "fpu fa4 .64 240 0\n" // =f14
791  "fpu fa5 .64 248 0\n" // =f15
792  "fpu fa6 .64 256 0\n" // =f16
793  "fpu fa7 .64 264 0\n" // =f17
794  "fpu fs2 .64 272 0\n" // =f18
795  "fpu fs3 .64 280 0\n" // =f19
796  "fpu fs4 .64 288 0\n" // =f20
797  "fpu fs5 .64 296 0\n" // =f21
798  "fpu fs6 .64 304 0\n" // =f22
799  "fpu fs7 .64 312 0\n" // =f23
800  "fpu fs8 .64 320 0\n" // =f24
801  "fpu fs9 .64 328 0\n" // =f25
802  "fpu fs10 .64 336 0\n" // =f26
803  "fpu fs11 .64 344 0\n" // =f27
804  "fpu ft8 .64 352 0\n" // =f28
805  "fpu ft9 .64 360 0\n" // =f29
806  "fpu ft10 .64 368 0\n" // =f30
807  "fpu ft11 .64 376 0\n" // =f31
808  "fpu fcsr .32 384 0\n"
809  "flg nx .1 3072 0\n"
810  "flg uf .1 3073 0\n"
811  "flg of .1 3074 0\n"
812  "flg dz .1 3075 0\n"
813  "flg nv .1 3076 0\n"
814  "flg frm .3 3077 0\n";
815 
816  break;
817  case 64:
818  p =
819  "=PC pc\n"
820  "=SP sp\n" // ABI: stack pointer
821  "=LR ra\n" // ABI: return address
822  "=BP s0\n" // ABI: frame pointer
823  "=A0 a0\n"
824  "=A1 a1\n"
825  "=A2 a2\n"
826  "=A3 a3\n"
827  "=A4 a4\n"
828  "=A5 a5\n"
829  "=A6 a6\n"
830  "=A7 a7\n"
831  "=R0 a0\n"
832  "=R1 a1\n"
833  "=SN a7\n" // ABI: syscall numer
834  "gpr pc .64 0 0\n"
835  // RV64I regs (ABI names)
836  // From user-Level ISA Specification, section 2.1 and 4.1
837  // "zero" has been left out as it ignores writes and always reads as zero
838  "gpr ra .64 8 0\n" // =x1
839  "gpr sp .64 16 0\n" // =x2
840  "gpr gp .64 24 0\n" // =x3
841  "gpr tp .64 32 0\n" // =x4
842  "gpr t0 .64 40 0\n" // =x5
843  "gpr t1 .64 48 0\n" // =x6
844  "gpr t2 .64 56 0\n" // =x7
845  "gpr s0 .64 64 0\n" // =x8
846  "gpr s1 .64 72 0\n" // =x9
847  "gpr a0 .64 80 0\n" // =x10
848  "gpr a1 .64 88 0\n" // =x11
849  "gpr a2 .64 96 0\n" // =x12
850  "gpr a3 .64 104 0\n" // =x13
851  "gpr a4 .64 112 0\n" // =x14
852  "gpr a5 .64 120 0\n" // =x15
853  "gpr a6 .64 128 0\n" // =x16
854  "gpr a7 .64 136 0\n" // =x17
855  "gpr s2 .64 144 0\n" // =x18
856  "gpr s3 .64 152 0\n" // =x19
857  "gpr s4 .64 160 0\n" // =x20
858  "gpr s5 .64 168 0\n" // =x21
859  "gpr s6 .64 176 0\n" // =x22
860  "gpr s7 .64 184 0\n" // =x23
861  "gpr s8 .64 192 0\n" // =x24
862  "gpr s9 .64 200 0\n" // =x25
863  "gpr s10 .64 208 0\n" // =x26
864  "gpr s11 .64 216 0\n" // =x27
865  "gpr t3 .64 224 0\n" // =x28
866  "gpr t4 .64 232 0\n" // =x29
867  "gpr t5 .64 240 0\n" // =x30
868  "gpr t6 .64 248 0\n" // =x31
869  // RV64F/D regs (ABI names)
870  "fpu ft0 .64 256 0\n" // =f0
871  "fpu ft1 .64 264 0\n" // =f1
872  "fpu ft2 .64 272 0\n" // =f2
873  "fpu ft3 .64 280 0\n" // =f3
874  "fpu ft4 .64 288 0\n" // =f4
875  "fpu ft5 .64 296 0\n" // =f5
876  "fpu ft6 .64 304 0\n" // =f6
877  "fpu ft7 .64 312 0\n" // =f7
878  "fpu fs0 .64 320 0\n" // =f8
879  "fpu fs1 .64 328 0\n" // =f9
880  "fpu fa0 .64 336 0\n" // =f10
881  "fpu fa1 .64 344 0\n" // =f11
882  "fpu fa2 .64 352 0\n" // =f12
883  "fpu fa3 .64 360 0\n" // =f13
884  "fpu fa4 .64 368 0\n" // =f14
885  "fpu fa5 .64 376 0\n" // =f15
886  "fpu fa6 .64 384 0\n" // =f16
887  "fpu fa7 .64 392 0\n" // =f17
888  "fpu fs2 .64 400 0\n" // =f18
889  "fpu fs3 .64 408 0\n" // =f19
890  "fpu fs4 .64 416 0\n" // =f20
891  "fpu fs5 .64 424 0\n" // =f21
892  "fpu fs6 .64 432 0\n" // =f22
893  "fpu fs7 .64 440 0\n" // =f23
894  "fpu fs8 .64 448 0\n" // =f24
895  "fpu fs9 .64 456 0\n" // =f25
896  "fpu fs10 .64 464 0\n" // =f26
897  "fpu fs11 .64 472 0\n" // =f27
898  "fpu ft8 .64 480 0\n" // =f28
899  "fpu ft9 .64 488 0\n" // =f29
900  "fpu ft10 .64 496 0\n" // =f30
901  "fpu ft11 .64 504 0\n" // =f31
902  "fpu fcsr .32 512 0\n"
903  "flg nx .1 4096 0\n"
904  "flg uf .1 4097 0\n"
905  "flg of .1 4098 0\n"
906  "flg dz .1 4099 0\n"
907  "flg nv .1 4100 0\n"
908  "flg frm .3 4101 0\n";
909 
910  break;
911  }
912  return (p && *p) ? strdup(p) : NULL;
913 }
void * p
Definition: libc.cpp:67
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")

References rz_analysis_t::bits, NULL, p, and strdup().

◆ riscv_op()

static int riscv_op ( RzAnalysis analysis,
RzAnalysisOp op,
ut64  addr,
const ut8 data,
int  len,
RzAnalysisOpMask  mask 
)
static

Definition at line 294 of file analysis_riscv.c.

294  {
295  const int no_alias = 1;
296  riscv_args_t args = { 0 };
297  ut64 word = 0;
298  int xlen = analysis->bits;
299  op->size = 4;
300  op->addr = addr;
301  op->type = RZ_ANALYSIS_OP_TYPE_UNK;
302 
303  if (len >= sizeof(ut64)) {
304  word = rz_read_ble64(data, analysis->big_endian);
305  } else if (len >= sizeof(ut16)) {
306  word = rz_read_ble16(data, analysis->big_endian);
307  } else {
308  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
309  return -1;
310  }
311 
312  struct riscv_opcode *o = get_opcode(word);
313  for (; o && o < &riscv_opcodes[NUMOPCODES]; o++) {
314  if (!(o->match_func)(o, word)) {
315  continue;
316  }
317  if (no_alias && (o->pinfo & INSN_ALIAS)) {
318  continue;
319  }
320  if (isdigit((ut8)o->subset[0]) && atoi(o->subset) != xlen) {
321  continue;
322  }
323  if (o->name) {
324  break;
325  }
326  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
327  return -1;
328  }
329  if (!o || o >= &riscv_opcodes[NUMOPCODES] || !o->name) {
330  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
331  return -1;
332  }
333 
335  op->mnemonic = strdup(o->name);
336  }
337 
338  if (o->args) {
339  const char *name = o->name;
340  // Test for compressed instruction
341  if (!strncmp("c.", o->name, 2)) {
342  name += 2;
343  op->size = 2;
344  }
345 #define ARG(x) (arg_n(&args, (x)))
346  get_insn_args(&args, o->args, word, addr);
347  if (!strcmp(name, "nop")) {
348  esilprintf(op, ",");
349  }
350  // math
351  else if (!strncmp(name, "addi16sp", 8)) {
352  esilprintf(op, "%s,sp,+,%s,=", ARG(1), ARG(0));
353  if (!strcmp(ARG(0), riscv_gpr_names[X_SP])) {
354  op->stackop = RZ_ANALYSIS_STACK_INC;
355  op->stackptr = rz_num_math(NULL, ARG(1));
356  }
357  } else if (!strncmp(name, "addiw", 5)) {
358  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,%s,&,", ARG(2), ARG(1));
359  rz_strbuf_appendf(&op->esil, "+,%s,=,", ARG(0));
360  rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0));
361  if (!strcmp(ARG(0), riscv_gpr_names[X_SP]) &&
362  !strcmp(ARG(1), riscv_gpr_names[X_SP])) {
363  op->stackop = RZ_ANALYSIS_STACK_INC;
364  op->stackptr = rz_num_math(NULL, ARG(2));
365  }
366  } else if (!strncmp(name, "addw", 4)) {
367  esilprintf(op, "0xffffffff,%s,&,", ARG(2));
368  rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1));
369  rz_strbuf_appendf(&op->esil, "+,%s,=,", ARG(0));
370  rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0));
371  } else if (!strncmp(name, "add", 3)) {
372  esilprintf(op, "%s,%s,+,%s,=", ARG(2), ARG(1), ARG(0));
373  if (name[3] == 'i' && !strcmp(ARG(0), riscv_gpr_names[X_SP]) &&
374  !strcmp(ARG(1), riscv_gpr_names[X_SP])) {
375  op->stackop = RZ_ANALYSIS_STACK_INC;
376  op->stackptr = -(signed)rz_num_math(NULL, ARG(2));
377  }
378  } else if (!strncmp(name, "subw", 4)) {
379  esilprintf(op, "0xffffffff,%s,&,", ARG(2));
380  rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1));
381  rz_strbuf_appendf(&op->esil, "-,%s,=,", ARG(0));
382  rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0));
383  } else if (!strncmp(name, "sub", 3)) {
384  esilprintf(op, "%s,%s,-,%s,=", ARG(2), ARG(1), ARG(0));
385  if (name[3] == 'i' && !strcmp(ARG(0), riscv_gpr_names[X_SP]) &&
386  !strcmp(ARG(1), riscv_gpr_names[X_SP])) {
387  op->stackop = RZ_ANALYSIS_STACK_INC;
388  op->stackptr = rz_num_math(NULL, ARG(2));
389  }
390  } else if (!strncmp(name, "mulw", 4)) {
391  esilprintf(op, "0xffffffff,%s,&,", ARG(2));
392  rz_strbuf_appendf(&op->esil, "0xffffffff,%s,&,", ARG(1));
393  rz_strbuf_appendf(&op->esil, "*,%s,=,", ARG(0));
394  rz_strbuf_appendf(&op->esil, "32,%s,~=", ARG(0));
395  } else if (!strncmp(name, "mul", 3)) {
396  esilprintf(op, "%s,%s,*,%s,=", ARG(2), ARG(1), ARG(0));
397  } else if (!strncmp(name, "div", 3)) {
398  esilprintf(op, "%s,%s,/,%s,=", ARG(2), ARG(1), ARG(0));
399  } else if (!strncmp(name, "rem", 3)) {
400  esilprintf(op, "%s,%s,%%,%s,=", ARG(2), ARG(1), ARG(0));
401  } else if (!strncmp(name, "xor", 3)) {
402  esilprintf(op, "%s,%s,^,%s,=", ARG(2), ARG(1), ARG(0));
403  } else if (!strncmp(name, "or", 2)) {
404  esilprintf(op, "%s,%s,|,%s,=", ARG(2), ARG(1), ARG(0));
405  } else if (!strncmp(name, "and", 3)) {
406  esilprintf(op, "%s,%s,&,%s,=", ARG(2), ARG(1), ARG(0));
407  } else if (!strcmp(name, "auipc")) {
408  esilprintf(op, "%s000,$$,+,%s,=", ARG(1), ARG(0));
409  } else if (!strncmp(name, "sll", 3)) {
410  esilprintf(op, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0));
411  if (name[3] == 'w' || !strncmp(name, "slliw", 5)) {
412  rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0));
413  }
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)) {
417  esilprintf(op, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0));
418  } else if (!strcmp(name, "sraiw")) {
419  esilprintf(op, "%s,%s,>>>>,%s,=,", ARG(2), ARG(1), ARG(0));
420  rz_strbuf_appendf(&op->esil, "%s,64,-,%s,~=", ARG(2), ARG(0));
421  } else if (!strncmp(name, "sra", 3)) {
422  esilprintf(op, "%s,%s,>>>>,%s,=", ARG(2), ARG(1), ARG(0));
423  }
424  // assigns
425  else if (!strcmp(name, "mv")) {
426  esilprintf(op, "%s,%s,=", ARG(1), ARG(0));
427  } else if (!strcmp(name, "li")) {
428  esilprintf(op, "%s,%s,=", ARG(1), ARG(0));
429  } else if (!strcmp(name, "lui")) {
430  esilprintf(op, "%s000,%s,=", ARG(1), ARG(0));
431  if (analysis->bits == 64) {
432  rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0));
433  }
434  }
435  // csr instrs
436  // <csr op> rd, rs1, CSR
437  else if (!strncmp(name, "csrrw", 5)) {
438  // Writes rs1 into CSR, places the old value in rd
439  esilprintf(op, "%s,0,+,%s,%s,=,%s,=", ARG(1), ARG(2), ARG(1), ARG(0));
440  } else if (!strncmp(name, "csrrs", 5)) {
441  // Ors rs1 with CSR, places old value in rd
442  esilprintf(op, "%s,0,+,%s,%s,|=,%s,=", ARG(1), ARG(2), ARG(1), ARG(0));
443  } else if (!strncmp(name, "csrrc", 5)) {
444  // Ands the inverse of rs1 with CSR, places old value in rd
445  esilprintf(op, "%s,0,+,%s,1,+,0,-,%s,&=,%s,=", ARG(1), ARG(1), ARG(2), ARG(0));
446  }
447  // stores
448  else if (!strcmp(name, "sd") || !strcmp(name, "sdsp")) {
449  esilprintf(op, "%s,%s,%s,+,=[8]", ARG(0), ARG(2), ARG(1));
450  } else if (!strcmp(name, "sw") || !strcmp(name, "swsp")) {
451  esilprintf(op, "%s,%s,%s,+,=[4]", ARG(0), ARG(2), ARG(1));
452  } else if (!strcmp(name, "sh") || !strcmp(name, "shsp")) {
453  esilprintf(op, "%s,%s,%s,+,=[2]", ARG(0), ARG(2), ARG(1));
454  } else if (!strcmp(name, "sb") || !strcmp(name, "sbsp")) {
455  esilprintf(op, "%s,%s,%s,+,=[1]", ARG(0), ARG(2), ARG(1));
456  } else if (!strcmp(name, "fsq") || !strcmp(name, "fsqsp")) {
457  esilprintf(op, "%s,%s,+,[16],%s,=", ARG(2), ARG(1), ARG(0));
458  } else if (!strcmp(name, "fsd") || !strcmp(name, "fsdsp")) {
459  esilprintf(op, "%s,%s,%s,+,=[8]", ARG(0), ARG(2), ARG(1));
460  } else if (!strcmp(name, "fsw") || !strcmp(name, "fswsp")) {
461  esilprintf(op, "%s,%s,%s,+,=[4]", ARG(0), ARG(2), ARG(1));
462  } else if (!strcmp(name, "fsh") || !strcmp(name, "fshsp")) {
463  esilprintf(op, "%s,%s,%s,+,=[2]", ARG(0), ARG(2), ARG(1));
464  } else if (!strcmp(name, "fsb") || !strcmp(name, "fsbsp")) {
465  esilprintf(op, "%s,%s,%s,+,=[1]", ARG(0), ARG(2), ARG(1));
466  }
467  // loads
468  else if (!strcmp(name, "ld") || !strcmp(name, "ldsp")) {
469  esilprintf(op, "%s,%s,+,[8],%s,=", ARG(2), ARG(1), ARG(0));
470  } else if (!strcmp(name, "lw") || !strcmp(name, "lwu") || !strcmp(name, "lwsp")) {
471  esilprintf(op, "%s,%s,+,[4],%s,=", ARG(2), ARG(1), ARG(0));
472  if ((analysis->bits == 64) && strcmp(name, "lwu")) {
473  rz_strbuf_appendf(&op->esil, ",32,%s,~=", ARG(0));
474  }
475  } else if (!strcmp(name, "lh") || !strcmp(name, "lhu") || !strcmp(name, "lhsp")) {
476  esilprintf(op, "%s,%s,+,[2],%s,=", ARG(2), ARG(1), ARG(0));
477  if (strcmp(name, "lwu")) {
478  rz_strbuf_appendf(&op->esil, ",16,%s,~=", ARG(0));
479  }
480  } else if (!strcmp(name, "lb") || !strcmp(name, "lbu") || !strcmp(name, "lbsp")) {
481  esilprintf(op, "%s,%s,+,[1],%s,=", ARG(2), ARG(1), ARG(0));
482  if (strcmp(name, "lbu")) {
483  rz_strbuf_appendf(&op->esil, ",8,%s,~=", ARG(0));
484  }
485  } else if (!strcmp(name, "flq") || !strcmp(name, "flqsp")) {
486  esilprintf(op, "%s,%s,+,[16],%s,=", ARG(2), ARG(1), ARG(0));
487  } else if (!strcmp(name, "fld") || !strcmp(name, "fldsp")) {
488  esilprintf(op, "%s,%s,+,[8],%s,=", ARG(2), ARG(1), ARG(0));
489  } else if (!strcmp(name, "flw") || !strcmp(name, "flwsp")) {
490  esilprintf(op, "%s,%s,+,[4],%s,=", ARG(2), ARG(1), ARG(0));
491  } else if (!strcmp(name, "flh") || !strcmp(name, "flhsp")) {
492  esilprintf(op, "%s,%s,+,[2],%s,=", ARG(2), ARG(1), ARG(0));
493  } else if (!strcmp(name, "flb") || !strcmp(name, "flbsp")) {
494  esilprintf(op, "%s,%s,+,[1],%s,=", ARG(2), ARG(1), ARG(0));
495  }
496  // jumps
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));
500  } else {
501  esilprintf(op, "%s,%s,+,pc,=", ARG(2), ARG(1));
502  }
503  } else if (!strcmp(name, "jal")) {
504  if (strcmp(ARG(0), "0")) {
505  if (args.num == 1) {
506  esilprintf(op, "%d,$$,+,ra,=,%s,pc,=", op->size, ARG(0));
507  } else {
508  esilprintf(op, "%d,$$,+,%s,=,%s,pc,=", op->size, ARG(0), ARG(1));
509  }
510  } else {
511  esilprintf(op, "%s,pc,=", ARG(1));
512  }
513  } else if (!strcmp(name, "jr") || !strcmp(name, "j")) {
514  esilprintf(op, "%s,pc,=", ARG(0));
515  } else if (!strcmp(name, "ecall") || !strcmp(name, "ebreak")) {
516  esilprintf(op, "TRAP");
517  }
518  // Branches & cmps
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)) {
544  esilprintf(op, "%s,%s,==,%s,=", ARG(2), ARG(1), ARG(0));
545  } else if (!strncmp(name, "sne", 3)) {
546  esilprintf(op, "%s,%s,!=,%s,=", ARG(2), ARG(1), ARG(0));
547  } else if (!strncmp(name, "sle", 3)) {
548  esilprintf(op, "%s,%s,<=,%s,=", ARG(2), ARG(1), ARG(0));
549  } else if (!strncmp(name, "slt", 3)) {
550  esilprintf(op, "%s,%s,<,%s,=", ARG(2), ARG(1), ARG(0));
551  } else if (!strncmp(name, "sge", 3)) {
552  esilprintf(op, "%s,%s,>=,%s,=", ARG(2), ARG(1), ARG(0));
553  } else if (!strncmp(name, "sgt", 3)) {
554  esilprintf(op, "%s,%s,>,%s,=", ARG(2), ARG(1), ARG(0));
555  }
556 #undef ARG
557  }
558 
559  // branch/jumps/calls/rets
560  if (is_any("jal")) {
561  // decide whether it's jump or call
562  int rd = (word >> OP_SH_RD) & OP_MASK_RD;
564  op->jump = EXTRACT_UJTYPE_IMM(word) + addr;
565  op->fail = addr + op->size;
566  } else if (is_any("c.jal")) {
568  op->jump = EXTRACT_RVC_IMM(word) + addr;
569  op->fail = addr + op->size;
570  } else if (is_any("jr")) {
571  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
572  } else if (is_any("c.j", "jump")) {
573  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
574  op->jump = EXTRACT_RVC_J_IMM(word) + addr;
575  } else if (is_any("jalr")) {
576  // decide whether it's ret or call
577  int rd = (word >> OP_SH_RD) & OP_MASK_RD;
579  if (rd != 0) {
580  op->val = EXTRACT_ITYPE_IMM(word);
581  }
582  } else if (is_any("c.ret")) {
583  op->type = RZ_ANALYSIS_OP_TYPE_RET;
584  } else if (is_any("c.jalr")) {
586  } else if (is_any("c.jr")) {
587  op->type = RZ_ANALYSIS_OP_TYPE_RET;
588  } else if (is_any("beqz", "beq", "blez", "bgez", "ble",
589  "bleu", "bge", "bgeu", "bltz", "bgtz", "blt", "bltu",
590  "bgt", "bgtu", "bnez", "bne")) {
592  op->jump = EXTRACT_SBTYPE_IMM(word) + addr;
593  op->fail = addr + op->size;
594  } else if (is_any("c.beqz", "c.bnez")) {
596  op->jump = EXTRACT_RVC_B_IMM(word) + addr;
597  op->fail = addr + op->size;
598  // math
599  } else if (is_any("c.addi", "c.addiw")) {
600  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
601  op->val = EXTRACT_RVC_IMM(word);
602  } else if (is_any("addi", "addiw")) {
603  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
604  op->val = EXTRACT_ITYPE_IMM(word);
605  } else if (is_any("c.addi4spn")) {
606  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
607  op->val = EXTRACT_RVC_ADDI4SPN_IMM(word);
608  } else if (is_any("c.addi16sp")) {
609  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
610  op->val = EXTRACT_RVC_ADDI16SP_IMM(word);
611  } else if (is_any("addw", "add", "c.addw", "c.add")) {
612  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
613  } else if (is_any("auipc")) {
614  op->type = RZ_ANALYSIS_OP_TYPE_ADD;
615  op->val = EXTRACT_UTYPE_IMM(word);
616  } else if (is_any("c.mv", "csrrw", "csrrc", "csrrs")) {
617  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
618  } else if (is_any("subi", "subw", "sub", "c.sub", "c.subw")) {
619  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
620  } else if (is_any("xori", "xor", "c.xor")) {
621  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
622  } else if (is_any("andi", "and", "c.andi", "c.and")) {
623  op->type = RZ_ANALYSIS_OP_TYPE_AND;
624  } else if (is_any("ori", "or", "c.or")) {
625  op->type = RZ_ANALYSIS_OP_TYPE_OR;
626  } else if (is_any("not")) {
627  op->type = RZ_ANALYSIS_OP_TYPE_NOT;
628  } else if (is_any("c.nop")) {
629  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
630  } else if (is_any("mul", "mulh", "mulhu", "mulhsu", "mulw")) {
631  op->type = RZ_ANALYSIS_OP_TYPE_MUL;
632  } else if (is_any("div", "divu", "divw", "divuw")) {
633  op->type = RZ_ANALYSIS_OP_TYPE_DIV;
634  } else if (is_any("sll", "slli", "sllw", "slliw", "c.slli")) {
635  op->type = RZ_ANALYSIS_OP_TYPE_SHL;
636  } else if (is_any("srl", "srlw", "srliw", "c.srli")) {
637  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
638  } else if (is_any("sra", "srai", "sraiw", "c.srai")) {
639  op->type = RZ_ANALYSIS_OP_TYPE_SAR;
640  // memory
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")) {
648  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
649  op->val = EXTRACT_UTYPE_IMM(word);
650  } else if (is_any("c.lui")) {
651  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
652  op->val = EXTRACT_RVC_IMM(word);
653  } else if (is_any("li")) {
654  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
655  op->val = EXTRACT_ITYPE_IMM(word);
656  } else if (is_any("c.li")) {
657  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
658  op->val = EXTRACT_RVC_IMM(word);
659  }
660  if (mask & RZ_ANALYSIS_OP_MASK_VAL && args.num) {
661  op->dst = RZ_NEW0(RzAnalysisValue);
662  char *argf = strdup(o->args);
663  const char *comma = NULL;
664  int dst_idx = 0, src_idx;
665  if (op->type == RZ_ANALYSIS_OP_TYPE_STORE) {
666  comma = rz_str_rchr(argf, argf + strlen(argf), ',');
667  if (comma) {
668  *(char *)comma++ = 0;
669  if (strchr(comma, '(')) {
670  dst_idx = args.num = args.num - 2;
671  } else {
672  dst_idx = args.num = args.num - 1;
673  }
674  }
675  } else {
676  comma = strtok(argf, ",");
677  dst_idx = 0;
678  }
679  if (comma && strchr(comma, '(')) {
680  op->dst->type = RZ_ANALYSIS_VAL_MEM;
681  op->dst->delta = (st64)rz_num_get(NULL, args.arg[dst_idx++]);
682  op->dst->reg = rz_reg_get(analysis->reg, args.arg[dst_idx], -1);
683  src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 2;
684  } else if (isdigit(args.arg[dst_idx][0])) {
685  op->dst->type = RZ_ANALYSIS_VAL_IMM;
686  op->dst->imm = rz_num_get(NULL, args.arg[dst_idx]);
687  src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 1;
688  } else {
689  op->dst->type = RZ_ANALYSIS_VAL_REG;
690  op->dst->reg = rz_reg_get(analysis->reg, args.arg[dst_idx], -1);
691  src_idx = op->type == RZ_ANALYSIS_OP_TYPE_STORE ? 0 : 1;
692  }
693 
695  ? strtok(argf, ",")
696  : strtok(NULL, ",");
697  int i;
698  for (i = 0; src_idx < args.num; i++, src_idx++) {
699  op->src[i] = RZ_NEW0(RzAnalysisValue);
700  if (comma && strchr(comma, '(')) {
701  op->src[i]->type = RZ_ANALYSIS_VAL_MEM;
702  op->src[i]->delta = (st64)rz_num_get(NULL, args.arg[src_idx]);
703  op->src[i]->reg = rz_reg_get(analysis->reg, args.arg[src_idx + 1], -1);
704  src_idx++;
705  } else if (isalpha(args.arg[src_idx][0])) {
706  op->src[i]->type = RZ_ANALYSIS_VAL_REG;
707  op->src[i]->reg = rz_reg_get(analysis->reg, args.arg[src_idx], -1);
708  } else {
709  op->src[i]->type = RZ_ANALYSIS_VAL_IMM;
710  op->src[i]->imm = rz_num_get(NULL, args.arg[src_idx]);
711  }
712  comma = strtok(NULL, ",");
713  }
714  free(argf);
715  }
716  return op->size;
717 }
size_t len
Definition: 6502dis.c:15
#define mask()
#define ARG(x)
#define is_any(...)
static void get_insn_args(riscv_args_t *args, const char *d, insn_t l, uint64_t pc)
static struct riscv_opcode * get_opcode(insn_t word)
lzma_index ** i
Definition: index.h:629
uint16_t ut16
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
#define signed
Definition: ansidecl.h:242
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
#define INSN_ALIAS
Definition: riscv.h:297
#define esilprintf(op, fmt,...)
Definition: rz_analysis.h:29
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_VAL_IMM
Definition: rz_analysis.h:770
@ RZ_ANALYSIS_VAL_REG
Definition: rz_analysis.h:768
@ RZ_ANALYSIS_VAL_MEM
Definition: rz_analysis.h:769
@ RZ_ANALYSIS_OP_MASK_DISASM
Definition: rz_analysis.h:445
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_MUL
Definition: rz_analysis.h:404
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_DIV
Definition: rz_analysis.h:405
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_NOT
Definition: rz_analysis.h:414
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
static ut16 rz_read_ble16(const void *src, bool big_endian)
Definition: rz_endian.h:493
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API const char * rz_str_rchr(const char *base, const char *p, int ch)
Definition: str.c:829
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define st64
Definition: rz_types_base.h:10
#define isalpha(c)
Definition: safe-ctype.h:125
#define isdigit(c)
Definition: safe-ctype.h:131
Definition: z80asm.h:102
const char * args
Definition: riscv.h:276
const char * name
Definition: riscv.h:272
unsigned long pinfo
Definition: riscv.h:293
int(* match_func)(const struct riscv_opcode *op, insn_t word)
Definition: riscv.h:289
const char * subset
Definition: riscv.h:274
static int comma
Definition: z80asm.c:76
static int addr
Definition: z80asm.c:58

References addr, ARG, args, riscv_opcode::args, rz_analysis_t::big_endian, rz_analysis_t::bits, comma, esilprintf, EXTRACT_ITYPE_IMM, EXTRACT_RVC_ADDI16SP_IMM, EXTRACT_RVC_ADDI4SPN_IMM, EXTRACT_RVC_B_IMM, EXTRACT_RVC_IMM, EXTRACT_RVC_J_IMM, EXTRACT_SBTYPE_IMM, EXTRACT_UJTYPE_IMM, EXTRACT_UTYPE_IMM, free(), get_insn_args(), get_opcode(), i, INSN_ALIAS, is_any, isalpha, isdigit, len, mask, riscv_opcode::match_func, riscv_opcode::name, NULL, NUMOPCODES, OP_MASK_RD, OP_SH_RD, riscv_opcode::pinfo, rd, rz_analysis_t::reg, riscv_gpr_names, riscv_opcodes, RZ_ANALYSIS_OP_MASK_DISASM, RZ_ANALYSIS_OP_MASK_VAL, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_AND, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_DIV, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_LOAD, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_MUL, RZ_ANALYSIS_OP_TYPE_NOP, RZ_ANALYSIS_OP_TYPE_NOT, RZ_ANALYSIS_OP_TYPE_OR, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_SAR, RZ_ANALYSIS_OP_TYPE_SHL, RZ_ANALYSIS_OP_TYPE_SHR, RZ_ANALYSIS_OP_TYPE_STORE, RZ_ANALYSIS_OP_TYPE_SUB, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UNK, RZ_ANALYSIS_OP_TYPE_XOR, RZ_ANALYSIS_STACK_INC, RZ_ANALYSIS_VAL_IMM, RZ_ANALYSIS_VAL_MEM, RZ_ANALYSIS_VAL_REG, RZ_NEW0, rz_num_get(), rz_num_math(), rz_read_ble16(), rz_read_ble64(), rz_reg_get(), rz_str_rchr(), rz_strbuf_appendf(), signed, st64, strdup(), riscv_opcode::subset, ut64(), and X_SP.

Variable Documentation

◆ init

bool init ( void  ) = false
static

Definition at line 16 of file analysis_riscv.c.

Referenced by get_opcode().

◆ riscv_fpr_names

const char* const* riscv_fpr_names = riscv_fpr_names_abi
static

Definition at line 18 of file analysis_riscv.c.

Referenced by get_insn_args().

◆ riscv_gpr_names

const char* const* riscv_gpr_names = riscv_gpr_names_abi
static

Definition at line 17 of file analysis_riscv.c.

Referenced by get_insn_args(), and riscv_op().

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
}
RzAnalysisPlugin rz_analysis_plugin_riscv
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_analysis.h:1239

Definition at line 935 of file analysis_riscv.c.

◆ rz_analysis_plugin_riscv

RzAnalysisPlugin rz_analysis_plugin_riscv
Initial value:
= {
.name = "riscv",
.desc = "RISC-V analysis plugin",
.license = "LGPL",
.arch = "riscv",
.bits = 32 | 64,
.archinfo = archinfo,
.op = &riscv_op,
.get_reg_profile = &get_reg_profile,
.esil = true,
}
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)

Definition at line 922 of file analysis_riscv.c.