1 /* radare2 - LGPL - Copyright 2019 - v3l0c1r4pt0r */
2 
3 #include <r_asm.h>
4 #include <r_anal.h>
5 #include <r_lib.h>
6 #include <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 ut32 cpu[32] = {0}; /* register contents */
21 static ut32 cpu_enable; /* allows to treat only registers with known value as
22 	valid */
23 
24 /**
25  * \brief Convert raw N operand to complete address
26  *
27  * \param n immediate, as appearing in instruction
28  * \param mask n operand mask
29  * \param addr address of current instruction
30  *
31  * \return 64-bit address
32  */
n_oper_to_addr(ut32 n,ut32 mask,ut64 addr)33 static ut64 n_oper_to_addr(ut32 n, ut32 mask, ut64 addr) {
34 	/* sign extension returns 32b unsigned N, then it is multiplied by 4, made
35 	 * signed to support negative offsets, added to address and made unsigned
36 	 * again */
37 	return (ut64) ((st64) ((st32) (sign_extend(n, mask) << 2)) + addr);
38 }
39 
insn_to_op(RAnal * a,RAnalOp * op,ut64 addr,insn_t * descr,insn_extra_t * extra,ut32 insn)40 static int insn_to_op(RAnal *a, RAnalOp *op, ut64 addr, insn_t *descr, insn_extra_t *extra, ut32 insn) {
41 	struct operands o = {0};
42 	insn_type_t type = type_of_opcode(descr, extra);
43 	insn_type_descr_t *type_descr = &types[INSN_X];
44 
45 	/* only use type descriptor if it has some useful data */
46 	if (has_type_descriptor(type) && is_type_descriptor_defined(type)) {
47 		type_descr = &types[type];
48 	}
49 
50 	if (extra == NULL) {
51 		op->type = descr->insn_type;
52 	} else {
53 		op->type = extra->insn_type;
54 	}
55 
56 	switch ((insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT) {
57 	case 0x00: /* l.j */
58 		o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
59 		op->eob = true;
60 		op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
61 				addr);
62 		op->delay = 1;
63 		break;
64 	case 0x01: /* l.jal */
65 		o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
66 		op->eob = true;
67 		op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
68 				addr);
69 		op->delay = 1;
70 		break;
71 	case 0x03: /* l.bnf */
72 		o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
73 		op->cond = R_ANAL_COND_NE;
74 		op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
75 				addr);
76 		op->fail = addr + 8;
77 		op->delay = 1;
78 		break;
79 	case 0x04: /* l.bf */
80 		o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
81 		op->cond = R_ANAL_COND_EQ;
82 		op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
83 				addr);
84 		op->fail = addr + 8;
85 		op->delay = 1;
86 		break;
87 	case 0x11: /* l.jr */
88 		o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
89 		op->eob = true;
90 		if (cpu_enable & (1 << o.rb)) {
91 			op->jump = cpu[o.rb];
92 		}
93 		op->delay = 1;
94 		break;
95 	case 0x12: /* l.jalr */
96 		o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
97 		op->eob = true;
98 		if (cpu_enable & (1 << o.rb)) {
99 			op->jump = cpu[o.rb];
100 		}
101 		op->delay = 1;
102 		break;
103 	case 0x06: /* extended */
104 		switch (insn & (1 << 16)) {
105 		case 0: /* l.movhi */
106 			o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
107 			o.k = get_operand_value(insn, type_descr, INSN_OPER_K);
108 			cpu[o.rd] = o.k << 16;
109 			cpu_enable |= (1 << o.rd);
110 			break;
111 		case 1: /* l.macrc */
112 			break;
113 		}
114 		break;
115 	case 0x27: /* l.addi */
116 		o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
117 		o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
118 		o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
119 		if (cpu_enable & (1 << o.ra) & cpu_enable & (1 << o.rd)) {
120 			cpu[o.rd] = cpu[o.ra] | o.i;
121 			cpu_enable |= (1 << o.rd);
122 			op->ptr = cpu[o.rd];
123 			op->direction = 8; /* reference */
124 		}
125 		break;
126 	case 0x2a: /* l.ori */
127 		o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
128 		o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
129 		o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
130 		if (cpu_enable & (1 << o.ra)) {
131 			cpu[o.rd] = cpu[o.ra] | o.i;
132 			cpu_enable |= (1 << o.rd);
133 			op->ptr = cpu[o.rd];
134 			op->direction = 8; /* reference */
135 		}
136 		break;
137 	default:
138 		/* if unknown instruction encountered, better forget state */
139 		cpu_enable = 0;
140 	}
141 
142 	/* temporary solution to prevent using wrong register values */
143 	if ((op->type & R_ANAL_OP_TYPE_JMP) == R_ANAL_OP_TYPE_JMP) {
144 		/* FIXME: handle delay slot after branches */
145 		cpu_enable = 0;
146 	}
147 	return 4;
148 }
149 
or1k_op(RAnal * a,RAnalOp * op,ut64 addr,const ut8 * data,int len,RAnalOpMask mask)150 static int or1k_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
151 	ut32 insn, opcode;
152 	ut8 opcode_idx;
153 	insn_t *insn_descr;
154 	insn_extra_t *extra_descr;
155 
156 	/* read instruction and basic opcode value */
157 	insn = r_read_be32(data);
158 	op->size = 4;
159 	opcode = (insn & INSN_OPCODE_MASK);
160 	opcode_idx = opcode >> INSN_OPCODE_SHIFT;
161 
162 	/* make sure instruction descriptor table is not overflowed */
163 	if (opcode_idx >= insns_count) {
164 		return op->size;
165 	}
166 
167 	/* if instruction is marked as invalid finish processing now */
168 	insn_descr = &or1k_insns[opcode_idx];
169 	if (insn_descr->type == INSN_INVAL) {
170 		return op->size;
171 	}
172 
173 	/* if name is null, but extra is present, it means 6 most significant bits
174 	 * are not enough to decode instruction */
175 	if ((insn_descr->name == NULL) && (insn_descr->extra != NULL)) {
176 		extra_descr = find_extra_descriptor(insn_descr->extra, insn);
177 		if (extra_descr != NULL) {
178 			insn_to_op(a, op, addr, insn_descr, extra_descr, insn);
179 		}
180 	}
181 	else {
182 		/* otherwise basic descriptor is enough */
183 		insn_to_op(a, op, addr, insn_descr, NULL, insn);
184 	}
185 
186 	return op->size;
187 }
188 
189 RAnalPlugin r_anal_plugin_or1k = {
190 	.name = "or1k",
191 	.desc = "OpenRISC 1000",
192 	.license = "LGPL3",
193 	.bits = 32,
194 	.arch = "or1k",
195 	.esil = false,
196 	.op = &or1k_op,
197 };
198 
199 #ifndef R2_PLUGIN_INCORE
200 R_API RLibStruct radare_plugin = {
201 	.type = R_LIB_TYPE_ANAL,
202 	.data = &r_anal_plugin_or1k,
203 	.version = R2_VERSION
204 };
205 #endif
206