def run_worklist(settings, interps, worklist): while len(worklist) > 0: work = worklist.pop() if isinstance(work, ClosureWork): if settings.opts.verbose: print("Found closure:") print(" Pointer:", show.show_pretty_pointer(settings, work.pointer)) if isinstance(work.pointer, Argument) or isinstance( work.pointer, CaseArgument) or isinstance( work.pointer, Offset) and isinstance( work.pointer.base, CasePointer): if settings.opts.verbose: print(" Simple closure!") print() continue if isinstance(work.pointer, StaticValue) and show.name_is_library( show.get_name_for_address(settings, work.pointer.value)): if settings.opts.verbose: print(" Library defined!") print() continue interps[work.pointer] = parse.read_closure(settings, worklist, work.heaps, work.pointer) elif isinstance(work, FunctionThunkWork): if settings.opts.verbose: print("Found function/thunk!") print( " Name:", show.demangle( show.get_name_for_address(settings, work.address))) print(" Arg pattern:", work.arg_pattern) if StaticValue(value=work.address) in interps: if settings.opts.verbose: print(" Seen before!") print() continue if show.name_is_library( show.get_name_for_address(settings, work.address)): if settings.opts.verbose: print(" Library defined!") print() continue interps[StaticValue( value=work.address)] = parse.read_function_thunk( settings, worklist, work.heaps, work.address, work.main_register, work.arg_pattern) else: assert False, "bad work in worklist" if settings.opts.verbose: print()
def run_worklist(settings, interps, worklist): while len(worklist) > 0: work = worklist.pop() if isinstance(work, ClosureWork): if settings.opts.verbose: print("Found closure:") print(" Pointer:", show.show_pretty_pointer(settings, work.pointer)) if ( isinstance(work.pointer, Argument) or isinstance(work.pointer, CaseArgument) or isinstance(work.pointer, Offset) and isinstance(work.pointer.base, CasePointer) ): if settings.opts.verbose: print(" Simple closure!") print() continue if isinstance(work.pointer, StaticValue) and show.name_is_library( show.get_name_for_address(settings, work.pointer.value) ): if settings.opts.verbose: print(" Library defined!") print() continue interps[work.pointer] = parse.read_closure(settings, worklist, work.heaps, work.pointer) elif isinstance(work, FunctionThunkWork): if settings.opts.verbose: print("Found function/thunk!") print(" Name:", show.demangle(show.get_name_for_address(settings, work.address))) print(" Arg pattern:", work.arg_pattern) if StaticValue(value=work.address) in interps: if settings.opts.verbose: print(" Seen before!") print() continue if show.name_is_library(show.get_name_for_address(settings, work.address)): if settings.opts.verbose: print(" Library defined!") print() continue interps[StaticValue(value=work.address)] = parse.read_function_thunk( settings, worklist, work.heaps, work.address, work.main_register, work.arg_pattern ) else: assert False, "bad work in worklist" if settings.opts.verbose: print()
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()
def read_function_thunk(settings, interps, heaps, address, main_register, arg_pattern): if settings.opts.verbose: print("Found function/thunk!") if StaticValue(value = address) in interps: if settings.opts.verbose: print(" Seen before!") return info_name = show.get_name_for_address(settings, address) if settings.opts.verbose: print(" Name:", show.demangle(info_name)) print(" Arg pattern:", arg_pattern) if show.name_is_library(info_name): if settings.opts.verbose: print(" Library Defined!") print() return extra_stack = [] registers = {} registers[settings.rt.main_register] = main_register for i in range(len(arg_pattern)): if arg_pattern[i] != 'v': if i < len(settings.rt.arg_registers): registers[settings.rt.arg_registers[i]] = ptrutil.make_tagged(settings, Argument(index = i, func = address)) else: extra_stack.append(ptrutil.make_tagged(settings, Argument(index = i, func = address))) interps[StaticValue(value = address)] = None body = read_code(settings, interps, heaps, address, extra_stack, registers) if arg_pattern == '': interps[StaticValue(value = address)] = body else: interps[StaticValue(value = address)] = Lambda(func = address, arg_pattern = arg_pattern, body = body)