Mercurial > paraspace
changeset 69:d07fd67e2b08
Add dalvik_opcode.py
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Fri, 01 Jul 2011 16:19:42 +0800 |
parents | b7432d6f7e93 |
children | 16a5a8eb1831 |
files | paraspace/dalvik_opcodes.py paraspace/tests/dalvik_opcodes_test.py |
diffstat | 2 files changed, 1243 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paraspace/dalvik_opcodes.py Fri Jul 01 16:19:42 2011 +0800 @@ -0,0 +1,1204 @@ +OP_NOP = 0x00 +OP_MOVE = 0x01 +OP_MOVE_FROM16 = 0x02 +OP_MOVE_16 = 0x03 +OP_MOVE_WIDE = 0x04 +OP_MOVE_WIDE_FROM16 = 0x05 +OP_MOVE_WIDE_16 = 0x06 +OP_MOVE_OBJECT = 0x07 +OP_MOVE_OBJECT_FROM16 = 0x08 +OP_MOVE_OBJECT_16 = 0x09 +OP_MOVE_RESULT = 0x0a +OP_MOVE_RESULT_WIDE = 0x0b +OP_MOVE_RESULT_OBJECT = 0x0c +OP_MOVE_EXCEPTION = 0x0d +OP_RETURN_VOID = 0x0e +OP_RETURN = 0x0f +OP_RETURN_WIDE = 0x10 +OP_RETURN_OBJECT = 0x11 +OP_CONST_4 = 0x12 +OP_CONST_16 = 0x13 +OP_CONST = 0x14 +OP_CONST_HIGH16 = 0x15 +OP_CONST_WIDE_16 = 0x16 +OP_CONST_WIDE_32 = 0x17 +OP_CONST_WIDE = 0x18 +OP_CONST_WIDE_HIGH16 = 0x19 +OP_CONST_STRING = 0x1a +OP_CONST_STRING_JUMBO = 0x1b +OP_CONST_CLASS = 0x1c +OP_MONITOR_ENTER = 0x1d +OP_MONITOR_EXIT = 0x1e +OP_CHECK_CAST = 0x1f +OP_INSTANCE_OF = 0x20 +OP_ARRAY_LENGTH = 0x21 +OP_NEW_INSTANCE = 0x22 +OP_NEW_ARRAY = 0x23 +OP_FILLED_NEW_ARRAY = 0x24 +OP_FILLED_NEW_ARRAY_RANGE = 0x25 +OP_FILL_ARRAY_DATA = 0x26 +OP_THROW = 0x27 +OP_GOTO = 0x28 +OP_GOTO_16 = 0x29 +OP_GOTO_32 = 0x2a +OP_PACKED_SWITCH = 0x2b +OP_SPARSE_SWITCH = 0x2c +OP_CMPL_FLOAT = 0x2d +OP_CMPG_FLOAT = 0x2e +OP_CMPL_DOUBLE = 0x2f +OP_CMPG_DOUBLE = 0x30 +OP_CMP_LONG = 0x31 +OP_IF_EQ = 0x32 +OP_IF_NE = 0x33 +OP_IF_LT = 0x34 +OP_IF_GE = 0x35 +OP_IF_GT = 0x36 +OP_IF_LE = 0x37 +OP_IF_EQZ = 0x38 +OP_IF_NEZ = 0x39 +OP_IF_LTZ = 0x3a +OP_IF_GEZ = 0x3b +OP_IF_GTZ = 0x3c +OP_IF_LEZ = 0x3d +OP_UNUSED_3E = 0x3e +OP_UNUSED_3F = 0x3f +OP_UNUSED_40 = 0x40 +OP_UNUSED_41 = 0x41 +OP_UNUSED_42 = 0x42 +OP_UNUSED_43 = 0x43 +OP_AGET = 0x44 +OP_AGET_WIDE = 0x45 +OP_AGET_OBJECT = 0x46 +OP_AGET_BOOLEAN = 0x47 +OP_AGET_BYTE = 0x48 +OP_AGET_CHAR = 0x49 +OP_AGET_SHORT = 0x4a +OP_APUT = 0x4b +OP_APUT_WIDE = 0x4c +OP_APUT_OBJECT = 0x4d +OP_APUT_BOOLEAN = 0x4e +OP_APUT_BYTE = 0x4f +OP_APUT_CHAR = 0x50 +OP_APUT_SHORT = 0x51 +OP_IGET = 0x52 +OP_IGET_WIDE = 0x53 +OP_IGET_OBJECT = 0x54 +OP_IGET_BOOLEAN = 0x55 +OP_IGET_BYTE = 0x56 +OP_IGET_CHAR = 0x57 +OP_IGET_SHORT = 0x58 +OP_IPUT = 0x59 +OP_IPUT_WIDE = 0x5a +OP_IPUT_OBJECT = 0x5b +OP_IPUT_BOOLEAN = 0x5c +OP_IPUT_BYTE = 0x5d +OP_IPUT_CHAR = 0x5e +OP_IPUT_SHORT = 0x5f +OP_SGET = 0x60 +OP_SGET_WIDE = 0x61 +OP_SGET_OBJECT = 0x62 +OP_SGET_BOOLEAN = 0x63 +OP_SGET_BYTE = 0x64 +OP_SGET_CHAR = 0x65 +OP_SGET_SHORT = 0x66 +OP_SPUT = 0x67 +OP_SPUT_WIDE = 0x68 +OP_SPUT_OBJECT = 0x69 +OP_SPUT_BOOLEAN = 0x6a +OP_SPUT_BYTE = 0x6b +OP_SPUT_CHAR = 0x6c +OP_SPUT_SHORT = 0x6d +OP_INVOKE_VIRTUAL = 0x6e +OP_INVOKE_SUPER = 0x6f +OP_INVOKE_DIRECT = 0x70 +OP_INVOKE_STATIC = 0x71 +OP_INVOKE_INTERFACE = 0x72 +OP_UNUSED_73 = 0x73 +OP_INVOKE_VIRTUAL_RANGE = 0x74 +OP_INVOKE_SUPER_RANGE = 0x75 +OP_INVOKE_DIRECT_RANGE = 0x76 +OP_INVOKE_STATIC_RANGE = 0x77 +OP_INVOKE_INTERFACE_RANGE = 0x78 +OP_UNUSED_79 = 0x79 +OP_UNUSED_7A = 0x7a +OP_NEG_INT = 0x7b +OP_NOT_INT = 0x7c +OP_NEG_LONG = 0x7d +OP_NOT_LONG = 0x7e +OP_NEG_FLOAT = 0x7f +OP_NEG_DOUBLE = 0x80 +OP_INT_TO_LONG = 0x81 +OP_INT_TO_FLOAT = 0x82 +OP_INT_TO_DOUBLE = 0x83 +OP_LONG_TO_INT = 0x84 +OP_LONG_TO_FLOAT = 0x85 +OP_LONG_TO_DOUBLE = 0x86 +OP_FLOAT_TO_INT = 0x87 +OP_FLOAT_TO_LONG = 0x88 +OP_FLOAT_TO_DOUBLE = 0x89 +OP_DOUBLE_TO_INT = 0x8a +OP_DOUBLE_TO_LONG = 0x8b +OP_DOUBLE_TO_FLOAT = 0x8c +OP_INT_TO_BYTE = 0x8d +OP_INT_TO_CHAR = 0x8e +OP_INT_TO_SHORT = 0x8f +OP_ADD_INT = 0x90 +OP_SUB_INT = 0x91 +OP_MUL_INT = 0x92 +OP_DIV_INT = 0x93 +OP_REM_INT = 0x94 +OP_AND_INT = 0x95 +OP_OR_INT = 0x96 +OP_XOR_INT = 0x97 +OP_SHL_INT = 0x98 +OP_SHR_INT = 0x99 +OP_USHR_INT = 0x9a +OP_ADD_LONG = 0x9b +OP_SUB_LONG = 0x9c +OP_MUL_LONG = 0x9d +OP_DIV_LONG = 0x9e +OP_REM_LONG = 0x9f +OP_AND_LONG = 0xa0 +OP_OR_LONG = 0xa1 +OP_XOR_LONG = 0xa2 +OP_SHL_LONG = 0xa3 +OP_SHR_LONG = 0xa4 +OP_USHR_LONG = 0xa5 +OP_ADD_FLOAT = 0xa6 +OP_SUB_FLOAT = 0xa7 +OP_MUL_FLOAT = 0xa8 +OP_DIV_FLOAT = 0xa9 +OP_REM_FLOAT = 0xaa +OP_ADD_DOUBLE = 0xab +OP_SUB_DOUBLE = 0xac +OP_MUL_DOUBLE = 0xad +OP_DIV_DOUBLE = 0xae +OP_REM_DOUBLE = 0xaf +OP_ADD_INT_2ADDR = 0xb0 +OP_SUB_INT_2ADDR = 0xb1 +OP_MUL_INT_2ADDR = 0xb2 +OP_DIV_INT_2ADDR = 0xb3 +OP_REM_INT_2ADDR = 0xb4 +OP_AND_INT_2ADDR = 0xb5 +OP_OR_INT_2ADDR = 0xb6 +OP_XOR_INT_2ADDR = 0xb7 +OP_SHL_INT_2ADDR = 0xb8 +OP_SHR_INT_2ADDR = 0xb9 +OP_USHR_INT_2ADDR = 0xba +OP_ADD_LONG_2ADDR = 0xbb +OP_SUB_LONG_2ADDR = 0xbc +OP_MUL_LONG_2ADDR = 0xbd +OP_DIV_LONG_2ADDR = 0xbe +OP_REM_LONG_2ADDR = 0xbf +OP_AND_LONG_2ADDR = 0xc0 +OP_OR_LONG_2ADDR = 0xc1 +OP_XOR_LONG_2ADDR = 0xc2 +OP_SHL_LONG_2ADDR = 0xc3 +OP_SHR_LONG_2ADDR = 0xc4 +OP_USHR_LONG_2ADDR = 0xc5 +OP_ADD_FLOAT_2ADDR = 0xc6 +OP_SUB_FLOAT_2ADDR = 0xc7 +OP_MUL_FLOAT_2ADDR = 0xc8 +OP_DIV_FLOAT_2ADDR = 0xc9 +OP_REM_FLOAT_2ADDR = 0xca +OP_ADD_DOUBLE_2ADDR = 0xcb +OP_SUB_DOUBLE_2ADDR = 0xcc +OP_MUL_DOUBLE_2ADDR = 0xcd +OP_DIV_DOUBLE_2ADDR = 0xce +OP_REM_DOUBLE_2ADDR = 0xcf +OP_ADD_INT_LIT16 = 0xd0 +OP_RSUB_INT = 0xd1 +OP_MUL_INT_LIT16 = 0xd2 +OP_DIV_INT_LIT16 = 0xd3 +OP_REM_INT_LIT16 = 0xd4 +OP_AND_INT_LIT16 = 0xd5 +OP_OR_INT_LIT16 = 0xd6 +OP_XOR_INT_LIT16 = 0xd7 +OP_ADD_INT_LIT8 = 0xd8 +OP_RSUB_INT_LIT8 = 0xd9 +OP_MUL_INT_LIT8 = 0xda +OP_DIV_INT_LIT8 = 0xdb +OP_REM_INT_LIT8 = 0xdc +OP_AND_INT_LIT8 = 0xdd +OP_OR_INT_LIT8 = 0xde +OP_XOR_INT_LIT8 = 0xdf +OP_SHL_INT_LIT8 = 0xe0 +OP_SHR_INT_LIT8 = 0xe1 +OP_USHR_INT_LIT8 = 0xe2 +OP_UNUSED_E3 = 0xe3 +OP_UNUSED_E4 = 0xe4 +OP_UNUSED_E5 = 0xe5 +OP_UNUSED_E6 = 0xe6 +OP_UNUSED_E7 = 0xe7 +OP_UNUSED_E8 = 0xe8 +OP_UNUSED_E9 = 0xe9 +OP_UNUSED_EA = 0xea +OP_UNUSED_EB = 0xeb +OP_UNUSED_EC = 0xec +OP_UNUSED_ED = 0xed +OP_EXECUTE_INLINE = 0xee +OP_UNUSED_EF = 0xef +OP_INVOKE_DIRECT_EMPTY = 0xf0 +OP_UNUSED_F1 = 0xf1 +OP_IGET_QUICK = 0xf2 +OP_IGET_WIDE_QUICK = 0xf3 +OP_IGET_OBJECT_QUICK = 0xf4 +OP_IPUT_QUICK = 0xf5 +OP_IPUT_WIDE_QUICK = 0xf6 +OP_IPUT_OBJECT_QUICK = 0xf7 +OP_INVOKE_VIRTUAL_QUICK = 0xf8 +OP_INVOKE_VIRTUAL_QUICK_RANGE = 0xf9 +OP_INVOKE_SUPER_QUICK = 0xfa +OP_INVOKE_SUPER_QUICK_RANGE = 0xfb +OP_UNUSED_FC = 0xfc +OP_UNUSED_FD = 0xfd +OP_UNUSED_FE = 0xfe +OP_UNUSED_FF = 0xff + +_g = dict(globals()) +opcode_names = sorted([name for name in _g if name.startswith('OP_')], + key=lambda name: _g[name]) +name_2_opcodes = dict([(name, code) for name, code in _g.items()]) +del _g + +opcode_widths = [0] * 256 + +w1_ops = '''OP_NOP +OP_MOVE +OP_MOVE_WIDE +OP_MOVE_OBJECT +OP_MOVE_RESULT +OP_MOVE_RESULT_WIDE +OP_MOVE_RESULT_OBJECT +OP_MOVE_EXCEPTION +OP_RETURN_VOID +OP_RETURN +OP_RETURN_WIDE +OP_RETURN_OBJECT +OP_CONST_4 +OP_MONITOR_ENTER +OP_MONITOR_EXIT +OP_ARRAY_LENGTH +OP_THROW +OP_GOTO +OP_NEG_INT +OP_NOT_INT +OP_NEG_LONG +OP_NOT_LONG +OP_NEG_FLOAT +OP_NEG_DOUBLE +OP_INT_TO_LONG +OP_INT_TO_FLOAT +OP_INT_TO_DOUBLE +OP_LONG_TO_INT +OP_LONG_TO_FLOAT +OP_LONG_TO_DOUBLE +OP_FLOAT_TO_INT +OP_FLOAT_TO_LONG +OP_FLOAT_TO_DOUBLE +OP_DOUBLE_TO_INT +OP_DOUBLE_TO_LONG +OP_DOUBLE_TO_FLOAT +OP_INT_TO_BYTE +OP_INT_TO_CHAR +OP_INT_TO_SHORT +OP_ADD_INT_2ADDR +OP_SUB_INT_2ADDR +OP_MUL_INT_2ADDR +OP_DIV_INT_2ADDR +OP_REM_INT_2ADDR +OP_AND_INT_2ADDR +OP_OR_INT_2ADDR +OP_XOR_INT_2ADDR +OP_SHL_INT_2ADDR +OP_SHR_INT_2ADDR +OP_USHR_INT_2ADDR +OP_ADD_LONG_2ADDR +OP_SUB_LONG_2ADDR +OP_MUL_LONG_2ADDR +OP_DIV_LONG_2ADDR +OP_REM_LONG_2ADDR +OP_AND_LONG_2ADDR +OP_OR_LONG_2ADDR +OP_XOR_LONG_2ADDR +OP_SHL_LONG_2ADDR +OP_SHR_LONG_2ADDR +OP_USHR_LONG_2ADDR +OP_ADD_FLOAT_2ADDR +OP_SUB_FLOAT_2ADDR +OP_MUL_FLOAT_2ADDR +OP_DIV_FLOAT_2ADDR +OP_REM_FLOAT_2ADDR +OP_ADD_DOUBLE_2ADDR +OP_SUB_DOUBLE_2ADDR +OP_MUL_DOUBLE_2ADDR +OP_DIV_DOUBLE_2ADDR +OP_REM_DOUBLE_2ADDR'''.split() + +for name in w1_ops: + opcode = name_2_opcodes[name] + opcode_widths[opcode] = 1 + pass + + +w2_ops = '''OP_MOVE_FROM16 +OP_MOVE_WIDE_FROM16 +OP_MOVE_OBJECT_FROM16 +OP_CONST_16 +OP_CONST_HIGH16 +OP_CONST_WIDE_16 +OP_CONST_WIDE_HIGH16 +OP_CONST_STRING +OP_CONST_CLASS +OP_CHECK_CAST +OP_INSTANCE_OF +OP_NEW_INSTANCE +OP_NEW_ARRAY +OP_CMPL_FLOAT +OP_CMPG_FLOAT +OP_CMPL_DOUBLE +OP_CMPG_DOUBLE +OP_CMP_LONG +OP_GOTO_16 +OP_IF_EQ +OP_IF_NE +OP_IF_LT +OP_IF_GE +OP_IF_GT +OP_IF_LE +OP_IF_EQZ +OP_IF_NEZ +OP_IF_LTZ +OP_IF_GEZ +OP_IF_GTZ +OP_IF_LEZ +OP_AGET +OP_AGET_WIDE +OP_AGET_OBJECT +OP_AGET_BOOLEAN +OP_AGET_BYTE +OP_AGET_CHAR +OP_AGET_SHORT +OP_APUT +OP_APUT_WIDE +OP_APUT_OBJECT +OP_APUT_BOOLEAN +OP_APUT_BYTE +OP_APUT_CHAR +OP_APUT_SHORT +OP_IGET +OP_IGET_WIDE +OP_IGET_OBJECT +OP_IGET_BOOLEAN +OP_IGET_BYTE +OP_IGET_CHAR +OP_IGET_SHORT +OP_IPUT +OP_IPUT_WIDE +OP_IPUT_OBJECT +OP_IPUT_BOOLEAN +OP_IPUT_BYTE +OP_IPUT_CHAR +OP_IPUT_SHORT +OP_SGET +OP_SGET_WIDE +OP_SGET_OBJECT +OP_SGET_BOOLEAN +OP_SGET_BYTE +OP_SGET_CHAR +OP_SGET_SHORT +OP_SPUT +OP_SPUT_WIDE +OP_SPUT_OBJECT +OP_SPUT_BOOLEAN +OP_SPUT_BYTE +OP_SPUT_CHAR +OP_SPUT_SHORT +OP_ADD_INT +OP_SUB_INT +OP_MUL_INT +OP_DIV_INT +OP_REM_INT +OP_AND_INT +OP_OR_INT +OP_XOR_INT +OP_SHL_INT +OP_SHR_INT +OP_USHR_INT +OP_ADD_LONG +OP_SUB_LONG +OP_MUL_LONG +OP_DIV_LONG +OP_REM_LONG +OP_AND_LONG +OP_OR_LONG +OP_XOR_LONG +OP_SHL_LONG +OP_SHR_LONG +OP_USHR_LONG +OP_ADD_FLOAT +OP_SUB_FLOAT +OP_MUL_FLOAT +OP_DIV_FLOAT +OP_REM_FLOAT +OP_ADD_DOUBLE +OP_SUB_DOUBLE +OP_MUL_DOUBLE +OP_DIV_DOUBLE +OP_REM_DOUBLE +OP_ADD_INT_LIT16 +OP_RSUB_INT +OP_MUL_INT_LIT16 +OP_DIV_INT_LIT16 +OP_REM_INT_LIT16 +OP_AND_INT_LIT16 +OP_OR_INT_LIT16 +OP_XOR_INT_LIT16 +OP_ADD_INT_LIT8 +OP_RSUB_INT_LIT8 +OP_MUL_INT_LIT8 +OP_DIV_INT_LIT8 +OP_REM_INT_LIT8 +OP_AND_INT_LIT8 +OP_OR_INT_LIT8 +OP_XOR_INT_LIT8 +OP_SHL_INT_LIT8 +OP_SHR_INT_LIT8 +OP_USHR_INT_LIT8'''.split() + +for name in w2_ops: + opcode = name_2_opcodes[name] + opcode_widths[opcode] = 2 + pass + + +w3_ops = '''OP_MOVE_16 +OP_MOVE_WIDE_16 +OP_MOVE_OBJECT_16 +OP_CONST +OP_CONST_WIDE_32 +OP_CONST_STRING_JUMBO +OP_GOTO_32 +OP_FILLED_NEW_ARRAY +OP_FILLED_NEW_ARRAY_RANGE +OP_FILL_ARRAY_DATA +OP_PACKED_SWITCH +OP_SPARSE_SWITCH +OP_INVOKE_VIRTUAL +OP_INVOKE_SUPER +OP_INVOKE_DIRECT +OP_INVOKE_STATIC +OP_INVOKE_INTERFACE +OP_INVOKE_VIRTUAL_RANGE +OP_INVOKE_SUPER_RANGE +OP_INVOKE_DIRECT_RANGE +OP_INVOKE_STATIC_RANGE +OP_INVOKE_INTERFACE_RANGE'''.split() + +for name in w3_ops: + opcode = name_2_opcodes[name] + opcode_widths[opcode] = 3 + pass + +opcode_widths[OP_CONST_WIDE] = 5 + +# +# Optimized instructions. We return negative size values for these +# to distinguish them. +# +w_2_ops = '''OP_IGET_QUICK +OP_IGET_WIDE_QUICK +OP_IGET_OBJECT_QUICK +OP_IPUT_QUICK +OP_IPUT_WIDE_QUICK +OP_IPUT_OBJECT_QUICK'''.split() + +for name in w_2_ops: + opcode = name_2_opcodes[name] + opcode_widths[opcode] = -2 + pass + + +w_3_ops = '''OP_INVOKE_VIRTUAL_QUICK +OP_INVOKE_VIRTUAL_QUICK_RANGE +OP_INVOKE_SUPER_QUICK +OP_INVOKE_SUPER_QUICK_RANGE +OP_EXECUTE_INLINE +OP_INVOKE_DIRECT_EMPTY'''.split() + +for name in w_3_ops: + opcode = name_2_opcodes[name] + opcode_widths[opcode] = -3 + pass + +w0_ops = '''OP_UNUSED_3E +OP_UNUSED_3F +OP_UNUSED_40 +OP_UNUSED_41 +OP_UNUSED_42 +OP_UNUSED_43 +OP_UNUSED_73 +OP_UNUSED_79 +OP_UNUSED_7A +OP_UNUSED_E3 +OP_UNUSED_E4 +OP_UNUSED_E5 +OP_UNUSED_E6 +OP_UNUSED_E7 +OP_UNUSED_E8 +OP_UNUSED_E9 +OP_UNUSED_EA +OP_UNUSED_EB +OP_UNUSED_EC +OP_UNUSED_ED +OP_UNUSED_EF +OP_UNUSED_F1 +OP_UNUSED_FC +OP_UNUSED_FD +OP_UNUSED_FE +OP_UNUSED_FF'''.split() + + +kFmtUnknown = 0 +kFmt10x = 1 +kFmt12x = 2 +kFmt11n = 3 +kFmt11x = 4 +kFmt10t = 5 +kFmt20t = 6 +kFmt22x = 7 +kFmt21t = 8 +kFmt21s = 9 +kFmt21h = 10 +kFmt21c = 11 +kFmt23x = 12 +kFmt22b = 13 +kFmt22t = 14 +kFmt22s = 15 +kFmt22c = 16 +kFmt22cs = 17 +kFmt32x = 18 +kFmt30t = 19 +kFmt31t = 20 +kFmt31i = 21 +kFmt31c = 22 +kFmt35c = 23 +kFmt35ms = 24 +kFmt35fs = 25 +kFmt3rc = 26 +kFmt3rms = 27 +kFmt3rfs = 28 +kFmt3inline = 29 +kFmt51l = 30 + +fmt_names = '''kFmtUnknown +kFmt10x +kFmt12x +kFmt11n +kFmt11x +kFmt10t +kFmt20t +kFmt22x +kFmt21t +kFmt21s +kFmt21h +kFmt21c +kFmt23x +kFmt22b +kFmt22t +kFmt22s +kFmt22c +kFmt22cs +kFmt32x +kFmt30t +kFmt31t +kFmt31i +kFmt31c +kFmt35c +kFmt35ms +kFmt35fs +kFmt3rc +kFmt3rms +kFmt3rfs +kFmt3inline +kFmt51l +'''.split() + +opcode_fmts = [0] * 256 + +opcode_fmts[OP_GOTO] = kFmt10t + +names = '''OP_NOP +OP_RETURN_VOID'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt10x + pass + + +opcode_fmts[OP_CONST_4] = kFmt11n + + +names = '''OP_CONST_HIGH16 +OP_CONST_WIDE_HIGH16'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt21h + pass + + +names = '''OP_MOVE_RESULT +OP_MOVE_RESULT_WIDE +OP_MOVE_RESULT_OBJECT +OP_MOVE_EXCEPTION +OP_RETURN +OP_RETURN_WIDE +OP_RETURN_OBJECT +OP_MONITOR_ENTER +OP_MONITOR_EXIT +OP_THROW'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt11x + pass + + +names = '''OP_MOVE +OP_MOVE_WIDE +OP_MOVE_OBJECT +OP_ARRAY_LENGTH +OP_NEG_INT +OP_NOT_INT +OP_NEG_LONG +OP_NOT_LONG +OP_NEG_FLOAT +OP_NEG_DOUBLE +OP_INT_TO_LONG +OP_INT_TO_FLOAT +OP_INT_TO_DOUBLE +OP_LONG_TO_INT +OP_LONG_TO_FLOAT +OP_LONG_TO_DOUBLE +OP_FLOAT_TO_INT +OP_FLOAT_TO_LONG +OP_FLOAT_TO_DOUBLE +OP_DOUBLE_TO_INT +OP_DOUBLE_TO_LONG +OP_DOUBLE_TO_FLOAT +OP_INT_TO_BYTE +OP_INT_TO_CHAR +OP_INT_TO_SHORT +OP_ADD_INT_2ADDR +OP_SUB_INT_2ADDR +OP_MUL_INT_2ADDR +OP_DIV_INT_2ADDR +OP_REM_INT_2ADDR +OP_AND_INT_2ADDR +OP_OR_INT_2ADDR +OP_XOR_INT_2ADDR +OP_SHL_INT_2ADDR +OP_SHR_INT_2ADDR +OP_USHR_INT_2ADDR +OP_ADD_LONG_2ADDR +OP_SUB_LONG_2ADDR +OP_MUL_LONG_2ADDR +OP_DIV_LONG_2ADDR +OP_REM_LONG_2ADDR +OP_AND_LONG_2ADDR +OP_OR_LONG_2ADDR +OP_XOR_LONG_2ADDR +OP_SHL_LONG_2ADDR +OP_SHR_LONG_2ADDR +OP_USHR_LONG_2ADDR +OP_ADD_FLOAT_2ADDR +OP_SUB_FLOAT_2ADDR +OP_MUL_FLOAT_2ADDR +OP_DIV_FLOAT_2ADDR +OP_REM_FLOAT_2ADDR +OP_ADD_DOUBLE_2ADDR +OP_SUB_DOUBLE_2ADDR +OP_MUL_DOUBLE_2ADDR +OP_DIV_DOUBLE_2ADDR +OP_REM_DOUBLE_2ADDR'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt12x + pass + + +opcode_fmts[OP_GOTO_16] = kFmt20t +opcode_fmts[OP_GOTO_32] = kFmt30t + + +names = '''OP_CONST_STRING +OP_CONST_CLASS +OP_CHECK_CAST +OP_NEW_INSTANCE +OP_SGET +OP_SGET_WIDE +OP_SGET_OBJECT +OP_SGET_BOOLEAN +OP_SGET_BYTE +OP_SGET_CHAR +OP_SGET_SHORT +OP_SPUT +OP_SPUT_WIDE +OP_SPUT_OBJECT +OP_SPUT_BOOLEAN +OP_SPUT_BYTE +OP_SPUT_CHAR +OP_SPUT_SHORT'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt21c + pass + +names = '''OP_CONST_16 +OP_CONST_WIDE_16'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt21s + pass + + +names = '''OP_IF_EQZ +OP_IF_NEZ +OP_IF_LTZ +OP_IF_GEZ +OP_IF_GTZ +OP_IF_LEZ'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt21t + pass + + +names = '''OP_FILL_ARRAY_DATA +OP_PACKED_SWITCH +OP_SPARSE_SWITCH'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt31t + pass + + +names = '''OP_ADD_INT_LIT8 +OP_RSUB_INT_LIT8 +OP_MUL_INT_LIT8 +OP_DIV_INT_LIT8 +OP_REM_INT_LIT8 +OP_AND_INT_LIT8 +OP_OR_INT_LIT8 +OP_XOR_INT_LIT8 +OP_SHL_INT_LIT8 +OP_SHR_INT_LIT8 +OP_USHR_INT_LIT8'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22b + pass + + +names = '''OP_INSTANCE_OF +OP_NEW_ARRAY +OP_IGET +OP_IGET_WIDE +OP_IGET_OBJECT +OP_IGET_BOOLEAN +OP_IGET_BYTE +OP_IGET_CHAR +OP_IGET_SHORT +OP_IPUT +OP_IPUT_WIDE +OP_IPUT_OBJECT +OP_IPUT_BOOLEAN +OP_IPUT_BYTE +OP_IPUT_CHAR +OP_IPUT_SHORT'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22c + pass + + +names = '''OP_ADD_INT_LIT16 +OP_RSUB_INT +OP_MUL_INT_LIT16 +OP_DIV_INT_LIT16 +OP_REM_INT_LIT16 +OP_AND_INT_LIT16 +OP_OR_INT_LIT16 +OP_XOR_INT_LIT16'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22s + pass + + +names = '''OP_IF_EQ +OP_IF_NE +OP_IF_LT +OP_IF_GE +OP_IF_GT +OP_IF_LE'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22t + pass + + +names = '''OP_MOVE_FROM16 +OP_MOVE_WIDE_FROM16 +OP_MOVE_OBJECT_FROM16'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22x + pass + + +names = '''OP_CMPL_FLOAT +OP_CMPG_FLOAT +OP_CMPL_DOUBLE +OP_CMPG_DOUBLE +OP_CMP_LONG +OP_AGET +OP_AGET_WIDE +OP_AGET_OBJECT +OP_AGET_BOOLEAN +OP_AGET_BYTE +OP_AGET_CHAR +OP_AGET_SHORT +OP_APUT +OP_APUT_WIDE +OP_APUT_OBJECT +OP_APUT_BOOLEAN +OP_APUT_BYTE +OP_APUT_CHAR +OP_APUT_SHORT +OP_ADD_INT +OP_SUB_INT +OP_MUL_INT +OP_DIV_INT +OP_REM_INT +OP_AND_INT +OP_OR_INT +OP_XOR_INT +OP_SHL_INT +OP_SHR_INT +OP_USHR_INT +OP_ADD_LONG +OP_SUB_LONG +OP_MUL_LONG +OP_DIV_LONG +OP_REM_LONG +OP_AND_LONG +OP_OR_LONG +OP_XOR_LONG +OP_SHL_LONG +OP_SHR_LONG +OP_USHR_LONG +OP_ADD_FLOAT +OP_SUB_FLOAT +OP_MUL_FLOAT +OP_DIV_FLOAT +OP_REM_FLOAT +OP_ADD_DOUBLE +OP_SUB_DOUBLE +OP_MUL_DOUBLE +OP_DIV_DOUBLE +OP_REM_DOUBLE'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt23x + pass + + +names = '''OP_CONST +OP_CONST_WIDE_32'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt31i + pass + + +opcode_fmts[OP_CONST_STRING_JUMBO] = kFmt31c + + +names = '''OP_MOVE_16 +OP_MOVE_WIDE_16 +OP_MOVE_OBJECT_16'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt32x + pass + + +names = '''OP_FILLED_NEW_ARRAY +OP_INVOKE_VIRTUAL +OP_INVOKE_SUPER +OP_INVOKE_DIRECT +OP_INVOKE_STATIC +OP_INVOKE_INTERFACE'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt35c + pass + + +names = '''OP_FILLED_NEW_ARRAY_RANGE +OP_INVOKE_VIRTUAL_RANGE +OP_INVOKE_SUPER_RANGE +OP_INVOKE_DIRECT_RANGE +OP_INVOKE_STATIC_RANGE +OP_INVOKE_INTERFACE_RANGE'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt3rc + pass + + +opcode_fmts[OP_CONST_WIDE] = kFmt51l + + +names = '''OP_IGET_QUICK +OP_IGET_WIDE_QUICK +OP_IGET_OBJECT_QUICK +OP_IPUT_QUICK +OP_IPUT_WIDE_QUICK +OP_IPUT_OBJECT_QUICK'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt22cs + pass + + +names = '''OP_INVOKE_VIRTUAL_QUICK +OP_INVOKE_SUPER_QUICK'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt35ms + pass + + +names = '''OP_INVOKE_VIRTUAL_QUICK_RANGE +OP_INVOKE_SUPER_QUICK_RANGE'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmt3rms + pass + + +opcode_fmts[OP_EXECUTE_INLINE] = kFmt3inline + +opcode_fmts[OP_INVOKE_DIRECT_EMPTY] = kFmt35c + + +names = '''OP_UNUSED_3E +OP_UNUSED_3F +OP_UNUSED_40 +OP_UNUSED_41 +OP_UNUSED_42 +OP_UNUSED_43 +OP_UNUSED_73 +OP_UNUSED_79 +OP_UNUSED_7A +OP_UNUSED_E3 +OP_UNUSED_E4 +OP_UNUSED_E5 +OP_UNUSED_E6 +OP_UNUSED_E7 +OP_UNUSED_E8 +OP_UNUSED_E9 +OP_UNUSED_EA +OP_UNUSED_EB +OP_UNUSED_EC +OP_UNUSED_ED +OP_UNUSED_EF +OP_UNUSED_F1 +OP_UNUSED_FC +OP_UNUSED_FD +OP_UNUSED_FE +OP_UNUSED_FF'''.split() +for name in names: + opcode = name_2_opcodes[name] + opcode_fmts[opcode] = kFmtUnknown + pass + + +fmt_fmtstr = { +'kFmtUnknown': '', +'kFmt10x': '', +'kFmt12x': 'vA, vB', +'kFmt11n': 'vA, #+B', +'kFmt11x': 'vAA', +'kFmt10t': '+AA', +'kFmt20t': '+AAAA', +'kFmt22x': 'vAA, vBBBB', +'kFmt21t': 'vAA, +BBBB', +'kFmt21s': 'vAA, #+BBBB', +'kFmt21h': 'vAA, #+BBBB00000[00000000]', +'kFmt21c': 'vAA, thing@BBBB', +'kFmt23x': 'vAA, vBB, vCC', +'kFmt22b': 'vAA, vBB, #+CC', +'kFmt22t': 'vA, vB, +CCCC', +'kFmt22s': 'vA, vB, #+CCCC', +'kFmt22c': 'vA, vB, thing@CCCC', +'kFmt22cs': 'vA, vB, field offset CCCC', +'kFmt32x': 'vAAAA, vBBBB', +'kFmt30t': '+AAAAAAAA', +'kFmt31t': 'vAA, +BBBBBBBB', +'kFmt31i': 'vAA, #+BBBBBBBB', +'kFmt31c': 'vAA, thing@BBBBBBBB', +'kFmt35c': '{vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)', +'kFmt35ms': 'invoke-virtual+super', +'kFmt35fs': 'invoke-interface', +'kFmt3rc': '{vCCCC .. v(CCCC+AA-1)}, meth@BBBB', +'kFmt3rms': 'invoke-virtual+super/range', +'kFmt3rfs': 'invoke-interface/range', +'kFmt3inline': 'inline invoke', +'kFmt51l': 'vAA, #+BBBBBBBBBBBBBBBB' +} + +fmt_parse_cfgs = { +'kFmtUnknown': (), # '' +'kFmt10x': (), # '' +'kFmt12x': (1, 1), # 'vA, vB' +'kFmt11n': (1, 2), # 'vA, #+B' +'kFmt11x': (2,), # 'vAA' +'kFmt10t': (2,), # '+AA' +'kFmt20t': (4,), # '+AAAA' +'kFmt22x': (2, 4), # 'vAA, vBBBB' +'kFmt21t': (2, 4), # 'vAA, +BBBB' +'kFmt21s': (2, 4), # 'vAA, #+BBBB' +'kFmt21h': (2, 4), # 'vAA, #+BBBB00000[00000000]' +'kFmt21c': (2, 4), # 'vAA, thing@BBBB' +'kFmt23x': (2, 2, 2), # 'vAA, vBB, vCC' +'kFmt22b': (2, 2, 2), # 'vAA, vBB, #+CC' +'kFmt22t': (1, 1, 4), # 'vA, vB, +CCCC' +'kFmt22s': (1, 1, 4), # 'vA, vB, #+CCCC' +'kFmt22c': (1, 1, 4), # 'vA, vB, thing@CCCC' +'kFmt22cs': (1, 1, 4), # 'vA, vB, field offset CCCC' +'kFmt32x': (4, 4), # 'vAAAA, vBBBB' +'kFmt30t': (8,), # '+AAAAAAAA' +'kFmt31t': (2, 8), # 'vAA, +BBBBBBBB' +'kFmt31i': (2, 8), # 'vAA, #+BBBBBBBB' +'kFmt31c': (2, 8), # 'vAA, thing@BBBBBBBB' +# '{vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)' +'kFmt35c': (1, 1, 4, 1, 1, 1, 1), +'kFmt35ms': (1, 1, 4, 1, 1, 1, 1), # 'invoke-virtual+super' +'kFmt35fs': (), # 'invoke-interface' +'kFmt3rc': (2, 4, 4), # '{vCCCC .. v(CCCC+AA-1)}, meth@BBBB' +'kFmt3rms': (2, 4, 4), # 'invoke-virtual+super/range' +'kFmt3rfs': (), # 'invoke-interface/range' +'kFmt3inline': (1, 1, 4, 1, 1, 1, 1), # 'inline invoke' +'kFmt51l': (2, 16) # 'vAA, #+BBBBBBBBBBBBBBBB' +} + +def decode_inst(insn): + def build_arg(sz): + if sz == 1: + if build_arg.off & 0x1: + arg = ord(insn[build_arg.off / 2]) >> 4 + else: + arg = ord(insn[build_arg.off / 2]) & 0xf + pass + build_arg.off = build_arg.off + 1 + pass + elif sz == 2: + build_arg.off = (build_arg.off + 1) & ~0x1 + arg = ord(insn[build_arg.off / 2]) + build_arg.off = build_arg.off + 2 + elif sz == 4: + build_arg.off = (build_arg.off + 3) & ~0x3 + arg = ord(insn[build_arg.off / 2]) | \ + (ord(insn[build_arg.off / 2 + 1]) << 8) + build_arg.off = build_arg.off + 4 + elif sz == 8: + build_arg.off = (build_arg.off + 3) & ~0x3 + arg = ord(insn[build_arg.off / 2]) | \ + (ord(insn[build_arg.off / 2 + 1]) << 8) | \ + (ord(insn[build_arg.off / 2 + 2]) << 16)| \ + (ord(insn[build_arg.off / 2 + 3]) << 24) + build_arg.off = build_arg.off + 8 + elif sz == 16: + build_arg.off = (build_arg.off + 3) & ~0x3 + arg = ord(insn[build_arg.off / 2]) | \ + (ord(insn[build_arg.off / 2 + 1]) << 8) | \ + (ord(insn[build_arg.off / 2 + 2]) << 16)| \ + (ord(insn[build_arg.off / 2 + 3]) << 24)| \ + (ord(insn[build_arg.off / 2 + 4]) << 32)| \ + (ord(insn[build_arg.off / 2 + 5]) << 40)| \ + (ord(insn[build_arg.off / 2 + 6]) << 48)| \ + (ord(insn[build_arg.off / 2 + 7]) << 52) + build_arg.off = build_arg.off + 16 + else: + raise ValueError, 'Invalid argument size %d' % (sz) + + return arg + + build_arg.off = 2 + + opcode = ord(insn[0]) + + fmt = opcode_fmts[opcode] + fmt_name = fmt_names[fmt] + fmt_parse_cfg = fmt_parse_cfgs[fmt_name] + + args = tuple([build_arg(sz) for sz in fmt_parse_cfg]) + op_vector = (opcode, args) + return op_vector + + +def encode_inst(op_vector): + def encode_arg(arg, sz): + if sz == 1: + if encode_arg.off & 0x1: + arg_txt = chr((arg << 4) | encode_arg.value) + else: + arg_txt = '' + encode_arg.value = arg + pass + encode_arg.off = encode_arg.off + 1 + pass + elif sz in (2, 4, 8, 16): + if encode_arg.off & 0x1: + arg_txt = chr(encode_arg.value) + encode_arg.off = encode_arg.off + 1 + else: + arg_txt = '' + pass + if sz == 2: + arg_txt = arg_txt + chr(arg) + encode_arg.off = encode_arg.off + 2 + elif sz in (4, 8, 16): + while encode_arg.off % 4: + encode_arg.off = encoe_arg.off + 1 + arg_txt = arg_txt + chr(0) + pass + for i in range(sz / 4): + arg_txt = arg_txt + \ + chr(arg & 0xff) + chr((arg >> 8) & 0xff) + pass + pass + pass + else: + raise ValueError, 'invalid argument size %d' % (sz) + + return arg_txt + encode_arg.off = 2 + encode_arg.value = 0 + + opcode, args = op_vector + + fmt = opcode_fmts[opcode] + fmt_name = fmt_names[fmt] + fmt_parse_cfg = fmt_parse_cfgs[fmt_name] + arg_part = ''.join([encode_arg(arg, sz) + for arg, sz in map(None, args, fmt_parse_cfg)]) + + inst = chr(opcode) + arg_part + return inst + +del name +del names +del opcode
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paraspace/tests/dalvik_opcodes_test.py Fri Jul 01 16:19:42 2011 +0800 @@ -0,0 +1,39 @@ +from paraspace.dalvik_opcodes import decode_inst, encode_inst + +def encode_inst_test(): + opv = (0x90, (00, 02, 03)) + insn = encode_inst(opv) + assert len(insn) == 4 + assert insn == '\x90\00\02\03' + + opv = (0x59, (0, 2, 0x0002)) + insn = encode_inst(opv) + assert insn == '\x59\x20\x02\x00' + + opv = (0x6f, (0, 1, 0xa601, 1, 0, 0, 0)) + insn = encode_inst(opv) + assert insn == '\x6f\x10\x01\xa6\x01\x00' + pass + +def decode_inst_test(): + insn = '\x90\00\02\03' + opv = decode_inst(insn) + opcode, args = opv + assert opcode == 0x90 + assert len(args) == 3 + assert args == (0, 2, 3) + + insn = '\x59\x20\x02\x00' + opv = decode_inst(insn) + opcode, args = opv + assert opcode == 0x59 + assert len(args) == 3 + assert args == (0, 2, 0x0002) + + insn = '\x6f\x10\x01\xa6\x01\x00' + opv = decode_inst(insn) + opcode, args = opv + assert opcode == 0x6f + assert len(args) == 7 + assert args == (0, 1, 0xa601, 1, 0, 0, 0) + pass