Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- import os, sys, bisect, re
- class Module:
- def __init__(self, name):
- self.name = name
- self.files = []
- self.funcs = []
- self.lines = []
- def parse_line(self, line):
- head, tail = line.split(" ", 1)
- if head == "FILE":
- filenum, name = tail.split(" ", 1)
- filenum = int(filenum, 10)
- if name.startswith("hg:"):
- name = name.split(":")[2]
- while len(self.files) <= filenum:
- self.files.append(None)
- self.files[filenum] = name
- elif head == "FUNC":
- addr, length, params, name = tail.split(" ", 3)
- addr = int(addr, 16)
- length = int(length, 16)
- self.funcs.append((addr, length, name))
- elif head == "PUBLIC" or head == "STACK":
- pass
- else:
- addr = int(head, 16)
- length, line, filenum = tail.split(" ", 2)
- length = int(length, 16)
- line = int(line, 10)
- filenum = int(filenum, 10)
- self.lines.append((addr, length, line, filenum))
- def lookup(self, addr):
- bf = bisect.bisect(self.funcs, (addr,))
- if bf == 0:
- return None
- faddr, flen, fname = self.funcs[bf - 1]
- if addr > faddr + flen:
- return None
- bl = bisect.bisect(self.lines, (addr,))
- if bl == 0:
- return fname
- laddr, llen, lline, lfile = self.lines[bl - 1]
- if addr > laddr + llen:
- return fname
- return ("%s %s:%d" % (fname, self.files[lfile], lline))
- def read_symbols(modules, path):
- this_module = None
- with open(path) as file:
- for line in file:
- line = line.rstrip()
- if line.startswith("MODULE "):
- kwd, os, arch, blob, name = line.split(" ", 4)
- if name not in modules:
- modules[name] = Module(name)
- this_module = modules[name]
- else:
- this_module.parse_line(line)
- def main(argv):
- modules = {}
- for arg in argv:
- if os.path.isfile(arg):
- read_symbols(modules, arg)
- else:
- for root, dirnames, filenames in os.walk(arg):
- for filename in filenames:
- if filename.endswith(".sym"): #???
- read_symbols(modules, os.path.join(root, filename))
- FIXABLE = re.compile('\?\?\?\[(.*/)?(?P<file>[^/]*)\+(?P<offset>0x[0-9a-f]+)\]')
- def fix(m):
- filename = m.group("file").rstrip()
- offset = int(m.group("offset"), 16)
- if filename not in modules:
- return m.group(0)
- xlation = modules[filename].lookup(offset)
- if not xlation:
- return m.group(0)
- return "%s (%s+0x%x)" % (xlation, filename, offset)
- for line in sys.stdin:
- sys.stdout.write(re.sub(FIXABLE, fix, line))
- if __name__ == '__main__':
- main(sys.argv[1:])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement