def build_rodata (rodata_stream): rodata = {} for line in rodata_stream: if not is_rodata_line.match (line): continue bits = line.split () rodata[int (bits[0][:-1], 16)] = int (bits[1], 16) rodata_min = min (rodata.keys ()) rodata_max = max (rodata.keys ()) + 4 assert rodata_min % 4 == 0 rodata_range = range (rodata_min, rodata_max, 4) for x in rodata_range: if x not in rodata: trace ('.rodata section gap at address %x' % x) struct_name = fresh_name ('rodata', structs) struct = Struct (struct_name, rodata_max - rodata_min, 1) structs[struct_name] = struct (start, end) = sections['.rodata'] assert start <= rodata_min assert end + 1 >= rodata_max return (rodata, mk_word32 (rodata_min), struct.typ)
def build_rodata(rodata_stream, rodata_ranges=[('Section', '.rodata')]): from syntax import structs, fresh_name, Struct, mk_word32 import syntax from target_objects import symbols, sections, trace act_rodata_ranges = [] for (kind, nm) in rodata_ranges: if kind == 'Symbol': (addr, size, _) = symbols[nm] act_rodata_ranges.append((addr, addr + size - 1)) elif kind == 'Section': if nm in sections: act_rodata_ranges.append(sections[nm]) else: # it's reasonable to supply .rodata as the # expected section only for it to be missing trace('No %r section in objdump.' % nm) else: assert kind in ['Symbol', 'Section'], rodata_ranges comb_ranges = [] for (start, end) in sorted(act_rodata_ranges): if comb_ranges and comb_ranges[-1][1] + 1 == start: (start, _) = comb_ranges[-1] comb_ranges[-1] = (start, end) else: comb_ranges.append((start, end)) rodata = {} for line in rodata_stream: if not is_rodata_line.match(line): continue bits = line.split() (addr, v) = (int(bits[0][:-1], 16), int(bits[1], 16)) if [ 1 for (start, end) in comb_ranges if start <= addr and addr <= end ]: assert addr % 4 == 0, addr rodata[addr] = v if len(comb_ranges) == 1: rodata_names = ['rodata_struct'] else: rodata_names = [ 'rodata_struct_%d' % (i + 1) for (i, _) in enumerate(comb_ranges) ] rodata_ptrs = [] for ((start, end), name) in zip(comb_ranges, rodata_names): struct_name = fresh_name(name, structs) struct = Struct(struct_name, (end - start) + 1, 1) structs[struct_name] = struct typ = syntax.get_global_wrapper(struct.typ) rodata_ptrs.append((mk_word32(start), typ)) return (rodata, comb_ranges, rodata_ptrs)
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)
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)
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)
def compile_struct_use (function): trace ('Compiling in %s.' % function.name) vs = get_vars (function) max_node = max (function.nodes.keys () + [2]) visit_vs = vs.keys () replaces = {} while visit_vs: v = visit_vs.pop () typ = vs[v] if typ.kind == 'Struct': fields = structs[typ.name].field_list elif typ.kind == 'Array': fields = [(i, typ.el_typ) for i in range (typ.num)] else: continue new_vs = [(nm, fresh_name ('%s.%s' % (v, nm), vs, f_typ), f_typ) for (nm, f_typ) in fields] replaces[v] = new_vs visit_vs.extend ([v_nm for (_, v_nm, _) in new_vs]) for n in function.nodes: node = function.nodes[n] if node.kind == 'Basic': node.upds = compile_upds (replaces, node.upds) elif node.kind == 'Basic': assert not node.lval[1].kind in ['Struct', 'Array'] node.val = compile_accs (replaces, node.val) elif node.kind == 'Call': node.args = expand_arg_fields (replaces, node.args) node.rets = expand_lval_list (replaces, node.rets) elif node.kind == 'Cond': node.cond = compile_accs (replaces, node.cond) else: assert not 'node kind understood' function.inputs = expand_lval_list (replaces, function.inputs) function.outputs = expand_lval_list (replaces, function.outputs) return len (replaces) == 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)
def compile_struct_use(function): trace('Compiling in %s.' % function.name) vs = get_vars(function) max_node = max(function.nodes.keys() + [2]) visit_vs = vs.keys() replaces = {} while visit_vs: v = visit_vs.pop() typ = vs[v] if typ.kind == 'Struct': fields = structs[typ.name].field_list elif typ.kind == 'Array': fields = [(i, typ.el_typ) for i in range(typ.num)] else: continue new_vs = [(nm, fresh_name('%s.%s' % (v, nm), vs, f_typ), f_typ) for (nm, f_typ) in fields] replaces[v] = new_vs visit_vs.extend([v_nm for (_, v_nm, _) in new_vs]) for n in function.nodes: node = function.nodes[n] if node.kind == 'Basic': node.upds = compile_upds(replaces, node.upds) elif node.kind == 'Basic': assert not node.lval[1].kind in ['Struct', 'Array'] node.val = compile_accs(replaces, node.val) elif node.kind == 'Call': node.args = expand_arg_fields(replaces, node.args) node.rets = expand_lval_list(replaces, node.rets) elif node.kind == 'Cond': node.cond = compile_accs(replaces, node.cond) else: assert not 'node kind understood' function.inputs = expand_lval_list(replaces, function.inputs) function.outputs = expand_lval_list(replaces, function.outputs) return len(replaces) == 0
def fresh_var (self, name, typ): name = fresh_name (name, self.vs, typ) return mk_var (name, typ)
def fresh_var(self, name, typ): name = fresh_name(name, self.vs, typ) return mk_var(name, typ)