#![doc = include_str!("../docs/BUILD.md")]
#![doc = include_str!("../docs/PREAMBLE.md")]
#![allow(unsafe_code)]
#![no_std]
#![recursion_limit = "256"]
#[doc = include_str!("../docs/LIFE_BEFORE_MAIN.md")]
pub mod life_before_main {}
mod item;
mod macros;
mod meta;
mod platform;
mod section_parse;
mod sections;
pub use item::SectionItemLocation;
pub use sections::{
MovableBackref, MovableRef, Ref, Section, TypedMovableSection, TypedMutableSection,
TypedReferenceSection, TypedSection,
};
#[deprecated(since = "0.17.1", note = "Use [`Ref`] from the crate root instead.")]
pub mod reference {
pub use crate::sections::Ref;
}
__declare_features!(
section: __section_features;
@default: type;
aux {
attr: [(aux(main = $($aux_name:tt)*)) => (($($aux_name)*))];
example: "aux(main = path::to::MAIN_SECTION)";
validate: [(($aux_name:path))];
};
crate_path {
attr: [(crate_path = $path:pat) => (($path))];
example: "crate_path = ::path::to::link_section";
};
name {
attr: [(name = $($name_path:tt)*) => (($($name_path)*))];
example: "name = my_crate::SECTION_NAME";
validate: [(($name_path:path))];
};
proc_macro {
feature: "proc_macro";
};
type {
attr: [
(type = $section_type:ident) => ($section_type)
];
example: "untyped | typed | mutable | movable | reference";
validate: [(untyped), (typed), (mutable), (movable), (reference)];
};
unsafe {
attr: [(unsafe) => (unsafe)];
};
);
#[cfg(doc)]
__generate_docs!(__section_features);
__declare_features!(
in_section: __in_section_features;
@default: section;
aux {
attr: [(aux(main = $($aux_name:tt)*)) => (($($aux_name)*))];
example: "aux(main = my_crate::SECTION_NAME)";
validate: [(($aux_name:path))];
};
name {
attr: [(name = $($name_path:tt)*) => (($($name_path)*))];
example: "name = my_crate::SECTION_NAME";
validate: [(($name_is_path:path))];
};
section {
attr: [(section = $($section_path:tt)*) => (($($section_path)*))];
example: "[section = ] ::path::to::SECTION";
validate: [(($section_path:path))];
};
section_type {
attr: [(type = $section_type_name:ident) => ($section_type_name)];
example: "type = untyped | typed | mutable | movable | reference";
validate: [(untyped), (typed), (mutable), (movable), (reference)];
};
unsafe {
attr: [(unsafe) => (unsafe)];
};
);
#[cfg(target_family = "wasm")]
extern crate alloc;
pub mod declarative {
pub use crate::__in_section_parse as in_section;
pub use crate::__section_parse as section;
}
#[doc(hidden)]
pub mod __support {
pub use crate::__add_section_link_attribute as add_section_link_attribute;
pub use crate::__in_section_crate as in_section_crate;
pub use crate::__in_section_parse as in_section_parse;
pub use crate::__section_parse as section_parse;
pub use crate::sections::IsUntypedSection;
pub use crate::{item::*, platform::*};
#[cfg(feature = "proc_macro")]
pub use linktime_proc_macro::combine;
#[doc(hidden)]
#[macro_export]
macro_rules! __hash_no_proc_macro {
(unsafe (($($__prefix:literal)*)) (($($name:ident)::*) $($literal2:literal ($($name2:ident)::*))?) (($($__suffix:literal)*)) $__hash_length:literal $__max_length:literal $__valid_section_chars:literal) => {
concat!($($__prefix,)* $(stringify!($name)),* $( ,$literal2 $(, stringify!($name2))* )? $(,$__suffix)*)
};
($($rest:tt)*) => {
compile_error!(concat!("link-section: No proc_macro feature enabled: `unsafe` is required", stringify!($($rest)*)));
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __hash_proc_macro {
(unsafe $prefix:tt $name:tt $suffix:tt $hash_length:literal $max_length:literal $valid_section_chars:literal) => {
$crate::__support::combine!(output=string input=(
__IF__(
test=(
__LE__(
a=(__LENGTH__(string=(
__TOIDENT__(input=(__RAW__(input=($name))))
)))
b=$max_length
)
)
then=(
$prefix
__TOIDENT__(input=(__RAW__(input=($name))))
$suffix
)
else=(
$prefix
__SUBSTRING__(input=(
__TOIDENT__(input=(__RAW__(input=($name))))
) end=(__SUB__(a=$max_length b=$hash_length)))
__SUBSTRING__(input=(
__HASH__(string=(__RAW__(input=($name))))
) length=$hash_length)
$suffix
)
)
))
};
($definition:tt $prefix:tt $name:tt $suffix:tt $hash_length:literal $max_length:literal $valid_section_chars:literal) => {
$crate::__support::combine!(output=string input=(
$prefix
__SUBSTRING__(input=(
__SUBSTRING__(input=(
__TOIDENT__(input=(__RAW__(input=($name))))
) end=(__SUB__(a=$max_length b=$hash_length)))
__LOCATIONHASH__(of=($definition $name) alphabet=[_0-9a-zA-Z])
) length=$max_length)
$suffix
))
};
}
#[cfg(feature = "proc_macro")]
pub use __hash_proc_macro as hash;
#[cfg(not(feature = "proc_macro"))]
pub use __hash_no_proc_macro as hash;
#[cfg(miri)]
#[doc(hidden)]
#[macro_export]
macro_rules! __address_of_symbol {
($ref_or_item:ident $section:ident $type:ident $name:tt) => {
::core::ptr::null() as *const ()
};
}
#[cfg(not(miri))]
#[doc(hidden)]
#[macro_export]
macro_rules! __address_of_symbol {
($ref_or_item:ident $section:ident $type:ident $name:tt) => {
{
$crate::__add_linktime_attributes_to_static!(
extern "C" {
#[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
static __SYMBOL: u8;
}
);
unsafe { ::core::ptr::addr_of!(__SYMBOL) as *const () }
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __add_section_link_attribute(
($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
$(#[$meta:meta])*
$vis:vis static $($static:tt)*
) => {
$crate::__add_linktime_attributes_to_static!(
#[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
$(#[$meta])*
$vis static $($static)*
);
};
($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
extern "C" {
$(#[$meta:meta])*
$vis:vis static $($static:tt)*
}
) => {
$crate::__add_linktime_attributes_to_static!(
extern "C" {
#[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
$(#[$meta])*
$vis static $($static)*
}
);
};
($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
$($item:tt)*) => {
$crate::__add_linktime_attributes_to_static!(
#[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
$($item)*
);
};
);
#[cfg(target_family = "wasm")]
#[macro_export]
#[doc(hidden)]
macro_rules! __if_wasm {
(($($true:tt)*) ($($false:tt)*)) => {
$($true)*
};
}
#[cfg(not(target_family = "wasm"))]
#[macro_export]
#[doc(hidden)]
macro_rules! __if_wasm {
(($($true:tt)*) ($($false:tt)*)) => {
$($false)*
};
}
#[macro_export]
#[doc(hidden)]
#[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
macro_rules! __in_section_crate {
((@v=0 ; (source=$source:ident) ; (type = untyped) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@untyped (($name)()), , $path, $meta $item);
};
((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@typed[$section_type] (($name)()), , $path, $meta $item);
};
((@v=0 ; (source=$source:ident) ; (type = untyped) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@untyped $section, , $($path)?, $meta $item);
};
((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, $meta $item);
};
(@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $($rest:tt)*)) => {
$crate::__add_section_link_attribute!(
item code section $section
#[link_section = __]
$($meta)*
$vis fn $($rest)*
);
$(
const _: () = {
$crate::Section::__validate(&$path);
};
)?
};
(@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($($rest:tt)*)) => {
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
$($meta)*
$($rest)*
);
$(
const _: () = {
$crate::Section::__validate(&$path);
};
)?
};
(@typed[$section_type:ident] $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? { $($body:tt)* })) => {
$($meta)*
$vis fn $ident_fn($($args)*) $(-> $ret)? {
$crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, () (
const _: fn($($args)*) $(-> $ret)? = $ident_fn;
));
$($body)*
}
};
(@typed[$section_type:ident] $section:tt, , , $meta:tt ($vis:vis $const_or_static:ident $name:tt : $ty:ty = $($rest:tt)*)) => {
$crate::__in_section_crate!(@typed[$section_type] $section, , $crate::TypedSection::<$ty>, $meta (
$vis $const_or_static $name: $ty = $($rest)*
));
};
(@type_select $path:path) => {
<$path as $crate::__support::SectionItemType>::Item
};
(@typed[typed] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident : $ty:ty = $value:expr;)) => {
$crate::__if_wasm!(
(
compile_error!("static items are not supported on WASM: use const items instead");
)
(
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
$($meta)*
$vis static $ident: $crate::__in_section_crate!(@type_select $path) = const {
const _: () = {
let _: *const <$path as $crate::__support::SectionItemTyped<$ty>>::Item = ::core::ptr::null();
};
$value
};
);
)
);
};
(@typed[mutable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
$($meta)*
$vis const $ident: $ty = const {
type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
$crate::__register_wasm_item!(mutable, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
$crate::__if_wasm!(() (
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> = $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
);
));
__LINK_SECTION_CONST_ITEM_VALUE
};
};
(@typed[mutable] $($rest:tt)*) => {
compile_error!("Only const items are supported in mutable sections");
};
(@typed[movable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
$($meta)*
$vis static $ident: $crate::MovableRef<$crate::__in_section_crate!(@type_select $path)> = const {
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
$crate::__if_wasm!((
{
$crate::__register_wasm_item!(
movable,
value=__LINK_SECTION_CONST_ITEM_VALUE,
slot=$crate::MovableRef::slot_ptr(&raw const $ident),
section=$section
);
$crate::MovableRef::new(::core::ptr::null())
}
)(
{
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> =
$crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
);
$crate::__add_section_link_attribute!(
backref data section $section
#[link_section = __]
static __LINK_SECTION_MOVABLE_BACKREF: $crate::__support::SyncUnsafeCell<
$crate::MovableBackref<__InSecStoredTy>
> = $crate::__support::SyncUnsafeCell::new(
$crate::MovableBackref::new(
$crate::MovableRef::slot_ptr(&raw const $ident),
)
);
);
$crate::MovableRef::new(
(&raw const __LINK_SECTION_CONST_ITEM)
.cast::<__InSecStoredTy>(),
)
}
))
};
};
(@typed[movable] $($rest:tt)*) => {
compile_error!("Only static items are supported in movable sections");
};
(@typed[$section_type:ident] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
$($meta)*
$vis const $ident: $ty = const {
type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
$crate::__if_wasm!((
$crate::__register_wasm_item!($section_type, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
) (
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
);
));
__LINK_SECTION_CONST_ITEM_VALUE
};
};
(@typed[reference] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
$crate::__if_wasm!(
(
$($meta)*
$vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = {
type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
$crate::__register_wasm_item!(reference, value=__LINK_SECTION_CONST_ITEM_VALUE, ref=$ident, section=$section);
$crate::reference::Ref::new()
};
)
(
#[cfg(not(target_family="wasm"))]
$crate::__add_section_link_attribute!(
item data section $section
#[link_section = __]
$($meta)*
$vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = $crate::reference::Ref::new($value);
);
)
);
};
($($input:tt)*) => {
compile_error!(concat!("Unexpected input to __in_section_crate: ", stringify!($($input)*)));
};
}
}
#[cfg(feature = "proc_macro")]
pub use ::linktime_proc_macro::section;
#[cfg(feature = "proc_macro")]
pub use ::linktime_proc_macro::in_section;