This repository has been archived by the owner on Jan 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 85
Zero cost stack overflow protection, take 2 #43
Merged
Conversation
This file contains 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
Now with Without $ arm-none-eabi-size -Ax app
section size addr
.vector_table 0x400 0x8000000
.text 0x94 0x8000400
.rodata 0x0 0x8000494
.stack 0x5000 0x20000000
.bss 0x4 0x20000000
.data 0x4 0x20000004
.heap 0x1000 0x20000008 And with $ arm-none-eabi-size -Ax app
section size addr
.vector_table 0x400 0x8000000
.text 0x94 0x8000400
.rodata 0x0 0x8000494
.stack 0x3ff8 0x20000000
.bss 0x4 0x20003ff8
.data 0x4 0x20003ffc
.heap 0x1000 0x20004000 |
r? @whitequark Thoughts on the required changes to implemented this? You expressed concerns about implementing stack overflow protection using this method so I want to know if you find the changes too invasive or complex. Basically, this PR:
|
LGTM on the basic concept. I see no better way. NAK on the name of the linker, just call it |
@whitequark Thanks for the feedback. Agree on renaming the linker wrapper. |
This is one possible solution to the stack overflow problem described in #34. This approach uses a linker wrapper, called [swap-ld], to generate the desired memory layout. See #34 for a description of the desired memory layout and #41 for a description of how `swap-ld` works. The observable effects of this change in cortex-m programs are: - the `_sbss` symbol is now override-able. - there is now a `.stack` linker section that denotes the span of the call stack. `.stack` won't be loaded into the program; it just exists for informative purposes (`swap-ld` uses this information). Given the following program: ``` rust fn main() { static mut X: u32 = 0; static mut Y: u32 = 1; loop { unsafe { ptr::write_volatile(&mut X, X + 1); ptr::write_volatile(&mut Y, Y + 1); } } } ``` If you link this program using the `arm-none-eabi-ld` linker, which is the cortex-m-quickstart default, you'll get the following memory layout: ``` console $ console section size addr .vector_table 0x130 0x8000000 .text 0x94 0x8000130 .rodata 0x0 0x80001c4 .stack 0x5000 0x20000000 .bss 0x4 0x20000000 .data 0x4 0x20000004 ``` Note how the space reserved for the stack (depicted by the `.stack` linker section) overlaps with the space where .bss and .data reside. If you, instead, link this program using `swap-ld` you'll get the following memory layout: ``` console $ arm-none-eabi-size -Ax app section size addr .vector_table 0x130 0x8000000 .text 0x94 0x8000130 .rodata 0x0 0x80001c4 .stack 0x4ff8 0x20000000 .bss 0x4 0x20004ff8 .data 0x4 0x20004ffc ``` Note that no overlap exists in this case and that the call stack size has reduced to accommodate the .bss and .data sections. Unlike #41 the addresses of static variables is now correct: ``` console $ arm-none-eabi-objdump -CD app Disassembly of section .vector_table: 08000000 <_svector_table>: 8000000: 20004ff8 strdcs r4, [r0], -r8 ; initial Stack Pointer 08000004 <cortex_m_rt::RESET_VECTOR>: 8000004: 08000131 stmdaeq r0, {r0, r4, r5, r8} 08000008 <EXCEPTIONS>: 8000008: 080001bd stmdaeq r0, {r0, r2, r3, r4, r5, r7, r8} (..) Disassembly of section .stack: 20000000 <.stack>: ... Disassembly of section .bss: 20004ff8 <cortex_m_quickstart::main::X>: 20004ff8: 00000000 andeq r0, r0, r0 Disassembly of section .data: 20004ffc <_sdata>: 20004ffc: 00000001 andeq r0, r0, r1 ``` closes #34 [swap-ld]: https://github.com/japaric/swap-ld
This adds a fictitious `.heap` linker section that denotes the span of a heap region. The size of this linker section is governed by the `_heap_size` symbol which defaults to 0 but can be overridden by the user.
also fix a bug when .bss was empty but .data was not
japaric
changed the title
[WIP] Zero cost stack overflow protection, take 2
Zero cost stack overflow protection, take 2
Feb 17, 2018
japaric
added a commit
that referenced
this pull request
Apr 6, 2018
this commit adds LLD support by removing all INFO sections. LLD kind of supports INFO in the form of NOLOAD but when the linker script contains NOLOAD sections LLD emits a binary with false `size` information: for example, it reported a fake increase of 20KB in .text and a fake increase of 1KB in .bss when compiling a program that only allocates a single Box. As the INFO sections are gone we can no longer support the stack overflow protection added in #43 so all the other related changes, like making _stack_start overridable, have been removed as well. If you want to continue using stack overflow protection you can stick to v0.3.x. As the .debug_gdb_scripts output section has been removed from the linker script these changes will only reliably support both LD and LLD if/when rust-lang/rust#49728 lands. closes #53
japaric
added a commit
that referenced
this pull request
Apr 8, 2018
this commit adds LLD support by removing all INFO sections. LLD kind of supports INFO in the form of NOLOAD but when the linker script contains NOLOAD sections LLD emits a binary with false `size` information: for example, it reported a fake increase of 20KB in .text and a fake increase of 1KB in .bss when compiling a program that only allocates a single Box. As the INFO sections are gone we can no longer support the stack overflow protection added in #43 so all the other related changes, like making _stack_start overridable, have been removed as well. If you want to continue using stack overflow protection you can stick to v0.3.x. As the .debug_gdb_scripts output section has been removed from the linker script these changes will only reliably support both LD and LLD if/when rust-lang/rust#49728 lands. closes #53
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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 is one possible solution to the stack overflow problem described in #34. This approach uses a
linker wrapper, called swap-ld, to generate the desired memory layout. See #34 for a description
of the desired memory layout and #41 for a description of how
swap-ld
works.The observable effects of this change in cortex-m programs are:
_sbss
symbol is now override-able..stack
linker section that denotes the span of the call stack..stack
won't beloaded into the program; it just exists for informative purposes (
swap-ld
uses thisinformation).
Given the following program:
If you link this program using the
arm-none-eabi-ld
linker, which is the cortex-m-quickstartdefault, you'll get the following memory layout:
Note how the space reserved for the stack (depicted by the
.stack
linker section) overlaps withthe space where .bss and .data reside.
If you, instead, link this program using
swap-ld
you'll get the following memory layout:Note that no overlap exists in this case and that the call stack size has reduced to accommodate the
.bss and .data sections.
Unlike #41 the addresses of static variables is now correct:
closes #34
TODO
.heap
regionswap-ld
cortex-m-rt-ld