Пример #1
0
def mk_num (x, typ):
	import logic
	if logic.is_int (typ):
		typ = Type ('Word', typ)
	assert typ.kind == 'Word', typ
	assert logic.is_int (x), x
	return Expr ('Num', typ, val = x)
Пример #2
0
def mk_word32_maybe(x):
	import logic
	if logic.is_int (x):
		return mk_word32 (x)
	else:
		assert x.typ == word32T
		return x
Пример #3
0
def assembly_point(p, n):
    (_, hints) = p.node_tags[n]
    if type(hints) != tuple or not logic.is_int(hints[1]):
        return None
    while p.node_tags[n][1][1] % 4 != 0:
        [n] = p.preds[n]
    return p.node_tags[n][1][1]
Пример #4
0
def graph_name(nodes, node_tags, n, prev=None):
    if type(n) == str:
        return 't_%s_%d' % (n, prev)
    if n not in nodes:
        return 'unknown_%d' % n
    if n not in node_tags:
        ident = '%d' % n
    else:
        (tag, details) = node_tags[n]
        if len(details) > 1 and logic.is_int(details[1]):
            ident = '%d_%s_%s_0x%x' % (n, tag, details[0], details[1])
        elif type(details) != str:
            details = '_'.join(map(str, details))
            ident = '%d_%s_%s' % (n, tag, details)
        else:
            ident = '%d_%s_%s' % (n, tag, details)
    ident = sanitise_str(ident)
    node = nodes[n]
    if node.kind == 'Call':
        return 'fcall_%s' % ident
    if node.kind == 'Cond':
        return ident
    if node.kind == 'Basic':
        return 'ass_%s' % ident
    assert not 'node kind understood'
Пример #5
0
def assembly_point(p, n):
    (_, hints) = p.node_tags[n]
    if type(hints) != tuple or not logic.is_int(hints[1]):
        return None
    while p.node_tags[n][1][1] % 4 != 0:
        [n] = p.preds[n]
    return p.node_tags[n][1][1]
Пример #6
0
def mk_acc (idx, expr, replaces):
	if logic.is_int (idx):
		assert expr.typ.kind == 'Array'
		return compile_array_acc (idx, expr, replaces)
	else:
		assert expr.typ.kind == 'Struct'
		return compile_field_acc (idx, expr, replaces)
Пример #7
0
def mk_acc(idx, expr, replaces):
    if logic.is_int(idx):
        assert expr.typ.kind == 'Array'
        return compile_array_acc(idx, expr, replaces)
    else:
        assert expr.typ.kind == 'Struct'
        return compile_field_acc(idx, expr, replaces)
Пример #8
0
def graph_name(nodes, node_tags, n, prev=None):
    if type(n) == str:
        return "t_%s_%d" % (n, prev)
    if n not in nodes:
        return "unknown_%d" % n
    if n not in node_tags:
        ident = "%d" % n
    else:
        (tag, details) = node_tags[n]
        if len(details) > 1 and logic.is_int(details[1]):
            ident = "%d_%s_%s_0x%x" % (n, tag, details[0], details[1])
        elif type(details) != str:
            details = "_".join(map(str, details))
            ident = "%d_%s_%s" % (n, tag, details)
        else:
            ident = "%d_%s_%s" % (n, tag, details)
    ident = sanitise_str(ident)
    node = nodes[n]
    if node.kind == "Call":
        return "fcall_%s" % ident
    if node.kind == "Cond":
        return ident
    if node.kind == "Basic":
        return "ass_%s" % ident
    assert not "node kind understood"
Пример #9
0
def compile_array_acc (i, expr, replaces, must = True):
	'''pseudo-compile access to array element i of expr'''
	if not logic.is_int (i) and i.kind == 'Num':
		assert i.typ == word32T
		i = i.val
	if expr.kind == 'Array':
		if logic.is_int (i):
			return expr.vals[i]
		else:
			expr2 = expr.vals[-1]
			for (j, v) in enumerate (expr.vals[:-1]):
				expr2 = mk_if (mk_eq (i, mk_word32 (j)), v, expr2)
			return expr2
	elif expr.is_op ('ArrayUpdate'):
		[arr, j, v] = expr.vals
		if j.kind == 'Num' and logic.is_int (i):
			if i == j.val:
				return v
			else:
				return compile_array_acc (i, arr, replaces)
		else:
			return mk_if (mk_eq (j, mk_word32_maybe (i)), v,
				compile_array_acc (i, arr, replaces))
	elif expr.is_op ('MemAcc'):
		[m, p] = expr.vals
		return mk_memacc (m, mk_arroffs (p, expr.typ, i), expr.typ.el_typ)
	elif expr.is_op ('IfThenElse'):
		[cond, left, right] = expr.vals
		return mk_if (cond, compile_array_acc (i, left, replaces),
			compile_array_acc (i, right, replaces))
	elif expr.kind == 'Var':
		assert expr.name in replaces
		if logic.is_int (i):
			(_, v_nm, typ) = replaces[expr.name][i]
			return mk_var (v_nm, typ)
		else:
			vs = [(mk_word32 (j), mk_var (v_nm, typ))
				for (j, v_nm, typ)
				in replaces[expr.name]]
			expr2 = vs[0][1]
			for (j, v) in vs[1:]:
				expr2 = mk_if (mk_eq (i, j), v, expr2)
			return expr2
	else:
		if not must:
			return None
		return mk_arr_index (expr, mk_word32_maybe (i))
Пример #10
0
def compile_array_acc(i, expr, replaces, must=True):
    '''pseudo-compile access to array element i of expr'''
    if not logic.is_int(i) and i.kind == 'Num':
        assert i.typ == word32T
        i = i.val
    if expr.kind == 'Array':
        if logic.is_int(i):
            return expr.vals[i]
        else:
            expr2 = expr.vals[-1]
            for (j, v) in enumerate(expr.vals[:-1]):
                expr2 = mk_if(mk_eq(i, mk_word32(j)), v, expr2)
            return expr2
    elif expr.is_op('ArrayUpdate'):
        [arr, j, v] = expr.vals
        if j.kind == 'Num' and logic.is_int(i):
            if i == j.val:
                return v
            else:
                return compile_array_acc(i, arr, replaces)
        else:
            return mk_if(mk_eq(j, mk_word32_maybe(i)), v,
                         compile_array_acc(i, arr, replaces))
    elif expr.is_op('MemAcc'):
        [m, p] = expr.vals
        return mk_memacc(m, mk_arroffs(p, expr.typ, i), expr.typ.el_typ)
    elif expr.is_op('IfThenElse'):
        [cond, left, right] = expr.vals
        return mk_if(cond, compile_array_acc(i, left, replaces),
                     compile_array_acc(i, right, replaces))
    elif expr.kind == 'Var':
        assert expr.name in replaces
        if logic.is_int(i):
            (_, v_nm, typ) = replaces[expr.name][i]
            return mk_var(v_nm, typ)
        else:
            vs = [(mk_word32(j), mk_var(v_nm, typ))
                  for (j, v_nm, typ) in replaces[expr.name]]
            expr2 = vs[0][1]
            for (j, v) in vs[1:]:
                expr2 = mk_if(mk_eq(i, j), v, expr2)
            return expr2
    else:
        if not must:
            return None
        return mk_arr_index(expr, mk_word32_maybe(i))
Пример #11
0
def serialise_bound(addr, bound_info):
    if bound_info == None:
        return [hex(addr), "None", "None"]
    else:
        (bound, kind) = bound_info
        assert logic.is_int(bound)
        assert str(kind) == kind
        return [hex(addr), str(bound), kind]
Пример #12
0
def serialise_bound(addr, bound_info):
    if bound_info == None:
        return [hex(addr), "None", "None"]
    else:
        (bound, kind) = bound_info
        assert logic.is_int(bound)
        assert str(kind) == kind
        return [hex(addr), str(bound), kind]
Пример #13
0
def mk_arroffs(p, typ, i):
	assert typ.kind == 'Array'
	import logic
	if logic.is_int (i):
		assert i < typ.num
		offs = i * typ.el_typ.size()
		assert offs == i or offs % 4 == 0
		return mk_plus (p, mk_word32 (offs))
	else:
		sz = typ.el_typ.size()
		return mk_plus (p, mk_times (i, mk_word32 (sz)))
Пример #14
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)
Пример #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)
Пример #16
0
def get_extra_sp_defs (rep, tag):
	"""all functions will keep the stack pointer equal, whether they have
	pairing partners or not. add these extra defs/equalities for the
	purposes of stack depth analysis."""
	# FIXME how to parametrise this?
	sp = mk_var ('r13', syntax.word32T)
	defs = {}
	items = [(n_vc, x) for (n_vc, x) in rep.funcs.iteritems ()
		if logic.is_int (n_vc[0])]
	for ((n, vc), (inputs, outputs, _)) in items:
		if rep.p.node_tags[n][0] == tag:
			inp_sp = solver.smt_expr (sp, inputs, rep.solv)
			inp_sp = solver.parse_s_expression (inp_sp)
			out_sp = solver.smt_expr (sp, outputs, rep.solv)
			out_sp = solver.parse_s_expression (out_sp)
			if inp_sp != out_sp:
				defs[out_sp] = inp_sp
	return defs
Пример #17
0
def graph_name (nodes, node_tags, n, prev=None):
	if type (n) == str:
		return 't_%s_%d' % (n, prev)
	if n not in nodes:
		return 'unknown_%d' % n
	if n not in node_tags:
		ident = '%d' % n
	else:
		(tag, details) = node_tags[n]
		if len (details) > 1 and logic.is_int (details[1]):
			ident = '%d_%s_%s_0x%x' % (n, tag,
				details[0], details[1])
		else:
			ident = '%d_%s_%s' % (n, tag, details)
	node = nodes[n]
	if node.kind == 'Call':
		return 'fcall_%s' % ident
	if node.kind == 'Cond':
		return ident
	if node.kind == 'Basic':
		return 'ass_%s' % ident
	assert not 'node kind understood'
Пример #18
0
def get_extra_sp_defs(rep, tag):
    """add extra defs/equalities about stack pointer for the
	purposes of stack depth analysis."""
    # FIXME how to parametrise this?
    sp = mk_var('r13', syntax.word32T)
    defs = {}

    fcalls = [
        n_vc for n_vc in rep.funcs if logic.is_int(n_vc[0])
        if rep.p.node_tags[n_vc[0]][0] == tag
        if preserves_sp(rep.p.nodes[n_vc[0]].fname)
    ]
    for (n, vc) in fcalls:
        (inputs, outputs, _) = rep.funcs[(n, vc)]
        if (sp.name, sp.typ) not in outputs:
            continue
        inp_sp = solver.smt_expr(sp, inputs, rep.solv)
        inp_sp = solver.parse_s_expression(inp_sp)
        out_sp = solver.smt_expr(sp, outputs, rep.solv)
        out_sp = solver.parse_s_expression(out_sp)
        if inp_sp != out_sp:
            defs[out_sp] = inp_sp
    return defs