xref: /aosp_15_r20/external/AFLplusplus/utils/dynamic_covfilter/make_symbol_list.py (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4#
5# Written by Christian Holler <decoder at mozilla dot com>
6
7import json
8import os
9import sys
10import subprocess
11
12if len(sys.argv) != 2:
13    print("Usage: %s binfile" % os.path.basename(sys.argv[0]))
14    sys.exit(1)
15
16binfile = sys.argv[1]
17
18addr2len = {}
19addrs = []
20
21output = subprocess.check_output(["objdump", "-t", binfile]).decode("utf-8")
22for line in output.splitlines():
23    line = line.replace("\t", " ")
24    components = [x for x in line.split(" ") if x]
25    if not components:
26        continue
27    try:
28        start_addr = int(components[0], 16)
29    except ValueError:
30        continue
31
32    # Length has variable position in objdump output
33    length = None
34    for comp in components[1:]:
35        if len(comp) == 16:
36            try:
37                length = int(comp, 16)
38                break
39            except:
40                continue
41
42    if length is None:
43        print("ERROR: Couldn't determine function section length: %s" % line)
44
45    func = components[-1]
46
47    addrs.append(start_addr)
48    addr2len[str(hex(start_addr))] = str(length)
49
50# The search implementation in the AFL runtime expects everything sorted.
51addrs.sort()
52addrs = [str(hex(addr)) for addr in addrs]
53
54# We symbolize in one go to speed things up with large binaries.
55output = subprocess.check_output([
56    "llvm-addr2line",
57    "--output-style=JSON",
58    "-f", "-C", "-a", "-e",
59    binfile],
60    input="\n".join(addrs).encode("utf-8")).decode("utf-8")
61
62output = output.strip().splitlines()
63for line in output:
64    output = json.loads(line)
65    if "Symbol" in output and output["Address"] in addr2len:
66        final_output = [
67            output["Address"],
68            addr2len[output["Address"]],
69            os.path.basename(output["ModuleName"]),
70            output["Symbol"][0]["FileName"],
71            output["Symbol"][0]["FunctionName"]
72        ]
73        print("\t".join(final_output))
74