1#!/usr/bin/env python
2from subprocess import Popen, PIPE, call
3import re
4import sys
5import os
6
7NM_FORMAT = "([0-9a-f]+) ([UuAaTtDdBbCcSsIi]) (.*)"
8
9nm_re = re.compile(NM_FORMAT)
10
11def 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
20def nm(file):
21    cmd = "nm %s" % file
22    p = Popen(cmd, shell=True, stdout=PIPE)
23    return p.stdout
24
25class 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
51def 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
57def 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
65KERNEL_FILE = None
66
67if( len(sys.argv) > 2 ):
68    usage()
69
70if( len(sys.argv) == 2 ):
71    KERNEL_FILE = sys.argv[1]
72
73if( KERNEL_FILE is None ):
74    KERNEL_FILE = os.environ.get("SYMBOLIFY_KERNEL")
75
76if( KERNEL_FILE is None ):
77    usage()
78
79print "using kernel file '%s'" % KERNEL_FILE
80
81symbolify(KERNEL_FILE, sys.stdin, min_width=40)
82
83