about summary refs log tree commit diff stats
path: root/src/focaccia/benchmark/_benchmark.py
blob: 0562035f9ce02c3b95beb720adc212e13c2cd160 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from focaccia.tools.benchmark_focaccia import make_argparser
from focaccia.benchmark.timer import Timer
from focaccia.qemu import _qemu_tool
from focaccia.deterministic import DeterministicLog
from focaccia.compare import compare_symbolic
import focaccia.parser as parser

import gdb
import subprocess
import time

def main():
    print("Benchmarking focaccia")
    args = make_argparser().parse_args()

    detlog = DeterministicLog(args.deterministic_log)
    if args.deterministic_log and detlog.base_directory is None:
        raise NotImplementedError(f'Deterministic log {args.deterministic_log} specified but '
                                   'Focaccia built without deterministic log support')

    # Emu exec continue
    try:
        timer = Timer("Emulator execution (continue)", paused=True, iterations=args.iterations)
        for i in range(timer.iterations):
            qemu_process = subprocess.Popen(
                [f"qemu-{args.guest_arch}", "-singlestep", "-g", args.port, args.binary],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL
            )
            time.sleep(0.5)
            timer.unpause()
            gdb_server = _qemu_tool.GDBServerStateIterator(f"localhost:{args.port}", detlog)
            gdb.execute("continue")
            qemu_process.wait()
            timer.pause()
        timer.log_time()
    except Exception as e:
        raise Exception(f'Unable to benchmark QEMU: {e}')

    # Emu exec stepping
    try:
        timer = Timer("Emulator execution (stepping)", paused=True, iterations=args.iterations)
        for i in range(timer.iterations):
            try:
                qemu_process = subprocess.Popen(
                        [f"qemu-{args.guest_arch}", "-g", args.port, args.binary],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL
                )
                time.sleep(0.5)
                timer.unpause()
                gdb_server = _qemu_tool.GDBServerStateIterator(f"localhost:{args.port}", detlog)
                state_iter = iter(gdb_server)
                while True:
                    cur_state = next(state_iter)
            except StopIteration:
                timer.pause()
        timer.log_time()
    except Exception as e:
        raise Exception(f'Unable to benchmark QEMU: {e}')

    try:
        with open(f"/tmp/benchmark-{args.binary.split('/')[-1]}-symbolic.trace", 'r') as strace:
            symb_transforms = parser.parse_transformations(strace)
    except Exception as e:
        raise Exception(f'Failed to parse state transformations from native trace: {e}')

    # emu exec tracing
    try:
        timer = Timer("Emulator tracing", iterations=args.iterations, paused=True)
        for i in range(timer.iterations):
            if timer.enabled:
                qemu_process = subprocess.Popen(
                        [f"qemu-{args.guest_arch}", "-g", args.port, args.binary],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL
                )
                time.sleep(0.5)
                timer.unpause()
                gdb_server = _qemu_tool.GDBServerStateIterator(f"localhost:{args.port}", detlog)

            conc_states, matched_transforms = _qemu_tool.collect_conc_trace(
                gdb_server,
                symb_transforms.states,
                symb_transforms.env.start_address,
                symb_transforms.env.stop_address)
            timer.pause()
        timer.log_time()
    except Exception as e:
        raise Exception(f'Failed to collect concolic trace from QEMU: {e}')

    # emu exec testing
    try:
        timer = Timer("Emulator testing", iterations=args.iterations)
        for i in range(timer.iterations):
            res = compare_symbolic(conc_states, matched_transforms)
        timer.log_time()
    except Exception as e:
        raise Exception('Error occured when comparing with symbolic equations: {e}')

if __name__ == "__main__":
    main()