Example #1
0
def guess_pv(p, n, addr_expr):
    vs = syntax.get_expr_var_set(addr_expr)
    [pred] = p.preds[n]
    pvs = []

    def vis(expr):
        if expr.is_op(["PValid", "PArrayValid"]):
            pvs.append(expr)

    p.nodes[pred].cond.visit(vis)
    match_pvs = [pv for pv in pvs if set.union(*[syntax.get_expr_var_set(v) for v in pv.vals[2:]]) == vs]
    if len(match_pvs) > 1:
        match_pvs = [pv for pv in match_pvs if pv.is_op("PArrayValid")]
    pv = match_pvs[0]
    return pv
Example #2
0
def node_const_rets(node):
    if "instruction'" in node.fname:
        return inst_const_rets(node)
    if node.fname in pre_pairings:
        if pre_pairings[node.fname]['ASM'] != node.fname:
            return None
        cc = get_asm_calling_convention_at_node(node)
        input_set = set(
            [v for arg in node.args for v in syntax.get_expr_var_set(arg)])
        callee_saved_set = set(cc['callee_saved'])
        return [
            mk_var(nm, typ) for (nm, typ) in node.rets
            if mk_var(nm, typ) in callee_saved_set if (nm, typ) in input_set
        ]
    elif preserves_sp(node.fname):
        if node.fname not in get_functions_with_tag('ASM'):
            return None
        f_outs = functions[node.fname].outputs
        return [
            mk_var(nm, typ)
            for ((nm, typ), (nm2, _)) in azip(node.rets, f_outs)
            if nm2 == 'r13'
        ]
    else:
        return None
Example #3
0
def compute_var_flows (nodes, outputs, preds, override_lvals_rvals = {}):
	# compute a graph of reverse var flows to pass to tarjan's algorithm
	graph = {}
	entries = ['Ret']
	for (n, node) in nodes.iteritems ():
		if node.kind == 'Basic':
			for (lv, rv) in node.upds:
				graph[(n, 'Post', lv)] = [(n, 'Pre', v)
					for v in syntax.get_expr_var_set (rv)]
		elif node.is_noop ():
			pass
		else:
			if n in override_lvals_rvals:
				(lvals, rvals) = override_lvals_rvals[n]
			else:
				rvals = syntax.get_node_rvals (node)
				rvals = set (rvals.iteritems ())
				lvals = set (node.get_lvals ())
			if node.kind != 'Basic':
				lvals = list (lvals) + ['PC']
				entries.append ((n, 'Post', 'PC'))
			for lv in lvals:
				graph[(n, 'Post', lv)] = [(n, 'Pre', rv)
					for rv in rvals]
	graph['Ret'] = [(n, 'Post', v)
		for n in preds['Ret'] for v in outputs (n)]
	vs = set ([v for k in graph for (_, _, v) in graph[k]])
	for v in vs:
		for n in nodes:
			graph.setdefault ((n, 'Post', v), [(n, 'Pre', v)])
			graph[(n, 'Pre', v)] = [(n2, 'Post', v)
				for n2 in preds[n]]

	comps = tarjan (graph, entries)
	return (graph, comps)
Example #4
0
def guess_pv(p, n, addr_expr):
    vs = syntax.get_expr_var_set(addr_expr)
    [pred] = p.preds[n]
    pvs = []

    def vis(expr):
        if expr.is_op(['PValid', 'PArrayValid']):
            pvs.append(expr)

    p.nodes[pred].cond.visit(vis)
    match_pvs = [
        pv for pv in pvs
        if set.union(*[syntax.get_expr_var_set(v) for v in pv.vals[2:]]) == vs
    ]
    if len(match_pvs) > 1:
        match_pvs = [pv for pv in match_pvs if pv.is_op('PArrayValid')]
    pv = match_pvs[0]
    return pv
Example #5
0
def adjusted_var_dep_outputs_for_tag(p, tag):
    (ent, fname, _) = p.get_entry_details(tag)
    fun = functions[fname]
    cc = get_asm_calling_convention(fname)
    callee_saved_set = set(cc['callee_saved'])
    ret_set = set([(nm, typ) for ret in cc['rets']
                   for (nm, typ) in syntax.get_expr_var_set(ret)])
    rets = [(nm2, typ)
            for ((nm, typ), (nm2, _)) in azip(fun.outputs, p.outputs[tag])
            if (nm, typ) in ret_set or mk_var(nm, typ) in callee_saved_set]
    return rets
Example #6
0
def adjusted_var_dep_outputs_for_tag (p, tag):
	(ent, fname, _) = p.get_entry_details (tag)
	fun = functions[fname]
	cc = get_asm_calling_convention (fname)
	callee_saved_set = set (cc['callee_saved'])
	ret_set = set ([(nm, typ) for ret in cc['rets']
		for (nm, typ) in syntax.get_expr_var_set (ret)])
	rets = [(nm2, typ) for ((nm, typ), (nm2, _))
			in azip (fun.outputs, p.outputs[tag])
			if (nm, typ) in ret_set
				or mk_var (nm, typ) in callee_saved_set]
	return rets
Example #7
0
def pseudo_node_lvals_rvals(node):
    assert node.kind == 'Call'
    cc = get_asm_calling_convention_at_node(node)
    if not cc:
        return None

    arg_vars = set(
        [var for arg in cc['args'] for var in syntax.get_expr_var_set(arg)])

    callee_saved_set = set(cc['callee_saved'])
    rets = [(nm, typ) for (nm, typ) in node.rets
            if mk_var(nm, typ) not in callee_saved_set]

    return (rets, arg_vars)
Example #8
0
def pseudo_node_lvals_rvals (node):
	assert node.kind == 'Call'
	cc = get_asm_calling_convention_at_node (node)
	if not cc:
		return None
	
	arg_vars = set ([var for arg in cc['args']
		for var in syntax.get_expr_var_set (arg)])

	callee_saved_set = set (cc['callee_saved'])
	rets = [(nm, typ) for (nm, typ) in node.rets
		if mk_var (nm, typ) not in callee_saved_set]

	return (rets, arg_vars)
Example #9
0
def node_const_rets (node):
	if "instruction'" in node.fname:
		return inst_const_rets (node)
	if node.fname not in pre_pairings:
		return None
	if pre_pairings[node.fname]['ASM'] != node.fname:
		return None
	cc = get_asm_calling_convention_at_node (node)
	input_set = set ([v for arg in node.args
		for v in syntax.get_expr_var_set (arg)])
	callee_saved_set = set (cc['callee_saved'])
	return [mk_var (nm, typ) for (nm, typ) in node.rets
		if mk_var (nm, typ) in callee_saved_set
		if (nm, typ) in input_set]
Example #10
0
def inst_const_rets (node):
	assert "instruction'" in node.fname
	bits = set ([s.lower () for s in node.fname.split ('_')])
	fun = functions[node.fname]
	def is_const (nm, typ):
		if typ in [builtinTs['Mem'], builtinTs['Dom']]:
			return True
		if typ != word32T:
			return False
		return not (nm in bits or [al for al in reg_aliases.get (nm, [])
				if al in bits])
	is_consts = [is_const (nm, typ) for (nm, typ) in fun.outputs]
	input_set = set ([v for arg in node.args
		for v in syntax.get_expr_var_set (arg)])
	return [mk_var (nm, typ)
		for ((nm, typ), const) in azip (node.rets, is_consts)
		if const and (nm, typ) in input_set]
Example #11
0
def inst_const_rets(node):
    assert "instruction'" in node.fname
    bits = set([s.lower() for s in node.fname.split('_')])
    fun = functions[node.fname]

    def is_const(nm, typ):
        if typ in [builtinTs['Mem'], builtinTs['Dom']]:
            return True
        if typ != word32T:
            return False
        return not (nm in bits
                    or [al for al in reg_aliases.get(nm, []) if al in bits])

    is_consts = [is_const(nm, typ) for (nm, typ) in fun.outputs]
    input_set = set(
        [v for arg in node.args for v in syntax.get_expr_var_set(arg)])
    return [
        mk_var(nm, typ) for ((nm, typ), const) in azip(node.rets, is_consts)
        if const and (nm, typ) in input_set
    ]
Example #12
0
def trace_var(rep, tag, m, v):
    p = rep.p
    ns = walk_model(rep, tag, m)
    vds = rep.p.compute_var_dependencies()
    trace = []
    vs = syntax.get_expr_var_set(v)

    def fetch((n, vc)):
        if n in vds and [(nm, typ)
                         for (nm, typ) in vs if (nm, typ) not in vds[n]]:
            return None
        try:
            (_, env) = rep.get_node_pc_env((n, vc), tag)
            s = solver.smt_expr(v, env, rep.solv)
            s_x = solver.parse_s_expression(s)
            ev = search.eval_model(m, s_x)
            return (s, solver.smt_expr(ev, {}, None))
        except solver.EnvMiss, e:
            return None
        except AssertionError, e:
            return None
Example #13
0
def contextual_conds (nodes, preds):
	"""computes a collection of conditions that can be assumed true
	at any point in the node graph."""
	pre_conds = {}
	arc_conds = {}
	visit = [n for n in nodes if not (preds[n])]
	while visit:
		n = visit.pop ()
		if n not in nodes:
			continue
		in_arc_conds = [arc_conds.get ((pre, n), set ())
			for pre in preds[n]]
		if not in_arc_conds:
			conds = set ()
		else:
			conds = set.intersection (* in_arc_conds)
		if pre_conds.get (n) == conds:
			continue
		pre_conds[n] = conds
		if n not in nodes:
			continue
		if nodes[n].kind == 'Cond' and nodes[n].left == nodes[n].right:
			c_conds = [conds, conds]
		elif nodes[n].kind == 'Cond':
			c_conds = [nodes[n].cond, mk_not_red (nodes[n].cond)]
			c_conds = [set.union (set ([c]), conds)
				for c in c_conds]
		else:
			upds = set (nodes[n].get_lvals ())
			c_conds = [set ([c for c in conds if
				not set.intersection (upds,
					syntax.get_expr_var_set (c))])]
		for (cont, conds) in zip (nodes[n].get_conts (), c_conds):
			arc_conds[(n, cont)] = conds
			visit.append (cont)
	return (arc_conds, pre_conds)