Is there a way to explain linker symbols used only for their address? In particular when this address is not meant as a pointer but as an integer only. I have 2 examples.
Example 1: Using a linker symbol to communicate a number
The riscv-rt crate uses a _heap_size symbol to let users configure the heap size through the linker script. In particular, they have a code that looks like this in their documentation:
extern "C" {
static _sheap: u8;
static _heap_size: u8;
}
fn main() {
unsafe {
let heap_bottom = &_sheap as *const u8 as usize;
let heap_size = &_heap_size as *const u8 as usize;
some_allocator::initialize(heap_bottom, heap_size);
}
}
We could argue whether u8 is the correct type. Let's assume it's a ZST to simplify this particular case.
Example 2: Using a linker symbol to "allocate" a unique (to the program) value
The defmt crate uses static variables in specific linker section (with specific name, but this is orthogonal to this issue) to allocate identifiers for interned strings. The address of the static variable (aka the value of the symbol) is the identifier. The static variable does not represent a proper allocation, and actually won't have any allocation at all from Rust point of view (the linker section is NOLOAD).
The proc-macro generating those static variables looks like this:
quote!(
#[cfg_attr(target_os = "macos", link_section = #section_for_macos)]
#[cfg_attr(not(target_os = "macos"), link_section = #section)]
#[export_name = #sym_name]
static #name: u8 = 0;
)
In this case, the u8 type matters. That's how the identifiers are unique and consecutive (they start at 1 so they can fit in a u16).
Related issues
I'm creating a new issue, although there are many related issues, because I feel this particular concern of static variables without allocation is not addressed yet. Here are the related issues:
Please dedup if I missed an issue or I'm wrong in my analysis.
Theoretical suggestion
There could be an attribute to indicate when a static does not have an allocation. It is thus UB for a static to not have an allocation if it does not have this attribute. Such "inaccessible statics" can only have their address taken. They don't have an allocation and can't be dereferenced.
#[inaccessible_static]
static MY_ADDRESS_IS_AN_IDENTIFIER: u8 = 0;
unsafe extern "C" {
#[inaccessible_static]
static MY_ADDRESS_IS_A_VALUE: ();
}
Is there a way to explain linker symbols used only for their address? In particular when this address is not meant as a pointer but as an integer only. I have 2 examples.
Example 1: Using a linker symbol to communicate a number
The
riscv-rtcrate uses a_heap_sizesymbol to let users configure the heap size through the linker script. In particular, they have a code that looks like this in their documentation:We could argue whether
u8is the correct type. Let's assume it's a ZST to simplify this particular case.Example 2: Using a linker symbol to "allocate" a unique (to the program) value
The
defmtcrate uses static variables in specific linker section (with specific name, but this is orthogonal to this issue) to allocate identifiers for interned strings. The address of the static variable (aka the value of the symbol) is the identifier. The static variable does not represent a proper allocation, and actually won't have any allocation at all from Rust point of view (the linker section isNOLOAD).The proc-macro generating those static variables looks like this:
In this case, the
u8type matters. That's how the identifiers are unique and consecutive (they start at 1 so they can fit in au16).Related issues
I'm creating a new issue, although there are many related issues, because I feel this particular concern of static variables without allocation is not addressed yet. Here are the related issues:
Please dedup if I missed an issue or I'm wrong in my analysis.
Theoretical suggestion
There could be an attribute to indicate when a static does not have an allocation. It is thus UB for a static to not have an allocation if it does not have this attribute. Such "inaccessible statics" can only have their address taken. They don't have an allocation and can't be dereferenced.