Rizin
unix-like reverse engineering framework and cli tools
analysis_riscv_cs.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_asm.h>
5 #include <rz_lib.h>
6 
7 #include <capstone/capstone.h>
8 #include <capstone/riscv.h>
9 
10 // http://www.mrc.uidaho.edu/mrc/people/jff/digital/RISCVir.html
11 
12 #define OPERAND(x) insn->detail->riscv.operands[x]
13 #define REGID(x) insn->detail->riscv.operands[x].reg
14 #define REG(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].reg)
15 #define IMM(x) insn->detail->riscv.operands[x].imm
16 #define MEMBASE(x) cs_reg_name(*handle, insn->detail->riscv.operands[x].mem.base)
17 #define MEMINDEX(x) insn->detail->riscv.operands[x].mem.index
18 #define MEMDISP(x) insn->detail->riscv.operands[x].mem.disp
19 #define OPCOUNT() insn->detail->riscv.op_count
20 // TODO scale and disp
21 
22 #define SET_VAL(op, i) \
23  if ((i) < OPCOUNT() && OPERAND(i).type == RISCV_OP_IMM) { \
24  (op)->val = OPERAND(i).imm; \
25  }
26 
27 #define CREATE_SRC_DST_3(op) \
28  (op)->src[0] = rz_analysis_value_new(); \
29  (op)->src[1] = rz_analysis_value_new(); \
30  (op)->dst = rz_analysis_value_new();
31 
32 #define CREATE_SRC_DST_2(op) \
33  (op)->src[0] = rz_analysis_value_new(); \
34  (op)->dst = rz_analysis_value_new();
35 
36 #define SET_SRC_DST_3_REGS(op) \
37  CREATE_SRC_DST_3(op); \
38  (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
39  (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
40  (op)->src[1]->reg = rz_reg_get(analysis->reg, REG(2), RZ_REG_TYPE_GPR);
41 
42 #define SET_SRC_DST_3_IMM(op) \
43  CREATE_SRC_DST_3(op); \
44  (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
45  (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
46  (op)->src[1]->imm = IMM(2);
47 
48 #define SET_SRC_DST_2_REGS(op) \
49  CREATE_SRC_DST_2(op); \
50  (op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
51  (op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR);
52 
53 #define SET_SRC_DST_3_REG_OR_IMM(op) \
54  if (OPERAND(2).type == RISCV_OP_IMM) { \
55  SET_SRC_DST_3_IMM(op); \
56  } else if (OPERAND(2).type == RISCV_OP_REG) { \
57  SET_SRC_DST_3_REGS(op); \
58  }
59 
60 // ESIL macros:
61 
62 // put the sign bit on the stack
63 #define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&"
64 
65 // call with delay slot
66 #define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr)
67 #define ES_CALL_D(addr) ES_CALL_DR("ra", addr)
68 
69 // call without delay slot
70 #define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr)
71 #define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr)
72 
73 #define USE_DS 0
74 #if USE_DS
75 // emit ERR trap if executed in a delay slot
76 #define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
77 // jump to address
78 #define ES_J(addr) addr ",SETJT,1,SETD"
79 #else
80 #define ES_TRAP_DS() ""
81 #define ES_J(addr) addr ",pc,="
82 #endif
83 
84 // sign extend 32 -> 64
85 #define ES_SIGN_EXT64(arg) \
86  arg ",0x80000000,&,0,<,?{," \
87  "0xffffffff00000000," arg ",|=," \
88  "}"
89 
90 #define PROTECT_ZERO() \
91  if (REG(0)[0] == 'z') { \
92  rz_strbuf_appendf(&op->esil, ","); \
93  } else
94 
95 #define ESIL_LOAD(size) \
96  PROTECT_ZERO() { \
97  rz_strbuf_appendf(&op->esil, "%s,[" size "],%s,=", \
98  ARG(1), REG(0)); \
99  }
100 
101 static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) {
102  int i;
103  PJ *pj = pj_new();
104  if (!pj) {
105  return;
106  }
107  pj_o(pj);
108  pj_ka(pj, "operands");
109  cs_riscv *x = &insn->detail->riscv;
110  for (i = 0; i < x->op_count; i++) {
111  cs_riscv_op *op = x->operands + i;
112  pj_o(pj);
113  switch (op->type) {
114  case RISCV_OP_REG:
115  pj_ks(pj, "type", "reg");
116  pj_ks(pj, "value", cs_reg_name(handle, op->reg));
117  break;
118  case RISCV_OP_IMM:
119  pj_ks(pj, "type", "imm");
120  pj_kN(pj, "value", op->imm);
121  break;
122  case RISCV_OP_MEM:
123  pj_ks(pj, "type", "mem");
124  if (op->mem.base != RISCV_REG_INVALID) {
125  pj_ks(pj, "base", cs_reg_name(handle, op->mem.base));
126  }
127  pj_kN(pj, "disp", op->mem.disp);
128  break;
129  default:
130  pj_ks(pj, "type", "invalid");
131  break;
132  }
133  pj_end(pj); /* o operand */
134  }
135  pj_end(pj); /* a operands */
136  pj_end(pj);
137 
140  pj_free(pj);
141 }
142 
143 static const char *arg(csh *handle, cs_insn *insn, char *buf, int n) {
144  *buf = 0;
145  switch (insn->detail->riscv.operands[n].type) {
146  case RISCV_OP_INVALID:
147  break;
148  case RISCV_OP_REG:
149  sprintf(buf, "%s",
151  insn->detail->riscv.operands[n].reg));
152  break;
153  case RISCV_OP_IMM: {
154  st64 x = (st64)insn->detail->riscv.operands[n].imm;
155  sprintf(buf, "%" PFMT64d, x);
156  break;
157  }
158  case RISCV_OP_MEM: {
159  st64 disp = insn->detail->riscv.operands[n].mem.disp;
160  if (disp < 0) {
161  sprintf(buf, "%" PFMT64d ",%s,-",
162  (ut64)-insn->detail->riscv.operands[n].mem.disp,
164  insn->detail->riscv.operands[n].mem.base));
165  } else {
166  sprintf(buf, "0x%" PFMT64x ",%s,+",
167  (ut64)insn->detail->riscv.operands[n].mem.disp,
169  insn->detail->riscv.operands[n].mem.base));
170  }
171  break;
172  }
173  }
174  return buf;
175 }
176 
177 #define ARG(x) (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x)
178 
179 static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
180  char str[8][32] = { { 0 } };
181  int i;
182 
183  rz_strbuf_init(&op->esil);
184  rz_strbuf_set(&op->esil, "");
185 
186  if (insn) {
187  // caching operands
188  for (i = 0; i < insn->detail->riscv.op_count && i < 8; i++) {
189  *str[i] = 0;
190  ARG(i);
191  }
192  }
193 
194  switch (insn->id) {
195  // case RISCV_INS_NOP:
196  // rz_strbuf_setf (&op->esil, ",");
197  // break;
198  }
199  return 0;
200 }
201 
202 static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
203  if (!reg) {
204  return -1;
205  }
206  switch (OPERAND(reg_num).type) {
207  case RISCV_OP_REG:
208  reg->name = (char *)cs_reg_name(handle, OPERAND(reg_num).reg);
209  break;
210  case RISCV_OP_MEM:
211  if (OPERAND(reg_num).mem.base != RISCV_REG_INVALID) {
212  reg->name = (char *)cs_reg_name(handle, OPERAND(reg_num).mem.base);
213  }
214  default:
215  break;
216  }
217  return 0;
218 }
219 
220 static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_insn *insn) {
221  static RzRegItem reg;
222  switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
224  if (OPERAND(1).type == RISCV_OP_MEM) {
225  ZERO_FILL(reg);
226  op->src[0] = rz_analysis_value_new();
227  op->src[0]->reg = &reg;
228  parse_reg_name(op->src[0]->reg, *handle, insn, 1);
229  op->src[0]->delta = OPERAND(1).mem.disp;
230  }
231  break;
233  if (OPERAND(1).type == RISCV_OP_MEM) {
234  ZERO_FILL(reg);
235  op->dst = rz_analysis_value_new();
236  op->dst->reg = &reg;
237  parse_reg_name(op->dst->reg, *handle, insn, 1);
238  op->dst->delta = OPERAND(1).mem.disp;
239  }
240  break;
250  break;
253  break;
254  case RZ_ANALYSIS_OP_TYPE_DIV: // UDIV
255 #if 0
256 capstone bug
257 ------------
258  $ rizin -a riscv -e cfg.bigendian=1 -c "wx 0083001b" -
259  // should be 3 regs, right?
260  [0x00000000]> aoj~{}
261  [
262  {
263  "opcode": "divu zero, a0, v1",
264  "disasm": "divu zero, a0, v1",
265  "mnemonic": "divu",
266  "sign": false,
267  "prefix": 0,
268  "id": 192,
269  "opex": {
270  "operands": [
271  {
272  "type": "reg",
273  "value": "a0"
274  },
275  {
276  "type": "reg",
277  "value": "v1"
278  }
279  ]
280  },
281 #endif
282  if (OPERAND(0).type == RISCV_OP_REG && OPERAND(1).type == RISCV_OP_REG && OPERAND(2).type == RISCV_OP_REG) {
284  } else if (OPERAND(0).type == RISCV_OP_REG && OPERAND(1).type == RISCV_OP_REG) {
286  } else {
287  RZ_LOG_ERROR("riscv: unknown div opcode at 0x%08" PFMT64x "\n", op->addr);
288  }
289  break;
290  }
291  if (insn && (insn->id == RISCV_INS_SLTI || insn->id == RISCV_INS_SLTIU)) {
293  }
294 }
295 
296 static void set_opdir(RzAnalysisOp *op) {
297  switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
299  op->direction = RZ_ANALYSIS_OP_DIR_READ;
300  break;
302  op->direction = RZ_ANALYSIS_OP_DIR_WRITE;
303  break;
305  op->direction = RZ_ANALYSIS_OP_DIR_REF;
306  break;
311  op->direction = RZ_ANALYSIS_OP_DIR_EXEC;
312  break;
313  default:
314  break;
315  }
316 }
317 
318 static int analop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) {
319  int n, ret, opsize = -1;
320  static csh hndl = 0;
321  static int omode = -1;
322  static int obits = 32;
323  cs_insn *insn;
324  int mode = (analysis->bits == 64) ? CS_MODE_RISCV64 : CS_MODE_RISCV32;
325  if (mode != omode || analysis->bits != obits) {
326  cs_close(&hndl);
327  hndl = 0;
328  omode = mode;
329  obits = analysis->bits;
330  }
331  // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64
332  op->addr = addr;
333  if (len < 4) {
334  return -1;
335  }
336  op->size = 4;
337  if (hndl == 0) {
338  ret = cs_open(CS_ARCH_RISCV, mode, &hndl);
339  if (ret != CS_ERR_OK) {
340  goto fin;
341  }
343  }
344  n = cs_disasm(hndl, (ut8 *)buf, len, addr, 1, &insn);
345  if (n < 1 || insn->size < 1) {
346  goto beach;
347  }
348  op->id = insn->id;
349  opsize = op->size = insn->size;
350  switch (insn->id) {
351  case RISCV_INS_C_NOP:
352  op->type = RZ_ANALYSIS_OP_TYPE_NOP;
353  break;
354  case RISCV_INS_INVALID:
355  op->type = RZ_ANALYSIS_OP_TYPE_ILL;
356  break;
357  case RISCV_INS_C_JALR:
359  break;
360  case RISCV_INS_C_JR:
362  break;
363  case RISCV_INS_C_MV:
364  op->type = RZ_ANALYSIS_OP_TYPE_MOV;
365  break;
366  case RISCV_INS_JAL:
368  op->jump = IMM(0);
369  op->fail = op->addr + op->size;
370  break;
371  case RISCV_INS_MRET:
372  case RISCV_INS_SRET:
373  case RISCV_INS_URET:
374  op->type = RZ_ANALYSIS_OP_TYPE_RET;
375  break;
376  }
377 beach:
378  set_opdir(op);
379  if (insn && mask & RZ_ANALYSIS_OP_MASK_OPEX) {
380  opex(&op->opex, hndl, insn);
381  }
383  if (analop_esil(analysis, op, addr, buf, len, &hndl, insn) != 0) {
384  rz_strbuf_fini(&op->esil);
385  }
386  }
388  op_fillval(analysis, op, &hndl, insn);
389  }
390  cs_free(insn, n);
391  // cs_close (&handle);
392 fin:
393  return opsize;
394 }
395 
396 static char *get_reg_profile(RzAnalysis *analysis) {
397  const char *p = NULL;
398  switch (analysis->bits) {
399  case 32:
400  p =
401  "=PC pc\n"
402  "=SP sp\n" // ABI: stack pointer
403  "=LR ra\n" // ABI: return address
404  "=BP s0\n" // ABI: frame pointer
405  "=A0 a0\n"
406  "=A1 a1\n"
407 
408  "gpr pc .32 0 0\n"
409  // RV32I regs (ABI names)
410  // From user-Level ISA Specification, section 2.1
411  // "zero" has been left out as it ignores writes and always reads as zero
412  "gpr ra .32 4 0\n" // =x1
413  "gpr sp .32 8 0\n" // =x2
414  "gpr gp .32 12 0\n" // =x3
415  "gpr tp .32 16 0\n" // =x4
416  "gpr t0 .32 20 0\n" // =x5
417  "gpr t1 .32 24 0\n" // =x6
418  "gpr t2 .32 28 0\n" // =x7
419  "gpr s0 .32 32 0\n" // =x8
420  "gpr s1 .32 36 0\n" // =x9
421  "gpr a0 .32 40 0\n" // =x10
422  "gpr a1 .32 44 0\n" // =x11
423  "gpr a2 .32 48 0\n" // =x12
424  "gpr a3 .32 52 0\n" // =x13
425  "gpr a4 .32 56 0\n" // =x14
426  "gpr a5 .32 60 0\n" // =x15
427  "gpr a6 .32 64 0\n" // =x16
428  "gpr a7 .32 68 0\n" // =x17
429  "gpr s2 .32 72 0\n" // =x18
430  "gpr s3 .32 76 0\n" // =x19
431  "gpr s4 .32 80 0\n" // =x20
432  "gpr s5 .32 84 0\n" // =x21
433  "gpr s6 .32 88 0\n" // =x22
434  "gpr s7 .32 92 0\n" // =x23
435  "gpr s8 .32 96 0\n" // =x24
436  "gpr s9 .32 100 0\n" // =x25
437  "gpr s10 .32 104 0\n" // =x26
438  "gpr s11 .32 108 0\n" // =x27
439  "gpr t3 .32 112 0\n" // =x28
440  "gpr t4 .32 116 0\n" // =x29
441  "gpr t5 .32 120 0\n" // =x30
442  "gpr t6 .32 124 0\n" // =x31
443  // RV32F/D regs (ABI names)
444  // From user-Level ISA Specification, section 8.1 and 9.1
445  "gpr ft0 .64 128 0\n" // =f0
446  "gpr ft1 .64 136 0\n" // =f1
447  "gpr ft2 .64 144 0\n" // =f2
448  "gpr ft3 .64 152 0\n" // =f3
449  "gpr ft4 .64 160 0\n" // =f4
450  "gpr ft5 .64 168 0\n" // =f5
451  "gpr ft6 .64 176 0\n" // =f6
452  "gpr ft7 .64 184 0\n" // =f7
453  "gpr fs0 .64 192 0\n" // =f8
454  "gpr fs1 .64 200 0\n" // =f9
455  "gpr fa0 .64 208 0\n" // =f10
456  "gpr fa1 .64 216 0\n" // =f11
457  "gpr fa2 .64 224 0\n" // =f12
458  "gpr fa3 .64 232 0\n" // =f13
459  "gpr fa4 .64 240 0\n" // =f14
460  "gpr fa5 .64 248 0\n" // =f15
461  "gpr fa6 .64 256 0\n" // =f16
462  "gpr fa7 .64 264 0\n" // =f17
463  "gpr fs2 .64 272 0\n" // =f18
464  "gpr fs3 .64 280 0\n" // =f19
465  "gpr fs4 .64 288 0\n" // =f20
466  "gpr fs5 .64 296 0\n" // =f21
467  "gpr fs6 .64 304 0\n" // =f22
468  "gpr fs7 .64 312 0\n" // =f23
469  "gpr fs8 .64 320 0\n" // =f24
470  "gpr fs9 .64 328 0\n" // =f25
471  "gpr fs10 .64 336 0\n" // =f26
472  "gpr fs11 .64 344 0\n" // =f27
473  "gpr ft8 .64 352 0\n" // =f28
474  "gpr ft9 .64 360 0\n" // =f29
475  "gpr ft10 .64 368 0\n" // =f30
476  "gpr ft11 .64 376 0\n" // =f31
477  "gpr fcsr .32 384 0\n"
478  "flg nx .1 3072 0\n"
479  "flg uf .1 3073 0\n"
480  "flg of .1 3074 0\n"
481  "flg dz .1 3075 0\n"
482  "flg nv .1 3076 0\n"
483  "flg frm .3 3077 0\n";
484 
485  break;
486  case 64:
487  p =
488  "=PC pc\n"
489  "=SP sp\n" // ABI: stack pointer
490  "=LR ra\n" // ABI: return address
491  "=BP s0\n" // ABI: frame pointer
492  "=A0 a0\n"
493  "=A1 a1\n"
494 
495  "gpr pc .64 0 0\n"
496  // RV64I regs (ABI names)
497  // From user-Level ISA Specification, section 2.1 and 4.1
498  // "zero" has been left out as it ignores writes and always reads as zero
499  "gpr ra .64 8 0\n" // =x1
500  "gpr sp .64 16 0\n" // =x2
501  "gpr gp .64 24 0\n" // =x3
502  "gpr tp .64 32 0\n" // =x4
503  "gpr t0 .64 40 0\n" // =x5
504  "gpr t1 .64 48 0\n" // =x6
505  "gpr t2 .64 56 0\n" // =x7
506  "gpr s0 .64 64 0\n" // =x8
507  "gpr s1 .64 72 0\n" // =x9
508  "gpr a0 .64 80 0\n" // =x10
509  "gpr a1 .64 88 0\n" // =x11
510  "gpr a2 .64 96 0\n" // =x12
511  "gpr a3 .64 104 0\n" // =x13
512  "gpr a4 .64 112 0\n" // =x14
513  "gpr a5 .64 120 0\n" // =x15
514  "gpr a6 .64 128 0\n" // =x16
515  "gpr a7 .64 136 0\n" // =x17
516  "gpr s2 .64 144 0\n" // =x18
517  "gpr s3 .64 152 0\n" // =x19
518  "gpr s4 .64 160 0\n" // =x20
519  "gpr s5 .64 168 0\n" // =x21
520  "gpr s6 .64 176 0\n" // =x22
521  "gpr s7 .64 184 0\n" // =x23
522  "gpr s8 .64 192 0\n" // =x24
523  "gpr s9 .64 200 0\n" // =x25
524  "gpr s10 .64 208 0\n" // =x26
525  "gpr s11 .64 216 0\n" // =x27
526  "gpr t3 .64 224 0\n" // =x28
527  "gpr t4 .64 232 0\n" // =x29
528  "gpr t5 .64 240 0\n" // =x30
529  "gpr t6 .64 248 0\n" // =x31
530  // RV64F/D regs (ABI names)
531  "gpr ft0 .64 256 0\n" // =f0
532  "gpr ft1 .64 264 0\n" // =f1
533  "gpr ft2 .64 272 0\n" // =f2
534  "gpr ft3 .64 280 0\n" // =f3
535  "gpr ft4 .64 288 0\n" // =f4
536  "gpr ft5 .64 296 0\n" // =f5
537  "gpr ft6 .64 304 0\n" // =f6
538  "gpr ft7 .64 312 0\n" // =f7
539  "gpr fs0 .64 320 0\n" // =f8
540  "gpr fs1 .64 328 0\n" // =f9
541  "gpr fa0 .64 336 0\n" // =f10
542  "gpr fa1 .64 344 0\n" // =f11
543  "gpr fa2 .64 352 0\n" // =f12
544  "gpr fa3 .64 360 0\n" // =f13
545  "gpr fa4 .64 368 0\n" // =f14
546  "gpr fa5 .64 376 0\n" // =f15
547  "gpr fa6 .64 384 0\n" // =f16
548  "gpr fa7 .64 392 0\n" // =f17
549  "gpr fs2 .64 400 0\n" // =f18
550  "gpr fs3 .64 408 0\n" // =f19
551  "gpr fs4 .64 416 0\n" // =f20
552  "gpr fs5 .64 424 0\n" // =f21
553  "gpr fs6 .64 432 0\n" // =f22
554  "gpr fs7 .64 440 0\n" // =f23
555  "gpr fs8 .64 448 0\n" // =f24
556  "gpr fs9 .64 456 0\n" // =f25
557  "gpr fs10 .64 464 0\n" // =f26
558  "gpr fs11 .64 472 0\n" // =f27
559  "gpr ft8 .64 480 0\n" // =f28
560  "gpr ft9 .64 488 0\n" // =f29
561  "gpr ft10 .64 496 0\n" // =f30
562  "gpr ft11 .64 504 0\n" // =f31
563  "gpr fcsr .32 512 0\n"
564  "flg nx .1 4096 0\n"
565  "flg uf .1 4097 0\n"
566  "flg of .1 4098 0\n"
567  "flg dz .1 4099 0\n"
568  "flg nv .1 4100 0\n"
569  "flg frm .3 4101 0\n";
570 
571  break;
572  }
573  return (p && *p) ? strdup(p) : NULL;
574 }
575 
576 static int archinfo(RzAnalysis *analysis, int q) {
577  switch (q) {
579  return 4;
581  return 4;
583  if (analysis->bits == 64) {
584  return 4;
585  }
586  return 2;
587  }
588  return 0;
589 }
590 
592  .name = "riscv.cs",
593  .desc = "Capstone RISCV analyzer",
594  .license = "BSD",
595  .esil = true,
596  .arch = "riscv",
597  .get_reg_profile = get_reg_profile,
598  .archinfo = archinfo,
599  .bits = 32 | 64,
600  .op = &analop,
601 };
602 
603 #ifndef RZ_PLUGIN_INCORE
608 };
609 #endif
size_t len
Definition: 6502dis.c:15
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
#define e(frag)
#define mask()
RzAnalysisPlugin rz_analysis_plugin_riscv_cs
static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num)
static char * get_reg_profile(RzAnalysis *analysis)
#define ARG(x)
#define OPERAND(x)
static void opex(RzStrBuf *buf, csh handle, cs_insn *insn)
#define SET_SRC_DST_3_REGS(op)
#define IMM(x)
static const char * arg(csh *handle, cs_insn *insn, char *buf, int n)
RZ_API RzLibStruct rizin_plugin
#define SET_SRC_DST_3_IMM(op)
#define SET_SRC_DST_2_REGS(op)
static int analop_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_insn *insn)
static void set_opdir(RzAnalysisOp *op)
static int analop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static int archinfo(RzAnalysis *analysis, int q)
#define SET_SRC_DST_3_REG_OR_IMM(op)
lzma_index ** i
Definition: index.h:629
static mcore_handle handle
Definition: asm_mcore.c:8
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
size_t csh
Definition: capstone.h:71
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
#define RZ_API
#define NULL
Definition: cris-opc.c:27
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
Definition: cs.c:798
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:501
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:646
voidpf void uLong size
Definition: ioapi.h:138
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
sprintf
Definition: kernel.h:365
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
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")
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
Definition: Arm.java:4
int CS_ERR_OK
Definition: __init__.py:235
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
@ RZ_ANALYSIS_OP_DIR_READ
Definition: rz_analysis.h:790
@ RZ_ANALYSIS_OP_DIR_EXEC
Definition: rz_analysis.h:792
@ RZ_ANALYSIS_OP_DIR_WRITE
Definition: rz_analysis.h:791
@ RZ_ANALYSIS_OP_DIR_REF
Definition: rz_analysis.h:793
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
@ RZ_ANALYSIS_OP_MASK_OPEX
Definition: rz_analysis.h:444
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ 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_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_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define PFMT64d
Definition: rz_types.h:394
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define RZ_VERSION
Definition: rz_version.h:8
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
Definition: rz_pj.h:12
const char * version
Definition: rz_analysis.h:1239
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58