fix(f722): bound flash operations from sram
This commit is contained in:
1 parent
9fec2fa095
commit
1c90870634
4 files changed
+302
-63
No files matched your search
@@ -28,7 +28,12 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
"Name": {"Name": ".text"},
|
||||
"Size": 8,
|
||||
"Address": 0x08000000,
|
||||
"Flags": {"Flags": [{"Name": "SHF_ALLOC"}]},
|
||||
"Flags": {
|
||||
"Flags": [
|
||||
{"Name": "SHF_ALLOC"},
|
||||
{"Name": "SHF_EXECINSTR"},
|
||||
]
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -68,8 +73,8 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
sections,
|
||||
[
|
||||
ANALYZER.Section(".text", 8, 0x08000000, True),
|
||||
ANALYZER.Section(".debug_info", 100, 0, False),
|
||||
ANALYZER.Section(".text", 8, 0x08000000, True, True),
|
||||
ANALYZER.Section(".debug_info", 100, 0, False, False),
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
@@ -79,10 +84,10 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
|
||||
def test_accepts_allocated_memory_and_ignores_debug_sections(self):
|
||||
sections = [
|
||||
ANALYZER.Section(".text", 0x80, 0x08000000, True),
|
||||
ANALYZER.Section(".bss", 0x40, 0x20000000, True),
|
||||
ANALYZER.Section(".debug_info", 0x1000, 0, False),
|
||||
ANALYZER.Section(".empty", 0, 0xDEADBEEF, True),
|
||||
ANALYZER.Section(".text", 0x80, 0x08000000, True, True),
|
||||
ANALYZER.Section(".bss", 0x40, 0x20000000, True, False),
|
||||
ANALYZER.Section(".debug_info", 0x1000, 0, False, False),
|
||||
ANALYZER.Section(".empty", 0, 0xDEADBEEF, True, False),
|
||||
]
|
||||
segments = [
|
||||
ANALYZER.LoadSegment(0x08000000, 0x08000000, 0x80, 0x80),
|
||||
@@ -92,8 +97,8 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
self.assertEqual(ANALYZER.validation_errors(LAYOUT, sections, segments), [])
|
||||
|
||||
def test_rejects_allocated_sections_outside_or_crossing_a_region(self):
|
||||
outside = [ANALYZER.Section(".text", 4, 0x08000200, True)]
|
||||
crossing = [ANALYZER.Section(".text", 2, 0x080000FF, True)]
|
||||
outside = [ANALYZER.Section(".text", 4, 0x08000200, True, True)]
|
||||
crossing = [ANALYZER.Section(".text", 2, 0x080000FF, True, True)]
|
||||
|
||||
self.assertIn(
|
||||
"allocated section .text",
|
||||
@@ -106,8 +111,8 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
|
||||
def test_usage_counts_data_load_image_without_double_counting_text(self):
|
||||
sections = [
|
||||
ANALYZER.Section(".text", 0x40, 0x08000000, True),
|
||||
ANALYZER.Section(".data", 0x10, 0x20000000, True),
|
||||
ANALYZER.Section(".text", 0x40, 0x08000000, True, True),
|
||||
ANALYZER.Section(".data", 0x10, 0x20000000, True, False),
|
||||
]
|
||||
segments = [
|
||||
ANALYZER.LoadSegment(0x08000000, 0x08000000, 0x40, 0x40),
|
||||
@@ -131,6 +136,53 @@ class FirmwareMemoryValidationTests(unittest.TestCase):
|
||||
self.assertTrue(any("virtual span" in error for error in errors))
|
||||
self.assertTrue(any("physical span" in error for error in errors))
|
||||
|
||||
def test_requires_one_executable_data_section_in_ram(self):
|
||||
valid = [ANALYZER.Section(".data", 0x20, 0x20000000, True, True)]
|
||||
non_executable = [
|
||||
ANALYZER.Section(".data", 0x20, 0x20000000, True, False)
|
||||
]
|
||||
in_flash = [ANALYZER.Section(".data", 0x20, 0x08000000, True, True)]
|
||||
|
||||
self.assertEqual(ANALYZER.flash_operation_section_errors(LAYOUT, valid), [])
|
||||
self.assertIn(
|
||||
"executable SRAM",
|
||||
ANALYZER.flash_operation_section_errors(LAYOUT, non_executable)[0],
|
||||
)
|
||||
self.assertIn(
|
||||
"reside completely in RAM",
|
||||
ANALYZER.flash_operation_section_errors(LAYOUT, in_flash)[0],
|
||||
)
|
||||
|
||||
def test_sram_control_flow_rejects_external_or_indirect_fetches(self):
|
||||
section = ANALYZER.Section(".data", 0x20, 0x20000000, True, True)
|
||||
safe = """
|
||||
20000000: bne 0x20000008 <.data+0x8>
|
||||
20000004: ldr r0, [r1]
|
||||
20000008: pop {r7, pc}
|
||||
"""
|
||||
external = "20000000: bl 0x08000100 <flash_helper>"
|
||||
indirect_call = "20000000: blx r3"
|
||||
indirect_branch = "20000000: bx r3"
|
||||
literal = "20000000: ldr r0, [pc, #4]"
|
||||
|
||||
self.assertEqual(ANALYZER.sram_control_flow_errors(section, safe), [])
|
||||
self.assertIn(
|
||||
"branches outside SRAM",
|
||||
ANALYZER.sram_control_flow_errors(section, external)[0],
|
||||
)
|
||||
self.assertIn(
|
||||
"indirect control transfer",
|
||||
ANALYZER.sram_control_flow_errors(section, indirect_call)[0],
|
||||
)
|
||||
self.assertIn(
|
||||
"indirect control transfer",
|
||||
ANALYZER.sram_control_flow_errors(section, indirect_branch)[0],
|
||||
)
|
||||
self.assertIn(
|
||||
"PC-relative load",
|
||||
ANALYZER.sram_control_flow_errors(section, literal)[0],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user