-
Notifications
You must be signed in to change notification settings - Fork 84
Fix common uses of INSERT AFTER with .bss and .text #287
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @therealprof (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I'm a bit confused why the label placement inside the section doesn't have the same effect. Is this known linker behaviour causing the label Anyway this looks fine to me. Any objections @jonas-schievink @adamgreig ? |
I'm sure this linker script is the most touched file in the repo and I'm always worried a simple PR will cause some undetected bug in six month's time, especially trying to support gcc and lld simultaneously. This looks fine but I also don't understand why it's needed exactly. @mattico, could you elaborate on the motivation for this change? It looks like maybe the common use of |
I believe this is correct. Also my GCC is doing something like INSERT AFTER for statics for some reason. I'll try to get a more thorough understanding of the issue. |
Alright so. https://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html
Not overriding the default linker script was an unexpected turn. However my reading of the rest is that it doesn't matter since our definitions come first for things we care about. As far as where things get inserted... https://sourceware.org/binutils/docs/ld/Orphan-Sections.html
Along with https://reviews.llvm.org/D42482 Seem to indicate that the linker will place https://sourceware.org/binutils/docs/ld/Location-Counter.html
This indicates that when the start/end symbols are outside of the section, the linker may place orphan sections between them, which may not be desirable. https://sourceware.org/binutils/docs/ld/Simple-Assignments.html
So Looking at the default linker script from
It uses the However for my case, that My conclusion is that linker behavior is rather poorly specified. I think we should follow the default linker script here because it seems to work. However, the only thing I really want now is to add |
Additionally, include COMMON symbols (uninitialized statics from C) in bss.
That's a very strange CI failure
I can't see how |
The issue was the alignment of the sections when stored in flash. It seems that old lld had a bug when dealing with aligned sections and I added We still want the align directives before the end symbols. Sections inserted before them might not have aligned ends and our |
ac06446
to
2c5077a
Compare
I can confirm this change works to fix the issues, I haven't noticed any bad effects from it either. (I have been using a custom linker script with this change for a while). Also, the same issue is present with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the thorough investigation!
bors merge
ha ha! We document that if you want to add new memory sections you can put them in I'm not immediately sure what the best remedy is, but if nothing else this will (when released) break anyone with |
Leaving the |
@jordens, do you think we should move the |
The intention behind I'm unsure why one would need to do that for the other sections ( Maybe the compromise is to have (a) all I suspect that #266 (from the top issue) and maybe also #267 (by extension) was in fact addressed by #286. And looking through Line 104 in 8c90451
Lot's of speculation and little hard data, I know. |
This puts most start/end address symbols back into the sections. Only `__ebss` and `__edata` are kept outside their sections so that potential user code with external libraries can inject stuff using `INSERT AFTER .bss/.data` and profit from the .bss/.data zeroing/loading mechanism. This also leads to the `__sbss` and `__veneer_base` symbols having the right section type (B not D in nm). Also the trust zone start and end address are aligned to 32 bytes as per the requirements. That section does cost up to 28 byte of FLASH due to that alignment even if empty. The .rodata start is kep free for the linker to alocate it after .text. This enables users to inject sections between .text and .rodata and removes the chance to get overlapping address errors. With this the linker will by default place .rodata after .text as before. This commit also adds and exposes a few more stable address start/end symbols (__[se]uninit, __stext, __srodata) that are usefull for debugging and hooking into. See rust-embedded#287 (comment) for discussion of the issues and description of this compromise solution.
323: link.x.in: put most __[se] symbols back into sections r=adamgreig a=jordens This puts most start/end address symbols back into the sections. Only `__ebss` and `__edata` are kept outside their sections so that potential user code with external libraries can inject stuff using `INSERT AFTER .bss/.data` and profit from the .bss/.data zeroing/loading mechanism. This also leads to the `__sbss` and `__veneer_base` symbols having the right section type (bss is B not D in nm). Also the trust zone start and end address are aligned to 32 bytes as per the requirements. That section does cost up to 28 byte of padding at the end of FLASH due to that alignment even if empty. But since flash is typically a multiple of 32 bytes and since the padding is at the end, there is no downside. The .rodata start is kept free for the linker to allocate it after .text. This enables users to inject sections between .text and .rodata and removes the chance to get overlapping address errors. With this the linker will by default place .rodata after .text as before. This commit also adds and exposes a few more stable address start/end symbols (__[se]uninit, __stext, __srodata) that are usefull for debugging and hooking into. See #287 (comment) for discussion of the issues and description of this compromise solution. Tested: * [x] [stm32h7 ITCM](quartiq/stabilizer#322) * [x] [sgstubs](#323 (comment)) * [x] `INSERT AFTER` for bss/data still works (#323 (comment)) Topics: * [x] `sgstubs` moved to be the last section in FLASH to minimize the impact of the 32 byte alignment. (Padding flash to 32 byte is considered benign.) * [ ] `INSERT AFTER` with binutils ld doesn't work. But that's independent of these changes. This is the `sgstubs`-in `memory.x` use case. Currently the `sgstubs` section is kept in `link.x`. Co-authored-by: Robert Jördens <rj@quartiq.de>
287: Fix common uses of INSERT AFTER with .bss and .text r=adamgreig a=mattico Fixes #267 Fixes #266 This fixes two related issues. 1. Named sections are often inserted after `.bss` or `.text` in order to have them handled as if they were part of that section. Defining the start/end symbols outside of the section allows this to work. 2. Uninitialized C statics will end up as common symbols which end up in the COMMON input section. If this section is orphaned, it will likely end up placed after `.bss`. C code often expects these statics to be zero initialized. The first change would cause these symbols to be placed before `__ebss` so they will get zeroed by the reset handler. Explicitly placing the common symbols into `.bss` ensures this happens. Users who want uninitialized symbols should use the `.uninit` section. See rust-embedded/cortex-m-rt#287 (comment) Co-authored-by: Matt Ickstadt <mattico8@gmail.com>
This puts most start/end address symbols back into the sections. Only `__ebss` and `__edata` are kept outside their sections so that potential user code with external libraries can inject stuff using `INSERT AFTER .bss/.data` and profit from the .bss/.data zeroing/loading mechanism. This also leads to the `__sbss` and `__veneer_base` symbols having the right section type (B not D in nm). Also the trust zone start and end address are aligned to 32 bytes as per the requirements. That section does cost up to 28 byte of FLASH due to that alignment even if empty. The .rodata start is kep free for the linker to alocate it after .text. This enables users to inject sections between .text and .rodata and removes the chance to get overlapping address errors. With this the linker will by default place .rodata after .text as before. This commit also adds and exposes a few more stable address start/end symbols (__[se]uninit, __stext, __srodata) that are usefull for debugging and hooking into. See rust-embedded/cortex-m-rt#287 (comment) for discussion of the issues and description of this compromise solution.
323: link.x.in: put most __[se] symbols back into sections r=adamgreig a=jordens This puts most start/end address symbols back into the sections. Only `__ebss` and `__edata` are kept outside their sections so that potential user code with external libraries can inject stuff using `INSERT AFTER .bss/.data` and profit from the .bss/.data zeroing/loading mechanism. This also leads to the `__sbss` and `__veneer_base` symbols having the right section type (bss is B not D in nm). Also the trust zone start and end address are aligned to 32 bytes as per the requirements. That section does cost up to 28 byte of padding at the end of FLASH due to that alignment even if empty. But since flash is typically a multiple of 32 bytes and since the padding is at the end, there is no downside. The .rodata start is kept free for the linker to allocate it after .text. This enables users to inject sections between .text and .rodata and removes the chance to get overlapping address errors. With this the linker will by default place .rodata after .text as before. This commit also adds and exposes a few more stable address start/end symbols (__[se]uninit, __stext, __srodata) that are usefull for debugging and hooking into. See rust-embedded/cortex-m-rt#287 (comment) for discussion of the issues and description of this compromise solution. Tested: * [x] [stm32h7 ITCM](quartiq/stabilizer#322) * [x] [sgstubs](rust-embedded/cortex-m-rt#323 (comment)) * [x] `INSERT AFTER` for bss/data still works (rust-embedded/cortex-m-rt#323 (comment)) Topics: * [x] `sgstubs` moved to be the last section in FLASH to minimize the impact of the 32 byte alignment. (Padding flash to 32 byte is considered benign.) * [ ] `INSERT AFTER` with binutils ld doesn't work. But that's independent of these changes. This is the `sgstubs`-in `memory.x` use case. Currently the `sgstubs` section is kept in `link.x`. Co-authored-by: Robert Jördens <rj@quartiq.de>
Fixes #267
Fixes #266
This fixes two related issues.
.bss
or.text
in order to have them handled as if they were part of that section. Defining the start/end symbols outside of the section allows this to work..bss
. C code often expects these statics to be zero initialized. The first change would cause these symbols to be placed before__ebss
so they will get zeroed by the reset handler. Explicitly placing the common symbols into.bss
ensures this happens. Users who want uninitialized symbols should use the.uninit
section.See #287 (comment)