a449c98db2
Fixes pylint warnings like this one: doc/conf.py:325:0: W1401: Anomalous backslash in string: '\s'. String constant might be missing an r prefix. (anomalous-backslash-in-string) The reason for this warning is that backslash escapes are interpreted in non-raw (non-r-prefixed) strings. For example, '\a' and r'\a' are not the same string (first one has a single ASCII bell character, second one has two characters). It just happens that there's no \s (or \., or \/) escape for example, and '\s' turns into two characters (as needed for a regex). It's risky to rely on stuff like that regexes though. Best to make them raw strings unless they're super trivial. Also note that '\s' and '\\s' turn into the same string. Another tip: A literal ' can be put into a string with "blah'blah" instead of 'blah\'blah'. Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
75 lines
2.6 KiB
Python
Executable file
75 lines
2.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
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(r'(?x)' # (allow whitespace)
|
|
r'^([a-zA-Z0-9_\.]+) \s+' # name
|
|
r' (0x[0-9a-f]+) \s+' # addr
|
|
r' (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)
|
|
|
|
if sec == "bss":
|
|
# Make sure we don't compare the last section of kernel data
|
|
# with the first section of application data, the kernel's bss
|
|
# and noinit are in between.
|
|
last_sec = None
|
|
continue
|
|
|
|
lmatch = load_addr_re.search(line.rstrip())
|
|
if lmatch:
|
|
lma = int(lmatch.group(1), 16)
|
|
else:
|
|
last_sec = None
|
|
continue
|
|
|
|
if last_sec is not 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
|