Exemple #1
0
def get_stack_sp(p, tag):
    """get stack and stack-pointer variables"""
    entry = p.get_entry(tag)
    renames = p.entry_exit_renames(tags=[tag])
    r = renames[tag + '_IN']

    sp = syntax.rename_expr(mk_var('r13', syntax.word32T), r)
    stack = syntax.rename_expr(mk_var('stack', syntax.builtinTs['Mem']), r)
    return (stack, sp)
Exemple #2
0
def get_stack_sp (p, tag):
	"""get stack and stack-pointer variables"""
	entry = p.get_entry (tag)
	renames = p.entry_exit_renames (tags = [tag])
	r = renames[tag + '_IN']

	sp = syntax.rename_expr (mk_var ('r13', syntax.word32T), r)
	stack = syntax.rename_expr (mk_var ('stack',
		syntax.builtinTs['Mem']), r)
	return (stack, sp)
Exemple #3
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]

	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 p.loop_id (n)]
	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:
		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 p.loop_id (n):
			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:
		(_, node) = stack_virtualise_node (p.nodes[n],
			ptr_offs.get (n, {}))
		adj_nodes[n] = node

	# finally do analysis on this collection of nodes

	preds = dict (p.preds)
	preds['Ret'] = [n for n in preds['Ret'] if p.node_tags[n][0] == tag]
	preds['Err'] = [n for n in preds['Err'] if p.node_tags[n][0] == tag]
	vds = logic.compute_var_deps (adj_nodes,
		adjusted_var_dep_outputs (p), preds)

	result = (vds, adj_nodes, loc_offs, upd_offsets)
	p.cached_analysis[cache_key] = result
	return result
Exemple #4
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
Exemple #5
0
def ident_callables (fname, callees, idents):
	from solver import to_smt_expr, smt_expr
	from syntax import mk_not, mk_and, true_term

	auto_callables = dict ([((ident, f, true_term), True)
		for ident in idents.get (fname, [true_term])
		for f in callees if f not in idents])

	if not [f for f in callees if f in idents]:
		return auto_callables

	fun = functions[fname]
	p = fun.as_problem (problem.Problem, name = 'Target')
	check_ns = [(n, ident, cond) for n in p.nodes
		if p.nodes[n].kind == 'Call'
		if p.nodes[n].fname in idents
		for (ident, cond) in ident_conds (p.nodes[n].fname, idents)]

	p.do_analysis ()
	assert check_ns

	rep = rep_graph.mk_graph_slice (p, fast = True)
	err_hyp = rep_graph.pc_false_hyp ((default_n_vc (p, 'Err'), 'Target'))

	callables = auto_callables
	nhyps = mk_not_callable_hyps (p)

	for (ident, cond) in ident_conds (fname, idents):
		renames = p.entry_exit_renames (tags = ['Target'])
		cond = syntax.rename_expr (cond, renames['Target_IN'])
		entry = p.get_entry ('Target')
		e_vis = ((entry, ()), 'Target')
		hyps = [err_hyp, rep_graph.eq_hyp ((cond, e_vis),
				(true_term, e_vis))]

		for (n, ident2, cond2) in check_ns:
			k = (ident, p.nodes[n].fname, ident2)
			(inp_env, _, _) = rep.get_func (default_n_vc (p, n))
			pc = rep.get_pc (default_n_vc (p, n))
			cond2 = to_smt_expr (cond2, inp_env, rep.solv)
			if rep.test_hyp_whyps (mk_not (mk_and (pc, cond2)),
					hyps + nhyps):
				callables[k] = False
			else:
				callables[k] = True
	return callables
Exemple #6
0
def inst_eqs(p, restrs, eqs, tag_map={}):
    addr_map = {}
    if not tag_map:
        tag_map = dict([(tag, tag) for tag in p.tags()])
    for (pair_tag, p_tag) in tag_map.iteritems():
        addr_map[pair_tag + '_IN'] = ((p.get_entry(p_tag), ()), p_tag)
        addr_map[pair_tag + '_OUT'] = (('Ret', restrs), p_tag)
    renames = p.entry_exit_renames(tag_map.values())
    for (pair_tag, p_tag) in tag_map.iteritems():
        renames[pair_tag + '_IN'] = renames[p_tag + '_IN']
        renames[pair_tag + '_OUT'] = renames[p_tag + '_OUT']
    hyps = []
    for (lhs, rhs) in eqs:
        vals = [(rename_expr(x, renames[x_addr]), addr_map[x_addr])
                for (x, x_addr) in (lhs, rhs)]
        hyps.append(eq_hyp(vals[0], vals[1]))
    return hyps
Exemple #7
0
def inst_eqs (p, restrs, eqs, tag_map = {}):
	addr_map = {}
	if not tag_map:
		tag_map = dict ([(tag, tag) for tag in p.tags ()])
	for (pair_tag, p_tag) in tag_map.iteritems ():
		addr_map[pair_tag + '_IN'] = ((p.get_entry (p_tag), ()), p_tag)
		addr_map[pair_tag + '_OUT'] = (('Ret', restrs), p_tag)
	renames = p.entry_exit_renames (tag_map.values ())
	for (pair_tag, p_tag) in tag_map.iteritems ():
		renames[pair_tag + '_IN'] = renames[p_tag + '_IN']
		renames[pair_tag + '_OUT'] = renames[p_tag + '_OUT']
	hyps = []
	for (lhs, rhs) in eqs:
		vals = [(rename_expr (x, renames[x_addr]), addr_map[x_addr])
			for (x, x_addr) in (lhs, rhs)]
		hyps.append (eq_hyp (vals[0], vals[1]))
	return hyps
Exemple #8
0
def ident_callables(fname, callees, idents):
    from solver import to_smt_expr, smt_expr
    from syntax import mk_not, mk_and, true_term

    auto_callables = dict([((ident, f, true_term), True)
                           for ident in idents.get(fname, [true_term])
                           for f in callees if f not in idents])

    if not [f for f in callees if f in idents]:
        return auto_callables

    fun = functions[fname]
    p = fun.as_problem(problem.Problem, name='Target')
    check_ns = [(n, ident, cond) for n in p.nodes if p.nodes[n].kind == 'Call'
                if p.nodes[n].fname in idents
                for (ident, cond) in ident_conds(p.nodes[n].fname, idents)]

    p.do_analysis()
    assert check_ns

    rep = rep_graph.mk_graph_slice(p, fast=True)
    err_hyp = rep_graph.pc_false_hyp((default_n_vc(p, 'Err'), 'Target'))

    callables = auto_callables
    nhyps = mk_not_callable_hyps(p)

    for (ident, cond) in ident_conds(fname, idents):
        renames = p.entry_exit_renames(tags=['Target'])
        cond = syntax.rename_expr(cond, renames['Target_IN'])
        entry = p.get_entry('Target')
        e_vis = ((entry, ()), 'Target')
        hyps = [err_hyp, rep_graph.eq_hyp((cond, e_vis), (true_term, e_vis))]

        for (n, ident2, cond2) in check_ns:
            k = (ident, p.nodes[n].fname, ident2)
            (inp_env, _, _) = rep.get_func(default_n_vc(p, n))
            pc = rep.get_pc(default_n_vc(p, n))
            cond2 = to_smt_expr(cond2, inp_env, rep.solv)
            if rep.test_hyp_whyps(mk_not(mk_and(pc, cond2)), hyps + nhyps):
                callables[k] = False
            else:
                callables[k] = True
    return callables