1*9a0e4156SSadaf Ebrahimi#!/usr/bin/env python 2*9a0e4156SSadaf Ebrahimi 3*9a0e4156SSadaf Ebrahimifrom __future__ import print_function 4*9a0e4156SSadaf Ebrahimiimport sys 5*9a0e4156SSadaf Ebrahimiimport bitstring 6*9a0e4156SSadaf Ebrahimifrom capstone import * 7*9a0e4156SSadaf Ebrahimifrom capstone.m68k import * 8*9a0e4156SSadaf Ebrahimi 9*9a0e4156SSadaf Ebrahimi# 10*9a0e4156SSadaf Ebrahimi# Objdump with the same output as his binary cousin 11*9a0e4156SSadaf Ebrahimi# 12*9a0e4156SSadaf Ebrahimi 13*9a0e4156SSadaf EbrahimiTODO = """ 14*9a0e4156SSadaf EbrahimiTODO : 15*9a0e4156SSadaf Ebrahimi 16*9a0e4156SSadaf Ebrahimi o need more testing on M68K_AM_*_DISP 17*9a0e4156SSadaf Ebrahimi o cleanup, etc ... 18*9a0e4156SSadaf Ebrahimi 19*9a0e4156SSadaf Ebrahimi""" 20*9a0e4156SSadaf Ebrahimi 21*9a0e4156SSadaf Ebrahimiobjdump_cmd_example = 'm68k-atari-mint-objdump -b binary -D -mm68k --adjust-vma 0x30664 u/m68k.bin' 22*9a0e4156SSadaf Ebrahimiobjdump_dumpheader_fmt = """ 23*9a0e4156SSadaf Ebrahimi%s: file format binary 24*9a0e4156SSadaf Ebrahimi 25*9a0e4156SSadaf Ebrahimi 26*9a0e4156SSadaf EbrahimiDisassembly of section .data: 27*9a0e4156SSadaf Ebrahimi 28*9a0e4156SSadaf Ebrahimi%08x <.data>:""" 29*9a0e4156SSadaf Ebrahimi 30*9a0e4156SSadaf Ebrahimi 31*9a0e4156SSadaf EbrahimiM68000_CODE = b"\x04\x40\x00\x40" 32*9a0e4156SSadaf Ebrahimi 33*9a0e4156SSadaf Ebrahimiall_tests = ( 34*9a0e4156SSadaf Ebrahimi (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_060, M68000_CODE, "M68060-32 (Big-endian)"), 35*9a0e4156SSadaf Ebrahimi) 36*9a0e4156SSadaf Ebrahimi 37*9a0e4156SSadaf Ebrahimi 38*9a0e4156SSadaf Ebrahimidef dump_bytes(b, len): 39*9a0e4156SSadaf Ebrahimi str = '' 40*9a0e4156SSadaf Ebrahimi i = 0 41*9a0e4156SSadaf Ebrahimi while i < len: 42*9a0e4156SSadaf Ebrahimi str += format("%02x%02x " % (b[i], b[i+1])) 43*9a0e4156SSadaf Ebrahimi i += 2 44*9a0e4156SSadaf Ebrahimi return str[:-1] 45*9a0e4156SSadaf Ebrahimi 46*9a0e4156SSadaf Ebrahimidef dump_op_reg(insn, op_reg): 47*9a0e4156SSadaf Ebrahimi if op_reg == M68K_REG_A7: 48*9a0e4156SSadaf Ebrahimi return "%sp" 49*9a0e4156SSadaf Ebrahimi if op_reg == M68K_REG_A6: 50*9a0e4156SSadaf Ebrahimi return "%fp" 51*9a0e4156SSadaf Ebrahimi return '%' + insn.reg_name(op_reg) 52*9a0e4156SSadaf Ebrahimi 53*9a0e4156SSadaf Ebrahimidef s8(value): 54*9a0e4156SSadaf Ebrahimi return bitstring.Bits(uint=value, length=8).unpack('int')[0] 55*9a0e4156SSadaf Ebrahimi 56*9a0e4156SSadaf Ebrahimidef s16(value): 57*9a0e4156SSadaf Ebrahimi return bitstring.Bits(uint=value, length=16).unpack('int')[0] 58*9a0e4156SSadaf Ebrahimi 59*9a0e4156SSadaf Ebrahimidef extsign8(value): 60*9a0e4156SSadaf Ebrahimi if value & 0x80: 61*9a0e4156SSadaf Ebrahimi return 0xffffffffffffff00 + value 62*9a0e4156SSadaf Ebrahimi return value 63*9a0e4156SSadaf Ebrahimi 64*9a0e4156SSadaf Ebrahimidef extsign1616(value): 65*9a0e4156SSadaf Ebrahimi if value & 0x8000: 66*9a0e4156SSadaf Ebrahimi return 0xffff0000 + value 67*9a0e4156SSadaf Ebrahimi return value 68*9a0e4156SSadaf Ebrahimi 69*9a0e4156SSadaf Ebrahimidef extsign1632(value): 70*9a0e4156SSadaf Ebrahimi if value & 0x8000: 71*9a0e4156SSadaf Ebrahimi return 0xffffffffffff0000 + value 72*9a0e4156SSadaf Ebrahimi return value 73*9a0e4156SSadaf Ebrahimi 74*9a0e4156SSadaf Ebrahimi 75*9a0e4156SSadaf Ebrahimidef printRegbitsRange(buffer, data, prefix): 76*9a0e4156SSadaf Ebrahimi str = '' 77*9a0e4156SSadaf Ebrahimi first = 0 78*9a0e4156SSadaf Ebrahimi run_length = 0 79*9a0e4156SSadaf Ebrahimi 80*9a0e4156SSadaf Ebrahimi i = 0 81*9a0e4156SSadaf Ebrahimi while i < 8: 82*9a0e4156SSadaf Ebrahimi if (data & (1 << i)): 83*9a0e4156SSadaf Ebrahimi first = i 84*9a0e4156SSadaf Ebrahimi run_length = 0 85*9a0e4156SSadaf Ebrahimi 86*9a0e4156SSadaf Ebrahimi while (i < 7 and (data & (1 << (i + 1)))): 87*9a0e4156SSadaf Ebrahimi i += 1 88*9a0e4156SSadaf Ebrahimi run_length += 1 89*9a0e4156SSadaf Ebrahimi 90*9a0e4156SSadaf Ebrahimi if len(buffer) or len(str): 91*9a0e4156SSadaf Ebrahimi str += "/" 92*9a0e4156SSadaf Ebrahimi 93*9a0e4156SSadaf Ebrahimi str += format("%%%s%d" % (prefix, first)) 94*9a0e4156SSadaf Ebrahimi if run_length > 0: 95*9a0e4156SSadaf Ebrahimi str += format("-%%%s%d" % (prefix, first + run_length)) 96*9a0e4156SSadaf Ebrahimi i += 1 97*9a0e4156SSadaf Ebrahimi return str 98*9a0e4156SSadaf Ebrahimi 99*9a0e4156SSadaf Ebrahimidef registerBits(op): 100*9a0e4156SSadaf Ebrahimi str = '' 101*9a0e4156SSadaf Ebrahimi data = op.register_bits 102*9a0e4156SSadaf Ebrahimi 103*9a0e4156SSadaf Ebrahimi str += printRegbitsRange(str, data & 0xff, "d") 104*9a0e4156SSadaf Ebrahimi str += printRegbitsRange(str, (data >> 8) & 0xff, "a") 105*9a0e4156SSadaf Ebrahimi str += printRegbitsRange(str, (data >> 16) & 0xff, "fp") 106*9a0e4156SSadaf Ebrahimi return str 107*9a0e4156SSadaf Ebrahimi 108*9a0e4156SSadaf Ebrahimidef dump_op_ea(insn, op): 109*9a0e4156SSadaf Ebrahimi s_spacing = " " 110*9a0e4156SSadaf Ebrahimi map_index_size_str = { 0: 'w', 1 : 'l' } 111*9a0e4156SSadaf Ebrahimi str = '' 112*9a0e4156SSadaf Ebrahimi 113*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_NONE: 114*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_REG_BITS: 115*9a0e4156SSadaf Ebrahimi return registerBits(op) 116*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_REG_PAIR: 117*9a0e4156SSadaf Ebrahimi return registerPair(op) 118*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_REG: 119*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) 120*9a0e4156SSadaf Ebrahimi 121*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REG_DIRECT_DATA: 122*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) 123*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REG_DIRECT_ADDR: 124*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) + "@" 125*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REGI_ADDR: 126*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) + "@" 127*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REGI_ADDR_POST_INC: 128*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) + "@+" 129*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REGI_ADDR_PRE_DEC: 130*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.reg) + "@-" 131*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_REGI_ADDR_DISP: 132*9a0e4156SSadaf Ebrahimi# str = dump_op_reg(insn, op.mem.base_reg - M68K_REG_A0 + 1) #double check and fixme '+1' : 02af 899f 2622 133*9a0e4156SSadaf Ebrahimi str = dump_op_reg(insn, op.mem.base_reg) 134*9a0e4156SSadaf Ebrahimi if op.mem.disp: 135*9a0e4156SSadaf Ebrahimi str += format("@(%d)" % s16(op.mem.disp)) 136*9a0e4156SSadaf Ebrahimi return str 137*9a0e4156SSadaf Ebrahimi 138*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_PCI_DISP: 139*9a0e4156SSadaf Ebrahimi return format("%%pc@(0x%x)" % ( extsign1616(op.mem.disp + 2))) 140*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_ABSOLUTE_DATA_SHORT: 141*9a0e4156SSadaf Ebrahimi return format("0x%x" % (extsign1616(op.imm & 0xffff))) 142*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_ABSOLUTE_DATA_LONG: 143*9a0e4156SSadaf Ebrahimi return format("0x%x" % (op.imm & 0xffffffff)) 144*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_IMMEDIATE: 145*9a0e4156SSadaf Ebrahimi if insn.op_size.type == M68K_SIZE_TYPE_FPU: 146*9a0e4156SSadaf Ebrahimi map_fpu_size_str = { M68K_FPU_SIZE_SINGLE : op.simm, M68K_FPU_SIZE_DOUBLE : op.dimm } 147*9a0e4156SSadaf Ebrahimi return format("#%f" % (insn.op_size.fpu_size[map_fpu_size_str])) 148*9a0e4156SSadaf Ebrahimi return format("#$%x" % (op.imm)) 149*9a0e4156SSadaf Ebrahimi 150*9a0e4156SSadaf Ebrahimi if op.address_mode in [ M68K_AM_PCI_INDEX_8_BIT_DISP, M68K_AM_AREGI_INDEX_8_BIT_DISP ]: 151*9a0e4156SSadaf Ebrahimi disp = op.mem.disp 152*9a0e4156SSadaf Ebrahimi if op.register_bits == 2: 153*9a0e4156SSadaf Ebrahimi disp = extsign8(op.mem.disp) 154*9a0e4156SSadaf Ebrahimi if op.register_bits == 4: 155*9a0e4156SSadaf Ebrahimi disp = extsign1632(op.mem.disp) 156*9a0e4156SSadaf Ebrahimi 157*9a0e4156SSadaf Ebrahimi str = dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016x}".format(disp) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size] 158*9a0e4156SSadaf Ebrahimi if op.register_bits: 159*9a0e4156SSadaf Ebrahimi str += format(":%u" % (op.register_bits)) 160*9a0e4156SSadaf Ebrahimi return str + ")" 161*9a0e4156SSadaf Ebrahimi 162*9a0e4156SSadaf Ebrahimi 163*9a0e4156SSadaf Ebrahimi if op.address_mode in [ M68K_AM_PCI_INDEX_BASE_DISP, M68K_AM_AREGI_INDEX_BASE_DISP ]: 164*9a0e4156SSadaf Ebrahimi str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) )) 165*9a0e4156SSadaf Ebrahimi str += format("@(%016x)@(%016x" % (extsign1632(op.mem.in_disp), extsign1632(op.mem.out_disp))) 166*9a0e4156SSadaf Ebrahimi if op.mem.index_reg: 167*9a0e4156SSadaf Ebrahimi str += "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size] 168*9a0e4156SSadaf Ebrahimi if op.register_bits: 169*9a0e4156SSadaf Ebrahimi str += format(":%u" % (op.register_bits)) 170*9a0e4156SSadaf Ebrahimi str += ")" 171*9a0e4156SSadaf Ebrahimi return str 172*9a0e4156SSadaf Ebrahimi 173*9a0e4156SSadaf Ebrahimi if op.mem.in_disp > 0: 174*9a0e4156SSadaf Ebrahimi str += format("$%x" % ( op.mem.in_disp)) 175*9a0e4156SSadaf Ebrahimi 176*9a0e4156SSadaf Ebrahimi str += format("(") 177*9a0e4156SSadaf Ebrahimi 178*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_PCI_INDEX_BASE_DISP: 179*9a0e4156SSadaf Ebrahimi str_size = '' 180*9a0e4156SSadaf Ebrahimi if op.mem.index_size: 181*9a0e4156SSadaf Ebrahimi str_size = "l" 182*9a0e4156SSadaf Ebrahimi else: 183*9a0e4156SSadaf Ebrahimi str_size = "w" 184*9a0e4156SSadaf Ebrahimi str += format("pc,%s%s.%s" % ( dump_op_reg(insn, op.mem.index_reg)), s_spacing, str_size) 185*9a0e4156SSadaf Ebrahimi else: 186*9a0e4156SSadaf Ebrahimi if op.mem.base_reg != M68K_REG_INVALID: 187*9a0e4156SSadaf Ebrahimi str += format("a%d,%s" % ( op.mem.base_reg - M68K_REG_A0, s_spacing)) 188*9a0e4156SSadaf Ebrahimi str_size = '' 189*9a0e4156SSadaf Ebrahimi if op.mem.index_size: 190*9a0e4156SSadaf Ebrahimi str_size = "l" 191*9a0e4156SSadaf Ebrahimi else: 192*9a0e4156SSadaf Ebrahimi str_size = "w" 193*9a0e4156SSadaf Ebrahimi str += format("%s.%s" % ( dump_op_reg(insn, op.mem.index_reg), str_size)) 194*9a0e4156SSadaf Ebrahimi 195*9a0e4156SSadaf Ebrahimi if op.mem.scale > 0: 196*9a0e4156SSadaf Ebrahimi str += format("%s*%s%d)" % ( s_spacing, s_spacing, op.mem.scale)) 197*9a0e4156SSadaf Ebrahimi else: 198*9a0e4156SSadaf Ebrahimi str += ")" 199*9a0e4156SSadaf Ebrahimi return str 200*9a0e4156SSadaf Ebrahimi 201*9a0e4156SSadaf Ebrahimi # It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler. 202*9a0e4156SSadaf Ebrahimi # While this is not strictly correct it makes the code 203*9a0e4156SSadaf Ebrahimi # easier and that is what actually happens when the code is executed anyway. 204*9a0e4156SSadaf Ebrahimi 205*9a0e4156SSadaf Ebrahimi if op.address_mode in [ M68K_AM_PC_MEMI_POST_INDEX, M68K_AM_PC_MEMI_PRE_INDEX, M68K_AM_MEMI_PRE_INDEX, M68K_AM_MEMI_POST_INDEX]: 206*9a0e4156SSadaf Ebrahimi if op.mem.base_reg: 207*9a0e4156SSadaf Ebrahimi str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) )) 208*9a0e4156SSadaf Ebrahimi if op.mem.in_disp: 209*9a0e4156SSadaf Ebrahimi value = op.mem.in_disp 210*9a0e4156SSadaf Ebrahimi if op.mem.in_disp & 0x8000: 211*9a0e4156SSadaf Ebrahimi value = 0xffffffffffff0000 + op.mem.in_disp 212*9a0e4156SSadaf Ebrahimi str += format("@(%016x)@(%016x)" % (value, op.mem.out_disp)) 213*9a0e4156SSadaf Ebrahimi return str 214*9a0e4156SSadaf Ebrahimi 215*9a0e4156SSadaf Ebrahimi str += format("([") 216*9a0e4156SSadaf Ebrahimi if op.mem.in_disp > 0: 217*9a0e4156SSadaf Ebrahimi str += format("$%x" % ( op.mem.in_disp)) 218*9a0e4156SSadaf Ebrahimi 219*9a0e4156SSadaf Ebrahimi if op.mem.base_reg != M68K_REG_INVALID: 220*9a0e4156SSadaf Ebrahimi if op.mem.in_disp > 0: 221*9a0e4156SSadaf Ebrahimi str += format(",%s%s" % ( s_spacing, dump_op_reg(insn, op.mem.base_reg))) 222*9a0e4156SSadaf Ebrahimi else: 223*9a0e4156SSadaf Ebrahimi str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg))) 224*9a0e4156SSadaf Ebrahimi 225*9a0e4156SSadaf Ebrahimi if op.address_mode in [ M68K_AM_MEMI_POST_INDEX, M68K_AM_PC_MEMI_POST_INDEX]: 226*9a0e4156SSadaf Ebrahimi str += format("]") 227*9a0e4156SSadaf Ebrahimi 228*9a0e4156SSadaf Ebrahimi if op.mem.index_reg != M68K_REG_INVALID: 229*9a0e4156SSadaf Ebrahimi str_size = '' 230*9a0e4156SSadaf Ebrahimi if op.mem.index_size: 231*9a0e4156SSadaf Ebrahimi str_size = "l" 232*9a0e4156SSadaf Ebrahimi else: 233*9a0e4156SSadaf Ebrahimi str_size = "w" 234*9a0e4156SSadaf Ebrahimi str += format(",%s%s.%s" % ( s_spacing, dump_op_reg(insn, op.mem.index_reg), str_size)) 235*9a0e4156SSadaf Ebrahimi if op.mem.scale > 0: 236*9a0e4156SSadaf Ebrahimi str += format("%s*%s%d" % ( s_spacing, s_spacing, op.mem.scale)) 237*9a0e4156SSadaf Ebrahimi if op.address_mode in [ M68K_AM_MEMI_PRE_INDEX, M68K_AM_PC_MEMI_PRE_INDEX]: 238*9a0e4156SSadaf Ebrahimi str += format("]") 239*9a0e4156SSadaf Ebrahimi if op.mem.out_disp > 0: 240*9a0e4156SSadaf Ebrahimi str += format(",%s$%x" % ( s_spacing, op.mem.out_disp)) 241*9a0e4156SSadaf Ebrahimi str += format(")") 242*9a0e4156SSadaf Ebrahimi return str 243*9a0e4156SSadaf Ebrahimi 244*9a0e4156SSadaf Ebrahimi 245*9a0e4156SSadaf Ebrahimi if op.mem.bitfield: 246*9a0e4156SSadaf Ebrahimi return format("%d:%d" % ( op.mem.offset, op.mem.width)) 247*9a0e4156SSadaf Ebrahimi 248*9a0e4156SSadaf Ebrahimi ############# OK 249*9a0e4156SSadaf Ebrahimi if op.address_mode == M68K_AM_AREGI_INDEX_BASE_DISP: 250*9a0e4156SSadaf Ebrahimi if op.mem.index_size: 251*9a0e4156SSadaf Ebrahimi str_size = "l" 252*9a0e4156SSadaf Ebrahimi else: 253*9a0e4156SSadaf Ebrahimi str_size = "w" 254*9a0e4156SSadaf Ebrahimi bits = op.mem.disp 255*9a0e4156SSadaf Ebrahimi return dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016b}".format(bits) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + str_size + ")" 256*9a0e4156SSadaf Ebrahimi return '' 257*9a0e4156SSadaf Ebrahimi 258*9a0e4156SSadaf Ebrahimi 259*9a0e4156SSadaf Ebrahimi 260*9a0e4156SSadaf Ebrahimi# M68K Addressing Modes 261*9a0e4156SSadaf Ebrahimi 262*9a0e4156SSadaf Ebrahimimap_address_mode_str = { 263*9a0e4156SSadaf Ebrahimi 0 : "M68K_AM_NONE", 264*9a0e4156SSadaf Ebrahimi 1 : "M68K_AM_REG_DIRECT_DATA", 265*9a0e4156SSadaf Ebrahimi 2 : "M68K_AM_REG_DIRECT_ADDR", 266*9a0e4156SSadaf Ebrahimi 3 : "M68K_AM_REGI_ADDR", 267*9a0e4156SSadaf Ebrahimi 4 : "M68K_AM_REGI_ADDR_POST_INC", 268*9a0e4156SSadaf Ebrahimi 5 : "M68K_AM_REGI_ADDR_PRE_DEC", 269*9a0e4156SSadaf Ebrahimi 6 : "M68K_AM_REGI_ADDR_DISP", 270*9a0e4156SSadaf Ebrahimi 7 : "M68K_AM_AREGI_INDEX_8_BIT_DISP", 271*9a0e4156SSadaf Ebrahimi 8 : "M68K_AM_AREGI_INDEX_BASE_DISP", 272*9a0e4156SSadaf Ebrahimi 9 : "M68K_AM_MEMI_POST_INDEX", 273*9a0e4156SSadaf Ebrahimi 10 : "M68K_AM_MEMI_PRE_INDEX", 274*9a0e4156SSadaf Ebrahimi 11 : "M68K_AM_PCI_DISP", 275*9a0e4156SSadaf Ebrahimi 12 : "M68K_AM_PCI_INDEX_8_BIT_DISP", 276*9a0e4156SSadaf Ebrahimi 13 : "M68K_AM_PCI_INDEX_BASE_DISP", 277*9a0e4156SSadaf Ebrahimi 14 : "M68K_AM_PC_MEMI_POST_INDEX", 278*9a0e4156SSadaf Ebrahimi 15 : "M68K_AM_PC_MEMI_PRE_INDEX", 279*9a0e4156SSadaf Ebrahimi 16 : "M68K_AM_ABSOLUTE_DATA_SHORT", 280*9a0e4156SSadaf Ebrahimi 17 : "M68K_AM_ABSOLUTE_DATA_LONG", 281*9a0e4156SSadaf Ebrahimi 18 : "M68K_AM_IMMEDIATE", 282*9a0e4156SSadaf Ebrahimi } 283*9a0e4156SSadaf Ebrahimi 284*9a0e4156SSadaf Ebrahimi 285*9a0e4156SSadaf Ebrahimi# Operand type for instruction's operands 286*9a0e4156SSadaf Ebrahimi 287*9a0e4156SSadaf Ebrahimimap_op_str = { 288*9a0e4156SSadaf Ebrahimi 0 : "M68K_OP_INVALID", 289*9a0e4156SSadaf Ebrahimi 1 : "M68K_OP_REG", 290*9a0e4156SSadaf Ebrahimi 2 : "M68K_OP_IMM", 291*9a0e4156SSadaf Ebrahimi 3 : "M68K_OP_MEM", 292*9a0e4156SSadaf Ebrahimi 4 : "M68K_OP_FP", 293*9a0e4156SSadaf Ebrahimi 5 : "M68K_OP_REG_BITS", 294*9a0e4156SSadaf Ebrahimi 6 : "M68K_OP_REG_PAIR", 295*9a0e4156SSadaf Ebrahimi} 296*9a0e4156SSadaf Ebrahimi 297*9a0e4156SSadaf Ebrahimi 298*9a0e4156SSadaf Ebrahimidef debug(insn, op): 299*9a0e4156SSadaf Ebrahimi if len(sys.argv) > 3: 300*9a0e4156SSadaf Ebrahimi print("id %d type %s address_mode %s" % (insn.id, map_op_str[op.type], map_address_mode_str[op.address_mode])) 301*9a0e4156SSadaf Ebrahimi 302*9a0e4156SSadaf Ebrahimi 303*9a0e4156SSadaf Ebrahimidef dump_ops(insn): 304*9a0e4156SSadaf Ebrahimi str = '' 305*9a0e4156SSadaf Ebrahimi mnemonic = insn.insn_name() 306*9a0e4156SSadaf Ebrahimi 307*9a0e4156SSadaf Ebrahimi i = 0 308*9a0e4156SSadaf Ebrahimi while i < len(insn.operands): 309*9a0e4156SSadaf Ebrahimi if i > 0: 310*9a0e4156SSadaf Ebrahimi str += ',' 311*9a0e4156SSadaf Ebrahimi op = insn.operands[i] 312*9a0e4156SSadaf Ebrahimi debug(insn, op) 313*9a0e4156SSadaf Ebrahimi # "data" instruction generated by SKIPDATA option has no detail 314*9a0e4156SSadaf Ebrahimi if insn.id == M68K_INS_INVALID: 315*9a0e4156SSadaf Ebrahimi return format("0x%04x" % (op.imm)) 316*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_REG: 317*9a0e4156SSadaf Ebrahimi str_op_reg = dump_op_ea(insn, op) 318*9a0e4156SSadaf Ebrahimi if str_op_reg == '' or op.address_mode == M68K_AM_REG_DIRECT_ADDR: 319*9a0e4156SSadaf Ebrahimi str_op_reg = dump_op_reg(insn, op.reg) 320*9a0e4156SSadaf Ebrahimi str += str_op_reg 321*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_IMM: 322*9a0e4156SSadaf Ebrahimi str_op_imm = format("#%u" % (op.imm)) 323*9a0e4156SSadaf Ebrahimi if mnemonic in ["bkpt"]: 324*9a0e4156SSadaf Ebrahimi str_op_imm = format("%u" % (op.imm)) 325*9a0e4156SSadaf Ebrahimi signed_insn = [ "move", "moveq", "cmp", "cmpi", "ori", "bclr", "pack", "unpk", "sub", "add" ] 326*9a0e4156SSadaf Ebrahimi if mnemonic in signed_insn: 327*9a0e4156SSadaf Ebrahimi if insn.op_size.size == 1 or mnemonic == "moveq": 328*9a0e4156SSadaf Ebrahimi str_op_imm = format("#%d" % s8(op.imm)) 329*9a0e4156SSadaf Ebrahimi if insn.op_size.size == 2 or mnemonic == "pack": 330*9a0e4156SSadaf Ebrahimi str_op_imm = format("#%d" % s16(op.imm)) 331*9a0e4156SSadaf Ebrahimi if insn.op_size.size == 4: 332*9a0e4156SSadaf Ebrahimi str_op_imm = format("#%d" % (op.imm)) 333*9a0e4156SSadaf Ebrahimi 334*9a0e4156SSadaf Ebrahimi dbxx_insn = [ "dbt", "dbf", "dbhi", "dbls", "dbcc", "dbcs", "dbne", "dbeq", "dbvc", "dbvs", "dbpl", "dbmi", "dbge", "dblt", "dbgt", "dble", "dbra" ] 335*9a0e4156SSadaf Ebrahimi if is_branch(insn) or mnemonic in dbxx_insn: 336*9a0e4156SSadaf Ebrahimi str_op_imm = format("0x%x" % (op.imm & 0xffffffff)) 337*9a0e4156SSadaf Ebrahimi str += str_op_imm 338*9a0e4156SSadaf Ebrahimi if op.type == M68K_OP_MEM: 339*9a0e4156SSadaf Ebrahimi str_op_mem = dump_op_ea(insn, op) 340*9a0e4156SSadaf Ebrahimi if str_op_mem == '': 341*9a0e4156SSadaf Ebrahimi str_op_mem = format("0x%x" % (op.imm)) 342*9a0e4156SSadaf Ebrahimi str += str_op_mem 343*9a0e4156SSadaf Ebrahimi if op.type in [ M68K_OP_REG_BITS, M68K_OP_REG_PAIR ]: 344*9a0e4156SSadaf Ebrahimi str += dump_op_ea(insn, op) 345*9a0e4156SSadaf Ebrahimi 346*9a0e4156SSadaf Ebrahimi# if insn.address == 0x3127c: 347*9a0e4156SSadaf Ebrahimi# import pdb;pdb.set_trace() 348*9a0e4156SSadaf Ebrahimi# print("type %u am %u\n" % (op.type, op.address_mode)) 349*9a0e4156SSadaf Ebrahimi i += 1 350*9a0e4156SSadaf Ebrahimi return str 351*9a0e4156SSadaf Ebrahimi 352*9a0e4156SSadaf Ebrahimi 353*9a0e4156SSadaf Ebrahimidef is_branch(insn): 354*9a0e4156SSadaf Ebrahimi mnemonic = insn.insn_name() 355*9a0e4156SSadaf Ebrahimi branch_insn = [ "bsr", "bra", "bhi", "bls", "bcc", "bcs", "bne", "beq", "bvc", "bvs", "bpl", "bmi", "bge", "blt", "bgt", "ble" ]; 356*9a0e4156SSadaf Ebrahimi return mnemonic in branch_insn 357*9a0e4156SSadaf Ebrahimi 358*9a0e4156SSadaf Ebrahimidef dump_mnemonic(insn): 359*9a0e4156SSadaf Ebrahimi # "data" instruction generated by SKIPDATA option has no detail 360*9a0e4156SSadaf Ebrahimi if insn.id == M68K_INS_INVALID: 361*9a0e4156SSadaf Ebrahimi return ".short" 362*9a0e4156SSadaf Ebrahimi mnemonic = insn.insn_name() 363*9a0e4156SSadaf Ebrahimi ext = { 0: '', 1:'b', 2:'w', 4:'l' } 364*9a0e4156SSadaf Ebrahimi if is_branch(insn): 365*9a0e4156SSadaf Ebrahimi ext.update({ 1:'s', 2:'w', 4:'l' }) 366*9a0e4156SSadaf Ebrahimi 367*9a0e4156SSadaf Ebrahimi no_size = [ "pea", "lea", "bset", "bclr", "bchg", "btst", "nbcd", "abcd", "sbcd", "exg", "scc", "sls", "scs", "shi" ] 368*9a0e4156SSadaf Ebrahimi sxx_insn = [ "st", "sf", "shi", "sls", "scc", "scs", "sne", "seq", "svc", "svs", "spl", "smi", "sge", "slt", "sgt", "sle", "stop" ] 369*9a0e4156SSadaf Ebrahimi no_size += sxx_insn 370*9a0e4156SSadaf Ebrahimi no_size += [ "tas" ] 371*9a0e4156SSadaf Ebrahimi if mnemonic in no_size: 372*9a0e4156SSadaf Ebrahimi ext.update({ 0:'', 1:'', 2:'', 4:'' }) 373*9a0e4156SSadaf Ebrahimi return mnemonic + ext[insn.op_size.size] 374*9a0e4156SSadaf Ebrahimi 375*9a0e4156SSadaf Ebrahimidef print_insn_detail_np(insn): 376*9a0e4156SSadaf Ebrahimi # objdump format hack 377*9a0e4156SSadaf Ebrahimi if insn.size == 2: 378*9a0e4156SSadaf Ebrahimi space = ' ' * 11 379*9a0e4156SSadaf Ebrahimi if insn.size == 4: 380*9a0e4156SSadaf Ebrahimi space = ' ' * 6 381*9a0e4156SSadaf Ebrahimi if insn.size >= 6: 382*9a0e4156SSadaf Ebrahimi space = ' ' 383*9a0e4156SSadaf Ebrahimi space_ops = '' 384*9a0e4156SSadaf Ebrahimi if len(insn.operands) > 0: 385*9a0e4156SSadaf Ebrahimi space_ops = ' ' 386*9a0e4156SSadaf Ebrahimi 387*9a0e4156SSadaf Ebrahimi print(" %x:\t%s%s\t%s%s%s" % (insn.address, dump_bytes(insn._raw.bytes, min(insn.size, 6)), space, dump_mnemonic(insn), space_ops, dump_ops(insn))) 388*9a0e4156SSadaf Ebrahimi 389*9a0e4156SSadaf Ebrahimi if insn.size > 6: 390*9a0e4156SSadaf Ebrahimi delta = min(insn.size, 6) 391*9a0e4156SSadaf Ebrahimi print(" %x:\t%s " % (insn.address+delta, dump_bytes(insn._raw.bytes[delta:], min(insn.size-delta, 6)))) 392*9a0e4156SSadaf Ebrahimi 393*9a0e4156SSadaf Ebrahimi 394*9a0e4156SSadaf Ebrahimidef print_objdump_dumpheader(filename='', address=0): 395*9a0e4156SSadaf Ebrahimi print(objdump_dumpheader_fmt % (filename, address)) 396*9a0e4156SSadaf Ebrahimi 397*9a0e4156SSadaf Ebrahimi# ## Test class Cs 398*9a0e4156SSadaf Ebrahimidef test_class(): 399*9a0e4156SSadaf Ebrahimi for (arch, mode, code, comment) in all_tests: 400*9a0e4156SSadaf Ebrahimi filename = "/dev/stdin" 401*9a0e4156SSadaf Ebrahimi address = 0 402*9a0e4156SSadaf Ebrahimi if len(sys.argv) > 1: 403*9a0e4156SSadaf Ebrahimi filename = sys.argv[1] 404*9a0e4156SSadaf Ebrahimi if len(sys.argv) > 2: 405*9a0e4156SSadaf Ebrahimi address = int(sys.argv[2],16) 406*9a0e4156SSadaf Ebrahimi if len(sys.argv) > 3: 407*9a0e4156SSadaf Ebrahimi debug_mode = True 408*9a0e4156SSadaf Ebrahimi 409*9a0e4156SSadaf Ebrahimi with open(filename, "rb") as f: 410*9a0e4156SSadaf Ebrahimi code = f.read() 411*9a0e4156SSadaf Ebrahimi 412*9a0e4156SSadaf Ebrahimi try: 413*9a0e4156SSadaf Ebrahimi md = Cs(arch, mode) 414*9a0e4156SSadaf Ebrahimi md.detail = True 415*9a0e4156SSadaf Ebrahimi 416*9a0e4156SSadaf Ebrahimi print_objdump_dumpheader(filename, address) 417*9a0e4156SSadaf Ebrahimi 418*9a0e4156SSadaf Ebrahimi for insn in md.disasm(code, address): 419*9a0e4156SSadaf Ebrahimi print_insn_detail_np(insn) 420*9a0e4156SSadaf Ebrahimi 421*9a0e4156SSadaf Ebrahimi except CsError as e: 422*9a0e4156SSadaf Ebrahimi print("ERROR: %s" % e) 423*9a0e4156SSadaf Ebrahimi 424*9a0e4156SSadaf Ebrahimi 425*9a0e4156SSadaf Ebrahimiif __name__ == '__main__': 426*9a0e4156SSadaf Ebrahimi test_class() 427