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:
parent
73b4ee69b7
commit
9882dcd3d2
1 changed files with 44 additions and 2 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue