#!/usr/bin/env python3 # Report which AArch64 encodings in NSO .text segments are not decoded by dynarmic. # Usage: a64_coverage.py [ ...] # The NSO files are only read. import struct import sys from collections import Counter import numpy as np def lz4_block_decompress(src, out_size): dst = bytearray(out_size) si = di = 0 n = len(src) while si < n: tok = src[si] si += 1 lit = tok >> 4 if lit == 15: while True: b = src[si] si += 1 lit += b if b != 255: break dst[di:di + lit] = src[si:si + lit] si += lit di += lit if si >= n: break off = src[si] | (src[si + 1] << 8) si += 2 ml = tok & 15 if ml == 15: while True: b = src[si] si += 1 ml += b if b != 255: break ml += 4 start = di - off if off >= ml: dst[di:di + ml] = dst[start:start + ml] else: for k in range(ml): dst[di + k] = dst[start + k] di += ml return bytes(dst) def nso_text(path): data = open(path, "rb").read() assert data[:4] == b"NSO0", path flags = struct.unpack_from("> 21) for x in rest) examples = {} for x in rest: examples.setdefault(int(x) >> 21, int(x)) print(f" {len(rest):9d} unnamed (mostly data in .text or zero padding); top groups:") for g, c in groups.most_common(15): print(f" {c:8d} top11={g:03x} e.g. {examples[g]:08x}") print("== total named:") for name, c in total_unknown.most_common(): print(f" {c:9d} {name}") if __name__ == "__main__": main()