document this feature in the unstable book
This commit is contained in:
parent
3c0907ce51
commit
39afcd0673
1 changed files with 153 additions and 0 deletions
153
src/doc/unstable-book/src/compiler-flags/emit-stack-sizes.md
Normal file
153
src/doc/unstable-book/src/compiler-flags/emit-stack-sizes.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
# `emit-stack-sizes`
|
||||
|
||||
The tracking issue for this feature is: [#54192]
|
||||
|
||||
[#54192]: https://github.com/rust-lang/rust/issues/54192
|
||||
|
||||
------------------------
|
||||
|
||||
The rustc flag `-Z emit-stack-sizes` makes LLVM emit stack size metadata.
|
||||
|
||||
Consider this crate:
|
||||
|
||||
```
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::ptr;
|
||||
|
||||
pub fn foo() {
|
||||
// this function doesn't use the stack
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
let xs = [0u32; 2];
|
||||
|
||||
// force LLVM to allocate `xs` on the stack
|
||||
unsafe { ptr::read_volatile(&xs.as_ptr()); }
|
||||
}
|
||||
```
|
||||
|
||||
Using the `-Z emit-stack-sizes` flag produces extra linker sections in the
|
||||
output *object file*.
|
||||
|
||||
``` console
|
||||
$ rustc -C opt-level=3 --emit=obj foo.rs
|
||||
|
||||
$ size -A foo.o
|
||||
foo.o :
|
||||
section size addr
|
||||
.text 0 0
|
||||
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
|
||||
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
|
||||
.note.GNU-stack 0 0
|
||||
.eh_frame 72 0
|
||||
Total 95
|
||||
|
||||
$ rustc -C opt-level=3 --emit=obj -Z emit-stack-sizes foo.rs
|
||||
|
||||
$ size -A foo.o
|
||||
foo.o :
|
||||
section size addr
|
||||
.text 0 0
|
||||
.text._ZN3foo3foo17he211d7b4a3a0c16eE 1 0
|
||||
.stack_sizes 9 0
|
||||
.text._ZN3foo3bar17h1acb594305f70c2eE 22 0
|
||||
.stack_sizes 9 0
|
||||
.note.GNU-stack 0 0
|
||||
.eh_frame 72 0
|
||||
Total 113
|
||||
```
|
||||
|
||||
As of LLVM 7.0 the data will be written into a section named `.stack_sizes` and
|
||||
the format is "an array of pairs of function symbol values (pointer size) and
|
||||
stack sizes (unsigned LEB128)".
|
||||
|
||||
``` console
|
||||
$ objdump -d foo.o
|
||||
|
||||
foo.o: file format elf64-x86-64
|
||||
|
||||
Disassembly of section .text._ZN3foo3foo17he211d7b4a3a0c16eE:
|
||||
|
||||
0000000000000000 <_ZN3foo3foo17he211d7b4a3a0c16eE>:
|
||||
0: c3 retq
|
||||
|
||||
Disassembly of section .text._ZN3foo3bar17h1acb594305f70c2eE:
|
||||
|
||||
0000000000000000 <_ZN3foo3bar17h1acb594305f70c2eE>:
|
||||
0: 48 83 ec 10 sub $0x10,%rsp
|
||||
4: 48 8d 44 24 08 lea 0x8(%rsp),%rax
|
||||
9: 48 89 04 24 mov %rax,(%rsp)
|
||||
d: 48 8b 04 24 mov (%rsp),%rax
|
||||
11: 48 83 c4 10 add $0x10,%rsp
|
||||
15: c3 retq
|
||||
|
||||
$ objdump -s -j .stack_sizes foo.o
|
||||
|
||||
foo.o: file format elf64-x86-64
|
||||
|
||||
Contents of section .stack_sizes:
|
||||
0000 00000000 00000000 00 .........
|
||||
Contents of section .stack_sizes:
|
||||
0000 00000000 00000000 10 .........
|
||||
```
|
||||
|
||||
It's important to note that linkers will discard this linker section by default.
|
||||
To preserve the section you can use a linker script like the one shown below.
|
||||
|
||||
``` text
|
||||
/* file: keep-stack-sizes.x */
|
||||
SECTIONS
|
||||
{
|
||||
.stack_sizes :
|
||||
{
|
||||
KEEP(*(.stack_sizes));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The linker script must be passed to the linker using a rustc flag like `-C
|
||||
link-arg`.
|
||||
|
||||
```
|
||||
// file: src/main.rs
|
||||
use std::ptr;
|
||||
|
||||
#[inline(never)]
|
||||
fn main() {
|
||||
let xs = [0u32; 2];
|
||||
|
||||
// force LLVM to allocate `xs` on the stack
|
||||
unsafe { ptr::read_volatile(&xs.as_ptr()); }
|
||||
}
|
||||
```
|
||||
|
||||
``` console
|
||||
$ RUSTFLAGS="-Z emit-stack-sizes" cargo build --release
|
||||
|
||||
$ size -A target/release/hello | grep stack_sizes || echo section was not found
|
||||
section was not found
|
||||
|
||||
$ RUSTFLAGS="-Z emit-stack-sizes" cargo rustc --release -- \
|
||||
-C link-arg=-Wl,-Tkeep-stack-sizes.x \
|
||||
-C link-arg=-N
|
||||
|
||||
$ size -A target/release/hello | grep stack_sizes
|
||||
.stack_sizes 90 205368
|
||||
|
||||
$ objdump -s -j .stack_sizes target/release/hello
|
||||
|
||||
target/release/hello: file format elf64-x86-64
|
||||
|
||||
Contents of section .stack_sizes:
|
||||
32238 c0040000 00000000 08f00400 00000000 ................
|
||||
32248 00080005 00000000 00000810 05000000 ................
|
||||
32258 00000000 20050000 00000000 10400500 .... ........@..
|
||||
32268 00000000 00087005 00000000 00000080 ......p.........
|
||||
32278 05000000 00000000 90050000 00000000 ................
|
||||
32288 00a00500 00000000 0000 ..........
|
||||
```
|
||||
|
||||
> Author note: I'm not entirely sure why, in *this* case, `-N` is required in
|
||||
> addition to `-Tkeep-stack-sizes.x`. For example, it's not required when
|
||||
> producing statically linked files for the ARM Cortex-M architecture.
|
||||
Loading…
Add table
Add a link
Reference in a new issue