Beispiel #1
0
	def warm_pc_env_cache (self, n_vc, tag):
		'this is to avoid recursion limits and spot bugs'
		prev_chain = []
		for i in range (5000):
			prevs = self.prevs (n_vc)
			try:
				prevs = [p for p in prevs
					if (tag, p[0], p[1])
						not in self.node_pc_envs
					if self.get_tag_vcount (p, None)
						== (tag, n_vc[1])]
			except self.TooGeneral:
				break
			if not prevs:
				break
			n_vc = prevs[0]
			prev_chain.append(n_vc)
		if not (len (prev_chain) < 5000):
			printout ([n for (n, vc) in prev_chain])
			assert len (prev_chain) < 5000, (prev_chain[:10],
				prev_chain[-10:])
		
		prev_chain.reverse ()
		for n_vc in prev_chain:
			self.get_node_pc_env (n_vc, tag, request = False)
Beispiel #2
0
def mk_stack_pairings (pairing_tups, stack_bounds_fname = None,
		quiet = True):
	"""build the stack-aware calling-convention-aware logical pairings
	once a collection of function pairs have been read."""

	# simplifies interactive testing of this function
	pre_pairings.clear ()

	for (asm_f, c_f) in pairing_tups:
		pair = {'ASM': asm_f, 'C': c_f}
		assert c_f not in pre_pairings
		assert asm_f not in pre_pairings
		pre_pairings[c_f] = pair
		pre_pairings[asm_f] = pair
	
	fn_hash = hash (tuple (sorted ([(f, hash (functions[f]))
		for f in functions])))
	prev_hash = read_fn_hash (stack_bounds_fname)
	if prev_hash == fn_hash:
		f = open (stack_bounds_fname)
		f.readline ()
		stack_bounds = deserialise_stack_bounds (f)
		f.close ()
	else:
		printout ('Computing stack bounds.')
		stack_bounds = compute_stack_bounds (quiet = quiet)
		f = open (stack_bounds_fname, 'w')
		f.write ('FunctionHash %s\n' % fn_hash)
		for line in serialise_stack_bounds (stack_bounds):
			f.write(line)
		f.close ()

	return mk_pairings (stack_bounds)
Beispiel #3
0
def check_no_symbols(nodes):
    import pseudo_compile
    symbs = pseudo_compile.nodes_symbols(nodes)
    if not symbs:
        return
    printout('Aborting %s: undefined symbols %s' % (self.name, symbs))
    raise Abort()
Beispiel #4
0
def mk_stack_pairings(pairing_tups, stack_bounds_fname=None, quiet=True):
    """build the stack-aware calling-convention-aware logical pairings
	once a collection of function pairs have been read."""

    # simplifies interactive testing of this function
    pre_pairings.clear()

    for (asm_f, c_f) in pairing_tups:
        pair = {'ASM': asm_f, 'C': c_f}
        assert c_f not in pre_pairings
        assert asm_f not in pre_pairings
        pre_pairings[c_f] = pair
        pre_pairings[asm_f] = pair

    fn_hash = hash(tuple(sorted([(f, hash(functions[f])) for f in functions])))
    prev_hash = read_fn_hash(stack_bounds_fname)
    if prev_hash == fn_hash:
        f = open(stack_bounds_fname)
        f.readline()
        stack_bounds = deserialise_stack_bounds(f)
        f.close()
    else:
        printout('Computing stack bounds.')
        stack_bounds = compute_stack_bounds(quiet=quiet)
        f = open(stack_bounds_fname, 'w')
        f.write('FunctionHash %s\n' % fn_hash)
        for line in serialise_stack_bounds(stack_bounds):
            f.write(line)
        f.close()

    problematic_synthetic()

    return mk_pairings(stack_bounds)
Beispiel #5
0
def check_no_inner_loop(p, head):
    subs = loop_inner_loops(p, head)
    if subs:
        printout('Aborting %s, complex loop' % p.name)
        trace('  sub-loops %s of loop at %s' % (subs, head))
        for (h, _) in subs:
            trace('    head %d tagged %s' % (h, p.node_tags[h]))
        raise Abort()
Beispiel #6
0
def get_loop_virtual_stack_analysis(p, tag):
    """computes variable liveness etc analyses with stack slots treated
	as virtual variables."""
    cache_key = ('loop_stack_analysis', tag)
    if cache_key in p.cached_analysis:
        return p.cached_analysis[cache_key]

    (ent, fname, _) = p.get_entry_details(tag)
    (_, sp) = get_stack_sp(p, tag)
    cc = get_asm_calling_convention(fname)
    rets = list(
        set([
            ptr for arg in cc['rets']
            for (ptr, _) in stack_virtualise_expr(arg, None)[0]
        ]))
    rets = [adjust_ret_ptr(ret) for ret in rets]
    renames = p.entry_exit_renames(tags=[tag])
    r = renames[tag + '_OUT']
    rets = [syntax.rename_expr(ret, r) for ret in rets]

    ns = [n for n in p.nodes if p.node_tags[n][0] == tag]
    loop_ns = logic.minimal_loop_node_set(p)

    ptrs = list(
        set([(n, ptr) for n in ns
             for ptr in (stack_virtualise_node(p.nodes[n], None))[0]]))
    ptrs += [(n, (sp, 'StackPointer')) for n in ns if n in loop_ns]
    offs = get_ptr_offsets(p, [(n, ptr) for (n, (ptr, _)) in ptrs],
                           [(ent, sp, 'stack')] + [(ent, ptr, 'indirect_ret')
                                                   for ptr in rets[:1]])

    ptr_offs = {}
    rep_offs = {}
    upd_offsets = {}
    for ((n, ptr), off, k) in offs:
        off = norm_int(off, 32)
        ptr_offs.setdefault(n, {})
        rep_offs.setdefault(n, {})
        ptr_offs[n][ptr] = (k, off)
        rep_offs[n][k] = (ptr, -off)

    for (n, (ptr, kind)) in ptrs:
        if kind == 'MemUpdate' and n in loop_ns:
            loop = p.loop_id(n)
            (k, off) = ptr_offs[n][ptr]
            upd_offsets.setdefault(loop, set())
            upd_offsets[loop].add((k, off))
    loc_offs = mk_get_local_offs(p, tag, rep_offs)

    adj_nodes = {}
    for n in ns:
        try:
            (_, node) = stack_virtualise_node(p.nodes[n], ptr_offs.get(n, {}))
        except StackOffsMissing, e:
            printout("Stack analysis issue at (%d, %s)." % (n, p.node_tags[n]))
            node = p.nodes[n]
        adj_nodes[n] = node
Beispiel #7
0
def build_proof (p):
	init_hyps = check.init_point_hyps (p)
	proof = build_proof_rec (default_searcher, p, (), list (init_hyps))

	trace ('Built proof for %s' % p.name)
	printout (repr (proof))
	last_proof[0] = proof

	return proof
Beispiel #8
0
def check_all (omit_set = set (), loops = True, tags = None,
		report_mode = False):
	pairs = list (set ([pair for f in pairings for pair in pairings[f]
		if omit_set.isdisjoint (pair.funs.values ())
		if not tags or tags.issubset (set (pair.tags))]))
	omitted = list (set ([pair for f in pairings for pair in pairings[f]
		if not omit_set.isdisjoint (pair.funs.values())]))
	random.shuffle (pairs)
	r = check_pairs (pairs, loops = loops, report_mode = report_mode)
	if omitted:
		printout ('  - %d pairings omitted: %s'
			% (len (omitted), [pair.name for pair in omitted]))
	return r
Beispiel #9
0
def check_deps (fname, report_mode = False):
	frontier = set ([fname])
	funs = set ()
	while frontier:
		fname = frontier.pop ()
		if fname in funs:
			continue
		funs.add (fname)
		frontier.update (functions[fname].function_calls ())
	funs = sorted (funs)
	funs = [fun for fun in funs if fun in pairings]
	printout ('Testing functions: %s' % funs)
	pairs = [pair for f in funs for pair in pairings[f]]
	return check_pairs (pairs, report_mode = report_mode)
Beispiel #10
0
def check_deps (fname, report_mode = False):
	frontier = set ([fname])
	funs = set ()
	while frontier:
		fname = frontier.pop ()
		if fname in funs:
			continue
		funs.add (fname)
		frontier.update (functions[fname].function_calls ())
	funs = sorted (funs)
	funs = [fun for fun in funs if fun in pairings]
	printout ('Testing functions: %s' % funs)
	pairs = [pair for f in funs for pair in pairings[f]]
	return check_pairs (pairs, report_mode = report_mode)
Beispiel #11
0
def problematic_synthetic():
    synth = [
        s for s in target_objects.symbols
        if '.clone.' in s or '.part.' in s or '.constprop.' in s
    ]
    synth = ['_'.join(s.split('.')) for s in synth]
    if not synth:
        return
    printout('Synthetic symbols: %s' % synth)
    synth_calls = set(
        [f for f in synth if f in functions if functions[f].function_calls()])
    printout('Synthetic symbols which make function calls: %s' % synth_calls)
    if not synth_calls:
        return
    synth_stack = set([
        f for f in synth_calls if [
            node for node in functions[f].nodes.itervalues()
            if node.kind == 'Basic' if ('r13', word32T) in node.get_lvals()
        ]
    ])
    printout('Synthetic symbols which call and move sp: %s' % synth_stack)
    synth_problems = set([
        f for f in synth_stack if [
            f2 for f2 in functions if f in functions[f2].function_calls()
            if len(set(functions[f2].function_calls())) > 1
        ]
    ])
    printout('Problematic synthetics: %s' % synth_problems)
    return synth_problems
Beispiel #12
0
def check_all (omit_set = set (), loops = True, tags = None,
		report_mode = False, only_build_problem = False):
	pairs = list (set ([pair for f in pairings for pair in pairings[f]
		if omit_set.isdisjoint (pair.funs.values ())
		if not tags or tags.issubset (set (pair.tags))]))
	omitted = list (set ([pair for f in pairings for pair in pairings[f]
		if not omit_set.isdisjoint (pair.funs.values())]))
	random.shuffle (pairs)
	r = check_pairs (pairs, loops = loops, report_mode = report_mode,
		only_build_problem = only_build_problem)
	if omitted:
		printout ('  - %d pairings omitted: %s'
			% (len (omitted), [pair.name for pair in omitted]))
	return r
Beispiel #13
0
def problematic_instructions():
    add_inst_specs(report_problematic=False)
    unhandled = {}
    for f in functions:
        for f2 in functions[f].function_calls():
            if "instruction'" not in f2:
                continue
            if functions[f2].entry:
                continue
            unhandled.setdefault(f, [])
            unhandled[f].append(f2)
    for f in unhandled:
        printout('Function %r contains unhandled instructions:' % f)
        printout('  %s' % unhandled[f])
    return unhandled
Beispiel #14
0
def compute_recursion_idents(group, extra_unfolds):
    idents = {}
    group = set(group)
    recursion_trace.append('Computing for group %s' % group)
    printout('Doing recursion analysis for function group:')
    printout('  %s' % list(group))
    prevs = set([
        f for f in functions
        if [f2 for f2 in functions[f].function_calls() if f2 in group]
    ])
    for f in prevs - group:
        recursion_trace.append('  checking for %s' % f)
        trace('Checking idents for %s' % f)
        while add_recursion_ident(f, group, idents, extra_unfolds):
            pass
    return idents
Beispiel #15
0
def build_compound_problem(fnames):
    """mirrors build_problem from check for multiple functions"""
    printout('Building compound problem for %s' % fnames)
    last_compound_problem_req[0] = list(fnames)
    p = problem.Problem(None, name=', '.join(fnames))
    fun_tag_pairs = []

    all_tags = {}
    for (i, fn) in enumerate(fnames):
        i = len(fnames) - i
        [pair] = pairings[fn]
        next_tags = {}
        scripts = get_problem_inline_scripts(pair)
        for (pair_tag, fname) in pair.funs.items():
            tag = '%s_%d_%s' % (fname, i, pair_tag)
            tag = syntax.fresh_name(tag, all_tags)
            next_tags[pair_tag] = tag
            p.add_entry_function(functions[fname], tag)
            p.hook_tag_hints[tag] = pair_tag
            p.replay_inline_script(tag, scripts[pair_tag])
        fun_tag_pairs.append((next_tags, pair))

    p.pad_merge_points()
    p.do_analysis()

    free_hyps = []
    for (tags, pair) in fun_tag_pairs:
        (inp_eqs, _) = pair.eqs
        free_hyps += check.inst_eqs(p, (), inp_eqs, tags)
        err_vis_opts = rep_graph.vc_options([0, 1, 2], [1])
        err_vis_vc = tuple([(n, err_vis_opts) for n in p.loop_heads()
                            if p.node_tags[n][0] == tags['C']])
        err_vis = (('Err', err_vis_vc), tags['C'])
        free_hyps.append(rep_graph.pc_false_hyp(err_vis))

    addr_map = {}
    for n in p.nodes:
        if not p.node_tags[n][0].endswith('_ASM'):
            continue
        if type(p.node_tags[n][1]) == tuple:
            (fname, data) = p.node_tags[n][1]
            if (logic.is_int(data) and is_addr(data)
                    and not fname.startswith("instruction'")):
                assert data not in addr_map, data
                addr_map[data] = n

    return (p, free_hyps, addr_map, fun_tag_pairs)
Beispiel #16
0
def build_compound_problem (fnames):
	"""mirrors build_problem from check for multiple functions"""
	printout ('Building compound problem for %s' % fnames)
	last_compound_problem_req[0] = list (fnames)
	p = problem.Problem (None, name = ', '.join(fnames))
	fun_tag_pairs = []

	all_tags = {}
	for (i, fn) in enumerate (fnames):
		i = len (fnames) - i
		[pair] = pairings[fn]
		next_tags = {}
		scripts = get_problem_inline_scripts (pair)
		for (pair_tag, fname) in pair.funs.items ():
			tag = '%s_%d_%s' % (fname, i, pair_tag)
			tag = syntax.fresh_name (tag, all_tags)
			next_tags[pair_tag] = tag
			p.add_entry_function (functions[fname], tag)
			p.hook_tag_hints[tag] = pair_tag
			p.replay_inline_script (tag, scripts[pair_tag])
		fun_tag_pairs.append ((next_tags, pair))

	p.pad_merge_points ()
	p.do_analysis ()

	free_hyps = []
	for (tags, pair) in fun_tag_pairs:
		(inp_eqs, _) = pair.eqs
		free_hyps += check.inst_eqs (p, (), inp_eqs, tags)
		err_vis_opts = rep_graph.vc_options ([0, 1, 2], [1])
		err_vis_vc = tuple ([(n, err_vis_opts) for n in p.loop_heads ()
			if p.node_tags[n][0] == tags['C']])
		err_vis = (('Err', err_vis_vc), tags['C'])
		free_hyps.append (rep_graph.pc_false_hyp (err_vis))

	addr_map = {}
	for n in p.nodes:
		if not p.node_tags[n][0].endswith ('_ASM'):
			continue
		if type (p.node_tags[n][1]) == tuple:
			(fname, data) = p.node_tags[n][1]
			if (logic.is_int (data) and is_addr (data)
					and not fname.startswith ("instruction'")):
				assert data not in addr_map, data
				addr_map[data] = n

	return (p, free_hyps, addr_map, fun_tag_pairs)
Beispiel #17
0
def compute_stack_bounds (quiet = False):
	prev_tracer = target_objects.tracer[0]
	if quiet:
		target_objects.tracer[0] = lambda s, n: ()

	c_fs = get_functions_with_tag ('C')
	idents = get_recursion_identifiers (c_fs)
	asm_idents = convert_recursion_idents (idents)
	asm_fs = get_functions_with_tag ('ASM')
	printout ('Computed recursion limits.')

	bounds = compute_asm_stack_bounds (asm_idents, asm_fs)
	printout ('Computed stack bounds.')

	if quiet:
		target_objects.tracer[0] = prev_tracer
	return bounds
Beispiel #18
0
def compute_immediate_stack_bounds(idents, names):
    from syntax import true_term
    immed = {}
    names = sorted(names)
    for (i, fname) in enumerate(names):
        printout('Doing stack analysis for %r. (%d of %d)' %
                 (fname, i + 1, len(names)))
        fun = functions[fname]
        (offs, fn_offs) = guess_asm_stack_depth(fun)
        callables = ident_callables(fname, fn_offs.keys(), idents)
        for ident in idents.get(fname, [true_term]):
            calls = [((fname2, ident2), fn_offs[fname2]) for fname2 in fn_offs
                     for ident2 in idents.get(fname2, [true_term])
                     if callables[(ident, fname2, ident2)]]
            immed[(fname, ident)] = (offs, dict(calls))
    last_immediate_stack_bounds[0] = immed
    return immed
Beispiel #19
0
    def add_function(self, fun, tag, node_renames, loop_id=None):
        if not fun.entry:
            printout("Aborting %s: underspecified %s" % (self.name, fun.name))
            raise Abort()
        node_renames.setdefault("Ret", "Ret")
        node_renames.setdefault("Err", "Err")
        new_node_renames = {}
        vs = syntax.get_vars(fun)
        vs = dict([(v, fresh_name(v, self.vs, vs[v])) for v in vs])
        ns = fun.reachable_nodes()
        for n in ns:
            assert n not in node_renames
            node_renames[n] = self.alloc_node(tag, (fun.name, n), loop_id=loop_id, hint=n)
            new_node_renames[n] = node_renames[n]
        for n in ns:
            self.nodes[node_renames[n]] = syntax.copy_rename(fun.nodes[n], (vs, node_renames))

        return (new_node_renames, vs)
Beispiel #20
0
def compute_immediate_stack_bounds (idents, names):
	from syntax import true_term
	immed = {}
	names = sorted (names)
	for (i, fname) in enumerate (names):
		printout ('Doing stack analysis for %r. (%d of %d)' % (fname,
			i + 1, len (names)))
		fun = functions[fname]
		(offs, fn_offs) = guess_asm_stack_depth (fun)
		callables = ident_callables (fname, fn_offs.keys (), idents)
		for ident in idents.get (fname, [true_term]):
			calls = [((fname2, ident2), fn_offs[fname2])
				for fname2 in fn_offs
				for ident2 in idents.get (fname2, [true_term])
				if callables[(ident, fname2, ident2)]]
			immed[(fname, ident)] = (offs, dict (calls))
	last_immediate_stack_bounds[0] = immed
	return immed
Beispiel #21
0
def compute_stack_bounds(quiet=False):
    prev_tracer = target_objects.tracer[0]
    if quiet:
        target_objects.tracer[0] = lambda s, n: ()

    try:
        c_fs = get_functions_with_tag('C')
        idents = get_recursion_identifiers(c_fs)
        asm_idents = convert_recursion_idents(idents)
        asm_fs = get_functions_with_tag('ASM')
        printout('Computed recursion limits.')

        bounds = compute_asm_stack_bounds(asm_idents, asm_fs)
        printout('Computed stack bounds.')
    except Exception, e:
        if quiet:
            target_objects.tracer[0] = prev_tracer
        raise
Beispiel #22
0
def aligned_address_sanity (functions, symbols, radix):
	for (f, func) in functions.iteritems ():
		if f not in symbols:
			# happens for static or invented functions sometimes
			continue
		if func.entry:
			addr = first_aligned_address (func.nodes, radix)
			if addr == None:
				printout ('Warning: %s: no aligned instructions' % f)
				continue
			addr2 = symbols[f][0]
			if addr != addr2:
				printout ('target mismatch on func %s' % f)
				printout ('  (starts at 0x%x not 0x%x)' % (addr, addr2))
				return False
			addr3 = entry_aligned_address (func, radix)
			if addr3 != addr2:
				printout ('entry mismatch on func %s' % f)
				printout ('  (enters at 0x%x not 0x%x)' % (addr3, addr2))
				return False
	return True
Beispiel #23
0
    def add_function(self, fun, tag, node_renames, loop_id=None):
        if not fun.entry:
            printout('Aborting %s: underspecified %s' % (self.name, fun.name))
            raise Abort()
        node_renames.setdefault('Ret', 'Ret')
        node_renames.setdefault('Err', 'Err')
        new_node_renames = {}
        vs = syntax.get_vars(fun)
        vs = dict([(v, fresh_name(v, self.vs, vs[v])) for v in vs])
        ns = fun.reachable_nodes()
        check_no_symbols([fun.nodes[n] for n in ns])
        for n in ns:
            assert n not in node_renames
            node_renames[n] = self.alloc_node(tag, (fun.name, n),
                                              loop_id=loop_id,
                                              hint=n)
            new_node_renames[n] = node_renames[n]
        for n in ns:
            self.nodes[node_renames[n]] = syntax.copy_rename(
                fun.nodes[n], (vs, node_renames))

        return (new_node_renames, vs)
Beispiel #24
0
def mk_asm_inst_spec(fname):
    if not fname.startswith("asm_instruction'"):
        return
    if functions[fname].entry:
        return
    (_, ident) = fname.split("'", 1)
    (args, ident) = split_inst_name_regs(ident)
    if not all([arg.startswith('%') for arg in args]):
        printout('Warning: asm instruction name: formatting: %r' % fname)
        return
    base_ident = ident.split("_")[0]
    if base_ident not in instruction_fun_specs:
        return
    (impl_fname, regspecs) = instruction_fun_specs[base_ident]
    add_impl_fun(impl_fname, regspecs)
    (iscs, imems, _) = logic.split_scalar_pairs(functions[fname].inputs)
    (oscs, omems, _) = logic.split_scalar_pairs(functions[fname].outputs)
    call = syntax.Node('Call', 'Ret',
                       ('r_' + impl_fname, iscs + [syntax.mk_token(ident)] +
                        imems, [(v.name, v.typ) for v in oscs + omems]))
    assert not functions[fname].nodes
    functions[fname].nodes[1] = call
    functions[fname].entry = 1
Beispiel #25
0
def check_pairs (pairs, loops = True, report_mode = False):
	num_pairs = len (pairs)
	results = [toplevel_check_wname (pair, check_loops = loops,
			report_mode = report_mode, count = (i, num_pairs))
		for (i, pair) in enumerate (pairs)]
	printout ('Result summary: %s' % results)
	count = len ([1 for (_, r) in results if r == 'True'])
	printout ('  - %d proofs checked' % count)
	count = len ([1 for (_, r) in results
		if r in ['ProofAbort', 'None']])
	printout ('  - %d proofs skipped' % count)
	fails = [(nm, r) for (nm, r) in results
		if r not in ['True', 'ProofAbort', 'None']]
	printout ('  - failures: %s' % fails)
	return syntax.foldr1 (comb_results, ['True']
		+ [r for (nm, r) in results])
Beispiel #26
0
def check_all (omit_set = set (), loops = True, tags = None,
		report_mode = False):
	pairs = list (set ([pair for f in pairings for pair in pairings[f]
		if omit_set.isdisjoint (pair.funs.values ())
		if not tags or tags.issubset (set (pair.tags))]))
	num_pairs = len (pairs)
	omitted = list (set ([pair for f in pairings for pair in pairings[f]
		if not omit_set.isdisjoint (pair.funs.values())]))
	random.shuffle (pairs)
	results = [toplevel_check_wname (pair, check_loops = loops,
			report_mode = report_mode, count = (i, num_pairs))
		for (i, pair) in enumerate (pairs)]
	printout ('Result summary: %s' % results)
	count = len ([1 for (_, r) in results if r == 'True'])
	printout ('  - %d proofs checked' % count)
	count = len ([1 for (_, r) in results
		if r in ['ProofAbort', None]])
	printout ('  - %d proofs skipped' % count)
	fails = [(nm, r) for (nm, r) in results
		if r not in ['True', 'ProofAbort', None]]
	printout ('  - failures: %s' % fails)
	if omitted:
		printout ('  - %d pairings omitted: %s'
			% (len (omitted), omitted))
Beispiel #27
0
def print_coverage_report (skipped_pairs, covered_pairs):
	try:
		from trace_refute import addrs_covered, funs_sort_by_num_addrs
		covered_fs = set ([f for pair in covered_pairs
			for f in [pair.l_f, pair.r_f]])
		coverage = addrs_covered (covered_fs)
		printout ('  - %.2f%% instructions covered' % (coverage * 100))
		skipped_fs = set ([f for pair in skipped_pairs
			for f in [pair.l_f, pair.r_f]])
		fs = funs_sort_by_num_addrs (set (skipped_fs))
		if not fs:
			return
		lrg_msgs = ['%s (%.2f%%)' % (f, addrs_covered ([f]) * 100)
			for f in reversed (fs[-3:])]
		printout ('  - largest skipped functions:')
		printout ('      %s' % ', '.join (lrg_msgs))
	except Exception, e:
		pass
Beispiel #28
0
				else:
					printout ('Refinement NOT proven.')
		except solver.SolverFailure, e:
			printout ('Solver timeout/failure in proof check.')
			result = 'CheckSolverFailure'
		except Exception, e:
			trace ('EXCEPTION in checking %s:' % p.name)
			exception = sys.exc_info ()
			result = 'CheckEXCEPT'

	except problem.Abort:
		result = 'ProofAbort'
	except search.NoSplit:
		result = 'ProofNoSplit'
	except solver.SolverFailure, e:
		printout ('Solver timeout/failure in proof search.')
		result = 'ProofSolverFailure'

	except Exception, e:
		trace ('EXCEPTION in handling %s:' % pair)
		exception = sys.exc_info ()
		result = 'ProofEXCEPT'

	end_time = time.time ()
	tracer[0] = prev_tracer
	if exception:
		(etype, evalue, tb) = exception
		traceback.print_exception (etype, evalue, tb,
			file = sys.stdout)

	if not report:
Beispiel #29
0
    try:
        p.do_analysis()
        p.check_no_inner_loops()
        inline_no_pre_pairing(p)
    except problem.Abort, e:
        return None
    rep = rep_graph.mk_graph_slice(p, fast=True)
    try:
        rep.get_pc(default_n_vc(p, 'Ret'), 'Target')
        err_pc = rep.get_pc(default_n_vc(p, 'Err'), 'Target')
    except solver.EnvMiss, e:
        return None

    inlined_funs = set([fn for (_, _, fn) in p.inline_scripts['Target']])
    if inlined_funs:
        printout('  (stack analysis also involves %s)' %
                 ', '.join(inlined_funs))

    return p


def guess_asm_stack_depth(fun):
    p = check_before_guess_asm_stack_depth(fun)
    if not p:
        return (0, {})

    last_asm_stack_depth_fun[0] = fun.name

    entry = p.get_entry('Target')
    (_, sp) = get_stack_sp(p, 'Target')

    nodes = get_asm_reachable_nodes(p, tag_set=['Target'])
Beispiel #30
0
def toplevel_check (pair, check_loops = True, report = False, count = None,
		only_build_problem = False):
	if not only_build_problem:
		printout ('Testing Function pair %s' % pair)
	if count and not only_build_problem:
		(i, n) = count
		printout ('  (function pairing %d of %d)' % (i + 1, n))

	for (tag, fname) in pair.funs.iteritems ():
		if not functions[fname].entry:
			printout ('Skipping %s, underspecified %s' % (pair, tag))
			return 'None'
	prev_tracer = tracer[0]
	if report:
		tracer[0] = lambda s, n: ()

	exception = None

	trace (time.asctime ())
	start_time = time.time()
	sys.stdout.flush ()
	try:
		p = check.build_problem (pair)
		if only_build_problem:
			tracer[0] = prev_tracer
			return 'True'
		if report:
			printout (' .. built problem, finding proof')
		if not check_loops and p.loop_data:
			printout ('Problem has loop!')
			tracer[0] = prev_tracer
			return 'Loop'
		if check_loops == 'only' and not p.loop_data:
			printout ('No loop in problem.')
			tracer[0] = prev_tracer
			return 'NoLoop'
		proof = search.build_proof (p)
		if report:
			printout (' .. proof found.')

		try:
			if report:
				result = check.check_proof_report (p, proof)
			else:
				result = check.check_proof (p, proof)
				if result:
					printout ('Refinement proven.')
				else:
					printout ('Refinement NOT proven.')
		except solver.SolverFailure, e:
			printout ('Solver timeout/failure in proof check.')
			result = 'CheckSolverFailure'
		except Exception, e:
			trace ('EXCEPTION in checking %s:' % p.name)
			exception = sys.exc_info ()
			result = 'CheckEXCEPT'
Beispiel #31
0
def check_proof_report_rec (p, restrs, hyps, proof, step_num, ctxt, inducts):
	import sys
	printout ('Step %d: %s' % (step_num, ctxt))
	if proof.kind == 'Restr':
		(kind, (x, y)) = proof.restr_range
		if kind == 'Offset':
			v = inducts[1][proof.point]
			rexpr = '{%s + %s ..< %s + %s}' % (v, x, v, y)
		else:
			rexpr = '{%s ..< %s}' % (x, y)
		printout ('  Prove the number of visits to %d is in %s'
			% (proof.point, rexpr))
		
		checks = proof_restr_checks (proof.point, proof.restr_range,
			p, restrs, hyps)
		cases = ['']
	elif proof.kind == 'Split':
		(l_dts, r_dts, eqs, n, lrmx) = proof.split
		v = next_induct_var (inducts[0])
		inducts = (inducts[0] + 1, dict (inducts[1]))
		inducts[1][l_dts[0]] = v
		inducts[1][r_dts[0]] = v
		printout ('  prove %s related to %s' % (pretty_vseq (l_dts),
			pretty_vseq (r_dts)))
		printout ('    with equalities')
		for (x, y) in eqs:
			printout ('      %s (@ addr %s)' % (pretty_lambda (x),
				l_dts[0]))
			printout ('      = %s (@ addr %s)' % (pretty_lambda (y),
				r_dts[0]))
		printout ('    and with invariants')
		for x in l_dts[2]:
			printout ('      %s (@ addr %s)'
				% (pretty_lambda (x), l_dts[0]))
		for x in r_dts[2]:
			printout ('      %s (@ addr %s)'
				% (pretty_lambda (x), r_dts[0]))
		checks = split_checks (p, restrs, hyps, proof.split)
		cases = ['case in (%d) where the length of the sequence < %d'
				% (step_num, n),
			'case in (%d) where the length of the sequence is %s + %s'
				% (step_num, v, n)]
	elif proof.kind == 'Leaf':
		printout ('  prove all verification conditions')
		checks = leaf_condition_checks (p, restrs, hyps)
		cases = []
	elif proof.kind == 'CaseSplit':
		printout ('  case split on whether %d is visited' % proof.point)
		checks = []
		cases = ['case in (%d) where %d is visited' % (step_num, proof.point),
			'case in (%d) where %d is not visited' % (step_num, proof.point)]

	if checks:
		groups = proof_check_groups (checks)
		for group in groups:
			rep = rep_graph.mk_graph_slice (p)
			(res, _) = test_hyp_group (rep, group)
			if not res:
				printout ('    .. failed to prove this.')
				sys.stdout.flush ()
				return

		printout ('    .. proven.')
		sys.stdout.flush ()

	subproblems = proof_subproblems (p, proof.kind,
		proof.args, restrs, hyps, '')
	xs = logic.azip (subproblems, proof.subproofs)
	xs = logic.azip (xs, cases)
	step_num += 1
	for ((subprob, subproof), case) in xs:
		(restrs, hyps, _) = subprob
		res = check_proof_report_rec (p, restrs, hyps, subproof,
			step_num, case, inducts)
		if not res:
			return
		(step_num, induct_var_num) = res
		inducts = (induct_var_num, inducts[1])
	return (step_num, inducts[0])
Beispiel #32
0
def toplevel_check (pair, check_loops = True, report = False, count = None):
	printout ('Testing Function pair %s' % pair)
	if count:
		(i, n) = count
		printout ('  (function pairing %d of %d)' % (i + 1, n))
	
	for (tag, fname) in pair.funs.iteritems ():
		if not functions[fname].entry:
			printout ('Skipping %s, underspecified %s' % (pair, tag))
			return 'None'
	prev_tracer = tracer[0]
	if report:
		tracer[0] = lambda s, n: ()

	exception = None

	trace (time.asctime ())
	start_time = time.time()
	sys.stdout.flush ()
	try:
		p = check.build_problem (pair)
		if report:
			printout (' .. built problem, finding proof')
		if not check_loops and p.loop_data:
			printout ('Problem has loop!')
			tracer[0] = prev_tracer
			return 'Loop'
		if check_loops == 'only' and not p.loop_data:
			printout ('No loop in problem.')
			tracer[0] = prev_tracer
			return 'NoLoop'
		proof = search.build_proof (p)
		if report:
			printout (' .. proof found.')

		try:
			if report:
				result = check.check_proof_report (p, proof)
			else:
				result = check.check_proof (p, proof)
				if result:
					printout ('Refinement proven.')
				else:
					printout ('Refinement NOT proven.')
		except solver.SolverFailure, e:
			printout ('Solver timeout/failure in proof check.')
			result = 'CheckSolverFailure'
		except Exception, e:
			trace ('EXCEPTION in checking %s:' % p.name)
			exception = sys.exc_info ()
			result = 'CheckEXCEPT'
Beispiel #33
0
				else:
					printout ('Refinement NOT proven.')
		except solver.SolverFailure, e:
			printout ('Solver timeout/failure in proof check.')
			result = 'CheckSolverFailure'
		except Exception, e:
			trace ('EXCEPTION in checking %s:' % p.name)
			exception = sys.exc_info ()
			result = 'CheckEXCEPT'

	except problem.Abort:
		result = 'ProblemAbort'
	except search.NoSplit:
		result = 'ProofNoSplit'
	except solver.SolverFailure, e:
		printout ('Solver timeout/failure in proof search.')
		result = 'ProofSolverFailure'

	except Exception, e:
		trace ('EXCEPTION in handling %s:' % pair)
		exception = sys.exc_info ()
		result = 'ProofEXCEPT'

	end_time = time.time ()
	tracer[0] = prev_tracer
	if exception:
		(etype, evalue, tb) = exception
		traceback.print_exception (etype, evalue, tb,
			file = sys.stdout)

	if not only_build_problem:
Beispiel #34
0
def check_pairs (pairs, loops = True, report_mode = False,
		only_build_problem = False):
	num_pairs = len (pairs)
	printout ('Checking %d function pair problems' % len (pairs))
	results = [(pair, toplevel_check (pair, check_loops = loops,
			report = report_mode, count = (i, num_pairs),
			only_build_problem = only_build_problem))
		for (i, pair) in enumerate (pairs)]
	result_dict = logic.dict_list ([(result_codes[r][1], pair)
		for (pair, r) in results])
	if not only_build_problem:
		printout ('Results: %s'
			% [(pair.name, r) for (pair, r) in results])
	printout ('Result summary:')
	success = result_dict.get ('Success', [])
	if only_build_problem:
		printout ('  - %d problems build' % len (success))
	else:
		printout ('  - %d proofs checked' % len (success))
	skipped = result_dict.get ('Skipped', [])
	printout ('  - %d proofs skipped' % len (skipped))
	fails = [pair.name for pair in result_dict.get ('Failed', [])]
	print_coverage_report (set (skipped), set (success + fails))
	printout ('  - failures: %s' % fails)
	return syntax.foldr1 (comb_results, ['True']
		+ [r for (_, r) in results])
Beispiel #35
0
				else:
					printout ('Refinement NOT proven.')
		except solver.SolverFailure, e:
			printout ('Solver timeout/failure in proof check.')
			result = 'CheckSolverFailure'
		except Exception, e:
			trace ('EXCEPTION in checking %s:' % p.name)
			exception = sys.exc_info ()
			result = 'CheckEXCEPT'

	except problem.Abort:
		result = 'ProofAbort'
	except search.NoSplit:
		result = 'ProofNoSplit'
	except solver.SolverFailure, e:
		printout ('Solver timeout/failure in proof search.')
		result = 'ProofSolverFailure'

	except Exception, e:
		trace ('EXCEPTION in handling %s:' % pair)
		exception = sys.exc_info ()
		result = 'ProofEXCEPT'

	end_time = time.time ()
	tracer[0] = prev_tracer
	if exception:
		(etype, evalue, tb) = exception
		traceback.print_exception (etype, evalue, tb,
			file = sys.stdout)

	printout ('Result %s for pair %s, time taken: %f'
Beispiel #36
0
def build_proof_rec (searcher, p, restrs, hyps, name = "problem"):
	trace ('doing build proof rec with restrs = %r, hyps = %r' % (restrs, hyps))

	(kind, details) = searcher (p, restrs, hyps)
	last_searcher_results.append ((p, restrs, hyps, kind, details, name))
	del last_searcher_results[:-10]
	if kind == 'Restr':
		(restr_kind, restr_points) = details
		printout ("Discovered that points [%s] can be bounded"
			% ', '.join ([restr_point_name (p, n)
				for n in restr_points]))
		printout ("  (in %s)" % name)
		return build_proof_rec_with_restrs (restr_points, restr_kind,
			searcher, p, restrs, hyps, name = name)
	elif kind == 'Leaf':
		return ProofNode ('Leaf', None, ())
	assert kind in ['CaseSplit', 'Split']
	split = details
	if kind == 'CaseSplit':
		(split, hints) = details
	[(_, hyps1, nm1), (_, hyps2, nm2)] = check.proof_subproblems (p, kind,
		split, restrs, hyps, name)
	if kind == 'CaseSplit':
		printout ("Decided to case split at %s" % str (split))
		printout ("  (in %s)" % name)
		restr_points = hints
		kinds = ['Number', 'Number']
	else:
		restr_points = check.split_heads (split)
		kinds = ['Number', 'Offset']
		printout ("Discovered a loop relation for split points %s"
			% list (restr_points))
		printout ("  (in %s)" % name)
	subpfs = [build_proof_rec_with_restrs (restr_points, k,
			searcher, p, restrs, hyps_i, must_find = False,
			name = nm)
		for (nm, hyps_i, k)
		in [(nm1, hyps1, kinds[0]), (nm2, hyps2, kinds[1])]]
	return ProofNode (kind, split, subpfs)
Beispiel #37
0
def check_proof_report_rec(p,
                           restrs,
                           hyps,
                           proof,
                           step_num,
                           ctxt,
                           inducts,
                           do_check=True):
    printout('Step %d: %s' % (step_num, ctxt))
    if proof.kind == 'Restr':
        (kind, (x, y)) = proof.restr_range
        if kind == 'Offset':
            v = inducts[1][proof.point]
            rexpr = '{%s + %s ..< %s + %s}' % (v, x, v, y)
        else:
            rexpr = '{%s ..< %s}' % (x, y)
        printout('  Prove the number of visits to %d is in %s' %
                 (proof.point, rexpr))

        checks = proof_restr_checks(proof.point, proof.restr_range, p, restrs,
                                    hyps)
        cases = ['']
    elif proof.kind == 'SingleRevInduct':
        printout('  Proving a predicate by future induction.')
        (eqs, n) = proof.eqs_proof
        point = proof.point
        printout('    proving these invariants by %d-induction' % n)
        for x in eqs:
            printout('      %s (@ addr %s)' % (pretty_lambda(x), point))
        printout('    then establishing this predicate')
        (pred, n_bound) = proof.rev_proof
        printout('      %s (@ addr %s)' % (pretty_lambda(pred), point))
        printout('    at large iterations (%d) and by back induction.' %
                 n_bound)
        cases = ['']
        checks = all_rev_induct_checks(p, restrs, hyps, point, proof.eqs_proof,
                                       proof.rev_proof)
    elif proof.kind == 'Split':
        (l_dts, r_dts, eqs, n, lrmx) = proof.split
        v = next_induct_var(inducts[0])
        inducts = (inducts[0] + 1, dict(inducts[1]))
        inducts[1][l_dts[0]] = v
        inducts[1][r_dts[0]] = v
        printout('  prove %s related to %s' %
                 (pretty_vseq(l_dts), pretty_vseq(r_dts)))
        printout('    with equalities')
        for (x, y) in eqs:
            printout('      %s (@ addr %s)' % (pretty_lambda(x), l_dts[0]))
            printout('      = %s (@ addr %s)' % (pretty_lambda(y), r_dts[0]))
        printout('    and with invariants')
        for x in l_dts[2]:
            printout('      %s (@ addr %s)' % (pretty_lambda(x), l_dts[0]))
        for x in r_dts[2]:
            printout('      %s (@ addr %s)' % (pretty_lambda(x), r_dts[0]))
        checks = split_checks(p, restrs, hyps, proof.split)
        cases = [
            'case in (%d) where the length of the sequence < %d' %
            (step_num, n),
            'case in (%d) where the length of the sequence is %s + %s' %
            (step_num, v, n)
        ]
    elif proof.kind == 'Leaf':
        printout('  prove all verification conditions')
        checks = leaf_condition_checks(p, restrs, hyps)
        cases = []
    elif proof.kind == 'CaseSplit':
        printout('  case split on whether %d is visited' % proof.point)
        checks = []
        cases = [
            'case in (%d) where %d is visited' % (step_num, proof.point),
            'case in (%d) where %d is not visited' % (step_num, proof.point)
        ]

    if checks and do_check:
        groups = proof_check_groups(checks)
        for group in groups:
            rep = rep_graph.mk_graph_slice(p)
            detail = [0]
            (res, _) = test_hyp_group(rep, group, detail)
            if not res:
                printout('    .. failed to prove this.')
                printout('      (failure kind: %r)' % detail[0])
                return

        printout('    .. proven.')

    subproblems = proof_subproblems(p, proof.kind, proof.args, restrs, hyps,
                                    '')
    xs = logic.azip(subproblems, proof.subproofs)
    xs = logic.azip(xs, cases)
    step_num += 1
    for ((subprob, subproof), case) in xs:
        (restrs, hyps, _) = subprob
        res = check_proof_report_rec(p,
                                     restrs,
                                     hyps,
                                     subproof,
                                     step_num,
                                     case,
                                     inducts,
                                     do_check=do_check)
        if not res:
            return
        (step_num, induct_var_num) = res
        inducts = (induct_var_num, inducts[1])
    return (step_num, inducts[0])