| #!/usr/bin/python |
| |
| import sys, re, os.path |
| import subprocess |
| from optparse import OptionParser |
| |
| class Addr2line: |
| def __init__(self, vmlinux, prefix = ''): |
| self.a2l = subprocess.Popen(['addr2line', '-fe', vmlinux], |
| stdin = subprocess.PIPE, |
| stdout = subprocess.PIPE, |
| stderr = subprocess.PIPE, |
| close_fds = True) |
| self.prefix = prefix |
| self.cache = dict() |
| def resolve(self, addr): |
| self.a2l.stdin.write('%08x\n' % addr) |
| symbol = self.a2l.stdout.readline().strip() |
| file = self.a2l.stdout.readline().strip() |
| if symbol == '??': |
| return None |
| if file.startswith(self.prefix): |
| file = file[len(self.prefix):] |
| return (symbol, file) |
| |
| class MultiResolver: |
| def __init__(self, resolvers): |
| self.resolvers = resolvers |
| def resolve(self, addr): |
| for resolver in self.resolvers: |
| ret = resolver.resolve(addr) |
| if ret: |
| return ret |
| |
| class Cache: |
| def __init__(self, resolver): |
| self.resolver = resolver |
| self.cache = dict() |
| def resolve(self, addr): |
| if not self.cache.has_key(addr): |
| self.cache[addr] = self.resolver.resolve(addr) |
| return self.cache[addr] |
| |
| optparser = OptionParser() |
| optparser.add_option('-g', '--guest', dest='guest', action='store_true', |
| default=True, |
| help='interpret kernel addresses as guest (default)') |
| optparser.add_option('-H', '--host', dest='guest', action='store_false', |
| help='interpret kernel addresses as host') |
| (options, args) = optparser.parse_args() |
| |
| basedir = os.getcwd() |
| basedir = re.sub(r'(.*/kvm)(/.*)', r'\1', basedir) |
| |
| addr_re = re.compile(r'\b[0-9a-fA-F]{8,16}\b') |
| if options.guest: |
| linux = Addr2line(basedir + '/qemu/vmlinux', |
| basedir + '/qemu/linux/') |
| else: |
| linux = Addr2line(basedir + '/kernel/vmlinux', |
| basedir + '/kernel/linux/') |
| addr2line = Cache(linux) |
| |
| def expand_addr(addr): |
| addr = addr.group(0) |
| result = addr2line.resolve(int(addr, 16)) |
| if result: |
| (symbol, file) = result |
| return '%s %s(%s)' % (addr, symbol, file) |
| else: |
| return addr |
| |
| try: |
| for line in sys.stdin: |
| line = addr_re.sub(expand_addr, line) |
| print line, |
| except KeyboardInterrupt: |
| sys.exit() |
| |