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