forked from apple/darwin-xnu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
symbolify.py
executable file
·89 lines (67 loc) · 2.22 KB
/
symbolify.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
86
87
88
#!/usr/bin/env python
from subprocess import Popen, PIPE, call
import re
import sys
import os
SLIDE = 0
NM_FORMAT = "([0-9a-f]+) ([UuAaTtDdBbCcSsIi]) (.*)"
nm_re = re.compile(NM_FORMAT)
def parse_nm_output(str):
"returns (start, type, name)"
m = nm_re.match(str)
if m:
start = int(m.group(1), 16)
return (start, m.group(2), m.group(3))
else:
return None
def nm(file):
cmd = "nm %s" % file
p = Popen(cmd, shell=True, stdout=PIPE)
return p.stdout
class SymbolLookup:
def __init__(self, file, min_width=16):
self.min_width = min_width
self.symbols = [parse_nm_output(l) for l in nm(file)]
self.symbols.sort(key=lambda x: x[0])
def padded(self, str):
return ("%%%ds" % self.min_width) % str
def __call__(self, saddr):
addr = int(saddr.group(0), 16)
last = (0, ' ', '<start of file>')
if( addr > SLIDE ):
addr -= SLIDE
# stupid linear search... feel free to improve
for s in self.symbols:
if s[0] == addr:
return self.padded(s[2])
elif s[0] > addr:
if last[2] == "_last_kernel_symbol":
return saddr.group(0)
return self.padded("<%s>+%x" % (last[2], addr - last[0]))
else:
last = s
if last[2] == "_last_kernel_symbol":
return saddr.group(0)
return self.padded("<%s>+%x" % (last[2], addr - last[0]))
def symbolify(objfile, input, *args, **kargs):
replacer = SymbolLookup(objfile, *args, **kargs)
for l in input:
print re.sub("(0x)?[0-9a-f]{6,16}", replacer, l),
def usage():
print "usage: %s [filename] [slide]" % sys.argv[0]
print "\tor speficy a filename in your SYMBOLIFY_KERNEL environment variable"
# die now
sys.exit(1)
KERNEL_FILE = None
if( len(sys.argv) > 3 ):
usage()
if( len(sys.argv) == 3 ):
SLIDE = int(sys.argv[2], 16)
if( len(sys.argv) >= 2 ):
KERNEL_FILE = sys.argv[1]
if( KERNEL_FILE is None ):
KERNEL_FILE = os.environ.get("SYMBOLIFY_KERNEL")
if( KERNEL_FILE is None ):
usage()
print "using kernel file '%s', slide 0x%x" % (KERNEL_FILE, SLIDE)
symbolify(KERNEL_FILE, sys.stdin, min_width=40)