Files
2025-09-29 00:52:08 +02:00

109 lines
4.1 KiB
Python
Executable File

import pdbparse
import os
from operator import itemgetter,attrgetter
from bisect import bisect_right
from pdbparse.undecorate import undecorate
from itertools import islice, count
class DummyOmap(object):
def remap(self, addr):
return addr
class Lookup(object):
def __init__(self, mods):
self.addrs = {}
self._cache = {}
not_found = []
for pdbname,base in mods:
pdbbase = ".".join(os.path.basename(pdbname).split('.')[:-1])
if not os.path.exists(pdbname):
print "WARN: %s not found" % pdbname
not_found.append( (base, pdbbase) )
continue
#print "Loading symbols for %s..." % pdbbase
try:
# Do this the hard way to avoid having to load
# the types stream in mammoth PDB files
pdb = pdbparse.parse(pdbname, fast_load=True)
pdb.STREAM_DBI.load()
pdb._update_names()
pdb.STREAM_GSYM = pdb.STREAM_GSYM.reload()
if pdb.STREAM_GSYM.size:
pdb.STREAM_GSYM.load()
pdb.STREAM_SECT_HDR = pdb.STREAM_SECT_HDR.reload()
pdb.STREAM_SECT_HDR.load()
# These are the dicey ones
pdb.STREAM_OMAP_FROM_SRC = pdb.STREAM_OMAP_FROM_SRC.reload()
pdb.STREAM_OMAP_FROM_SRC.load()
pdb.STREAM_SECT_HDR_ORIG = pdb.STREAM_SECT_HDR_ORIG.reload()
pdb.STREAM_SECT_HDR_ORIG.load()
except AttributeError, e:
pass
#except Exception, e:
# print "WARN: error %s parsing %s, skipping" % (e,pdbbase)
# not_found.append( (base, pdbbase) )
# continue
try:
sects = pdb.STREAM_SECT_HDR_ORIG.sections
omap = pdb.STREAM_OMAP_FROM_SRC
except AttributeError as e:
# In this case there is no OMAP, so we use the given section
# headers and use the identity function for omap.remap
sects = pdb.STREAM_SECT_HDR.sections
omap = DummyOmap()
gsyms = pdb.STREAM_GSYM
if not hasattr(gsyms, 'globals'):
gsyms.globals = []
last_sect = max(sects, key=attrgetter('VirtualAddress'))
limit = base + last_sect.VirtualAddress + last_sect.Misc.VirtualSize
self.addrs[base,limit] = {}
self.addrs[base,limit]['name'] = pdbbase
self.addrs[base,limit]['addrs'] = []
for sym in gsyms.globals:
if not hasattr(sym, 'offset'): continue
off = sym.offset
try:
virt_base = sects[sym.segment-1].VirtualAddress
except IndexError:
continue
mapped = omap.remap(off+virt_base) + base
self.addrs[base,limit]['addrs'].append((mapped,sym.name))
self.addrs[base,limit]['addrs'].sort(key=itemgetter(0))
self.locs = {}
self.names = {}
for base,limit in self.addrs:
mod = self.addrs[base,limit]['name']
symbols = self.addrs[base,limit]['addrs']
self.locs[base,limit] = [a[0] for a in symbols]
self.names[base,limit] = [a[1] for a in symbols]
def lookup(self, loc):
if loc in self._cache:
return self._cache[loc]
for base,limit in self.addrs:
if loc >= base and loc < limit:
mod = self.addrs[base,limit]['name']
symbols = self.addrs[base,limit]['addrs']
locs = self.locs[base,limit]
names = self.names[base,limit]
idx = bisect_right(locs, loc) - 1
diff = loc - locs[idx]
if diff:
ret = "%s!%s+%#x" % (mod,names[idx],diff)
else:
ret = "%s!%s" % (mod,names[idx])
self._cache[loc] = ret
return ret
return "unknown"