runtime/libtock_layout.ld: use FLASH-segment LMAs for all sections#478
Merged
bors[bot] merged 2 commits intotock:masterfrom Jul 10, 2023
Merged
runtime/libtock_layout.ld: use FLASH-segment LMAs for all sections#478bors[bot] merged 2 commits intotock:masterfrom
bors[bot] merged 2 commits intotock:masterfrom
Conversation
added 2 commits
June 29, 2023 08:49
There's no reason as to why `.data` should be placed directly after `.rodata` in FLASH. We can use the `> $VMASEGMENT AT > $LMASEGMENT` syntax to simply place it at the next well-aligned offset in the FLASH segment. This reduces the overall complexity of the linker scripts, and avoids accidentally placing multiple sections at competing addresses.
Previously, `.stack` and `.bss` sections were simply instructed to be
placed into RAM. Without an explicitly specified load address or load
address region, this means that their ELF-segment's `PhysAddr` will be
set to its `VirtAddr` (and hence point into RAM):
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x20030000 0x20030000 0x00000 0x00060 R 0x1000
LOAD 0x001060 0x20030060 0x20030060 0x00d64 0x00d64 R E 0x1000
LOAD 0x001dc4 0x20030dc4 0x20030dc4 0x001ec 0x001ec R 0x1000
LOAD 0x002000 0x10004000 0x10004000 0x00000 0x00100 RW 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0
Section to Segment mapping:
Segment Sections...
00 .tbf_header
01 .start .text
02 .rodata
03 .stack
04
When, for any reason, these segments contain any actual
data (`FileSiz` != 0), for instance under certain alignment
constraints[1], this will cause a ROM-loader such as elf2tab to place
them at their specified `PhysAddr` offset. As a result, if
`ORIGIN(FLASH)` precedes `ORIGIN(RAM)`, the binary is blown up due to
padding. If `ORIGIN(RAM)` precedes `ORIGIN(FLASH)`, the `rt_header`
internal offsets are incorrect because the actual FLASH load address
is now offset by `ORIGIN(FLASH) - ORIGIN(RAM)`. With this change, no
`LOAD`able segment will have a `PhysAddr` outside of the `FLASH`
memory region. This does not have any effect on zero-sized
sections (they will not increase flash usage):
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x20030000 0x20030000 0x00fb0 0x00fb0 RWE 0x1000
LOAD 0x000800 0x10004800 0x20030fb0 0x00000 0x00100 RW 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
Section to Segment mapping:
Segment Sections...
00 .tbf_header .start .text .rodata
01 .stack
02
The reason why this worked in the past was that `elf2tab` skipped
segments with a `FileSiz` == 0, and did so even before calculating
paddings. We should probably not rely on such an implementation detail
of our loader, which can further break if the linker were to insert
any padding into a segment.
[1]: See tock#477 for an example.
jrvanwhy
approved these changes
Jun 29, 2023
Collaborator
|
bors r+ |
Contributor
|
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change ensures that no ELF-segment will have a
PhysAddrwhich points outside of theFLASHmemory region. This is important for ROM-loaders such as elf2tab to reliably produce correct binaries.Motivation
Previously,
.stackand.bsssections were simply instructed to be placed into RAM. Without an explicitly specified load address or load address region, this means that their ELF-segment'sPhysAddrwill be set to itsVirtAddr(and hence point into RAM):When, for any reason, these segments contain any actual data (
FileSiz!= 0), for instance under certain alignmentconstraints[1], this will cause a ROM-loader such as elf2tab to place them at their specified
PhysAddroffset. As a result, ifORIGIN(FLASH)precedesORIGIN(RAM), the binary is blown up due to padding. IfORIGIN(RAM)precedesORIGIN(FLASH), thert_headerinternal offsets are incorrect because the actual FLASH load address is now offset byORIGIN(FLASH) - ORIGIN(RAM). With this change, noLOADable segment will have aPhysAddroutside of theFLASHmemory region. This does not have any effect on zero-sized sections (they will not increase flash usage):The reason why this worked in the past was that
elf2tabskipped segments with aFileSiz== 0, and did so even before calculating paddings. We should probably not rely on such an implementation detail of our loader, which can further break if the linker were to insert any padding into a segment.[1]: See #477 for an example.