Rizin
unix-like reverse engineering framework and cli tools
analysis_riscv_cs.c File Reference
#include <rz_asm.h>
#include <rz_lib.h>
#include <capstone/capstone.h>
#include <capstone/riscv.h>

Go to the source code of this file.

Macros

#define OPERAND(x)   insn->detail->riscv.operands[x]
 
#define REGID(x)   insn->detail->riscv.operands[x].reg
 
#define REG(x)   cs_reg_name(*handle, insn->detail->riscv.operands[x].reg)
 
#define IMM(x)   insn->detail->riscv.operands[x].imm
 
#define MEMBASE(x)   cs_reg_name(*handle, insn->detail->riscv.operands[x].mem.base)
 
#define MEMINDEX(x)   insn->detail->riscv.operands[x].mem.index
 
#define MEMDISP(x)   insn->detail->riscv.operands[x].mem.disp
 
#define OPCOUNT()   insn->detail->riscv.op_count
 
#define SET_VAL(op, i)
 
#define CREATE_SRC_DST_3(op)
 
#define CREATE_SRC_DST_2(op)
 
#define SET_SRC_DST_3_REGS(op)
 
#define SET_SRC_DST_3_IMM(op)
 
#define SET_SRC_DST_2_REGS(op)
 
#define SET_SRC_DST_3_REG_OR_IMM(op)
 
#define ES_IS_NEGATIVE(arg)   "1," arg ",<<<,1,&"
 
#define ES_CALL_DR(ra, addr)   "pc,4,+," ra ",=," ES_J(addr)
 
#define ES_CALL_D(addr)   ES_CALL_DR("ra", addr)
 
#define ES_CALL_NDR(ra, addr)   "pc," ra ",=," ES_J(addr)
 
#define ES_CALL_ND(addr)   ES_CALL_NDR("ra", addr)
 
#define USE_DS   0
 
#define ES_TRAP_DS()   ""
 
#define ES_J(addr)   addr ",pc,="
 
#define ES_SIGN_EXT64(arg)
 
#define PROTECT_ZERO()
 
#define ESIL_LOAD(size)
 
#define ARG(x)   (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x)
 

Functions

static void opex (RzStrBuf *buf, csh handle, cs_insn *insn)
 
static const char * arg (csh *handle, cs_insn *insn, char *buf, int n)
 
static int analop_esil (RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
 
static int parse_reg_name (RzRegItem *reg, csh handle, cs_insn *insn, int reg_num)
 
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 char * get_reg_profile (RzAnalysis *analysis)
 
static int archinfo (RzAnalysis *analysis, int q)
 

Variables

RzAnalysisPlugin rz_analysis_plugin_riscv_cs
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ ARG

#define ARG (   x)    (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x)

Definition at line 177 of file analysis_riscv_cs.c.

◆ CREATE_SRC_DST_2

#define CREATE_SRC_DST_2 (   op)
Value:
ut8 op
Definition: 6502dis.c:13
RZ_API RzAnalysisValue * rz_analysis_value_new(void)
Definition: value.c:6
lzma_index * src
Definition: index.h:567
char * dst
Definition: lz4.h:724

Definition at line 32 of file analysis_riscv_cs.c.

◆ CREATE_SRC_DST_3

#define CREATE_SRC_DST_3 (   op)
Value:

Definition at line 27 of file analysis_riscv_cs.c.

◆ ES_CALL_D

#define ES_CALL_D (   addr)    ES_CALL_DR("ra", addr)

Definition at line 67 of file analysis_riscv_cs.c.

◆ ES_CALL_DR

#define ES_CALL_DR (   ra,
  addr 
)    "pc,4,+," ra ",=," ES_J(addr)

Definition at line 66 of file analysis_riscv_cs.c.

◆ ES_CALL_ND

#define ES_CALL_ND (   addr)    ES_CALL_NDR("ra", addr)

Definition at line 71 of file analysis_riscv_cs.c.

◆ ES_CALL_NDR

#define ES_CALL_NDR (   ra,
  addr 
)    "pc," ra ",=," ES_J(addr)

Definition at line 70 of file analysis_riscv_cs.c.

◆ ES_IS_NEGATIVE

#define ES_IS_NEGATIVE (   arg)    "1," arg ",<<<,1,&"

Definition at line 63 of file analysis_riscv_cs.c.

◆ ES_J

#define ES_J (   addr)    addr ",pc,="

Definition at line 81 of file analysis_riscv_cs.c.

◆ ES_SIGN_EXT64

#define ES_SIGN_EXT64 (   arg)
Value:
arg ",0x80000000,&,0,<,?{," \
"0xffffffff00000000," arg ",|=," \
"}"

Definition at line 85 of file analysis_riscv_cs.c.

◆ ES_TRAP_DS

#define ES_TRAP_DS ( )    ""

Definition at line 80 of file analysis_riscv_cs.c.

◆ ESIL_LOAD

#define ESIL_LOAD (   size)
Value:
rz_strbuf_appendf(&op->esil, "%s,[" size "],%s,=", \
ARG(1), REG(0)); \
}
#define ARG(x)
#define PROTECT_ZERO()
#define REG(x)
voidpf void uLong size
Definition: ioapi.h:138
Definition: dis.c:32

Definition at line 95 of file analysis_riscv_cs.c.

◆ IMM

#define IMM (   x)    insn->detail->riscv.operands[x].imm

Definition at line 15 of file analysis_riscv_cs.c.

◆ MEMBASE

#define MEMBASE (   x)    cs_reg_name(*handle, insn->detail->riscv.operands[x].mem.base)

Definition at line 16 of file analysis_riscv_cs.c.

◆ MEMDISP

#define MEMDISP (   x)    insn->detail->riscv.operands[x].mem.disp

Definition at line 18 of file analysis_riscv_cs.c.

◆ MEMINDEX

#define MEMINDEX (   x)    insn->detail->riscv.operands[x].mem.index

Definition at line 17 of file analysis_riscv_cs.c.

◆ OPCOUNT

#define OPCOUNT ( )    insn->detail->riscv.op_count

Definition at line 19 of file analysis_riscv_cs.c.

◆ OPERAND

#define OPERAND (   x)    insn->detail->riscv.operands[x]

Definition at line 12 of file analysis_riscv_cs.c.

◆ PROTECT_ZERO

#define PROTECT_ZERO ( )
Value:
if (REG(0)[0] == 'z') { \
rz_strbuf_appendf(&op->esil, ","); \
} else

Definition at line 90 of file analysis_riscv_cs.c.

◆ REG

#define REG (   x)    cs_reg_name(*handle, insn->detail->riscv.operands[x].reg)

Definition at line 14 of file analysis_riscv_cs.c.

◆ REGID

#define REGID (   x)    insn->detail->riscv.operands[x].reg

Definition at line 13 of file analysis_riscv_cs.c.

◆ SET_SRC_DST_2_REGS

#define SET_SRC_DST_2_REGS (   op)
Value:
(op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
(op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR);
#define CREATE_SRC_DST_2(op)
#define reg(n)
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21

Definition at line 48 of file analysis_riscv_cs.c.

◆ SET_SRC_DST_3_IMM

#define SET_SRC_DST_3_IMM (   op)
Value:
(op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
(op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
(op)->src[1]->imm = IMM(2);
#define imm
#define IMM(x)
#define CREATE_SRC_DST_3(op)

Definition at line 42 of file analysis_riscv_cs.c.

◆ SET_SRC_DST_3_REG_OR_IMM

#define SET_SRC_DST_3_REG_OR_IMM (   op)
Value:
if (OPERAND(2).type == RISCV_OP_IMM) { \
SET_SRC_DST_3_IMM(op); \
} else if (OPERAND(2).type == RISCV_OP_REG) { \
SET_SRC_DST_3_REGS(op); \
}
#define OPERAND(x)
int type
Definition: mipsasm.c:17

Definition at line 53 of file analysis_riscv_cs.c.

◆ SET_SRC_DST_3_REGS

#define SET_SRC_DST_3_REGS (   op)
Value:
(op)->dst->reg = rz_reg_get(analysis->reg, REG(0), RZ_REG_TYPE_GPR); \
(op)->src[0]->reg = rz_reg_get(analysis->reg, REG(1), RZ_REG_TYPE_GPR); \
(op)->src[1]->reg = rz_reg_get(analysis->reg, REG(2), RZ_REG_TYPE_GPR);

Definition at line 36 of file analysis_riscv_cs.c.

◆ SET_VAL

#define SET_VAL (   op,
  i 
)
Value:
if ((i) < OPCOUNT() && OPERAND(i).type == RISCV_OP_IMM) { \
(op)->val = OPERAND(i).imm; \
}
#define OPCOUNT()
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6

Definition at line 22 of file analysis_riscv_cs.c.

◆ USE_DS

#define USE_DS   0

Definition at line 73 of file analysis_riscv_cs.c.

Function Documentation

◆ analop()

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

Definition at line 318 of file analysis_riscv_cs.c.

318  {
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 }
size_t len
Definition: 6502dis.c:15
#define mask()
static void opex(RzStrBuf *buf, csh handle, cs_insn *insn)
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)
@ 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
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 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
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
int n
Definition: mipsasm.c:19
int CS_ERR_OK
Definition: __init__.py:235
@ 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
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ 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_API void rz_strbuf_fini(RzStrBuf *sb)
Definition: strbuf.c:365
static int addr
Definition: z80asm.c:58

References addr, analop_esil(), rz_analysis_t::bits, cs_close(), cs_disasm(), capstone::CS_ERR_OK, cs_free(), cs_open(), CS_OPT_DETAIL, CS_OPT_ON, cs_option(), IMM, len, mask, n, op_fillval(), opex(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_MASK_OPEX, RZ_ANALYSIS_OP_MASK_VAL, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_NOP, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UJMP, rz_strbuf_fini(), and set_opdir().

◆ analop_esil()

static int analop_esil ( RzAnalysis a,
RzAnalysisOp op,
ut64  addr,
const ut8 buf,
int  len,
csh handle,
cs_insn *  insn 
)
static

Definition at line 179 of file analysis_riscv_cs.c.

179  {
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 }
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33

References ARG, i, rz_strbuf_init(), rz_strbuf_set(), and cmd_descs_generate::str.

Referenced by analop().

◆ archinfo()

static int archinfo ( RzAnalysis analysis,
int  q 
)
static

Definition at line 576 of file analysis_riscv_cs.c.

576  {
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 }
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98

References rz_analysis_t::bits, RZ_ANALYSIS_ARCHINFO_ALIGN, RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE, and RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE.

◆ arg()

static const char* arg ( csh handle,
cs_insn *  insn,
char *  buf,
int  n 
)
static

Definition at line 143 of file analysis_riscv_cs.c.

143  {
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 }
static mcore_handle handle
Definition: asm_mcore.c:8
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
sprintf
Definition: kernel.h:365
int x
Definition: mipsasm.c:20
#define PFMT64d
Definition: rz_types.h:394
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References cs_reg_name(), handle, n, PFMT64d, PFMT64x, sprintf, st64, ut64(), and x.

◆ get_reg_profile()

static char* get_reg_profile ( RzAnalysis analysis)
static

Definition at line 396 of file analysis_riscv_cs.c.

396  {
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 }
#define NULL
Definition: cris-opc.c:27
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().

◆ op_fillval()

static void op_fillval ( RzAnalysis analysis,
RzAnalysisOp op,
csh handle,
cs_insn *  insn 
)
static

Definition at line 220 of file analysis_riscv_cs.c.

220  {
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 }
#define e(frag)
static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num)
#define SET_SRC_DST_3_REGS(op)
#define SET_SRC_DST_3_IMM(op)
#define SET_SRC_DST_2_REGS(op)
#define SET_SRC_DST_3_REG_OR_IMM(op)
Definition: Arm.java:4
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAR
Definition: rz_analysis.h:409
@ 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_SHL
Definition: rz_analysis.h:407
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41

References a, c, e, handle, OPERAND, parse_reg_name(), PFMT64x, reg, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_AND, RZ_ANALYSIS_OP_TYPE_DIV, RZ_ANALYSIS_OP_TYPE_LOAD, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_OR, 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_XOR, rz_analysis_value_new(), RZ_LOG_ERROR, SET_SRC_DST_2_REGS, SET_SRC_DST_3_IMM, SET_SRC_DST_3_REG_OR_IMM, SET_SRC_DST_3_REGS, type, and ZERO_FILL.

Referenced by analop().

◆ opex()

static void opex ( RzStrBuf buf,
csh  handle,
cs_insn *  insn 
)
static

Definition at line 101 of file analysis_riscv_cs.c.

101  {
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 }
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 bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
Definition: rz_pj.h:12

References cs_reg_name(), handle, i, pj_end(), pj_free(), pj_ka(), pj_kN(), pj_ks(), pj_new(), pj_o(), pj_string(), rz_strbuf_append(), rz_strbuf_init(), and x.

Referenced by analop().

◆ parse_reg_name()

static int parse_reg_name ( RzRegItem reg,
csh  handle,
cs_insn *  insn,
int  reg_num 
)
static

Definition at line 202 of file analysis_riscv_cs.c.

202  {
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 }

References cs_reg_name(), handle, OPERAND, reg, and type.

Referenced by op_fillval().

◆ set_opdir()

static void set_opdir ( RzAnalysisOp op)
static

Definition at line 296 of file analysis_riscv_cs.c.

296  {
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 }
@ 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
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417

References RZ_ANALYSIS_OP_DIR_EXEC, RZ_ANALYSIS_OP_DIR_READ, RZ_ANALYSIS_OP_DIR_REF, RZ_ANALYSIS_OP_DIR_WRITE, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_LEA, RZ_ANALYSIS_OP_TYPE_LOAD, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ANALYSIS_OP_TYPE_STORE, RZ_ANALYSIS_OP_TYPE_UCALL, and RZ_ANALYSIS_OP_TYPE_UJMP.

Referenced by analop().

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
}
RzAnalysisPlugin rz_analysis_plugin_riscv_cs
@ 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 604 of file analysis_riscv_cs.c.

◆ rz_analysis_plugin_riscv_cs

RzAnalysisPlugin rz_analysis_plugin_riscv_cs
Initial value:
= {
.name = "riscv.cs",
.desc = "Capstone RISCV analyzer",
.license = "BSD",
.esil = true,
.arch = "riscv",
.get_reg_profile = get_reg_profile,
.archinfo = archinfo,
.bits = 32 | 64,
.op = &analop,
}
static char * get_reg_profile(RzAnalysis *analysis)
static int analop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
static int archinfo(RzAnalysis *analysis, int q)

Definition at line 591 of file analysis_riscv_cs.c.