summaryrefslogtreecommitdiff
path: root/controller/fw/tools/linktracer.py
diff options
context:
space:
mode:
Diffstat (limited to 'controller/fw/tools/linktracer.py')
-rw-r--r--controller/fw/tools/linktracer.py118
1 files changed, 0 insertions, 118 deletions
diff --git a/controller/fw/tools/linktracer.py b/controller/fw/tools/linktracer.py
deleted file mode 100644
index 0c53a60..0000000
--- a/controller/fw/tools/linktracer.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python3
-
-import re
-import subprocess
-import tempfile
-import pprint
-
-ARCHIVE_RE = r'([^(]*)(\([^)]*\))?'
-
-def trace_source_files(linker, cmdline):
- with tempfile.NamedTemporaryFile() as mapfile:
- output = subprocess.check_output([linker, f'-Wl,--Map={mapfile.name}', *cmdline])
-
- # intentionally use generator here
- idx = 0
- lines = [ line.rstrip() for line in mapfile.read().decode().splitlines() if line.strip() ]
-
- for idx, line in enumerate(lines[idx:], start=idx):
- #print('Dropping', line)
- if line == 'Linker script and memory map':
- break
-
- idx += 1
- objects = []
- symbols = {}
- sections = {}
- current_object = None
- last_offset = None
- last_symbol = None
- cont_sec = None
- cont_ind = None
- current_section = None
- for idx, line in enumerate(lines[idx:], start=idx):
- print(f'Processing >{line}')
- if line.startswith('LOAD'):
- _load, obj = line.split()
- objects.append(obj)
- continue
-
- if line.startswith('OUTPUT'):
- break
-
- m = re.match(r'^( ?)([^ ]+)? +(0x[0-9a-z]+) +(0x[0-9a-z]+)?(.*)?$', line)
- if m is None:
- m = re.match(r'^( ?)([^ ]+)?$', line)
- if m:
- cont_ind, cont_sec = m.groups()
- else:
- cont_ind, cont_sec = None, None
- last_offset, last_symbol = None, None
- continue
- indent, sec, offx, size, sym_or_src = m.groups()
- if sec is None:
- sec = cont_sec
- ind = cont_ind
- cont_sec = None
- cont_ind = None
- print(f'vals: indent={indent} sec={sec} offx={offx} size={size} sym_or_src={sym_or_src}')
- if not re.match('^[a-zA-Z_0-9<>():*]+$', sym_or_src):
- continue
-
- if indent == '':
- print(f'Section: {sec} 0x{size:x}')
- current_section = sec
- sections[sec] = size
- last_offset = None
- last_symbol = None
- continue
-
- if offx is not None:
- offx = int(offx, 16)
- if size is not None:
- size = int(size, 16)
-
- if size is not None and sym_or_src is not None:
- # archive/object line
- archive, _member = re.match(ARCHIVE_RE, sym_or_src).groups()
- current_object = archive
- last_offset = offx
- else:
- if sym_or_src is not None:
- assert size is None
- if last_offset is not None:
- last_size = offx - last_offset
- symbols[last_symbol] = (last_size, current_section)
- print(f'Symbol: {last_symbol} 0x{last_size:x} @{current_section}')
- last_offset = offx
- last_symbol = sym_or_src
-
- idx += 1
-
- for idx, line in enumerate(lines[idx:], start=idx):
- if line == 'Cross Reference Table':
- break
-
- idx += 1
-
- # map which symbol was pulled from which object in the end
- used_defs = {}
- for line in lines:
- *left, right = line.split()
-
- archive, _member = re.match(ARCHIVE_RE, right).groups()
- if left:
- used_defs[''.join(left)] = archive
-
- #pprint.pprint(symbols)
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument('linker_binary')
- parser.add_argument('linker_args', nargs=argparse.REMAINDER)
- args = parser.parse_args()
-
- source_files = trace_source_files(args.linker_binary, args.linker_args)
-