mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-10 01:01:34 +00:00
53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
|
|
import gdb
|
|
from typing import List, Tuple, Dict
|
|
import os
|
|
|
|
|
|
def get_symbol_addresses(symbol: str) -> List[int]:
|
|
raw = gdb.execute("info variables %s" % symbol, False, True)
|
|
addresses = [int(x.split(" ")[0], 0) for x in raw.split("\n") if x.startswith("0x")]
|
|
return addresses
|
|
|
|
|
|
def get_filename(addr: int) -> str:
|
|
path = gdb.execute("info symbol %d" % addr, False, True).split(" ")[-1].strip()
|
|
return os.path.basename(path)
|
|
|
|
|
|
def get_tables() -> Dict[str, Tuple[int, int]]:
|
|
starts = get_symbol_addresses("__start___sancov_cntrs")
|
|
stops = get_symbol_addresses("__stop___sancov_cntrs")
|
|
if len(starts) != len(stops):
|
|
raise Exception("start and stop sancov cntrs do not match")
|
|
tables = {get_filename(x): (x, y - x) for (x, y) in zip(starts, stops)}
|
|
return tables
|
|
|
|
|
|
class CoverageCommand(gdb.Command):
|
|
def __init__(self):
|
|
super(self.__class__, self).__init__("coverage", gdb.COMMAND_DATA)
|
|
|
|
def invoke(self, arg, _):
|
|
argv = gdb.string_to_argv(arg)
|
|
(exe, test_input, result_path) = argv
|
|
|
|
gdb.execute("file {}".format(exe))
|
|
gdb.Breakpoint("exit")
|
|
gdb.execute("r {} 2>&1 >/dev/null".format(test_input))
|
|
|
|
tables = get_tables()
|
|
|
|
for (module, (addr, length)) in tables.items():
|
|
mem = gdb.selected_inferior().read_memory(addr, length)
|
|
|
|
with open(os.path.join(result_path, module + ".cov"), "wb") as handle:
|
|
handle.write(mem)
|
|
|
|
|
|
CoverageCommand()
|