sanitycheck: look for misaligned XIP VMA/LMA addresses

XIP is currently implemented in Zephyr by copying only the RW
sections from flash into RAM. For these sections, if the VMA spacing
is different than the LMA spacing the sections in RAM will not be
at the right addresses. Warn about this situation.

Change-Id: I59a55fc27703103e37a7f0bbc34f236047621e0e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2015-10-07 14:25:51 -07:00 committed by Anas Nashif
commit 9882dcd3d2

View file

@ -326,6 +326,7 @@ class SizeCalculator:
self.sections = []
self.rom_size = 0
self.ram_size = 0
self.mismatches = []
self._calculate_sizes()
@ -354,6 +355,17 @@ class SizeCalculator:
slist.append(v["name"])
return slist
def mismatched_sections(self):
"""Get a list of sections in the binary whose LMA and VMA offsets
from the previous section aren't proportional. This leads to issues
on XIP systems as they aren't correctly copied in to RAM
"""
slist = []
for v in self.sections:
if v["lma_off"] != v["vma_off"]:
slist.append((v["name"], v["lma_off"], v["vma_off"]))
return slist
def _calculate_sizes(self):
""" Calculate RAM and ROM usage by section """
objdump_command = "objdump -h " + self.filename
@ -378,6 +390,9 @@ class SizeCalculator:
# it doesn't include linker-imposed padding between sections.
# It is close though.
size = int(words[2], 16)
if size == 0:
continue
load_addr = int(words[4], 16)
virt_addr = int(words[3], 16)
@ -400,9 +415,23 @@ class SizeCalculator:
stype = "unknown"
recognized = False
lma_off = 0
vma_off = 0
# Look for different section padding for LMA and VMA, if present
# this really messes up XIP systems as __csSet() copies all of
# them off flash into RAM as a single large block of memory
if self.is_xip and len(self.sections) > 0:
p = self.sections[-1]
if stype == "rw" and p["type"] == "rw":
lma_off = load_addr - p["load_addr"]
vma_off = virt_addr - p["virt_addr"]
self.sections.append({"name" : name, "load_addr" : load_addr,
"size" : size, "virt_addr" : virt_addr,
"type" : stype, "recognized" : recognized})
"type" : stype, "recognized" : recognized,
"lma_off" : lma_off, "vma_off" : vma_off})
class MakeGoal:
@ -1213,6 +1242,7 @@ class TestSuite:
goal.metrics["ram_size"] = sc.get_ram_size()
goal.metrics["rom_size"] = sc.get_rom_size()
goal.metrics["unrecognized"] = sc.unrecognized_sections()
goal.metrics["mismatched"] = sc.mismatched_sections()
return self.goals
def discard_report(self, filename):
@ -1455,10 +1485,17 @@ def chatty_test_cb(instances, goals, goal):
def size_report(sc):
info(sc.filename)
info("SECTION NAME VMA LMA SIZE HEX SZ TYPE")
for v in sc.sections:
for i in range(len(sc.sections)):
v = sc.sections[i]
info("%-17s 0x%08x 0x%08x %8d 0x%05x %-7s" %
(v["name"], v["virt_addr"], v["load_addr"], v["size"], v["size"],
v["type"]))
if v["lma_off"] != v["vma_off"]:
info(" WARNING: LMA and VMA offsets between %s and %s differ: %d vs %d" %
(sc.sections[i-1]["name"], v["name"], v["lma_off"],
v["vma_off"]))
info("Totals: %d bytes (ROM), %d bytes (RAM)" %
(sc.rom_size, sc.ram_size))
info("")
@ -1542,6 +1579,11 @@ def main():
(COLOR_RED, COLOR_NORMAL, goal.name,
str(goal.metrics["unrecognized"])))
failed += 1
elif goal.metrics["mismatched"]:
info("%sFAILED%s: %s has mismatched section offsets for: %s" %
(COLOR_RED, COLOR_NORMAL, goal.name,
str(goal.metrics["mismatched"])))
failed += 1
info("%s%d of %d%s tests passed with %s%d%s warnings in %d seconds" %
(COLOR_RED if failed else COLOR_GREEN, len(goals) - failed,