Rizin
unix-like reverse engineering framework and cli tools
asm_or1k.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2019 v3l0c1r4pt0r <v3l0c1r4pt0r@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_asm.h>
5 #include <rz_lib.h>
6 #include "../arch/or1k/or1k_disas.h"
7 
8 struct operands {
9  ut32 rd;
10  ut32 ra;
11  ut32 rb;
12  ut32 n;
13  ut32 k1;
14  ut32 k2;
15  ut32 k;
16  ut32 i;
17  ut32 l;
18 };
19 
20 static int insn_to_str(RzAsm *a, char **line, insn_t *descr, insn_extra_t *extra, ut32 insn) {
21  struct operands o = { 0 };
22  char *name;
23  insn_type_t type = type_of_opcode(descr, extra);
24  insn_type_descr_t *type_descr = &types[INSN_X];
25 
26  /* only use type descriptor if it has some useful data */
28  type_descr = &types[type];
29  }
30 
31  o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
32  o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
33  o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
34  o.k1 = get_operand_value(insn, type_descr, INSN_OPER_K1);
35  o.k2 = get_operand_value(insn, type_descr, INSN_OPER_K2);
36  o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
37  o.k = get_operand_value(insn, type_descr, INSN_OPER_K);
38  o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
39  o.l = get_operand_value(insn, type_descr, INSN_OPER_L);
40 
41  name = extra ? extra->name : descr->name;
42 
43  if (!name || !type_descr->format) {
44  /* this should not happen, give up */
45  *line = sdb_fmt("invalid");
46  return 4;
47  }
48 
49  switch (type) {
50  case INSN_X:
51  *line = sdb_fmt(type_descr->format, name);
52  break;
53  case INSN_N:
54  *line = sdb_fmt(type_descr->format, name,
55  (sign_extend(o.n, get_operand_mask(type_descr, INSN_OPER_N)) << 2) +
56  a->pc);
57  break;
58  case INSN_K:
59  *line = sdb_fmt(type_descr->format, name, o.k);
60  break;
61  case INSN_DK:
62  *line = sdb_fmt(type_descr->format, name, o.rd, o.k);
63  break;
64  case INSN_DN:
65  *line = sdb_fmt(type_descr->format, name, o.rd, o.n << 13);
66  break;
67  case INSN_B:
68  *line = sdb_fmt(type_descr->format, name, o.rb);
69  break;
70  case INSN_D:
71  *line = sdb_fmt(type_descr->format, name, o.rd);
72  break;
73  case INSN_AI:
74  *line = sdb_fmt(type_descr->format, name, o.ra, o.i);
75  break;
76  case INSN_DAI:
77  *line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
78  break;
79  case INSN_DAK:
80  *line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
81  break;
82  case INSN_DAL:
83  *line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.l);
84  break;
85  case INSN_DA:
86  *line = sdb_fmt(type_descr->format, name, o.rd, o.ra);
87  break;
88  case INSN_DAB:
89  *line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.rb);
90  break;
91  case INSN_AB:
92  *line = sdb_fmt(type_descr->format, name, o.ra, o.rb);
93  break;
94  case INSN_IABI:
95  *line = sdb_fmt(type_descr->format, name,
96  o.ra, o.rb, (o.k1 << 11) | o.k2);
97  break;
98  case INSN_KABK:
99  *line = sdb_fmt(type_descr->format, name,
100  o.ra, o.rb, (o.k1 << 11) | o.k2);
101  break;
102  default:
103  *line = sdb_fmt("invalid");
104  }
105  return 4;
106 }
107 
108 static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
109  ut32 insn, opcode;
110  ut8 opcode_idx;
111  char *line = NULL;
112  insn_t *insn_descr;
113  insn_extra_t *extra_descr;
114 
115  op->size = -1;
116 
117  if (len < 4) {
118  line = sdb_fmt("invalid");
119  rz_strbuf_set(&op->buf_asm, line);
120  return op->size;
121  }
122 
123  /* read instruction and basic opcode value */
124  insn = rz_read_be32(buf);
125  op->size = 4;
126  opcode = (insn & INSN_OPCODE_MASK);
127  opcode_idx = opcode >> INSN_OPCODE_SHIFT;
128 
129  /* make sure instruction descriptor table is not overflowed */
130  if (opcode_idx >= insns_count) {
131  line = sdb_fmt("invalid");
132  rz_strbuf_set(&op->buf_asm, line);
133  return op->size;
134  }
135 
136  /* if instruction is marked as invalid finish processing now */
137  insn_descr = &or1k_insns[opcode_idx];
138  if (insn_descr->type == INSN_INVAL) {
139  line = sdb_fmt("invalid");
140  rz_strbuf_set(&op->buf_asm, line);
141  return op->size;
142  }
143 
144  /* if name is null, but extra is present, it means 6 most significant bits
145  * are not enough to decode instruction */
146  if (!insn_descr->name && insn_descr->extra) {
147  if ((extra_descr = find_extra_descriptor(insn_descr->extra, insn)) != NULL) {
148  insn_to_str(a, &line, insn_descr, extra_descr, insn);
149  } else {
150  line = "invalid";
151  }
152  rz_strbuf_set(&op->buf_asm, line);
153  } else {
154  /* otherwise basic descriptor is enough */
155  insn_to_str(a, &line, insn_descr, NULL, insn);
156  rz_strbuf_set(&op->buf_asm, line);
157  }
158  return op->size;
159 }
160 
162  .name = "or1k",
163  .desc = "OpenRISC 1000",
164  .license = "LGPL3",
165  .arch = "or1k",
166  .bits = 32,
167  .endian = RZ_SYS_ENDIAN_BIG,
168  .disassemble = &disassemble,
169 };
170 
171 #ifndef RZ_PLUGIN_INCORE
174 };
175 #endif
size_t len
Definition: 6502dis.c:15
static void sign_extend(st32 *value, ut8 bit)
RzAsmPlugin rz_asm_plugin_or1k
Definition: asm_or1k.c:161
RZ_API RzLibStruct rizin_plugin
Definition: asm_or1k.c:172
static int insn_to_str(RzAsm *a, char **line, insn_t *descr, insn_extra_t *extra, ut32 insn)
Definition: asm_or1k.c:20
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm_or1k.c:108
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
int type
Definition: mipsasm.c:17
line
Definition: setup.py:34
const char * name
Definition: op.c:541
insn_t or1k_insns[]
Definition: or1k_disas.c:219
insn_type_descr_t types[]
Definition: or1k_disas.c:7
size_t insns_count
Definition: or1k_disas.c:286
insn_extra_t * find_extra_descriptor(insn_extra_t *extra_descr, ut32 insn)
Definition: or1k_disas.c:288
static ut32 get_operand_mask(insn_type_descr_t *type_descr, insn_oper_t operand)
Definition: or1k_disas.h:152
static int is_type_descriptor_defined(insn_type_t type)
Definition: or1k_disas.h:168
static int has_type_descriptor(insn_type_t type)
Definition: or1k_disas.h:164
@ INSN_D
Definition: or1k_disas.h:60
@ INSN_DAB
Definition: or1k_disas.h:73
@ INSN_KABK
Definition: or1k_disas.h:69
@ INSN_DA
Definition: or1k_disas.h:72
@ INSN_X
Definition: or1k_disas.h:55
@ INSN_AI
Definition: or1k_disas.h:62
@ INSN_N
Definition: or1k_disas.h:56
@ INSN_B
Definition: or1k_disas.h:61
@ INSN_DN
Definition: or1k_disas.h:57
@ INSN_DAL
Definition: or1k_disas.h:67
@ INSN_IABI
Definition: or1k_disas.h:75
@ INSN_K
Definition: or1k_disas.h:58
@ INSN_DAI
Definition: or1k_disas.h:63
@ INSN_AB
Definition: or1k_disas.h:71
@ INSN_DK
Definition: or1k_disas.h:59
@ INSN_INVAL
Definition: or1k_disas.h:54
@ INSN_DAK
Definition: or1k_disas.h:65
static ut32 get_operand_value(ut32 insn, insn_type_descr_t *type_descr, insn_oper_t operand)
Definition: or1k_disas.h:160
@ INSN_OPER_A
Definition: or1k_disas.h:83
@ INSN_OPER_B
Definition: or1k_disas.h:84
@ INSN_OPER_I
Definition: or1k_disas.h:88
@ INSN_OPER_N
Definition: or1k_disas.h:85
@ INSN_OPER_K
Definition: or1k_disas.h:86
@ INSN_OPER_D
Definition: or1k_disas.h:87
@ INSN_OPER_L
Definition: or1k_disas.h:89
@ INSN_OPER_K2
Definition: or1k_disas.h:82
@ INSN_OPER_K1
Definition: or1k_disas.h:81
static insn_type_t type_of_opcode(insn_t *descr, insn_extra_t *extra_descr)
Definition: or1k_disas.h:172
#define INSN_OPCODE_MASK
Definition: or1k_disas.h:10
#define INSN_OPCODE_SHIFT
Definition: or1k_disas.h:11
enum insn_type insn_type_t
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
#define RZ_SYS_ENDIAN_BIG
Definition: rz_types.h:527
#define RZ_VERSION
Definition: rz_version.h:8
#define a(i)
Definition: sha256.c:41
char * name
Definition: or1k_disas.h:107
insn_extra_t * extra
Definition: or1k_disas.h:118
char * name
Definition: or1k_disas.h:115
int type
Definition: or1k_disas.h:116
Definition: z80asm.h:102
const char * name
Definition: rz_asm.h:130
const char * version
Definition: rz_asm.h:133
Definition: dis.c:32