]> git.saurik.com Git - apple/xnu.git/blob - tools/symbolify.py
dde29a7326d0fab1467a835c9f6792242b8b9b7a
[apple/xnu.git] / tools / symbolify.py
1 #!/usr/bin/env python
2 from subprocess import Popen, PIPE, call
3 import re
4 import sys
5 import os
6
7 NM_FORMAT = "([0-9a-f]+) ([UuAaTtDdBbCcSsIi]) (.*)"
8
9 nm_re = re.compile(NM_FORMAT)
10
11 def parse_nm_output(str):
12 "returns (start, type, name)"
13 m = nm_re.match(str)
14 if m:
15 start = int(m.group(1), 16)
16 return (start, m.group(2), m.group(3))
17 else:
18 return None
19
20 def nm(file):
21 cmd = "nm %s" % file
22 p = Popen(cmd, shell=True, stdout=PIPE)
23 return p.stdout
24
25 class SymbolLookup:
26 def __init__(self, file, min_width=16):
27 self.min_width = min_width
28 self.symbols = [parse_nm_output(l) for l in nm(file)]
29 self.symbols.sort(key=lambda x: x[0])
30
31 def padded(self, str):
32 return ("%%%ds" % self.min_width) % str
33
34 def __call__(self, saddr):
35 addr = int(saddr.group(0), 16)
36 last = (0, ' ', '<start of file>')
37 # stupid linear search... feel free to improve
38 for s in self.symbols:
39 if s[0] == addr:
40 return self.padded(s[2])
41 elif s[0] > addr:
42 if last[2] == "_last_kernel_symbol":
43 return saddr.group(0)
44 return self.padded("<%s>+%x" % (last[2], addr - last[0]))
45 else:
46 last = s
47 if last[2] == "_last_kernel_symbol":
48 return saddr.group(0)
49 return self.padded("<%s>+%x" % (last[2], addr - last[0]))
50
51 def symbolify(objfile, input, *args, **kargs):
52 replacer = SymbolLookup(objfile, *args, **kargs)
53 for l in input:
54 print re.sub("(0x)?[0-9a-f]{6,16}", replacer, l),
55
56
57 def usage():
58
59 print "usage: %s [filename]" % sys.argv[0]
60 print "\tor speficy a filename in your SYMBOLIFY_KERNEL environment variable"
61
62 # die now
63 sys.exit(1)
64
65 KERNEL_FILE = None
66
67 if( len(sys.argv) > 2 ):
68 usage()
69
70 if( len(sys.argv) == 2 ):
71 KERNEL_FILE = sys.argv[1]
72
73 if( KERNEL_FILE is None ):
74 KERNEL_FILE = os.environ.get("SYMBOLIFY_KERNEL")
75
76 if( KERNEL_FILE is None ):
77 usage()
78
79 print "using kernel file '%s'" % KERNEL_FILE
80
81 symbolify(KERNEL_FILE, sys.stdin, min_width=40)
82