summaryrefslogtreecommitdiff
path: root/mapparse.py
diff options
context:
space:
mode:
Diffstat (limited to 'mapparse.py')
-rw-r--r--mapparse.py129
1 files changed, 0 insertions, 129 deletions
diff --git a/mapparse.py b/mapparse.py
deleted file mode 100644
index c1f460a..0000000
--- a/mapparse.py
+++ /dev/null
@@ -1,129 +0,0 @@
-
-import re
-from collections import defaultdict, namedtuple
-
-Section = namedtuple('Section', ['name', 'offset', 'objects'])
-ObjectEntry = namedtuple('ObjectEntry', ['filename', 'object', 'offset', 'size'])
-FileEntry = namedtuple('FileEntry', ['section', 'object', 'offset', 'length'])
-
-class Memory:
- def __init__(self, name, origin, length, attrs=''):
- self.name, self.origin, self.length, self.attrs = name, origin, length, attrs
- self.sections = {}
- self.files = defaultdict(lambda: [])
- self.totals = defaultdict(lambda: 0)
-
- def add_toplevel(self, name, offx, length):
- self.sections[name] = Section(offx, length, [])
-
- def add_obj(self, name, offx, length, fn, obj):
- base_section, sep, subsec = name[1:].partition('.')
- base_section = '.'+base_section
- if base_section in self.sections:
- sec = secname, secoffx, secobjs = self.sections[base_section]
- secobjs.append(ObjectEntry(fn, obj, offx, length))
- else:
- sec = None
- self.files[fn].append(FileEntry(sec, obj, offx, length))
- self.totals[fn] += length
-
-class MapFile:
- def __init__(self, s):
- self._lines = s.splitlines()
- self.memcfg = {}
- self.defaultmem = Memory('default', 0, 0xffffffffffffffff)
- self._parse()
-
- def __getitem__(self, offx_or_name):
- ''' Lookup a memory area by name or address '''
- if offx_or_name in self.memcfg:
- return self.memcfg[offx_or_name]
-
- elif isinstance(offx_or_name, int):
- for mem in self.memcfg.values():
- if mem.origin <= offx_or_name < mem.origin+mem.length:
- return mem
- else:
- return self.defaultmem
-
- raise ValueError('Invalid argument type for indexing')
-
- def _skip(self, regex):
- matcher = re.compile(regex)
- for l in self:
- if matcher.match(l):
- break
-
- def __iter__(self):
- while self._lines:
- yield self._lines.pop(0)
-
- def _parse(self):
- self._skip('^Memory Configuration')
-
- # Parse memory segmentation info
- self._skip('^Name')
- for l in self:
- if not l:
- break
- name, origin, length, *attrs = l.split()
- if not name.startswith('*'):
- self.memcfg[name] = Memory(name, int(origin, 16), int(length, 16), attrs[0] if attrs else '')
-
- # Parse section information
- toplevel_m = re.compile('^(\.[a-zA-Z0-9_.]+)\s+(0x[0-9a-fA-F]+)\s+(0x[0-9a-fA-F]+)')
- secondlevel_m = re.compile('^ (\.[a-zA-Z0-9_.]+)\s+(0x[0-9a-fA-F]+)\s+(0x[0-9a-fA-F]+)\s+(.*)$')
- secondlevel_linebreak_m = re.compile('^ (\.[a-zA-Z0-9_.]+)\n')
- filelike = re.compile('^(/?[^()]*\.[a-zA-Z0-9-_]+)(\(.*\))?')
- linebreak_section = None
- for l in self:
- # Toplevel section
- match = toplevel_m.match(l)
- if match:
- name, offx, length = match.groups()
- offx, length = int(offx, 16), int(length, 16)
- self[offx].add_toplevel(name, offx, length)
-
- match = secondlevel_linebreak_m.match(l)
- if match:
- linebreak_section, = match.groups()
- continue
-
- if linebreak_section:
- l = ' {} {}'.format(linebreak_section, l)
- linebreak_section = None
-
- # Second-level section
- match = secondlevel_m.match(l)
- if match:
- name, offx, length, misc = match.groups()
- match = filelike.match(misc)
- if match:
- fn, obj = match.groups()
- obj = obj.strip('()') if obj else None
- offx, length = int(offx, 16), int(length, 16)
- self[offx].add_obj(name, offx, length, fn, obj)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser(description='Parser GCC map file')
- parser.add_argument('mapfile', type=argparse.FileType('r'), help='The GCC .map file to parse')
- parser.add_argument('-m', '--memory', type=str, help='The memory segments to print, comma-separated')
- args = parser.parse_args()
- mf = MapFile(args.mapfile.read())
- args.mapfile.close()
-
- mems = args.memory.split(',') if args.memory else mf.memcfg.keys()
-
- for name in mems:
- mem = mf.memcfg[name]
- print('Symbols by file for memory', name)
- for tot, fn in reversed(sorted( (tot, fn) for fn, tot in mem.totals.items() )):
- print(' {:>8} {}'.format(tot, fn))
- for length, offx, sec, obj in reversed(sorted(( (length, offx, sec, obj) for sec, obj, offx, length in
- mem.files[fn] ), key=lambda e: e[0] )):
- name = sec.name if sec else None
- print(' {:>8} {:>#08x} {}'.format(length, offx, obj))
- #print('{:>16} 0x{:016x} 0x{:016x} ({:>24}) {}'.format(name, origin, length, length, attrs))
-