From d629131bafa186a2d85e1aec340097f4ecc671c4 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 7 Oct 2015 14:37:25 +0200 Subject: [PATCH] Initial support for capstone-m68k --- libr/anal/p/anal_m68k_cs.c | 593 +++++++++++++++++++++++++++++++++++++ libr/anal/p/anal_mips_cs.c | 1 - libr/anal/p/m68k_cs.mk | 13 + libr/asm/p/asm_m68k.c | 2 - libr/asm/p/asm_m68k_cs.c | 115 +++++++ libr/asm/p/m68k_cs.mk | 17 ++ libr/include/r_anal.h | 1 + libr/include/r_asm.h | 2 +- plugins.def.cfg | 2 + 9 files changed, 742 insertions(+), 4 deletions(-) create mode 100644 libr/anal/p/anal_m68k_cs.c create mode 100644 libr/anal/p/m68k_cs.mk create mode 100644 libr/asm/p/asm_m68k_cs.c create mode 100644 libr/asm/p/m68k_cs.mk diff --git a/libr/anal/p/anal_m68k_cs.c b/libr/anal/p/anal_m68k_cs.c new file mode 100644 index 0000000000..0f38a64a75 --- /dev/null +++ b/libr/anal/p/anal_m68k_cs.c @@ -0,0 +1,593 @@ +/* radare2 - LGPL - Copyright 2015 - pancake */ + +#include +#include +#include + +#if CS_API_MAJOR>=4 && CS_NEXT_VERSION>=3 +#define CAPSTONE_HAS_M68K 1 +#else +#define CAPSTONE_HAS_M68K 0 +#warning Cannot find capstone-m68k support +#endif + +#if CAPSTONE_HAS_M68K +#include +// http://www.mrc.uidaho.edu/mrc/people/jff/digital/M68Kir.html + +#define OPERAND(x) insn->detail->m68k.operands[x] +#define REG(x) cs_reg_name (*handle, insn->detail->m68k.operands[x].reg) +#define IMM(x) insn->detail->m68k.operands[x].imm +#define MEMBASE(x) cs_reg_name(*handle, insn->detail->m68k.operands[x].mem.base) +#define MEMINDEX(x) insn->detail->m68k.operands[x].mem.index +#define MEMDISP(x) insn->detail->m68k.operands[x].mem.disp +// TODO scale and disp + +static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { + int n, ret, opsize = -1; + static csh handle = 0; + static int omode = -1; + static int obits = 32; + cs_insn* insn; + int mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; + + mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32; + if (mode != omode || a->bits != obits) { + cs_close (&handle); + handle = 0; + omode = mode; + obits = a->bits; + } +// XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 + op->delay = 0; + op->size = 4; + if (handle == 0) { + ret = cs_open (CS_ARCH_M68K, mode, &handle); + if (ret != CS_ERR_OK) goto fin; + cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); + } + n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn); + if (n<1 || insn->size<1) + goto beach; + op->type = R_ANAL_OP_TYPE_NULL; + op->delay = 0; + opsize = op->size = insn->size; + switch (insn->id) { + case M68K_INS_INVALID: + op->type = R_ANAL_OP_TYPE_ILL; + break; + case M68K_INS_ADD: + case M68K_INS_ADDA: + case M68K_INS_ADDI: + case M68K_INS_ADDQ: + case M68K_INS_ADDX: + op->type = R_ANAL_OP_TYPE_ADD; + break; + case M68K_INS_AND: + case M68K_INS_ANDI: + op->type = R_ANAL_OP_TYPE_AND; + break; + case M68K_INS_ASL: + op->type = R_ANAL_OP_TYPE_SHL; + break; + case M68K_INS_ASR: + op->type = R_ANAL_OP_TYPE_SHR; + break; + case M68K_INS_ABCD: + break; + case M68K_INS_BHS: + case M68K_INS_BLO: + case M68K_INS_BHI: + case M68K_INS_BLS: + case M68K_INS_BCC: + case M68K_INS_BCS: + case M68K_INS_BNE: + case M68K_INS_BEQ: + case M68K_INS_BVC: + case M68K_INS_BVS: + case M68K_INS_BPL: + case M68K_INS_BMI: + case M68K_INS_BGE: + case M68K_INS_BLT: + case M68K_INS_BGT: + case M68K_INS_BLE: + op->type = R_ANAL_OP_TYPE_CJMP; + break; + case M68K_INS_BRA: + op->type = R_ANAL_OP_TYPE_JMP; + break; + case M68K_INS_BSR: + op->type = R_ANAL_OP_TYPE_CALL; + break; + case M68K_INS_BCHG: + case M68K_INS_BCLR: + case M68K_INS_BSET: + case M68K_INS_BTST: + case M68K_INS_BFCHG: + case M68K_INS_BFCLR: + case M68K_INS_BFEXTS: + case M68K_INS_BFEXTU: + case M68K_INS_BFFFO: + case M68K_INS_BFINS: + case M68K_INS_BFSET: + case M68K_INS_BFTST: + case M68K_INS_BKPT: + case M68K_INS_CALLM: + case M68K_INS_CAS: + case M68K_INS_CAS2: + case M68K_INS_CHK: + case M68K_INS_CHK2: + case M68K_INS_CLR: + // TODO: + break; + case M68K_INS_CMP: + case M68K_INS_CMPA: + case M68K_INS_CMPI: + case M68K_INS_CMPM: + case M68K_INS_CMP2: + op->type = R_ANAL_OP_TYPE_CMP; + break; + case M68K_INS_CINVL: + case M68K_INS_CINVP: + case M68K_INS_CINVA: + op->type = R_ANAL_OP_TYPE_ILL; + break; + case M68K_INS_CPUSHL: + case M68K_INS_CPUSHP: + case M68K_INS_CPUSHA: + case M68K_INS_DBT: + case M68K_INS_DBF: + case M68K_INS_DBHI: + case M68K_INS_DBLS: + case M68K_INS_DBCC: + case M68K_INS_DBCS: + case M68K_INS_DBNE: + case M68K_INS_DBEQ: + case M68K_INS_DBVC: + case M68K_INS_DBVS: + case M68K_INS_DBPL: + case M68K_INS_DBMI: + case M68K_INS_DBGE: + case M68K_INS_DBLT: + case M68K_INS_DBGT: + case M68K_INS_DBLE: + case M68K_INS_DBRA: + break; + case M68K_INS_DIVS: + case M68K_INS_DIVSL: + case M68K_INS_DIVU: + case M68K_INS_DIVUL: + op->type = R_ANAL_OP_TYPE_DIV; + break; + case M68K_INS_EOR: + case M68K_INS_EORI: + op->type = R_ANAL_OP_TYPE_XOR; + break; + case M68K_INS_EXG: + case M68K_INS_EXT: + case M68K_INS_EXTB: + break; + case M68K_INS_FABS: + case M68K_INS_FSABS: + case M68K_INS_FDABS: + case M68K_INS_FACOS: + case M68K_INS_FADD: + case M68K_INS_FSADD: + case M68K_INS_FDADD: + case M68K_INS_FASIN: + case M68K_INS_FATAN: + case M68K_INS_FATANH: + case M68K_INS_FBF: + case M68K_INS_FBEQ: + case M68K_INS_FBOGT: + case M68K_INS_FBOGE: + case M68K_INS_FBOLT: + case M68K_INS_FBOLE: + case M68K_INS_FBOGL: + case M68K_INS_FBOR: + case M68K_INS_FBUN: + case M68K_INS_FBUEQ: + case M68K_INS_FBUGT: + case M68K_INS_FBUGE: + case M68K_INS_FBULT: + case M68K_INS_FBULE: + case M68K_INS_FBNE: + case M68K_INS_FBT: + case M68K_INS_FBSF: + case M68K_INS_FBSEQ: + case M68K_INS_FBGT: + case M68K_INS_FBGE: + case M68K_INS_FBLT: + case M68K_INS_FBLE: + case M68K_INS_FBGL: + case M68K_INS_FBGLE: + case M68K_INS_FBNGLE: + case M68K_INS_FBNGL: + case M68K_INS_FBNLE: + case M68K_INS_FBNLT: + case M68K_INS_FBNGE: + case M68K_INS_FBNGT: + case M68K_INS_FBSNE: + case M68K_INS_FBST: + case M68K_INS_FCMP: + case M68K_INS_FCOS: + case M68K_INS_FCOSH: + case M68K_INS_FDBF: + case M68K_INS_FDBEQ: + case M68K_INS_FDBOGT: + case M68K_INS_FDBOGE: + case M68K_INS_FDBOLT: + case M68K_INS_FDBOLE: + case M68K_INS_FDBOGL: + case M68K_INS_FDBOR: + case M68K_INS_FDBUN: + case M68K_INS_FDBUEQ: + case M68K_INS_FDBUGT: + case M68K_INS_FDBUGE: + case M68K_INS_FDBULT: + case M68K_INS_FDBULE: + case M68K_INS_FDBNE: + case M68K_INS_FDBT: + case M68K_INS_FDBSF: + case M68K_INS_FDBSEQ: + case M68K_INS_FDBGT: + case M68K_INS_FDBGE: + case M68K_INS_FDBLT: + case M68K_INS_FDBLE: + case M68K_INS_FDBGL: + case M68K_INS_FDBGLE: + case M68K_INS_FDBNGLE: + case M68K_INS_FDBNGL: + case M68K_INS_FDBNLE: + case M68K_INS_FDBNLT: + case M68K_INS_FDBNGE: + case M68K_INS_FDBNGT: + case M68K_INS_FDBSNE: + case M68K_INS_FDBST: + case M68K_INS_FDIV: + case M68K_INS_FSDIV: + case M68K_INS_FDDIV: + case M68K_INS_FETOX: + case M68K_INS_FETOXM1: + case M68K_INS_FGETEXP: + case M68K_INS_FGETMAN: + case M68K_INS_FINT: + case M68K_INS_FINTRZ: + case M68K_INS_FLOG10: + case M68K_INS_FLOG2: + case M68K_INS_FLOGN: + case M68K_INS_FLOGNP1: + case M68K_INS_FMOD: + case M68K_INS_FMOVE: + case M68K_INS_FSMOVE: + case M68K_INS_FDMOVE: + case M68K_INS_FMOVECR: + case M68K_INS_FMOVEM: + case M68K_INS_FMUL: + case M68K_INS_FSMUL: + case M68K_INS_FDMUL: + case M68K_INS_FNEG: + case M68K_INS_FSNEG: + case M68K_INS_FDNEG: + case M68K_INS_FNOP: + case M68K_INS_FREM: + case M68K_INS_FRESTORE: + case M68K_INS_FSAVE: + case M68K_INS_FSCALE: + case M68K_INS_FSGLDIV: + case M68K_INS_FSGLMUL: + case M68K_INS_FSIN: + case M68K_INS_FSINCOS: + case M68K_INS_FSINH: + case M68K_INS_FSQRT: + case M68K_INS_FSSQRT: + case M68K_INS_FDSQRT: + case M68K_INS_FSF: + case M68K_INS_FSBEQ: + case M68K_INS_FSOGT: + case M68K_INS_FSOGE: + case M68K_INS_FSOLT: + case M68K_INS_FSOLE: + case M68K_INS_FSOGL: + case M68K_INS_FSOR: + case M68K_INS_FSUN: + case M68K_INS_FSUEQ: + case M68K_INS_FSUGT: + case M68K_INS_FSUGE: + case M68K_INS_FSULT: + case M68K_INS_FSULE: + case M68K_INS_FSNE: + case M68K_INS_FST: + case M68K_INS_FSSF: + case M68K_INS_FSSEQ: + case M68K_INS_FSGT: + case M68K_INS_FSGE: + case M68K_INS_FSLT: + case M68K_INS_FSLE: + case M68K_INS_FSGL: + case M68K_INS_FSGLE: + case M68K_INS_FSNGLE: + case M68K_INS_FSNGL: + case M68K_INS_FSNLE: + case M68K_INS_FSNLT: + case M68K_INS_FSNGE: + case M68K_INS_FSNGT: + case M68K_INS_FSSNE: + case M68K_INS_FSST: + case M68K_INS_FSUB: + case M68K_INS_FSSUB: + case M68K_INS_FDSUB: + case M68K_INS_FTAN: + case M68K_INS_FTANH: + case M68K_INS_FTENTOX: + case M68K_INS_FTRAPF: + case M68K_INS_FTRAPEQ: + case M68K_INS_FTRAPOGT: + case M68K_INS_FTRAPOGE: + case M68K_INS_FTRAPOLT: + case M68K_INS_FTRAPOLE: + case M68K_INS_FTRAPOGL: + case M68K_INS_FTRAPOR: + case M68K_INS_FTRAPUN: + case M68K_INS_FTRAPUEQ: + case M68K_INS_FTRAPUGT: + case M68K_INS_FTRAPUGE: + case M68K_INS_FTRAPULT: + case M68K_INS_FTRAPULE: + case M68K_INS_FTRAPNE: + case M68K_INS_FTRAPT: + case M68K_INS_FTRAPSF: + case M68K_INS_FTRAPSEQ: + case M68K_INS_FTRAPGT: + case M68K_INS_FTRAPGE: + case M68K_INS_FTRAPLT: + case M68K_INS_FTRAPLE: + case M68K_INS_FTRAPGL: + case M68K_INS_FTRAPGLE: + case M68K_INS_FTRAPNGLE: + case M68K_INS_FTRAPNGL: + case M68K_INS_FTRAPNLE: + case M68K_INS_FTRAPNLT: + case M68K_INS_FTRAPNGE: + case M68K_INS_FTRAPNGT: + case M68K_INS_FTRAPSNE: + case M68K_INS_FTRAPST: + case M68K_INS_FTST: + case M68K_INS_FTWOTOX: + op->type = R_ANAL_OP_TYPE_UNK; + op->family = R_ANAL_OP_FAMILY_FPU; + break; + case M68K_INS_HALT: + op->type = R_ANAL_OP_TYPE_NOP; + break; + case M68K_INS_ILLEGAL: + op->type = R_ANAL_OP_TYPE_ILL; + break; + case M68K_INS_JMP: + op->type = R_ANAL_OP_TYPE_JMP; + break; + case M68K_INS_JSR: + op->type = R_ANAL_OP_TYPE_CALL; + break; + case M68K_INS_LINK: + case M68K_INS_LPSTOP: + case M68K_INS_LSL: + op->type = R_ANAL_OP_TYPE_SHL; + break; + case M68K_INS_LSR: + op->type = R_ANAL_OP_TYPE_SHR; + break; + case M68K_INS_LEA: + case M68K_INS_MOVE: + case M68K_INS_MOVEA: + case M68K_INS_MOVEC: + case M68K_INS_MOVEM: + case M68K_INS_MOVEP: + case M68K_INS_MOVEQ: + case M68K_INS_MOVES: + case M68K_INS_MOVE16: + op->type = R_ANAL_OP_TYPE_MOV; + break; + case M68K_INS_MULS: + case M68K_INS_MULU: + op->type = R_ANAL_OP_TYPE_MUL; + break; + case M68K_INS_NBCD: + case M68K_INS_NEG: + case M68K_INS_NEGX: + break; + case M68K_INS_NOP: + op->type = R_ANAL_OP_TYPE_NOP; + break; + case M68K_INS_NOT: + case M68K_INS_OR: + case M68K_INS_ORI: + op->type = R_ANAL_OP_TYPE_OR; + break; + case M68K_INS_PACK: + case M68K_INS_PEA: + case M68K_INS_PFLUSH: + case M68K_INS_PFLUSHA: + case M68K_INS_PFLUSHAN: + case M68K_INS_PFLUSHN: + case M68K_INS_PLOADR: + case M68K_INS_PLOADW: + case M68K_INS_PLPAR: + case M68K_INS_PLPAW: + case M68K_INS_PMOVE: + case M68K_INS_PMOVEFD: + case M68K_INS_PTESTR: + case M68K_INS_PTESTW: + case M68K_INS_PULSE: + case M68K_INS_REMS: + case M68K_INS_REMU: + case M68K_INS_RESET: + case M68K_INS_ROL: + case M68K_INS_ROR: + case M68K_INS_ROXL: + case M68K_INS_ROXR: + case M68K_INS_RTD: + case M68K_INS_RTE: + case M68K_INS_RTM: + case M68K_INS_RTR: + case M68K_INS_RTS: + case M68K_INS_SBCD: + case M68K_INS_ST: + case M68K_INS_SF: + case M68K_INS_SHI: + case M68K_INS_SLS: + case M68K_INS_SCC: + case M68K_INS_SHS: + case M68K_INS_SCS: + case M68K_INS_SLO: + case M68K_INS_SNE: + case M68K_INS_SEQ: + case M68K_INS_SVC: + case M68K_INS_SVS: + case M68K_INS_SPL: + case M68K_INS_SMI: + case M68K_INS_SGE: + case M68K_INS_SLT: + case M68K_INS_SGT: + case M68K_INS_SLE: + case M68K_INS_STOP: + break; + case M68K_INS_SUB: + case M68K_INS_SUBA: + case M68K_INS_SUBI: + case M68K_INS_SUBQ: + case M68K_INS_SUBX: + op->type = R_ANAL_OP_TYPE_SUB; + break; + case M68K_INS_SWAP: + op->type = R_ANAL_OP_TYPE_MOV; + break; + case M68K_INS_TAS: + break; + case M68K_INS_TRAP: + case M68K_INS_TRAPV: + case M68K_INS_TRAPT: + case M68K_INS_TRAPF: + case M68K_INS_TRAPHI: + case M68K_INS_TRAPLS: + case M68K_INS_TRAPCC: + case M68K_INS_TRAPHS: + case M68K_INS_TRAPCS: + case M68K_INS_TRAPLO: + case M68K_INS_TRAPNE: + case M68K_INS_TRAPEQ: + case M68K_INS_TRAPVC: + case M68K_INS_TRAPVS: + case M68K_INS_TRAPPL: + case M68K_INS_TRAPMI: + case M68K_INS_TRAPGE: + case M68K_INS_TRAPLT: + case M68K_INS_TRAPGT: + case M68K_INS_TRAPLE: + op->type = R_ANAL_OP_TYPE_TRAP; + break; + case M68K_INS_TST: + op->type = R_ANAL_OP_TYPE_CMP; + break; + case M68K_INS_UNLK: + case M68K_INS_UNPK: + break; + } + beach: + cs_free (insn, n); + //cs_close (&handle); + fin: + return opsize; +} + +static int set_reg_profile(RAnal *anal) { + // XXX : 64bit profile + char *p = "=pc pc\n" + "=sp sp\n" + "=a0 a0\n" + "=a1 a1\n" + "=a2 a2\n" + "=a3 a3\n" + "gpr d0 .32 0 0\n" + "gpr d1 .32 4 0\n" + "gpr d2 .32 8 0\n" + "gpr d3 .32 12 0\n" + "gpr d4 .32 16 0\n" + "gpr d5 .32 20 0\n" + "gpr d6 .32 24 0\n" + "gpr d7 .32 28 0\n" + "gpr a0 .32 32 0\n" + "gpr a1 .32 36 0\n" + "gpr a1 .32 40 0\n" + "gpr a2 .32 44 0\n" + "gpr a3 .32 48 0\n" + "gpr a4 .32 52 0\n" + "gpr a5 .32 56 0\n" + "gpr a6 .32 60 0\n" + "gpr a7 .32 64 0\n" + "gpr fp0 .32 68 0\n" + "gpr fp1 .32 72 0\n" + "gpr fp2 .32 76 0\n" + "gpr fp3 .32 80 0\n" + "gpr fp4 .32 84 0\n" + "gpr fp5 .32 88 0\n" + "gpr fp6 .32 92 0\n" + "gpr fp7 .32 96 0\n" + "gpr pc .32 100 0\n" + "gpr sr .32 104 0\n" + "gpr ccr .32 108 0\n" + "gpr sfc .32 112 0\n" + "gpr dfc .32 116 0\n" + "gpr usp .32 120 0\n" + "gpr vbr .32 124 0\n" + "gpr cacr .32 128 0\n" + "gpr caar .32 132 0\n" + "gpr msp .32 136 0\n" + "gpr isp .32 140 0\n" + "gpr tc .32 144 0\n" + "gpr itt0 .32 144 0\n" + "gpr itt1 .32 144 0\n" + "gpr dtt0 .32 144 0\n" + "gpr dtt1 .32 144 0\n" + "gpr mmusr .32 144 0\n" + "gpr urp .32 144 0\n" + "gpr srp .32 144 0\n" + "gpr fpcr .32 144 0\n" + "gpr fpsr .32 144 0\n" + "gpr fpiar .32 144 0\n"; + return r_reg_set_profile_string (anal->reg, p); +} + +RAnalPlugin r_anal_plugin_m68k_cs = { + .name = "m68k.mk", + .desc = "Capstone M68K analyzer", + .license = "BSD", + .esil = false, + .arch = R_SYS_ARCH_M68K, + .set_reg_profile = set_reg_profile, + .bits = 32, + .op = &analop, +}; + +#ifndef CORELIB +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_ANAL, + .data = &r_anal_plugin_m68k_cs, + .version = R2_VERSION +}; +#endif +#else +static RAnalPlugin r_anal_plugin_m68k_cs = { + .name = "m68k.cs (unsupported)", + .desc = "Capstone M68K analyzer (unsupported)", + .license = "BSD", + .arch = "m68k", + .bits = 32, +}; + +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_ANAL, + .data = &r_anal_plugin_m68k_cs, + .version = R2_VERSION +}; +#endif diff --git a/libr/anal/p/anal_mips_cs.c b/libr/anal/p/anal_mips_cs.c index 31a61a21b8..162f7673f3 100644 --- a/libr/anal/p/anal_mips_cs.c +++ b/libr/anal/p/anal_mips_cs.c @@ -326,7 +326,6 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) { op->size = 4; if (handle == 0) { ret = cs_open (CS_ARCH_MIPS, mode, &handle); -eprintf ("Plantilla\n"); if (ret != CS_ERR_OK) goto fin; cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON); } diff --git a/libr/anal/p/m68k_cs.mk b/libr/anal/p/m68k_cs.mk new file mode 100644 index 0000000000..98c320dbd2 --- /dev/null +++ b/libr/anal/p/m68k_cs.mk @@ -0,0 +1,13 @@ +OBJ_M68K_CS=anal_m68k_cs.o + +include ${CURDIR}capstone.mk + +STATIC_OBJ+=$(OBJ_M68K_CS) + +TARGET_M68K_CS=anal_m68k_cs.${EXT_SO} + +ALL_TARGETS+=${TARGET_M68K_CS} + +${TARGET_M68K_CS}: ${OBJ_M68K_CS} + ${CC} ${CFLAGS} $(call libname,anal_m68k_cs) $(CS_CFLAGS) \ + -o anal_m68k_cs.${EXT_SO} ${OBJ_M68K_CS} $(CS_LDFLAGS) diff --git a/libr/asm/p/asm_m68k.c b/libr/asm/p/asm_m68k.c index a915a748bd..98a59287cc 100644 --- a/libr/asm/p/asm_m68k.c +++ b/libr/asm/p/asm_m68k.c @@ -43,8 +43,6 @@ RAsmPlugin r_asm_plugin_m68k = { .license = "BSD", .bits = 16|32, .desc = "Motorola 68000", - .init = NULL, - .fini = NULL, .disassemble = &disassemble, .assemble = NULL }; diff --git a/libr/asm/p/asm_m68k_cs.c b/libr/asm/p/asm_m68k_cs.c new file mode 100644 index 0000000000..e6bf4f3374 --- /dev/null +++ b/libr/asm/p/asm_m68k_cs.c @@ -0,0 +1,115 @@ +/* radare2 - LGPL - Copyright 2015 - pancake */ + +#include +#include +#include + +#if CS_API_MAJOR>=4 && CS_NEXT_VERSION>=3 +#define CAPSTONE_HAS_M68K 1 +#else +#define CAPSTONE_HAS_M68K 0 +#warning Cannot find capstone-m68k support +#endif + +#if CAPSTONE_HAS_M68K + +static bool check_features(RAsm *a, cs_insn *insn); +static csh cd; + +static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { + cs_insn* insn = NULL; + cs_mode mode = 0; + int ret, n = 0; + mode |= (a->big_endian)? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN; + + // replace this with the asm.features? + if (a->cpu && strstr (a->cpu, "mclass")) + mode |= CS_MODE_MCLASS; + if (a->cpu && strstr (a->cpu, "v8")) + mode |= CS_MODE_V8; + op->size = 4; + op->buf_asm[0] = 0; + ret = cs_open (CS_ARCH_M68K, mode, &cd); + if (ret) { + ret = -1; + goto beach; + } + if (a->syntax == R_ASM_SYNTAX_REGNUM) { + cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME); + } else cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT); + if (a->features && *a->features) { + cs_option (cd, CS_OPT_DETAIL, CS_OPT_ON); + } else { + cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF); + } + n = cs_disasm (cd, buf, R_MIN (4, len), + a->pc, 1, &insn); + if (n<1) { + ret = -1; + goto beach; + } + op->size = 0; + if (insn->size<1) { + ret = -1; + goto beach; + } + if (a->features && *a->features) { + if (!check_features (a, insn)) { + op->size = insn->size; + strcpy (op->buf_asm, "illegal"); + } + } + if (!op->size) { + op->size = insn->size; + snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s", + insn->mnemonic, + insn->op_str[0]?" ":"", + insn->op_str); + r_str_rmch (op->buf_asm, '#'); + } + cs_free (insn, n); + beach: + cs_close (&cd); + if (!op->buf_asm[0]) + strcpy (op->buf_asm, "invalid"); + return op->size; +} + +RAsmPlugin r_asm_plugin_m68k_cs = { + .name = "m68k.cs", + .desc = "Capstone M68K disassembler", + .cpus = "68000,68010,68020,68030,68040,68060", + .license = "BSD", + .arch = "m68k", + .bits = 32, + .disassemble = &disassemble, + .features = NULL +}; + +static bool check_features(RAsm *a, cs_insn *insn) { + /* TODO: Implement support for m68k */ + return true; +} + +#ifndef CORELIB +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_ASM, + .data = &r_asm_plugin_m68k_cs, + .version = R2_VERSION +}; +#endif + +#else +RAsmPlugin r_asm_plugin_m68k_cs = { + .name = "m68k.cs (unsupported)", + .desc = "Capstone M68K disassembler (unsupported)", + .license = "BSD", + .arch = "m68k", + .bits = 32, +}; +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_ASM, + .data = &r_asm_plugin_m68k_cs, + .version = R2_VERSION +}; +#endif diff --git a/libr/asm/p/m68k_cs.mk b/libr/asm/p/m68k_cs.mk new file mode 100644 index 0000000000..f551c228dd --- /dev/null +++ b/libr/asm/p/m68k_cs.mk @@ -0,0 +1,17 @@ +# capstone-m68k + +OBJ_M68KCS=asm_m68k_cs.o + +include p/capstone.mk + +STATIC_OBJ+=${OBJ_M68KCS} +SHARED_OBJ+=${SHARED_M68KCS} +TARGET_M68KCS=asm_m68k_cs.${EXT_SO} + +ifeq ($(WITHPIC),1) +ALL_TARGETS+=${TARGET_M68KCS} + +${TARGET_M68KCS}: ${OBJ_M68KCS} + ${CC} $(call libname,asm_m68k_cs) ${LDFLAGS} ${CFLAGS} ${CS_CFLAGS} \ + -o ${TARGET_M68KCS} ${OBJ_M68KCS} ${CS_LDFLAGS} +endif diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 79d6d41516..aea4f41dcd 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -1477,6 +1477,7 @@ extern RAnalPlugin r_anal_plugin_sh; extern RAnalPlugin r_anal_plugin_sparc_gnu; extern RAnalPlugin r_anal_plugin_bf; extern RAnalPlugin r_anal_plugin_m68k; +extern RAnalPlugin r_anal_plugin_m68k_cs; extern RAnalPlugin r_anal_plugin_z80; extern RAnalPlugin r_anal_plugin_i8080; extern RAnalPlugin r_anal_plugin_8051; diff --git a/libr/include/r_asm.h b/libr/include/r_asm.h index 8b9d767ec3..e09c8ee135 100644 --- a/libr/include/r_asm.h +++ b/libr/include/r_asm.h @@ -180,7 +180,6 @@ extern RAsmPlugin r_asm_plugin_arm_as; extern RAsmPlugin r_asm_plugin_armthumb; extern RAsmPlugin r_asm_plugin_arm_winedbg; extern RAsmPlugin r_asm_plugin_csr; -extern RAsmPlugin r_asm_plugin_m68k; extern RAsmPlugin r_asm_plugin_ppc_gnu; extern RAsmPlugin r_asm_plugin_ppc_cs; extern RAsmPlugin r_asm_plugin_sparc_gnu; @@ -191,6 +190,7 @@ extern RAsmPlugin r_asm_plugin_sh; extern RAsmPlugin r_asm_plugin_z80; extern RAsmPlugin r_asm_plugin_i8080; extern RAsmPlugin r_asm_plugin_m68k; +extern RAsmPlugin r_asm_plugin_m68k_cs; extern RAsmPlugin r_asm_plugin_arc; extern RAsmPlugin r_asm_plugin_rar; extern RAsmPlugin r_asm_plugin_dcpu16; diff --git a/plugins.def.cfg b/plugins.def.cfg index e2c3e655da..471ec50094 100644 --- a/plugins.def.cfg +++ b/plugins.def.cfg @@ -14,6 +14,7 @@ anal.h8300 anal.i8080 anal.java anal.m68k +anal.m68k_cs anal.malbolge anal.mips_cs anal.mips_gnu @@ -58,6 +59,7 @@ asm.i8080 asm.java asm.lm32 asm.m68k +asm.m68k_cs asm.malbolge asm.mips_cs asm.mips_gnu