1 /* radare2 - LGPL - Copyright 2014-2015 - pancake */
2 
3 #include <r_asm.h>
4 #include <r_lib.h>
5 
analop(RAnal * a,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)6 static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
7 	int opsize = -1;
8 	op->type = -1;
9 	opsize = 2;
10 	switch (buf[0]) {
11 	case 0x3f:
12 	case 0x4f:
13 		op->type = R_ANAL_OP_TYPE_MOV;
14 		opsize = 4;
15 		break;
16 	case 0x6f:
17 		op->type = R_ANAL_OP_TYPE_MOV;
18 		opsize = 6;
19 		break;
20 	case 0x7f:
21 		op->type = R_ANAL_OP_TYPE_LEA;
22 		if (len > 5) {
23 			op->ptr = buf[2];
24 			op->ptr |= buf[3]<<8;
25 			op->ptr |= buf[4]<<16;
26 			op->ptr |= ((ut32)(0xff&buf[5]))<<24;
27 			op->ptr += addr;
28 			opsize = 6;
29 		} else {
30 			// error
31 			op->ptr = UT64_MAX;
32 		}
33 		break;
34 	case 0xbf: // bsr
35 		op->type = R_ANAL_OP_TYPE_CALL;
36 		if (len > 5) {
37 			st32 delta = buf[2];
38 			delta |= buf[3]<<8;
39 			delta |= buf[4]<<16;
40 			delta |= buf[5]<<24;
41 			op->jump = addr + delta;
42 		} else {
43 			op->jump = UT64_MAX;
44 		}
45 		op->fail = addr + 6;
46 		opsize = 6;
47 		break;
48 	case 0x00:
49 		if (buf[1] == 0x00) {
50 			op->type = R_ANAL_OP_TYPE_TRAP;
51 		} else {
52 			op->type = R_ANAL_OP_TYPE_JMP;
53 			{
54 				st8 delta = buf[0];
55 				op->jump = addr + delta;
56 			}
57 		}
58 		break;
59 	case 0xf0:
60 		if (buf[1]==0xb9) {
61 			op->type = R_ANAL_OP_TYPE_RET;
62 		}
63 		break;
64 	default:
65 		switch (buf[1]) {
66 		case 0x00:
67 			op->type = R_ANAL_OP_TYPE_CJMP; // BCC
68 			break;
69 		case 0xf3:
70 			op->type = R_ANAL_OP_TYPE_SHR;
71 			break;
72 		case 0x96: // move.d r, r
73 			if (buf[0] >=0xc0) {
74 				op->type = R_ANAL_OP_TYPE_CMP;
75 			} else {
76 				op->type = R_ANAL_OP_TYPE_MOV;
77 			}
78 			break;
79 		case 0xf2:
80 		case 0x0b:
81 		case 0x72:
82 			op->type = R_ANAL_OP_TYPE_CMP;
83 			break;
84 		case 0x05:
85 			if (buf[0] == 0xb0) {
86 				op->type = R_ANAL_OP_TYPE_NOP;
87 			}
88 			break;
89 		case 0x01:
90 		case 0x02:
91 		case 0xc2:
92 		case 0xf5:
93 		case 0x91:
94 		case 0x41:
95 		case 0x61:
96 		case 0x65:
97 			op->type = R_ANAL_OP_TYPE_ADD;
98 			break;
99 		case 0x12:
100 		case 0xf6:
101 		case 0xe2:
102 			op->type = R_ANAL_OP_TYPE_SUB;
103 			break;
104 		case 0x82: // moveq i, r
105 		case 0xba: // move.d [r], r
106 		case 0xeb: // move.d r, [r]
107 		case 0xc6: // move.d r, r
108 		case 0x92: // moveq i, r
109 		case 0x9b: // move.d i, r
110 		case 0xbe: // move [sp+], srp
111 		case 0x06:
112 		case 0x26:
113 		case 0xfb:
114 		case 0x9a:
115 		case 0xb2:
116 		case 0xda:
117 		case 0x2b:
118 		case 0x6f:
119 		case 0xa2:
120 		case 0x2f:
121 		case 0x8b:
122 		case 0x1b:
123 		case 0xaa:
124 		case 0xa6:
125 		case 0xb6:
126 			op->type = R_ANAL_OP_TYPE_MOV;
127 			break;
128 		case 0xe0:
129 			op->type = R_ANAL_OP_TYPE_JMP;
130 			{
131 				st8 delta = buf[0];
132 				op->jump = addr + delta;
133 			}
134 			break;
135 		case 0x10:
136 		case 0x30:
137 		case 0x20:
138 		case 0x2d:
139 			op->type = R_ANAL_OP_TYPE_CJMP;
140 			op->jump = addr + buf[0];
141 			op->fail = addr + 2; // delay slot here?
142 			break;
143 		case 0xbf:
144 			op->type = R_ANAL_OP_TYPE_CALL; // bsr
145 			break;
146 		case 0xb9:
147 			op->type = R_ANAL_OP_TYPE_UJMP; // jsr reg
148 			break;
149 		}
150 	}
151 #if 0
152 	switch (*buf) {
153 	case 0x3f: // adds.w N, R
154 		opsize = 4;
155 	case 0x01:
156 	case 0x53: // addi, acr.w, r3, acr
157 	case 0x04:
158 	case 0x61:
159 	case 0x62:
160 	case 0x63:
161 		op->type = R_ANAL_OP_TYPE_ADD;
162 		break;
163 	case 0x88:
164 	case 0x84:
165 	case 0x81:
166 	case 0x8c:
167 	case 0xad:
168 		op->type = R_ANAL_OP_TYPE_SUB;
169 		break;
170 	case 0x7f: // lapc <addr>, <reg>
171 		op->type = R_ANAL_OP_TYPE_LEA;
172 		break;
173 	case 0xcf:
174 	case 0xbe:
175 	case 0x60:
176 	case 0x6f:
177 	case 0x6a: // move.d reg, reg
178 	case 0x7e:
179 	case 0xfe:
180 		op->type = R_ANAL_OP_TYPE_MOV;
181 		break;
182 	case 0x00:
183 		op->type = R_ANAL_OP_TYPE_JMP;
184 		// jsr acr
185 		break;
186 	case 0xff:
187 		opsize = 6;
188 	case 0x14:
189 	case 0x0e:
190 	case 0x1a:
191 	case 0x9c:
192 	case 0x6d: // bne
193 		op->type = R_ANAL_OP_TYPE_CJMP;
194 		// jsr acr
195 		break;
196 	case 0xbf:
197 		opsize = 6;
198 	case 0xb1:
199 	case 0xb2:
200 	case 0xb3:
201 	case 0xb4:
202 	case 0xb5:
203 	case 0xb6:
204 	case 0xb7:
205 	case 0xb8:
206 	case 0xb9:
207 		op->type = R_ANAL_OP_TYPE_UJMP;
208 		// jsr acr
209 		break;
210 	case 0x8f: // test.b [acr]
211 	case 0xc0:
212 	case 0xe1:
213 	case 0xaa:
214 		op->type = R_ANAL_OP_TYPE_CMP;
215 		break;
216 	default:
217 		switch (*w) {
218 		case 0xb0b9: //// jsr r0
219 			op->type = R_ANAL_OP_TYPE_CJMP;
220 			break;
221 		case 0xb005:
222 		case 0x05b0:
223 			op->type = R_ANAL_OP_TYPE_NOP;
224 			break;
225 		case 0xf0b9:
226 		case 0xb9f0:
227 			op->type = R_ANAL_OP_TYPE_RET;
228 			break;
229 		default:
230 			op->type = R_ANAL_OP_TYPE_MOV;
231 			break;
232 		}
233 	}
234 #endif
235 	op->size = opsize;
236 	//op->delay = 1;
237 	return opsize;
238 }
239 
set_reg_profile(RAnal * anal)240 static bool set_reg_profile(RAnal *anal) {
241 	const char *p =
242 		"=PC	pc\n"
243 		"=SP	r14\n" // XXX
244 		"=BP	srp\n" // XXX
245 		"=A0	r0\n"
246 		"=A1	r1\n"
247 		"=A2	r2\n"
248 		"=A3	r3\n"
249 		"gpr	sp	.32	56	0\n" // r14
250 		"gpr	acr	.32	60	0\n" // r15
251 		"gpr	pc	.32	64	0\n" // r16 // out of context
252 		"gpr	srp	.32	68	0\n" // like rbp on x86 // out of context
253 		// GPR
254 		"gpr	r0	.32	0	0\n"
255 		"gpr	r1	.32	4	0\n"
256 		"gpr	r2	.32	8	0\n"
257 		"gpr	r3	.32	12	0\n"
258 		"gpr	r4	.32	16	0\n"
259 		"gpr	r5	.32	20	0\n"
260 		"gpr	r6	.32	24	0\n"
261 		"gpr	r7	.32	28	0\n"
262 		"gpr	r8	.32	32	0\n"
263 		"gpr	r9	.32	36	0\n"
264 		"gpr	r10	.32	40	0\n"
265 		"gpr	r11	.32	44	0\n"
266 		"gpr	r12	.32	48	0\n"
267 		"gpr	r13	.32	52	0\n"
268 
269 		// STACK POINTER
270 		"gpr	r14	.32	56	0\n"
271 		"gpr	r15	.32	60	0\n"
272 		// ADD P REGISTERS
273 		;
274 	return r_reg_set_profile_string (anal->reg, p);
275 }
276 
277 RAnalPlugin r_anal_plugin_cris = {
278 	.name = "cris",
279 	.desc = "Axis Communications 32-bit embedded processor",
280 	.license = "LGPL3",
281 	.esil = false,
282 	.arch = "cris",
283 	.set_reg_profile = set_reg_profile,
284 	.bits = 32,
285 	.op = &analop,
286 };
287 
288 #ifndef R2_PLUGIN_INCORE
289 R_API RLibStruct radare_plugin = {
290 	.type = R_LIB_TYPE_ANAL,
291 	.data = &r_anal_plugin_cris,
292 	.version = R2_VERSION
293 };
294 #endif
295