Skip to content

Commit 763beff

Browse files
author
Jorge Aparicio
committed
add documentation to the unstable book
1 parent bbe5411 commit 763beff

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

src/doc/unstable-book/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
- [unwind_attributes](unwind-attributes.md)
204204
- [update_panic_count](update-panic-count.md)
205205
- [use_extern_macros](use-extern-macros.md)
206+
- [used](used.md)
206207
- [utf8_error_error_len](utf8-error-error-len.md)
207208
- [vec_remove_item](vec-remove-item.md)
208209
- [windows_c](windows-c.md)

src/doc/unstable-book/src/used.md

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# `used`
2+
3+
The tracking issue for this feature is: 40289.
4+
5+
------------------------
6+
7+
The `#[used]` attribute can be applied to `static` variables to prevent the Rust
8+
compiler from optimizing them away even if they appear to be unused by the crate
9+
(appear to be "dead code").
10+
11+
``` rust
12+
#![feature(used)]
13+
14+
#[used]
15+
static FOO: i32 = 1;
16+
17+
static BAR: i32 = 2;
18+
19+
fn main() {}
20+
```
21+
22+
If you compile this program into an object file, you'll see that `FOO` makes it
23+
to the object file but `BAR` doesn't. Neither static variable is used by the
24+
program.
25+
26+
``` text
27+
$ rustc -C opt-level=3 --emit=obj used.rs
28+
29+
$ nm -C used.o
30+
0000000000000000 T main
31+
U std::rt::lang_start
32+
0000000000000000 r used::FOO
33+
0000000000000000 t used::main
34+
```
35+
36+
Note that the *linker* knows nothing about the `#[used]` attribute and will
37+
remove `#[used]` symbols if they are not referenced by other parts of the
38+
program:
39+
40+
``` text
41+
$ rustc -C opt-level=3 used.rs
42+
43+
$ nm -C used | grep FOO
44+
```
45+
46+
"This doesn't sound too useful then!" you may think but keep reading.
47+
48+
To preserve the symbols all the way to the final binary, you'll need the
49+
cooperation of the linker. Here's one example:
50+
51+
The ELF standard defines two special sections, `.init_array` and
52+
`.pre_init_array`, that may contain function pointers which will be executed
53+
*before* the `main` function is invoked. The linker will preserve symbols placed
54+
in these sections (at least when linking programs that target the `*-*-linux-*`
55+
targets).
56+
57+
``` rust
58+
#![feature(used)]
59+
60+
extern "C" fn before_main() {
61+
println!("Hello, world!");
62+
}
63+
64+
#[link_section = ".init_array"]
65+
#[used]
66+
static INIT_ARRAY: [extern "C" fn(); 1] = [before_main];
67+
68+
fn main() {}
69+
```
70+
71+
So, `#[used]` and `#[link_section]` can be combined to obtain "life before
72+
main".
73+
74+
``` text
75+
$ rustc -C opt-level=3 before-main.rs
76+
77+
$ ./before-main
78+
Hello, world!
79+
```
80+
81+
Another example: ARM Cortex-M microcontrollers need their reset handler, a
82+
pointer to the function that will executed right after the microcontroller is
83+
turned on, to be placed near the start of their FLASH memory to boot properly.
84+
85+
This condition can be met using `#[used]` and `#[link_section]` plus a linker
86+
script.
87+
88+
``` rust
89+
#![feature(lang_items)]
90+
#![feature(used)]
91+
#![no_main]
92+
#![no_std]
93+
94+
extern "C" fn reset_handler() -> ! {
95+
loop {}
96+
}
97+
98+
#[link_section = ".reset_handler"]
99+
#[used]
100+
static RESET_HANDLER: extern "C" fn() -> ! = reset_handler;
101+
102+
#[lang = "panic_fmt"]
103+
fn panic_fmt() {}
104+
```
105+
106+
``` text
107+
MEMORY
108+
{
109+
FLASH : ORIGIN = 0x08000000, LENGTH = 128K
110+
RAM : ORIGIN = 0x20000000, LENGTH = 20K
111+
}
112+
113+
SECTIONS
114+
{
115+
.text ORIGIN(FLASH) :
116+
{
117+
/* Vector table */
118+
LONG(ORIGIN(RAM) + LENGTH(RAM)); /* initial SP value */
119+
KEEP(*(.reset_handler));
120+
121+
/* Omitted: The rest of the vector table */
122+
123+
*(.text.*);
124+
} > FLASH
125+
126+
/DISCARD/ :
127+
{
128+
/* Unused unwinding stuff */
129+
*(.ARM.exidx.*)
130+
}
131+
}
132+
```
133+
134+
``` text
135+
$ xargo rustc --target thumbv7m-none-eabi --release -- \
136+
-C link-arg=-Tlink.x -C link-arg=-nostartfiles
137+
138+
$ arm-none-eabi-objdump -Cd target/thumbv7m-none-eabi/release/app
139+
./target/thumbv7m-none-eabi/release/app: file format elf32-littlearm
140+
141+
142+
Disassembly of section .text:
143+
144+
08000000 <app::RESET_HANDLER-0x4>:
145+
8000000: 20005000 .word 0x20005000
146+
147+
08000004 <app::RESET_HANDLER>:
148+
8000004: 08000009 ....
149+
150+
08000008 <app::reset_handler>:
151+
8000008: e7fe b.n 8000008 <app::reset_handler>
152+
```

0 commit comments

Comments
 (0)