Portable #[link_section] for Rust
A macro to provide support for portable #[link_section] annotations in Rust.
This respects the following binary file formats:
Usage
In essence the #[portable_link_section] macro is a restricted version of #[link_section].
The #[portable_link_section] macro accepts one of the following segment identifiers:
text: codedata: writable datarodata: read-only databss: zero-initialized data
When given text or data the macro expects another group identifier that has to follow some strict rules to provide portability.
Interpreters might have a use for portable #[link_section] in order to have more control where certain operator handler functions are placed in memory in order to improve I-cache efficiency by grouping hot and cold code.
Examples
Apply text on fn items.
Apply data, rodata or bss on static items.
static DATA_0: i32 = 42;
static DATA_1: i32 = 42;
static DATA_2: i32 = 0;
Strict Rules Examples
Certain group identifiers have special meaning on some platforms,
therefore their usage is forbidden as to not end up with non-conformant
semantics across platforms.
// ~ERROR: const is reserved for `text` in MACH-O and therefore forbidden
// ~ERROR: common is reserved for `data` in MACH-O and therefore forbidden
static DATA_0: i32 = 42;
The MACH-O file format has a strict limit on the structure of link section identifiers
as their length is capped to 16 bytes. Since they are represented as zero-terminated strings
we allow a maximum of 15 bytes per group identifier.
// ~ERROR: MACH-O has a limit of 15 bytes per identifier
Macro Expansion
The following Rust code that uses the #[portable_link_section]:
Gets expanded into the following Rust code:
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.