Rizin
unix-like reverse engineering framework and cli tools
analysis_riscv.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2015-2019 qnix <qnix@0x80.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 #include <rz_types.h>
6 #include <rz_lib.h>
7 #include <rz_asm.h>
8 #include <rz_analysis.h>
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++])
15 
16 static bool init = false;
17 static const char *const *riscv_gpr_names = riscv_gpr_names_abi;
18 static const char *const *riscv_fpr_names = riscv_fpr_names_abi;
19 
20 typedef struct riscv_args {
21  int num;
24 
25 #define is_any(...) _is_any(o->name, __VA_ARGS__, NULL)
26 static bool _is_any(const char *str, ...) {
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 }
43 
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";
46  snprintf(buf, RISCVARGSIZE, "%s", s);
47 }
48 
49 static struct riscv_opcode *get_opcode(insn_t word) {
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 }
66 
67 /* Print insn arguments for 32/64-bit code. */
68 static void get_insn_args(riscv_args_t *args, const char *d, insn_t l, uint64_t pc) {
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 }
286 
287 static const char *arg_n(riscv_args_t *args, int n) {
288  if (n >= args->num || !strcmp(args->arg[n], "zero")) {
289  return "0";
290  }
291  return args->arg[n];
292 }
293 
294 static int riscv_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) {
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 }
718 
719 static char *get_reg_profile(RzAnalysis *analysis) {
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 }
914 
915 static int archinfo(RzAnalysis *a, int q) {
917  return 6;
918  }
919  return 2;
920 }
921 
923  .name = "riscv",
924  .desc = "RISC-V analysis plugin",
925  .license = "LGPL",
926  .arch = "riscv",
927  .bits = 32 | 64,
928  .archinfo = archinfo,
929  .op = &riscv_op,
930  .get_reg_profile = &get_reg_profile,
931  .esil = true,
932 };
933 
934 #ifndef RZ_PLUGIN_INCORE
937  .data = &rz_analysis_plugin_riscv,
939 };
940 #endif
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
#define rd()
#define mask()
static const char * arg_n(riscv_args_t *args, int n)
#define RISCVARGN(x)
static const char *const * riscv_fpr_names
static char * get_reg_profile(RzAnalysis *analysis)
#define ARG(x)
#define ARRAY_SIZE(a)
#define RISCVARGSMAX
static int riscv_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
static bool init
static int archinfo(RzAnalysis *a, int q)
RzAnalysisPlugin rz_analysis_plugin_riscv
RZ_API RzLibStruct rizin_plugin
#define is_any(...)
#define RISCVARGSIZE
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)
#define OP_HASH_IDX(i)
static void arg_p2(char *buf, unsigned long val, const char *const *array, size_t size)
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
#define NUMOPCODES
Definition: hppa.h:1079
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
#define signed
Definition: ansidecl.h:242
#define OP_MASK_OP
Definition: mips.h:64
#define OP_MASK_RD
Definition: mips.h:84
#define OP_SH_RD
Definition: mips.h:85
#define RS2(x)
Definition: sparc.h:203
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")
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
static const char *const riscv_gpr_names_abi[NGPR]
Definition: riscv-opc.c:39
static const char *const riscv_fpr_names_abi[NFPR]
Definition: riscv-opc.c:54
static struct riscv_opcode * riscv_opcodes
Definition: riscv-opc.c:685
#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 INSN_ALIAS
Definition: riscv.h:297
#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
static RzSocket * s
Definition: rtr.c:28
#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
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ 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_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
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 PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define RZ_VERSION
Definition: rz_version.h:8
#define isalpha(c)
Definition: safe-ctype.h:125
#define isdigit(c)
Definition: safe-ctype.h:131
unsigned long uint64_t
Definition: sftypes.h:28
#define d(i)
Definition: sha256.c:44
#define a(i)
Definition: sha256.c:41
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
const char * version
Definition: rz_analysis.h:1239
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int comma
Definition: z80asm.c:76
static int addr
Definition: z80asm.c:58