Beispiel #1
0
def process_one(cg, func, xform_pass):
    global subiter_cnt, update_cnt
    upward_queue = [func]
    downward_queue = []
    cnt = 0

    cur_queue = upward_queue
    while upward_queue or downward_queue:
        subiter_cnt += 1
        cnt += 1
        if not cur_queue:
            if cur_queue is upward_queue:
                cur_queue = downward_queue
            else:
                cur_queue = upward_queue
        func = cur_queue.pop(0)

        print("--- Next to process: %s ---" % func)
        progdb.clear_updated()

        cfg = CFG_MAP["pre"][func].copy()

        call_lo_union = xform_inter.calc_callsites_live_out(cg, func)
        progdb.update_cfg_prop(cfg, "callsites_live_out", call_lo_union)
        print("%s: callsites_live_out set to %s" %
              (func, utils.repr_stable(call_lo_union)))
        if "modifieds" in progdb.FUNC_DB[func]:
            progdb.FUNC_DB[func]["returns"] = arch.ret_filter(
                progdb.FUNC_DB[func]["modifieds"] & call_lo_union)
        else:
            print("%s: doesn't yet have modifieds!" % func)

        xform_pass.apply(cfg)

        if progdb.UPDATED_FUNCS:
            assert len(progdb.UPDATED_FUNCS) == 1, repr(progdb.UPDATED_FUNCS)
            func2 = progdb.UPDATED_FUNCS.pop()
            assert func2 == func
            update_cnt += 1

            progdb.update_funcdb(cfg)
            save_cfg(cfg, ".1")
            CFG_MAP["pre"][func].props = cfg.props

            upward_queue.extend(maybesorted(cg.pred(func)))

            for callee in maybesorted(cg.succ(func)):
                print("! updating callee", callee)
                if callee not in downward_queue:
                    downward_queue.insert(0, callee)

            print("--- Finished processing: %s ---" % func)
            print("# New up (caller) queue:", upward_queue)
            print("# New down (callee) queue:", downward_queue)
        else:
            print("%s not updated" % func)

    print("Subiters:", cnt)
Beispiel #2
0
def process_preorder(cg, func, xform_pass):
    print("  pre:", func)
    cfg = CFG_MAP["pre"][func].copy()
    xform_pass.apply(cfg)
    progdb.update_funcdb(cfg)
    save_cfg(cfg, ".2")

    for callee in cg.succ(func):
        process_preorder(cg, callee, xform_pass)
Beispiel #3
0
def handle_file_unprotected(args):
    p = Parser(args.file)
    cfg = p.parse()
    cfg.parser = p

    # If we want to get asm back, i.e. stay close to the input, don't remove
    # trailing jumps. This will work OK for data flow algos, but will produce
    # broken or confusing output for control flow algos (for which asm output
    # shouldn't be used of course).
    # Update: it's unsafe to use this during dataflow analysis
    #if args.format != "asm":
    #    foreach_bblock(cfg, remove_trailing_jumps)

    if args.debug:
        with open(args.file + ".0.bb", "w") as f:
            dump_bblocks(cfg, f, no_graph_header=args.no_graph_header)
        with open(args.file + ".0.dot", "w") as f:
            dot.dot(cfg, f)

    if args.script:
        for s in args.script:
            mod = __import__(s)
            mod.apply(cfg)
    elif hasattr(p, "script"):
        for op_type, op_name in p.script:
            if op_type == "xform:":
                func = globals()[op_name]
                func(cfg)
            elif op_type == "xform_bblock:":
                func = globals()[op_name]
                foreach_bblock(cfg, func)
            elif op_type == "xform_inst:":
                func = globals()[op_name]
                foreach_inst(cfg, func)
            elif op_type == "script:":
                mod = __import__(op_name)
                mod.apply(cfg)
            else:
                assert 0

    if args.debug:
        with open(args.file + ".out.bb", "w") as f:
            dump_bblocks(cfg, f, no_graph_header=args.no_graph_header)
        with open(args.file + ".out.dot", "w") as f:
            dot.dot(cfg, f)

    if args.output and args.format != "none":
        out = open(args.output, "w")
    else:
        out = sys.stdout

    if args.no_comments:
        Inst.show_comments = False

    if args.format == "bblocks":
        p = CFGPrinter(cfg, out)
        if args.no_graph_header:
            p.print_graph_header = lambda: None
        p.inst_printer = repr if args.repr else str
        p.no_dead = args.no_dead
        p.print()
    elif args.format == "asm":
        p = AsmPrinter(cfg, out)
        p.no_dead = args.no_dead
        p.print()
    elif args.format == "c":
        #foreach_bblock(cfg, remove_trailing_jumps)
        cfg.number_postorder()
        Inst.trail = ";"
        cprinter.no_dead = args.no_dead
        cprinter.dump_c(cfg, out)

    if out is not sys.stdout:
        out.close()

    progdb.update_funcdb(cfg)

    return cfg
Beispiel #4
0
def handle_file_unprotected(args):
    p = Parser(args.file)
    cfg = p.parse()
    cfg.parser = p

    # If we want to get asm back, i.e. stay close to the input, don't remove
    # trailing jumps. This will work OK for data flow algos, but will produce
    # broken or confusing output for control flow algos (for which asm output
    # shouldn't be used of course).
    # Update: it's unsafe to use this during dataflow analysis
    #if args.format != "asm":
    #    foreach_bblock(cfg, remove_trailing_jumps)

    if args.debug:
        with open(args.file + ".0.bb", "w") as f:
            dump_bblocks(cfg, f, no_graph_header=args.no_graph_header)
        with open(args.file + ".0.dot", "w") as f:
            dot.dot(cfg, f)

    if args.script:
        for s in args.script:
            mod = __import__(s)
            mod.apply(cfg)
    elif hasattr(p, "script"):
        for op_type, op_name in p.script:
            if op_type == "xform:":
                func = globals()[op_name]
                func(cfg)
            elif op_type == "xform_bblock:":
                func = globals()[op_name]
                foreach_bblock(cfg, func)
            elif op_type == "xform_inst:":
                func = globals()[op_name]
                foreach_inst(cfg, func)
            elif op_type == "script:":
                mod = __import__(op_name)
                mod.apply(cfg)
            else:
                assert 0

    if args.debug:
        with open(args.file + ".out.bb", "w") as f:
            dump_bblocks(cfg, f, no_graph_header=args.no_graph_header)
        with open(args.file + ".out.dot", "w") as f:
            dot.dot(cfg, f)

    if args.output and args.format != "none":
        out = open(args.output, "w")
    else:
        out = sys.stdout

    if args.no_comments:
        Inst.show_comments = False

    if args.format == "bblocks":
        p = CFGPrinter(cfg, out)
        if args.no_graph_header:
            p.print_graph_header = lambda: None
        p.inst_printer = repr if args.repr else str
        p.no_dead = args.no_dead
        p.print()
    elif args.format == "asm":
        p = AsmPrinter(cfg, out)
        p.no_dead = args.no_dead
        p.print()
    elif args.format == "c":
        #foreach_bblock(cfg, remove_trailing_jumps)
        cfg.number_postorder()
        Inst.trail = ";"
        cprinter.no_dead = args.no_dead
        cprinter.dump_c(cfg, out)

    if out is not sys.stdout:
        out.close()

    progdb.update_funcdb(cfg)

    return cfg
def process_one(cg, func, xform_pass):
    global subiter_cnt, update_cnt
    upward_queue = [func]
    downward_queue = []
    cnt = 0

    cur_queue = upward_queue
    while upward_queue or downward_queue:
        subiter_cnt += 1
        cnt += 1
        if not cur_queue:
            if cur_queue is upward_queue:
                cur_queue = downward_queue
            else:
                cur_queue = upward_queue
        func = cur_queue.pop(0)

        print("--- Next to process: %s ---" % func)
        progdb.clear_updated()

        cfg = CFG_MAP["pre"][func].copy()

        call_lo_union = xform_inter.calc_callsites_live_out(cg, func)
        progdb.update_cfg_prop(cfg, "callsites_live_out", call_lo_union)
        print("%s: callsites_live_out set to %s" % (func, utils.repr_stable(call_lo_union)))
        if "modifieds" in progdb.FUNC_DB[func]:
            progdb.FUNC_DB[func]["returns"] = arch.ret_filter(progdb.FUNC_DB[func]["modifieds"] & call_lo_union)
        else:
            print("%s: doesn't yet have modifieds!" % func)

        xform_pass.apply(cfg)

        if progdb.UPDATED_FUNCS:
            func_stats[func][0] += 1
            assert len(progdb.UPDATED_FUNCS) == 1, repr(progdb.UPDATED_FUNCS)
            func2 = progdb.UPDATED_FUNCS.pop()
            assert func2 == func
            update_cnt += 1

            progdb.update_funcdb(cfg)
            save_cfg(cfg, ".1")
            dot.save_dot(cfg, ".1")
            CFG_MAP["pre"][func].props = cfg.props

            for x in maybesorted(cg.pred(func)):
                if x not in upward_queue:
                    upward_queue.append(x)

            for callee in maybesorted(cg.succ(func)):
                print("! updating callee", callee)
                if callee not in downward_queue:
                    downward_queue.append(callee)

            print("--- Finished processing: %s ---" % func)
            print("# New up (caller) queue:", upward_queue)
            print("# New down (callee) queue:", downward_queue)
        else:
            func_stats[func][1] += 1
            print("%s not updated" % func)
            # Maybe funcdb properties not updated, but bblocks props can very well be
            save_cfg(cfg, ".1")
            dot.save_dot(cfg, ".1")

    print("Subiters:", cnt)