aboutsummaryrefslogtreecommitdiffstats
path: root/psp_out/phase1_build_idbs.py
blob: 2d99db81a2307a708b8761907e8ddb3ae8e645c0 (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
"""Phase 1 of the complete version-diff plan: build a base IDB for EVERY firmware
build and record coverage metrics. No symbol porting yet — this phase only
establishes that every build analyses cleanly and reports how much of each image
IDA actually recognised as code.

Anti-corner-cutting: every build is reported, including failures. A build with
anomalously low coverage is a problem to fix, not to silently skip.
"""
import glob, os, sys, json, time
import idapro, idautils, idc

rows=[]
elfs = sorted(glob.glob('handover/elf/versions/*/*.elf'))
print("building IDBs for %d builds\n" % len(elfs), flush=True)
for i, p in enumerate(elfs, 1):
    fam = os.path.basename(os.path.dirname(p))
    name = os.path.basename(p)
    t0=time.time()
    try:
        rc = idapro.open_database(p, run_auto_analysis=True)
        if rc != 0:
            rows.append(dict(fam=fam, name=name, ok=False, err="open rc=%s"%rc)); continue
        fns = list(idautils.Functions())
        tot = sum(idc.get_func_attr(f, idc.FUNCATTR_END)-f for f in fns)
        span = sum(idc.get_segm_end(s)-idc.get_segm_start(s) for s in idautils.Segments())
        cov = 100.0*tot/span if span else 0.0
        rows.append(dict(fam=fam, name=name, ok=True, nfunc=len(fns), bytes_in_funcs=tot,
                         span=span, coverage=round(cov,1), secs=round(time.time()-t0,1)))
        idapro.close_database(save=True)
        print("  [%2d/%2d] %-40s funcs=%-5d cov=%5.1f%%  (%.1fs)" %
              (i, len(elfs), name, len(fns), cov, time.time()-t0), flush=True)
    except Exception as e:
        rows.append(dict(fam=fam, name=name, ok=False, err=repr(e)[:120]))
        print("  [%2d/%2d] %-40s FAILED %r" % (i, len(elfs), name, e), flush=True)

json.dump(rows, open('phase1_coverage.json','w'), indent=1)
print("\nwrote phase1_coverage.json")