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 = ®
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 = ®
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 = ®
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