zephyr/scripts/check_link_map.py
David Brown 8405ce13a1 scripts: Explicitly call out python2
At least one Linux distribution (Arch) has made python 3 the default
interpreter, and Debian and Ubuntu have expressed a desire to eventually
make this the case.  As such, invoking 'python' or '/usr/bin/python'
will possibly run python 3 instead of version 2.

Distributions have included a 'python2' link for quite some time now,
and given that we have some scripts that require python 3, we should be
explicit about those that require python 2.

In addition, be more consistent about how python is invoked, preferring
the:

  #!/usr/bin/env python2

construct rather than a hardcoded path to python.  This allows the user
to have an alternative python in their path that will be used in
preference to the system provided version.

Jira: ZEP-1548
Change-Id: I125c2af808dc268f74277bc97a092df3acad23c0
Signed-off-by: David Brown <david.brown@linaro.org>
2017-01-12 10:28:02 -07:00

68 lines
2.3 KiB
Python
Executable File

#!/usr/bin/env python2
import fileinput
import re
import sys
# Linker address generation validity checker. By default, GNU ld is
# broken when faced with sections where the load address (i.e. the
# spot in the XIP program binary where initialized data lives) differs
# from the virtual address (i.e. the location in RAM where that data
# will live at runtime. We need to be sure we're using the
# ALIGN_WITH_INPUT feature correctly everywhere, which is hard --
# especially so given that many of these bugs are semi-invisible at
# runtime (most initialized data is still a bunch of zeros and often
# "works" even if it's wrong).
#
# This quick test just checks the offsets between sequential segments
# with separate VMA/LMA addresses and verifies that the size deltas
# are identical.
#
# Note that this is assuming that the address generation is always
# in-order and that there is only one "ROM" LMA block. It's possible
# to write a valid linker script that will fail this script, but we
# don't have such a use case and one isn't forseen.
section_re = re.compile('(?x)' # (allow whitespace)
'^([a-zA-Z0-9_\.]+) \s+' # name
' (0x[0-9a-f]+) \s+' # addr
' (0x[0-9a-f]+) \s+') # size
load_addr_re = re.compile('load address (0x[0-9a-f]+)')
in_prologue = True
lma = 0
last_sec = None
for line in fileinput.input():
# Skip the header junk
if line.find("Linker script and memory map") >= 0:
in_prologue = False
continue
match = section_re.match(line.rstrip())
if match:
sec = match.group(1)
vma = int(match.group(2), 16)
size = int(match.group(3), 16)
lmatch = load_addr_re.search(line.rstrip())
if lmatch:
lma = int(lmatch.group(1), 16)
else:
last_sec = None
continue
if last_sec != None:
dv = vma - last_vma
dl = lma - last_lma
if dv != dl:
sys.stderr.write("ERROR: section %s is %d bytes "
"in the virtual/runtime address space, "
"but only %d in the loaded/XIP section!\n"
% (last_sec, dv, dl))
sys.exit(1)
last_sec = sec
last_vma = vma
last_lma = lma