-
Notifications
You must be signed in to change notification settings - Fork 1
/
cmp-nm-size-sort.py
executable file
·85 lines (62 loc) · 1.78 KB
/
cmp-nm-size-sort.py
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
#!/usr/bin/env python3
# Parses and compares 2 files made by 'nm --size-sort'
import sys
from pathlib import Path
def prune_fname(name):
for N in ('.lto_priv', '.cold', '.part', '.isra', '.constprop', '.llvm.'):
if N in name:
name = name[:name.index(N)]
return name
def parse(path):
symbols = {}
lines = path.open().read().splitlines()
for line in lines:
size, t, name = line.split()
size = int(size, 16)
name = prune_fname(name)
if t not in ('t', 'T'):
continue
if name not in symbols:
symbols[name] = 0
symbols[name] += size
return symbols
sfile = Path(sys.argv[1])
dfile = Path(sys.argv[2])
source = parse(sfile)
dest = parse(dfile)
totals = sum(source.values())
totald = sum(dest.values())
print(' symbols size')
print(sfile.stem + ':', len(source), totals)
print(dfile.stem + ':', len(dest), totald, f'({100.0 * totald / totals:.1f} %)')
print()
same_names = 0
different_size1 = 0
different_size2 = 0
diffs = []
verbose = len(sys.argv) >= 4 and sys.argv[3] == '-v'
for symname, size in source.items():
if symname in dest:
same_names += 1
diffs.append((symname, dest[symname] - size))
else:
different_size1 += size
if verbose:
print('>', symname)
for symname, size in dest.items():
if symname not in source:
different_size2 += size
if verbose:
print('<', symname)
print('Common symbols:', same_names)
# print('Different size:', different_size1, different_size2)
diffs = sorted(diffs, key=lambda x: x[1], reverse=True)
wins = 0
loses = 0
for d in diffs:
v = d[1]
if v < 0:
wins += v
else:
loses += v
print('wins:', wins, 'loses:', loses, 'DIFF:', wins + loses)