1 /* radare2 - LGPL - Copyright 2015-2018 - pancake */
2 
3 #include <r_asm.h>
4 #include <r_lib.h>
5 #include <capstone.h>
6 
7 #ifdef CAPSTONE_M68K_H
8 #define CAPSTONE_HAS_M68K 1
9 #else
10 #define CAPSTONE_HAS_M68K 0
11 #ifdef _MSC_VER
12 #pragma message ("Cannot find capstone-m68k support")
13 #else
14 #warning Cannot find capstone-m68k support
15 #endif
16 #endif
17 
18 #if CAPSTONE_HAS_M68K
19 #include <m68k.h>
20 // http://www.mrc.uidaho.edu/mrc/people/jff/digital/M68Kir.html
21 
22 #define OPERAND(x) insn->detail->m68k.operands[x]
23 #define REG(x) cs_reg_name (*handle, insn->detail->m68k.operands[x].reg)
24 #define IMM(x) insn->detail->m68k.operands[x].imm
25 #define MEMBASE(x) cs_reg_name(*handle, insn->detail->m68k.operands[x].mem.base)
26 #define MEMINDEX(x) insn->detail->m68k.operands[x].mem.index
27 #define MEMDISP(x) insn->detail->m68k.operands[x].mem.disp
28 
make_64bits_address(ut64 address)29 static inline ut64 make_64bits_address(ut64 address) {
30 	return UT32_MAX & address;
31 }
32 
handle_branch_instruction(RAnalOp * op,ut64 addr,cs_m68k * m68k,ut32 type,int index)33 static inline void handle_branch_instruction(RAnalOp *op, ut64 addr, cs_m68k *m68k, ut32 type, int index) {
34 #if CS_API_MAJOR >= 4
35 		if (m68k->operands[index].type == M68K_OP_BR_DISP) {
36 			op->type = type;
37 			// TODO: disp_size is ignored
38 			op->jump = make_64bits_address (addr + m68k->operands[index].br_disp.disp + 2);
39 			op->fail = make_64bits_address (addr + op->size);
40 		}
41 #else
42 		op->type = type;
43 		// TODO: disp_size is ignored
44 		op->jump = make_64bits_address (addr + m68k->operands[index].br_disp.disp + 2);
45 		op->fail = make_64bits_address (addr + op->size);
46 #endif
47 }
48 
handle_jump_instruction(RAnalOp * op,ut64 addr,cs_m68k * m68k,ut32 type)49 static inline void handle_jump_instruction(RAnalOp *op, ut64 addr, cs_m68k *m68k, ut32 type) {
50 	op->type = type;
51 
52 	// Handle PC relative mode jump
53 	if (m68k->operands[0].address_mode == M68K_AM_PCI_DISP) {
54 		op->jump = make_64bits_address (addr + m68k->operands[0].mem.disp + 2);
55 	} else {
56 		op->jump = make_64bits_address (m68k->operands[0].imm);
57 	}
58 
59 	op->fail = make_64bits_address (addr + op->size);
60 }
61 
opex(RStrBuf * buf,csh handle,cs_insn * insn)62 static void opex(RStrBuf *buf, csh handle, cs_insn *insn) {
63 	int i;
64 	PJ *pj = pj_new ();
65 	if (!pj) {
66 		return;
67 	}
68 	pj_o (pj);
69 	cs_m68k *x = &insn->detail->m68k;
70 	pj_ka (pj, "operands");
71 	for (i = 0; i < x->op_count; i++) {
72 		cs_m68k_op *op = x->operands + i;
73 		pj_o (pj);
74 		switch (op->type) {
75 		case M68K_OP_REG:
76 			pj_ks (pj, "type", "reg");
77 			pj_ks (pj, "value", cs_reg_name (handle, op->reg));
78 			break;
79 		case M68K_OP_IMM:
80 			pj_ks (pj, "type", "imm");
81 			pj_kN (pj, "value", (st64)op->imm);
82 			break;
83 		case M68K_OP_MEM:
84 			pj_ks (pj, "type", "mem");
85 			if (op->mem.base_reg != M68K_REG_INVALID) {
86 				pj_ks (pj, "base_reg", cs_reg_name (handle, op->mem.base_reg));
87 			}
88 			if (op->mem.index_reg != M68K_REG_INVALID) {
89 				pj_ks (pj, "index_reg", cs_reg_name (handle, op->mem.index_reg));
90 			}
91 			if (op->mem.in_base_reg != M68K_REG_INVALID) {
92 				pj_ks (pj, "in_base_reg", cs_reg_name (handle, op->mem.in_base_reg));
93 			}
94 			pj_kN (pj, "in_disp", op->mem.in_disp);
95 			pj_kN (pj, "out_disp", op->mem.out_disp);
96 			pj_ki (pj, "disp", op->mem.disp);
97 			pj_ki (pj, "scale", op->mem.scale);
98 			pj_ki (pj, "bitfield", op->mem.bitfield);
99 			pj_ki (pj, "width", op->mem.width);
100 			pj_ki (pj, "offset", op->mem.offset);
101 			pj_ki (pj, "index_size", op->mem.index_size);
102 			break;
103 		default:
104 			pj_ks (pj, "type", "invalid");
105 			break;
106 		}
107 		pj_end (pj); /* o operand */
108 	}
109 	pj_end (pj); /* a operands */
110 	pj_end (pj);
111 
112 	r_strbuf_init (buf);
113 	r_strbuf_append (buf, pj_string (pj));
114 	pj_free (pj);
115 }
116 
parse_reg_name(RRegItem * reg,csh handle,cs_insn * insn,int reg_num)117 static int parse_reg_name(RRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
118 	if (!reg) {
119 		return -1;
120 	}
121 	switch (OPERAND (reg_num).type) {
122 	case M68K_OP_REG:
123 		reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).reg);
124 		break;
125 	case M68K_OP_MEM:
126 		if (OPERAND (reg_num).mem.base_reg != M68K_REG_INVALID) {
127 			reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).mem.base_reg);
128 		}
129 		break;
130 	default:
131 		break;
132 	}
133 	return 0;
134 }
135 
op_fillval(RAnalOp * op,csh handle,cs_insn * insn)136 static void op_fillval(RAnalOp *op, csh handle, cs_insn *insn) {
137 	static RRegItem reg;
138 	switch (op->type & R_ANAL_OP_TYPE_MASK) {
139 	case R_ANAL_OP_TYPE_MOV:
140 		ZERO_FILL (reg);
141 		if (OPERAND(1).type == M68K_OP_MEM) {
142 			op->src[0] = r_anal_value_new ();
143 			op->src[0]->reg = &reg;
144 			parse_reg_name (op->src[0]->reg, handle, insn, 1);
145 			op->src[0]->delta = OPERAND(0).mem.disp;
146 		} else if (OPERAND(0).type == M68K_OP_MEM) {
147 			op->dst = r_anal_value_new ();
148 			op->dst->reg = &reg;
149 			parse_reg_name (op->dst->reg, handle, insn, 0);
150 			op->dst->delta = OPERAND(1).mem.disp;
151 		}
152 		break;
153 	case R_ANAL_OP_TYPE_LEA:
154 		ZERO_FILL (reg);
155 		if (OPERAND(1).type == M68K_OP_MEM) {
156 			op->dst = r_anal_value_new ();
157 			op->dst->reg = &reg;
158 			parse_reg_name (op->dst->reg, handle, insn, 1);
159 			op->dst->delta = OPERAND(1).mem.disp;
160 		}
161 		break;
162 	}
163 }
164 
analop(RAnal * a,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)165 static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
166 	int n, ret, opsize = -1;
167 	static csh handle = 0;
168 	static int omode = -1;
169 	static int obits = 32;
170 	cs_insn* insn;
171 	cs_m68k *m68k;
172 	cs_detail *detail;
173 
174 	int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;
175 
176 	//mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32;
177 	if (mode != omode || a->bits != obits) {
178 		cs_close (&handle);
179 		handle = 0;
180 		omode = mode;
181 		obits = a->bits;
182 	}
183 // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64
184 	// replace this with the asm.features?
185 	if (a->cpu && strstr (a->cpu, "68000")) {
186 		mode |= CS_MODE_M68K_000;
187 	}
188 	if (a->cpu && strstr (a->cpu, "68010")) {
189 		mode |= CS_MODE_M68K_010;
190 	}
191 	if (a->cpu && strstr (a->cpu, "68020")) {
192 		mode |= CS_MODE_M68K_020;
193 	}
194 	if (a->cpu && strstr (a->cpu, "68030")) {
195 		mode |= CS_MODE_M68K_030;
196 	}
197 	if (a->cpu && strstr (a->cpu, "68040")) {
198 		mode |= CS_MODE_M68K_040;
199 	}
200 	if (a->cpu && strstr (a->cpu, "68060")) {
201 		mode |= CS_MODE_M68K_060;
202 	}
203 	op->size = 4;
204 	if (handle == 0) {
205 		ret = cs_open (CS_ARCH_M68K, mode, &handle);
206 		if (ret != CS_ERR_OK) {
207 			goto fin;
208 		}
209 		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
210 	}
211 	n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn);
212 	if (n < 1 || insn->size < 1) {
213 		op->type = R_ANAL_OP_TYPE_ILL;
214 		op->size = 2;
215 		opsize = -1;
216 		goto beach;
217 	}
218 	if (!memcmp (buf, "\xff\xff", R_MIN (len, 2))) {
219 		op->type = R_ANAL_OP_TYPE_ILL;
220 		op->size = 2;
221 		opsize = -1;
222 		goto beach;
223 	}
224 	detail = insn->detail;
225 	m68k = &detail->m68k;
226 	op->id = insn->id;
227 	opsize = op->size = insn->size;
228 	if (mask & R_ANAL_OP_MASK_OPEX) {
229 		opex (&op->opex, handle, insn);
230 	}
231 	switch (insn->id) {
232 	case M68K_INS_INVALID:
233 		op->type  = R_ANAL_OP_TYPE_ILL;
234 		break;
235 	case M68K_INS_ADD:
236 	case M68K_INS_ADDA:
237 	case M68K_INS_ADDI:
238 	case M68K_INS_ADDQ:
239 	case M68K_INS_ADDX:
240 		op->type  = R_ANAL_OP_TYPE_ADD;
241 		break;
242 	case M68K_INS_AND:
243 	case M68K_INS_ANDI:
244 		op->type  = R_ANAL_OP_TYPE_AND;
245 		break;
246 	case M68K_INS_ASL:
247 		op->type  = R_ANAL_OP_TYPE_SHL;
248 		break;
249 	case M68K_INS_ASR:
250 		op->type  = R_ANAL_OP_TYPE_SHR;
251 		break;
252 	case M68K_INS_ABCD:
253 		break;
254 	case M68K_INS_BHS:
255 	case M68K_INS_BLO:
256 	case M68K_INS_BHI:
257 	case M68K_INS_BLS:
258 	case M68K_INS_BCC:
259 	case M68K_INS_BCS:
260 	case M68K_INS_BNE:
261 	case M68K_INS_BEQ:
262 	case M68K_INS_BVC:
263 	case M68K_INS_BVS:
264 	case M68K_INS_BPL:
265 	case M68K_INS_BMI:
266 	case M68K_INS_BGE:
267 	case M68K_INS_BLT:
268 	case M68K_INS_BGT:
269 	case M68K_INS_BLE:
270 		handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CJMP, 0);
271 		break;
272 	case M68K_INS_BRA:
273 		handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_JMP, 0);
274 		break;
275 	case M68K_INS_BSR:
276 		handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CALL, 0);
277 		break;
278 	case M68K_INS_BCHG:
279 	case M68K_INS_BCLR:
280 	case M68K_INS_BSET:
281 	case M68K_INS_BTST:
282 	case M68K_INS_BFCHG:
283 	case M68K_INS_BFCLR:
284 	case M68K_INS_BFEXTS:
285 	case M68K_INS_BFEXTU:
286 	case M68K_INS_BFFFO:
287 	case M68K_INS_BFINS:
288 	case M68K_INS_BFSET:
289 	case M68K_INS_BFTST:
290 	case M68K_INS_BKPT:
291 	case M68K_INS_CALLM:
292 	case M68K_INS_CAS:
293 	case M68K_INS_CAS2:
294 	case M68K_INS_CHK:
295 	case M68K_INS_CHK2:
296 	case M68K_INS_CLR:
297 		// TODO:
298 		break;
299 	case M68K_INS_CMP:
300 	case M68K_INS_CMPA:
301 	case M68K_INS_CMPI:
302 	case M68K_INS_CMPM:
303 	case M68K_INS_CMP2:
304 		op->type = R_ANAL_OP_TYPE_CMP;
305 		break;
306 	case M68K_INS_CINVL:
307 	case M68K_INS_CINVP:
308 	case M68K_INS_CINVA:
309 		op->type = R_ANAL_OP_TYPE_ILL;
310 		break;
311 	case M68K_INS_CPUSHL:
312 	case M68K_INS_CPUSHP:
313 	case M68K_INS_CPUSHA:
314 		break;
315 	case M68K_INS_DBT:
316 	case M68K_INS_DBF:
317 	case M68K_INS_DBHI:
318 	case M68K_INS_DBLS:
319 	case M68K_INS_DBCC:
320 	case M68K_INS_DBCS:
321 	case M68K_INS_DBNE:
322 	case M68K_INS_DBEQ:
323 	case M68K_INS_DBVC:
324 	case M68K_INS_DBVS:
325 	case M68K_INS_DBPL:
326 	case M68K_INS_DBMI:
327 	case M68K_INS_DBGE:
328 	case M68K_INS_DBLT:
329 	case M68K_INS_DBGT:
330 	case M68K_INS_DBLE:
331 	case M68K_INS_DBRA:
332 		handle_branch_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CJMP, 1);
333 		break;
334 	case M68K_INS_DIVS:
335 	case M68K_INS_DIVSL:
336 	case M68K_INS_DIVU:
337 	case M68K_INS_DIVUL:
338 		op->type = R_ANAL_OP_TYPE_DIV;
339 		break;
340 	case M68K_INS_EOR:
341 	case M68K_INS_EORI:
342 		op->type = R_ANAL_OP_TYPE_XOR;
343 		break;
344 	case M68K_INS_EXG:
345 		op->type = R_ANAL_OP_TYPE_MOV;
346 		break;
347 	case M68K_INS_EXT:
348 	case M68K_INS_EXTB:
349 		break;
350 	case M68K_INS_FABS:
351 	case M68K_INS_FSABS:
352 	case M68K_INS_FDABS:
353 	case M68K_INS_FACOS:
354 	case M68K_INS_FADD:
355 	case M68K_INS_FSADD:
356 	case M68K_INS_FDADD:
357 	case M68K_INS_FASIN:
358 	case M68K_INS_FATAN:
359 	case M68K_INS_FATANH:
360 	case M68K_INS_FBF:
361 	case M68K_INS_FBEQ:
362 	case M68K_INS_FBOGT:
363 	case M68K_INS_FBOGE:
364 	case M68K_INS_FBOLT:
365 	case M68K_INS_FBOLE:
366 	case M68K_INS_FBOGL:
367 	case M68K_INS_FBOR:
368 	case M68K_INS_FBUN:
369 	case M68K_INS_FBUEQ:
370 	case M68K_INS_FBUGT:
371 	case M68K_INS_FBUGE:
372 	case M68K_INS_FBULT:
373 	case M68K_INS_FBULE:
374 	case M68K_INS_FBNE:
375 	case M68K_INS_FBT:
376 	case M68K_INS_FBSF:
377 	case M68K_INS_FBSEQ:
378 	case M68K_INS_FBGT:
379 	case M68K_INS_FBGE:
380 	case M68K_INS_FBLT:
381 	case M68K_INS_FBLE:
382 	case M68K_INS_FBGL:
383 	case M68K_INS_FBGLE:
384 	case M68K_INS_FBNGLE:
385 	case M68K_INS_FBNGL:
386 	case M68K_INS_FBNLE:
387 	case M68K_INS_FBNLT:
388 	case M68K_INS_FBNGE:
389 	case M68K_INS_FBNGT:
390 	case M68K_INS_FBSNE:
391 	case M68K_INS_FBST:
392 	case M68K_INS_FCMP:
393 	case M68K_INS_FCOS:
394 	case M68K_INS_FCOSH:
395 	case M68K_INS_FDBF:
396 	case M68K_INS_FDBEQ:
397 	case M68K_INS_FDBOGT:
398 	case M68K_INS_FDBOGE:
399 	case M68K_INS_FDBOLT:
400 	case M68K_INS_FDBOLE:
401 	case M68K_INS_FDBOGL:
402 	case M68K_INS_FDBOR:
403 	case M68K_INS_FDBUN:
404 	case M68K_INS_FDBUEQ:
405 	case M68K_INS_FDBUGT:
406 	case M68K_INS_FDBUGE:
407 	case M68K_INS_FDBULT:
408 	case M68K_INS_FDBULE:
409 	case M68K_INS_FDBNE:
410 	case M68K_INS_FDBT:
411 	case M68K_INS_FDBSF:
412 	case M68K_INS_FDBSEQ:
413 	case M68K_INS_FDBGT:
414 	case M68K_INS_FDBGE:
415 	case M68K_INS_FDBLT:
416 	case M68K_INS_FDBLE:
417 	case M68K_INS_FDBGL:
418 	case M68K_INS_FDBGLE:
419 	case M68K_INS_FDBNGLE:
420 	case M68K_INS_FDBNGL:
421 	case M68K_INS_FDBNLE:
422 	case M68K_INS_FDBNLT:
423 	case M68K_INS_FDBNGE:
424 	case M68K_INS_FDBNGT:
425 	case M68K_INS_FDBSNE:
426 	case M68K_INS_FDBST:
427 	case M68K_INS_FDIV:
428 	case M68K_INS_FSDIV:
429 	case M68K_INS_FDDIV:
430 	case M68K_INS_FETOX:
431 	case M68K_INS_FETOXM1:
432 	case M68K_INS_FGETEXP:
433 	case M68K_INS_FGETMAN:
434 	case M68K_INS_FINT:
435 	case M68K_INS_FINTRZ:
436 	case M68K_INS_FLOG10:
437 	case M68K_INS_FLOG2:
438 	case M68K_INS_FLOGN:
439 	case M68K_INS_FLOGNP1:
440 	case M68K_INS_FMOD:
441 	case M68K_INS_FMOVE:
442 	case M68K_INS_FSMOVE:
443 	case M68K_INS_FDMOVE:
444 	case M68K_INS_FMOVECR:
445 	case M68K_INS_FMOVEM:
446 	case M68K_INS_FMUL:
447 	case M68K_INS_FSMUL:
448 	case M68K_INS_FDMUL:
449 	case M68K_INS_FNEG:
450 	case M68K_INS_FSNEG:
451 	case M68K_INS_FDNEG:
452 	case M68K_INS_FNOP:
453 	case M68K_INS_FREM:
454 	case M68K_INS_FRESTORE:
455 	case M68K_INS_FSAVE:
456 	case M68K_INS_FSCALE:
457 	case M68K_INS_FSGLDIV:
458 	case M68K_INS_FSGLMUL:
459 	case M68K_INS_FSIN:
460 	case M68K_INS_FSINCOS:
461 	case M68K_INS_FSINH:
462 	case M68K_INS_FSQRT:
463 	case M68K_INS_FSSQRT:
464 	case M68K_INS_FDSQRT:
465 	case M68K_INS_FSF:
466 	case M68K_INS_FSBEQ:
467 	case M68K_INS_FSOGT:
468 	case M68K_INS_FSOGE:
469 	case M68K_INS_FSOLT:
470 	case M68K_INS_FSOLE:
471 	case M68K_INS_FSOGL:
472 	case M68K_INS_FSOR:
473 	case M68K_INS_FSUN:
474 	case M68K_INS_FSUEQ:
475 	case M68K_INS_FSUGT:
476 	case M68K_INS_FSUGE:
477 	case M68K_INS_FSULT:
478 	case M68K_INS_FSULE:
479 	case M68K_INS_FSNE:
480 	case M68K_INS_FST:
481 	case M68K_INS_FSSF:
482 	case M68K_INS_FSSEQ:
483 	case M68K_INS_FSGT:
484 	case M68K_INS_FSGE:
485 	case M68K_INS_FSLT:
486 	case M68K_INS_FSLE:
487 	case M68K_INS_FSGL:
488 	case M68K_INS_FSGLE:
489 	case M68K_INS_FSNGLE:
490 	case M68K_INS_FSNGL:
491 	case M68K_INS_FSNLE:
492 	case M68K_INS_FSNLT:
493 	case M68K_INS_FSNGE:
494 	case M68K_INS_FSNGT:
495 	case M68K_INS_FSSNE:
496 	case M68K_INS_FSST:
497 	case M68K_INS_FSUB:
498 	case M68K_INS_FSSUB:
499 	case M68K_INS_FDSUB:
500 	case M68K_INS_FTAN:
501 	case M68K_INS_FTANH:
502 	case M68K_INS_FTENTOX:
503 	case M68K_INS_FTRAPF:
504 	case M68K_INS_FTRAPEQ:
505 	case M68K_INS_FTRAPOGT:
506 	case M68K_INS_FTRAPOGE:
507 	case M68K_INS_FTRAPOLT:
508 	case M68K_INS_FTRAPOLE:
509 	case M68K_INS_FTRAPOGL:
510 	case M68K_INS_FTRAPOR:
511 	case M68K_INS_FTRAPUN:
512 	case M68K_INS_FTRAPUEQ:
513 	case M68K_INS_FTRAPUGT:
514 	case M68K_INS_FTRAPUGE:
515 	case M68K_INS_FTRAPULT:
516 	case M68K_INS_FTRAPULE:
517 	case M68K_INS_FTRAPNE:
518 	case M68K_INS_FTRAPT:
519 	case M68K_INS_FTRAPSF:
520 	case M68K_INS_FTRAPSEQ:
521 	case M68K_INS_FTRAPGT:
522 	case M68K_INS_FTRAPGE:
523 	case M68K_INS_FTRAPLT:
524 	case M68K_INS_FTRAPLE:
525 	case M68K_INS_FTRAPGL:
526 	case M68K_INS_FTRAPGLE:
527 	case M68K_INS_FTRAPNGLE:
528 	case M68K_INS_FTRAPNGL:
529 	case M68K_INS_FTRAPNLE:
530 	case M68K_INS_FTRAPNLT:
531 	case M68K_INS_FTRAPNGE:
532 	case M68K_INS_FTRAPNGT:
533 	case M68K_INS_FTRAPSNE:
534 	case M68K_INS_FTRAPST:
535 	case M68K_INS_FTST:
536 	case M68K_INS_FTWOTOX:
537 		op->type = R_ANAL_OP_TYPE_UNK;
538 		op->family = R_ANAL_OP_FAMILY_FPU;
539 		break;
540 	case M68K_INS_HALT:
541 		op->type = R_ANAL_OP_TYPE_NOP;
542 		break;
543 	case M68K_INS_ILLEGAL:
544 		op->type = R_ANAL_OP_TYPE_ILL;
545 		break;
546 	case M68K_INS_JMP:
547 		handle_jump_instruction (op, addr, m68k, R_ANAL_OP_TYPE_JMP);
548 		break;
549 	case M68K_INS_JSR:
550 		handle_jump_instruction (op, addr, m68k, R_ANAL_OP_TYPE_CALL);
551 		break;
552 	case M68K_INS_LPSTOP:
553 		op->type = R_ANAL_OP_TYPE_NOP;
554 		break;
555 	case M68K_INS_LSL:
556 		op->type = R_ANAL_OP_TYPE_SHL;
557 		break;
558 	case M68K_INS_LINK:
559 		op->type = R_ANAL_OP_TYPE_PUSH;
560 		op->stackop = R_ANAL_STACK_INC;
561 		op->stackptr = -(st16)IMM(1);
562 		break;
563 	case M68K_INS_LSR:
564 		op->type = R_ANAL_OP_TYPE_SHR;
565 		break;
566 	case M68K_INS_PEA:
567 	case M68K_INS_LEA:
568 		op->type = R_ANAL_OP_TYPE_LEA;
569 		break;
570 	case M68K_INS_MOVE:
571 	case M68K_INS_MOVEA:
572 	case M68K_INS_MOVEC:
573 	case M68K_INS_MOVEM:
574 	case M68K_INS_MOVEP:
575 	case M68K_INS_MOVEQ:
576 	case M68K_INS_MOVES:
577 	case M68K_INS_MOVE16:
578 		op->type = R_ANAL_OP_TYPE_MOV;
579 		break;
580 	case M68K_INS_MULS:
581 	case M68K_INS_MULU:
582 		op->type = R_ANAL_OP_TYPE_MUL;
583 		break;
584 	case M68K_INS_NBCD:
585 	case M68K_INS_NEG:
586 	case M68K_INS_NEGX:
587 		break;
588 	case M68K_INS_NOP:
589 		op->type = R_ANAL_OP_TYPE_NOP;
590 		break;
591 	case M68K_INS_NOT:
592 		op->type = R_ANAL_OP_TYPE_NOT;
593 		break;
594 	case M68K_INS_OR:
595 	case M68K_INS_ORI:
596 		op->type = R_ANAL_OP_TYPE_OR;
597 		break;
598 	case M68K_INS_PACK:
599 	case M68K_INS_PFLUSH:
600 	case M68K_INS_PFLUSHA:
601 	case M68K_INS_PFLUSHAN:
602 	case M68K_INS_PFLUSHN:
603 	case M68K_INS_PLOADR:
604 	case M68K_INS_PLOADW:
605 	case M68K_INS_PLPAR:
606 	case M68K_INS_PLPAW:
607 	case M68K_INS_PMOVE:
608 	case M68K_INS_PMOVEFD:
609 	case M68K_INS_PTESTR:
610 	case M68K_INS_PTESTW:
611 	case M68K_INS_PULSE:
612 	case M68K_INS_REMS:
613 	case M68K_INS_REMU:
614 	case M68K_INS_RESET:
615 		break;
616 	case M68K_INS_ROL:
617 		op->type = R_ANAL_OP_TYPE_ROL;
618 		break;
619 	case M68K_INS_ROR:
620 		op->type = R_ANAL_OP_TYPE_ROR;
621 		break;
622 	case M68K_INS_ROXL:
623 	case M68K_INS_ROXR:
624 		break;
625 	case M68K_INS_RTD:
626 	case M68K_INS_RTE:
627 	case M68K_INS_RTM:
628 	case M68K_INS_RTR:
629 	case M68K_INS_RTS:
630 		op->type = R_ANAL_OP_TYPE_RET;
631 		break;
632 	case M68K_INS_SBCD:
633 	case M68K_INS_ST:
634 	case M68K_INS_SF:
635 	case M68K_INS_SHI:
636 	case M68K_INS_SLS:
637 	case M68K_INS_SCC:
638 	case M68K_INS_SHS:
639 	case M68K_INS_SCS:
640 	case M68K_INS_SLO:
641 	case M68K_INS_SNE:
642 	case M68K_INS_SEQ:
643 	case M68K_INS_SVC:
644 	case M68K_INS_SVS:
645 	case M68K_INS_SPL:
646 	case M68K_INS_SMI:
647 	case M68K_INS_SGE:
648 	case M68K_INS_SLT:
649 	case M68K_INS_SGT:
650 	case M68K_INS_SLE:
651 	case M68K_INS_STOP:
652 		break;
653 	case M68K_INS_SUB:
654 	case M68K_INS_SUBA:
655 	case M68K_INS_SUBI:
656 	case M68K_INS_SUBQ:
657 	case M68K_INS_SUBX:
658 		op->type = R_ANAL_OP_TYPE_SUB;
659 		break;
660 	case M68K_INS_SWAP:
661 		op->type = R_ANAL_OP_TYPE_MOV;
662 		break;
663 	case M68K_INS_TAS:
664 		break;
665 	case M68K_INS_TRAP:
666 	case M68K_INS_TRAPV:
667 	case M68K_INS_TRAPT:
668 	case M68K_INS_TRAPF:
669 	case M68K_INS_TRAPHI:
670 	case M68K_INS_TRAPLS:
671 	case M68K_INS_TRAPCC:
672 	case M68K_INS_TRAPHS:
673 	case M68K_INS_TRAPCS:
674 	case M68K_INS_TRAPLO:
675 	case M68K_INS_TRAPNE:
676 	case M68K_INS_TRAPEQ:
677 	case M68K_INS_TRAPVC:
678 	case M68K_INS_TRAPVS:
679 	case M68K_INS_TRAPPL:
680 	case M68K_INS_TRAPMI:
681 	case M68K_INS_TRAPGE:
682 	case M68K_INS_TRAPLT:
683 	case M68K_INS_TRAPGT:
684 	case M68K_INS_TRAPLE:
685 		op->type = R_ANAL_OP_TYPE_TRAP;
686 		break;
687 	case M68K_INS_TST:
688 		op->type = R_ANAL_OP_TYPE_CMP;
689 		break;
690 	case M68K_INS_UNPK: // unpack BCD
691 		op->type = R_ANAL_OP_TYPE_MOV;
692 		break;
693 	case M68K_INS_UNLK:
694 		op->type = R_ANAL_OP_TYPE_POP;
695 		// reset stackframe
696 		op->stackop = R_ANAL_STACK_SET;
697 		op->stackptr = 0;
698 		break;
699 	}
700 	if (mask & R_ANAL_OP_MASK_VAL) {
701 		op_fillval (op, handle, insn);
702 	}
703 beach:
704 	cs_free (insn, n);
705 	//cs_close (&handle);
706 fin:
707 	return opsize;
708 }
709 
set_reg_profile(RAnal * anal)710 static bool set_reg_profile(RAnal *anal) {
711 	const char *p = \
712 		"=PC    pc\n"
713 		"=SP    a7\n"
714 		"=BP    a6\n"
715 		"=A0    a0\n"
716 		"=A1    a1\n"
717 		"=A2    a2\n"
718 		"=A3    a3\n"
719 		"gpr	d0	.32	0	0\n"
720 		"gpr	d1	.32	4	0\n"
721 		"gpr	d2	.32	8	0\n"
722 		"gpr	d3	.32	12	0\n"
723 		"gpr	d4	.32	16	0\n"
724 		"gpr	d5	.32	20	0\n"
725 		"gpr	d6	.32	24	0\n"
726 		"gpr	d7	.32	28	0\n"
727 		"gpr	a0	.32	32	0\n"
728 		"gpr	a1	.32	36	0\n"
729 		"gpr	a2 	.32	40	0\n"
730 		"gpr	a3 	.32	44	0\n"
731 		"gpr	a4 	.32	48	0\n"
732 		"gpr	a5	.32	52	0\n"
733 		"gpr	a6 	.32	56	0\n"
734 		"gpr	a7 	.32	60	0\n"
735 		"gpr	fp0	.32	64	0\n" //FPU register 0, 96bits to write and read max
736 		"gpr	fp1	.32	68	0\n" //FPU register 1, 96bits to write and read max
737 		"gpr	fp2	.32	72	0\n" //FPU register 2, 96bits to write and read max
738 		"gpr	fp3 	.32	76	0\n" //FPU register 3, 96bits to write and read max
739 		"gpr	fp4 	.32	80	0\n" //FPU register 4, 96bits to write and read max
740 		"gpr	fp5 	.32	84	0\n" //FPU register 5, 96bits to write and read max
741 		"gpr	fp6 	.32	88	0\n" //FPU register 6, 96bits to write and read max
742 		"gpr	fp7 	.32	92	0\n" //FPU register 7, 96bits to write and read max
743 		"gpr	pc 	.32	96	0\n"
744 		"gpr	sr 	.32	100	0\n" //only available for read and write access during supervisor mode 16bit
745 		"gpr	ccr 	.32	104	0\n" //subset of the SR, available from any mode
746 		"gpr	sfc 	.32	108	0\n" //source function code register
747 		"gpr	dfc	.32	112	0\n" //destination function code register
748 		"gpr	usp	.32	116	0\n" //user stack point this is an shadow register of A7 user mode, SR bit 0xD is 0
749 		"gpr	vbr	.32	120	0\n" //vector base register, this is a Address pointer
750 		"gpr	cacr	.32	124	0\n" //cache control register, implementation specific
751 		"gpr	caar	.32	128	0\n" //cache address register, 68020, 68EC020, 68030 and 68EC030 only.
752 		"gpr	msp	.32	132	0\n" //master stack pointer, this is an shadow register of A7 supervisor mode, SR bits 0xD && 0xC are set
753 		"gpr	isp	.32	136	0\n" //interrupt stack pointer, this is an shadow register of A7  supervisor mode, SR bit 0xD is set, 0xC is not.
754 		"gpr	tc	.32	140	0\n"
755 		"gpr	itt0	.32	144	0\n" //in 68EC040 this is IACR0
756 		"gpr	itt1	.32	148	0\n" //in 68EC040 this is IACR1
757 		"gpr	dtt0	.32	156	0\n" //in 68EC040 this is DACR0
758 		"gpr	dtt1	.32	160	0\n" //in 68EC040 this is DACR1
759 		"gpr	mmusr	.32	164	0\n"
760 		"gpr	urp	.32	168	0\n"
761 		"gpr	srp	.32	172	0\n"
762 		"gpr	fpcr	.32	176	0\n"
763 		"gpr	fpsr	.32	180	0\n"
764 		"gpr	fpiar	.32	184	0\n";
765 	return r_reg_set_profile_string (anal->reg, p);
766 }
767 
768 RAnalPlugin r_anal_plugin_m68k_cs = {
769 	.name = "m68k",
770 	.desc = "Capstone M68K analyzer",
771 	.license = "BSD",
772 	.esil = false,
773 	.arch = "m68k",
774 	.set_reg_profile = &set_reg_profile,
775 	.bits = 32,
776 	.op = &analop,
777 };
778 #else
779 RAnalPlugin r_anal_plugin_m68k_cs = {
780 	.name = "m68k (unsupported)",
781 	.desc = "Capstone M68K analyzer (unsupported)",
782 	.license = "BSD",
783 	.arch = "m68k",
784 	.bits = 32,
785 };
786 #endif
787 
788 #ifndef R2_PLUGIN_INCORE
789 R_API RLibStruct radare_plugin = {
790 	.type = R_LIB_TYPE_ANAL,
791 	.data = &r_anal_plugin_m68k_cs,
792 	.version = R2_VERSION
793 };
794 #endif
795