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