add documentation to the unstable book
This commit is contained in:
parent
bbe5411587
commit
763beff5d1
2 changed files with 153 additions and 0 deletions
|
|
@ -203,6 +203,7 @@
|
|||
- [unwind_attributes](unwind-attributes.md)
|
||||
- [update_panic_count](update-panic-count.md)
|
||||
- [use_extern_macros](use-extern-macros.md)
|
||||
- [used](used.md)
|
||||
- [utf8_error_error_len](utf8-error-error-len.md)
|
||||
- [vec_remove_item](vec-remove-item.md)
|
||||
- [windows_c](windows-c.md)
|
||||
|
|
|
|||
152
src/doc/unstable-book/src/used.md
Normal file
152
src/doc/unstable-book/src/used.md
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# `used`
|
||||
|
||||
The tracking issue for this feature is: 40289.
|
||||
|
||||
------------------------
|
||||
|
||||
The `#[used]` attribute can be applied to `static` variables to prevent the Rust
|
||||
compiler from optimizing them away even if they appear to be unused by the crate
|
||||
(appear to be "dead code").
|
||||
|
||||
``` rust
|
||||
#![feature(used)]
|
||||
|
||||
#[used]
|
||||
static FOO: i32 = 1;
|
||||
|
||||
static BAR: i32 = 2;
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
||||
If you compile this program into an object file, you'll see that `FOO` makes it
|
||||
to the object file but `BAR` doesn't. Neither static variable is used by the
|
||||
program.
|
||||
|
||||
``` text
|
||||
$ rustc -C opt-level=3 --emit=obj used.rs
|
||||
|
||||
$ nm -C used.o
|
||||
0000000000000000 T main
|
||||
U std::rt::lang_start
|
||||
0000000000000000 r used::FOO
|
||||
0000000000000000 t used::main
|
||||
```
|
||||
|
||||
Note that the *linker* knows nothing about the `#[used]` attribute and will
|
||||
remove `#[used]` symbols if they are not referenced by other parts of the
|
||||
program:
|
||||
|
||||
``` text
|
||||
$ rustc -C opt-level=3 used.rs
|
||||
|
||||
$ nm -C used | grep FOO
|
||||
```
|
||||
|
||||
"This doesn't sound too useful then!" you may think but keep reading.
|
||||
|
||||
To preserve the symbols all the way to the final binary, you'll need the
|
||||
cooperation of the linker. Here's one example:
|
||||
|
||||
The ELF standard defines two special sections, `.init_array` and
|
||||
`.pre_init_array`, that may contain function pointers which will be executed
|
||||
*before* the `main` function is invoked. The linker will preserve symbols placed
|
||||
in these sections (at least when linking programs that target the `*-*-linux-*`
|
||||
targets).
|
||||
|
||||
``` rust
|
||||
#![feature(used)]
|
||||
|
||||
extern "C" fn before_main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
#[link_section = ".init_array"]
|
||||
#[used]
|
||||
static INIT_ARRAY: [extern "C" fn(); 1] = [before_main];
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
|
||||
So, `#[used]` and `#[link_section]` can be combined to obtain "life before
|
||||
main".
|
||||
|
||||
``` text
|
||||
$ rustc -C opt-level=3 before-main.rs
|
||||
|
||||
$ ./before-main
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
Another example: ARM Cortex-M microcontrollers need their reset handler, a
|
||||
pointer to the function that will executed right after the microcontroller is
|
||||
turned on, to be placed near the start of their FLASH memory to boot properly.
|
||||
|
||||
This condition can be met using `#[used]` and `#[link_section]` plus a linker
|
||||
script.
|
||||
|
||||
``` rust
|
||||
#![feature(lang_items)]
|
||||
#![feature(used)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern "C" fn reset_handler() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[link_section = ".reset_handler"]
|
||||
#[used]
|
||||
static RESET_HANDLER: extern "C" fn() -> ! = reset_handler;
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
fn panic_fmt() {}
|
||||
```
|
||||
|
||||
``` text
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text ORIGIN(FLASH) :
|
||||
{
|
||||
/* Vector table */
|
||||
LONG(ORIGIN(RAM) + LENGTH(RAM)); /* initial SP value */
|
||||
KEEP(*(.reset_handler));
|
||||
|
||||
/* Omitted: The rest of the vector table */
|
||||
|
||||
*(.text.*);
|
||||
} > FLASH
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
/* Unused unwinding stuff */
|
||||
*(.ARM.exidx.*)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
``` text
|
||||
$ xargo rustc --target thumbv7m-none-eabi --release -- \
|
||||
-C link-arg=-Tlink.x -C link-arg=-nostartfiles
|
||||
|
||||
$ arm-none-eabi-objdump -Cd target/thumbv7m-none-eabi/release/app
|
||||
./target/thumbv7m-none-eabi/release/app: file format elf32-littlearm
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
08000000 <app::RESET_HANDLER-0x4>:
|
||||
8000000: 20005000 .word 0x20005000
|
||||
|
||||
08000004 <app::RESET_HANDLER>:
|
||||
8000004: 08000009 ....
|
||||
|
||||
08000008 <app::reset_handler>:
|
||||
8000008: e7fe b.n 8000008 <app::reset_handler>
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue