Example #1
0
 def test_negative_float_str(self):
     value = Opcodes.make_addr_regoff(Opcodes.REGINDEX_TH, -42,
                                      Opcodes.ADDR_VALTYPE_FLOAT)
     self.assertEqual(Opcodes.make_addr_str(value).str, '[%TH-42]f')
Example #2
0
 def test_reg_addr_str(self):
     value = Opcodes.make_addr_reg(Opcodes.REGINDEX_TH)
     self.assertEqual(Opcodes.make_addr_str(value).str, '%TH')
Example #3
0
 def test_positive_int_str(self):
     value = Opcodes.make_addr_regoff(Opcodes.REGINDEX_TH, 42,
                                      Opcodes.ADDR_VALTYPE_INT)
     self.assertEqual(Opcodes.make_addr_str(value).str, '[%TH+42]i')
Example #4
0
def disasm_one(bytecode, offset):
    label = '0x%04x' % offset
    opcode = bytecode[offset]
    prev_offset = offset
    offset += 1
    maintype = Opcodes.opcode_type(opcode)
    subtype = Opcodes.opcode_subtype(opcode)
    variant = Opcodes.opcode_variant(opcode)

    if maintype == Opcodes.OPCODE_TYPE_BINARY:
        dst = Opcodes.make_addr_str(bytecode[offset:])
        offset += dst.size

        if variant == Opcodes.OPCODE_VARIANT_C:
            src, = struct.unpack('<%s' % dst.type, bytecode[offset:offset + 4])
            offset += 4
        elif variant == Opcodes.OPCODE_VARIANT_A:
            src = Opcodes.make_addr_str(bytecode[offset:])
            offset += src.size
        else:
            raise NotImplementedError

        name = {
            Opcodes.OPCODE_SUBTYPE_BINARY_ADD: 'ADD',
            Opcodes.OPCODE_SUBTYPE_BINARY_SUB: 'SUB',
            Opcodes.OPCODE_SUBTYPE_BINARY_MUL: 'MUL',
            Opcodes.OPCODE_SUBTYPE_BINARY_DIV: 'DIV',
            Opcodes.OPCODE_SUBTYPE_BINARY_CLT: 'CLT',
            Opcodes.OPCODE_SUBTYPE_BINARY_CGT: 'CGT',
            Opcodes.OPCODE_SUBTYPE_BINARY_CLTE: 'CLTE',
            Opcodes.OPCODE_SUBTYPE_BINARY_CGTE: 'CGTE',
            Opcodes.OPCODE_SUBTYPE_BINARY_CE: 'CE',
            Opcodes.OPCODE_SUBTYPE_BINARY_CN: 'CN',
            Opcodes.OPCODE_SUBTYPE_BINARY_AND: 'AND',
            Opcodes.OPCODE_SUBTYPE_BINARY_OR: 'OR',
            Opcodes.OPCODE_SUBTYPE_BINARY_LOAD: 'LOAD',
            Opcodes.OPCODE_SUBTYPE_BINARY_CAST: 'CAST',
        }[subtype]

        instr = '%- 10s %s, %s' % (name, dst, src)
    elif maintype == Opcodes.OPCODE_TYPE_UNARY:
        dst = Opcodes.make_addr_str(bytecode[offset:])
        offset += dst.size

        name = {
            Opcodes.OPCODE_SUBTYPE_UNARY_NOT: 'NOT',
            Opcodes.OPCODE_SUBTYPE_UNARY_NEG: 'NEG',
        }[subtype]
        instr = '%- 10s %s' % (name, dst)
    elif maintype == Opcodes.OPCODE_TYPE_STACK:
        if subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSHI:
            val, = struct.unpack('<i', bytecode[offset:offset + 4])
            offset += 4
            instr = '%- 10s %s' % ('PUSH', val)
        elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSHF:
            val, = struct.unpack('<f', bytecode[offset:offset + 4])
            offset += 4
            instr = '%- 10s %s' % ('PUSH', val)
        elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSH:
            src = Opcodes.make_addr_str(bytecode[offset:])
            offset += src.size
            instr = '%- 10s %s' % ('PUSH', src)
        elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_POP:
            src = Opcodes.make_addr_str(bytecode[offset:])
            offset += src.size
            instr = '%- 10s %s' % ('POP', src)
    elif maintype == Opcodes.OPCODE_TYPE_FLOW:
        if subtype == Opcodes.OPCODE_SUBTYPE_FLOW_JZ:
            if variant == Opcodes.OPCODE_VARIANT_A:
                cond = Opcodes.make_addr_str(bytecode[offset:])
                offset += cond.size
            elif variant == Opcode.OPCODE_VARIANT_CI:
                cond = struct.unpack('<i', bytecode[offset:offset + 2])
                offset += 2
            elif variant == Opcode.OPCODE_VARIANT_CF:
                cond = struct.unpack('<f', bytecode[offset:offset + 4])
                offset += 4
            else:
                raise NotImplementedError
            jumpto, = struct.unpack('<H', bytecode[offset:offset + 2])
            offset += 2
            instr = '%- 10s %s, 0x%04x' % ('JZ', cond, jumpto)
        elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_JUMP:
            jumpto, = struct.unpack('<H', bytecode[offset:offset + 2])
            offset += 2
            instr = '%- 10s 0x%04x' % ('JUMP', jumpto)
        elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_YIELD:
            instr = '%- 10s' % 'YIELD'
        elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_RET:
            instr = '%- 10s' % 'RET'
        elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_CALL:
            jumpto, = struct.unpack('<H', bytecode[offset:offset + 2])
            offset += 2
            instr = '%- 10s 0x%04x' % ('CALL', jumpto)
        else:
            raise NotImplementedError
    else:
        raise NotImplementedError

    print('%s %- 40s %s' % (label, instr, ' '.join(
        ['%02X' % val for val in bytecode[prev_offset:offset]])))

    return offset