Merge remote-tracking branch 'origin/GP-3725_Ives_ghidragdb-module-base--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-10-17 10:27:57 -04:00
commit 2a23fdd1ea

View file

@ -14,6 +14,7 @@
# limitations under the License. # limitations under the License.
## ##
from collections import namedtuple from collections import namedtuple
import bisect
import re import re
import gdb import gdb
@ -56,6 +57,23 @@ GNU_DEBUGDATA_PREFIX = ".gnu_debugdata for "
class Module(namedtuple('BaseModule', ['name', 'base', 'max', 'sections'])): class Module(namedtuple('BaseModule', ['name', 'base', 'max', 'sections'])):
pass pass
class Index:
def __init__(self, regions):
self.regions = {}
self.bases = []
for r in regions:
self.regions[r.start] = r
self.bases.append(r.start)
def compute_base(self, address):
floor = self.bases[bisect.bisect_right(self.bases, address) - 1]
if floor == None:
return address
else:
region = self.regions[floor]
if region.objfile == None or region.end <= address:
return address
else:
return region.start
class Section(namedtuple('BaseSection', ['name', 'start', 'end', 'offset', 'attrs'])): class Section(namedtuple('BaseSection', ['name', 'start', 'end', 'offset', 'attrs'])):
def better(self, other): def better(self, other):
@ -97,17 +115,17 @@ class ModuleInfoReader(object):
attrs = [a for a in mat['attrs'].split(' ') if a != ''] attrs = [a for a in mat['attrs'].split(' ') if a != '']
return Section(name, start, end, offset, attrs) return Section(name, start, end, offset, attrs)
def finish_module(self, name, sections): def finish_module(self, name, sections, index):
alloc = {k: s for k, s in sections.items() if 'ALLOC' in s.attrs} alloc = {k: s for k, s in sections.items() if 'ALLOC' in s.attrs}
if len(alloc) == 0: if len(alloc) == 0:
return Module(name, 0, 0, alloc) return Module(name, 0, 0, alloc)
# TODO: This may not be the module base, depending on headers base_addr = min(index.compute_base(s.start) for s in alloc.values())
base_addr = min(s.start - s.offset for s in alloc.values())
max_addr = max(s.end for s in alloc.values()) max_addr = max(s.end for s in alloc.values())
return Module(name, base_addr, max_addr, alloc) return Module(name, base_addr, max_addr, alloc)
def get_modules(self): def get_modules(self):
modules = {} modules = {}
index = Index(REGION_INFO_READER.get_regions())
out = gdb.execute(self.cmd, to_string=True) out = gdb.execute(self.cmd, to_string=True)
name = None name = None
sections = None sections = None
@ -115,7 +133,7 @@ class ModuleInfoReader(object):
n = self.name_from_line(line) n = self.name_from_line(line)
if n is not None: if n is not None:
if name is not None: if name is not None:
modules[name] = self.finish_module(name, sections) modules[name] = self.finish_module(name, sections, index)
name = n name = n
sections = {} sections = {}
continue continue
@ -128,7 +146,7 @@ class ModuleInfoReader(object):
s = s.better(sections[s.name]) s = s.better(sections[s.name])
sections[s.name] = s sections[s.name] = s
if name is not None: if name is not None:
modules[name] = self.finish_module(name, sections) modules[name] = self.finish_module(name, sections, index)
return modules return modules