Ejemplo n.º 1
0
def read_closure(settings, interps, heaps, pointer):
    try:
        if isinstance(pointer, Argument) or isinstance(pointer, CaseArgument) or isinstance(pointer, Offset) and isinstance(pointer.base, CasePointer):
            return

        if settings.opts.verbose:
            print("Found closure:")
            print("    Pointer:", show.show_pretty_pointer(settings, pointer))

        if isinstance(pointer, StaticValue) and show.name_is_library(show.get_name_for_address(settings, pointer.value)):
            if settings.opts.verbose:
                print("    Library defined!")
                print()
            return

        info_pointer = ptrutil.dereference(settings, pointer, heaps, []).untagged
        assert isinstance(info_pointer, StaticValue)
        info_address = info_pointer.value

        info_type = info.read_closure_type(settings, info_address)
        if info_type[:11] == 'constructor':
            num_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*4)
            num_non_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*3)

            args = []
            arg_pointer = ptrutil.make_tagged(settings, pointer)._replace(tag = 0)
            for i in range(num_ptrs + num_non_ptrs):
                arg_pointer = ptrutil.pointer_offset(settings, arg_pointer, settings.rt.word.size);
                args.append(ptrutil.dereference(settings, arg_pointer.untagged, heaps, []))

            arg_pattern = 'p' * num_ptrs + 'n' * num_non_ptrs

            interps[pointer] = Apply(func = Pointer(info_pointer), func_type = 'constructor', args = interp_args(args, arg_pattern), pattern = arg_pattern)
            if settings.opts.verbose:
                print()

            for arg in args[:num_ptrs]:
                read_closure(settings, interps, arg.untagged)

            return
        elif info_type[:8] == 'function':
            arg_pattern = info.read_arg_pattern(settings, info_address)
        else:
            arg_pattern = ''

        if settings.opts.verbose:
            print()

        interps[pointer] = Pointer(info_pointer)

        read_function_thunk(settings, interps, heaps, info_address, ptrutil.make_tagged(settings, pointer)._replace(tag = len(arg_pattern)), arg_pattern)
    except:
        e_type, e_obj, e_tb = sys.exc_info()
        print("Error when processing closure at", show.show_pretty_pointer(settings, pointer))
        print("    Error:", e_obj)
        print("    Error Location:", e_tb.tb_lineno)
        print("    No Disassembly Available")
        print()
Ejemplo n.º 2
0
def read_closure(settings, worklist, heaps, pointer):
    try:
        info_pointer = ptrutil.dereference(settings, pointer, heaps, []).untagged
        assert isinstance(info_pointer, StaticValue)
        info_address = info_pointer.value

        info_type = info.read_closure_type(settings, info_address)
        if settings.opts.verbose:
            print("    Type:", info_type)

        if info_type[:11] == 'constructor':
            num_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*4)
            num_non_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*3)

            args = []
            arg_pointer = ptrutil.make_tagged(settings, pointer)._replace(tag = 0)
            for i in range(num_ptrs + num_non_ptrs):
                arg_pointer = ptrutil.pointer_offset(settings, arg_pointer, settings.rt.word.size);
                args.append(ptrutil.dereference(settings, arg_pointer.untagged, heaps, []))

            arg_pattern = 'p' * num_ptrs + 'n' * num_non_ptrs

            for arg in args[:num_ptrs]:
                worklist.append(ClosureWork(heaps = heaps, pointer = arg.untagged))

            return Apply(func = Pointer(info_pointer), func_type = 'constructor', args = interp_args(args, arg_pattern), pattern = arg_pattern)
        elif info_type[:11] == 'indirection':
            tagged = ptrutil.make_tagged(settings, pointer)._replace(tag = 0)
            offset = ptrutil.pointer_offset(settings, tagged, settings.rt.word.size)
            new_ptr = ptrutil.dereference(settings, offset.untagged, heaps, [])

            if settings.opts.verbose:
                print()

            worklist.append(ClosureWork(heaps = heaps, pointer = new_ptr.untagged))
            return Pointer(new_ptr.untagged)
        elif info_type[:8] == 'function':
            arg_pattern = info.read_arg_pattern(settings, info_address)
        else:
            arg_pattern = ''

        worklist.append(FunctionThunkWork(heaps = heaps, address = info_address, main_register = ptrutil.make_tagged(settings, pointer)._replace(tag = len(arg_pattern)), arg_pattern = arg_pattern))
        return Pointer(info_pointer)

    except:
        e_type, e_obj, e_tb = sys.exc_info()
        print("Error when processing closure at", show.show_pretty_pointer(settings, pointer))
        print("    Error:", e_obj)
        print("    Error Location:", e_tb.tb_lineno)
        print("    No Disassembly Available")
        print()
        return UnknownInterpretation()
Ejemplo n.º 3
0
def read_closure_type(settings, address):
    type_table = {
        1: 'constructor',
        2: 'constructor (1 ptr, 0 nonptr)',
        3: 'constructor (0 ptr, 1 nonptr)',
        4: 'constructor (2 ptr, 0 nonptr)',
        5: 'constructor (1 ptr, 1 nonptr)',
        6: 'constructor (0 ptr, 2 nonptr)',
        7: 'constructor (static)',
        8: 'constructor (no CAF, static)',
        9: 'function',
        10: 'function (1 ptr, 0 nonptr)',
        11: 'function (0 ptr, 1 nonptr)',
        12: 'function (2 ptr, 0 nonptr)',
        13: 'function (1 ptr, 1 nonptr)',
        14: 'function (0 ptr, 2 nonptr)',
        15: 'function (static)',
        16: 'thunk',
        17: 'thunk (1 ptr, 0 nonptr)',
        18: 'thunk (0 ptr, 1 nonptr)',
        19: 'thunk (2 ptr, 0 nonptr)',
        20: 'thunk (1 ptr, 1 nonptr)',
        21: 'thunk (0 ptr, 2 nonptr)',
        22: 'thunk (static)',
        23: 'selector',
        28: 'indirection',
        29: 'indirection (permanent)',
        30: 'indirection (static)'
    }
    type = ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*2)
    if type in type_table:
        return type_table[type]
    else:
        return 'unknown: ' + str(type)
Ejemplo n.º 4
0
def read_closure_type(settings, address):
    type_table = {
        1: 'constructor',
        2: 'constructor (1 ptr, 0 nonptr)',
        3: 'constructor (0 ptr, 1 nonptr)',
        4: 'constructor (2 ptr, 0 nonptr)',
        5: 'constructor (1 ptr, 1 nonptr)',
        6: 'constructor (0 ptr, 2 nonptr)',
        7: 'constructor (static)',
        8: 'constructor (no CAF, static)',
        9: 'function',
        10: 'function (1 ptr, 0 nonptr)',
        11: 'function (0 ptr, 1 nonptr)',
        12: 'function (2 ptr, 0 nonptr)',
        13: 'function (1 ptr, 1 nonptr)',
        14: 'function (0 ptr, 2 nonptr)',
        15: 'function (static)',
        16: 'thunk',
        17: 'thunk (1 ptr, 0 nonptr)',
        18: 'thunk (0 ptr, 1 nonptr)',
        19: 'thunk (2 ptr, 0 nonptr)',
        20: 'thunk (1 ptr, 1 nonptr)',
        21: 'thunk (0 ptr, 2 nonptr)',
        22: 'thunk (static)',
        23: 'selector'
    }
    type = ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*2)
    if type in type_table:
        return type_table[type]
    else:
        return 'unknown: ' + str(type)
Ejemplo n.º 5
0
def read_closure_type(settings, address):
    type_table = {
        1: "constructor",
        2: "constructor (1 ptr, 0 nonptr)",
        3: "constructor (0 ptr, 1 nonptr)",
        4: "constructor (2 ptr, 0 nonptr)",
        5: "constructor (1 ptr, 1 nonptr)",
        6: "constructor (0 ptr, 2 nonptr)",
        7: "constructor (static)",
        8: "constructor (no CAF, static)",
        9: "function",
        10: "function (1 ptr, 0 nonptr)",
        11: "function (0 ptr, 1 nonptr)",
        12: "function (2 ptr, 0 nonptr)",
        13: "function (1 ptr, 1 nonptr)",
        14: "function (0 ptr, 2 nonptr)",
        15: "function (static)",
        16: "thunk",
        17: "thunk (1 ptr, 0 nonptr)",
        18: "thunk (0 ptr, 1 nonptr)",
        19: "thunk (2 ptr, 0 nonptr)",
        20: "thunk (1 ptr, 1 nonptr)",
        21: "thunk (0 ptr, 2 nonptr)",
        22: "thunk (static)",
        23: "selector",
        28: "indirection",
        29: "indirection (permanent)",
        30: "indirection (static)",
    }
    type = ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size * 2)
    if type in type_table:
        return type_table[type]
    else:
        return "unknown: " + str(type)
Ejemplo n.º 6
0
def read_function_type(settings, address):
    type_table = {
        3: '',
        4: 'n',
        5: 'p',
        12: 'nn',
        13: 'np',
        14: 'pn',
        15: 'pp',
        16: 'nnn',
        17: 'nnp',
        18: 'npn',
        19: 'npp',
        20: 'pnn',
        21: 'pnp',
        22: 'ppn',
        23: 'ppp',
        24: 'pppp',
        25: 'ppppp',
        26: 'pppppp',
        27: 'ppppppp',
        28: 'pppppppp'
    }
    type = ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*6)
    if type >= 12 and settings.version < (7, 8, 0):
        # Introduction of vector arguments
        type += 3
    if type in type_table:
        return type_table[type]
    elif type == 0:
        bitmap = ptrutil.read_word(settings, settings.text_offset + address - settings.rt.word.size*5)
        size = bitmap & (settings.word.size - 1)
        bits = bitmap >> settings.word.lg_size
        ret = ''
        for i in range(size):
            if bits % 2 == 0:
                ret += 'p'
            else:
                ret += 'n'
            bits //= 2
        return ret
    else:
       # TODO: Read large bitmaps
       #assert False, "unknown function type" + str(type) + " at "+str(hex(address))
       print("##################")
       print("##################")
       print("##################")
       return 'x'
Ejemplo n.º 7
0
def read_function_type(settings, address):
    type_table = {
        3: '',
        4: 'n',
        5: 'p',
        12: 'nn',
        13: 'np',
        14: 'pn',
        15: 'pp',
        16: 'nnn',
        17: 'nnp',
        18: 'npn',
        19: 'npp',
        20: 'pnn',
        21: 'pnp',
        22: 'ppn',
        23: 'ppp',
        24: 'pppp',
        25: 'ppppp',
        26: 'pppppp',
        27: 'ppppppp',
        28: 'pppppppp'
    }
    type = ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*6)
    if type >= 12 and settings.version < (7, 8, 0):
        # Introduction of vector arguments
        type += 3
    if type in type_table:
        return type_table[type]
    elif type == 0:
        bitmap = ptrutil.read_word(settings, settings.text_offset + address - settings.rt.word.size*5)
        size = bitmap & (settings.word.size - 1)
        bits = bitmap >> settings.word.lg_size
        ret = ''
        for i in range(size):
            if bits % 2 == 0:
                ret += 'p'
            else:
                ret += 'n'
            bits //= 2
        return ret
    else:
       # TODO: Read large bitmaps
       assert False, "unknown function type"
Ejemplo n.º 8
0
def read_num_args(settings, address):
    return ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*5)
Ejemplo n.º 9
0
def read_num_args(settings, address):
    return ptrutil.read_half_word(settings, settings.text_offset + address - settings.rt.halfword.size*5)