#![doc = include_str!("../docs/BUILD.md")]
#![doc = include_str!("../docs/PREAMBLE.md")]
#![allow(unsafe_code)]
#![cfg_attr(linktime_used_linker, doc(test(attr(feature(used_with_arg)))))]
#![no_std]
#[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";
};
macro_unique_name {
attr: [(macro_unique_name = $macro_unique_name_str:ident) => (($macro_unique_name_str))];
example: "macro_unique_name = my_unique_name_1234";
};
no_macro {
attr: [(no_macro) => (no_macro)];
};
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)];
};
);
#[cfg(doc)]
__generate_docs!(__section_features);
__declare_features!(
in_section: __in_section_features;
@default: section;
section {
attr: [(section = $($section_path:tt)*) => (($($section_path)*))];
example: "[section = ] ::path::to::SECTION";
validate: [(($section_path:path))];
};
aux {
attr: [(aux(main = $aux_str:ident)) => ($aux_str)];
example: "aux(main = MAIN_SECTION)";
};
name {
attr: [(name = $name_str:ident) => ($name_str)];
example: "name = SECTION";
};
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::hash;
#[cfg(feature = "proc_macro")]
pub use linktime_proc_macro::ident_concat;
#[doc(hidden)]
#[macro_export]
macro_rules! __hash_no_proc_macro {
((__) (($($__prefix:literal $(,)?)*)) ($($name:tt)*) (($($__suffix:literal $(,)?)*)) $__hash_length:literal $__max_length:literal $__valid_section_chars:literal) => {
concat!($($__prefix,)* $(stringify!($name)),* $(,$__suffix)*);
};
}
#[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:ident $($aux:ident)?) => {
::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:ident $($aux:ident)?) => {
{
$crate::__add_linktime_attributes_to_static!(
extern "C" {
#[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
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:ident $($aux:ident)? #[$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 $($aux)?)]
$(#[$meta])*
$vis static $($static)*
);
};
($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)? #[$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 $($aux)?)]
$(#[$meta])*
$vis static $($static)*
}
);
};
($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
$($item:tt)*) => {
$crate::__add_linktime_attributes_to_static!(
#[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
$($item)*
);
};
);
#[doc(hidden)]
#[macro_export]
macro_rules! __declare_macro {
($vis:vis $ident:ident $generic_macro:ident) => {
#[doc(hidden)]
$vis use $crate::$generic_macro as $ident;
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __in_section_helper_macro_generic {
(($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=typed) ; $($args)*)); }
}
#[macro_export]
#[doc(hidden)]
macro_rules! __in_section_helper_macro_generic_mutable {
(($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=mutable) ; $($args)*)); }
}
#[macro_export]
#[doc(hidden)]
macro_rules! __in_section_helper_macro_generic_movable {
(($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=movable) ; $($args)*)); }
}
#[macro_export]
#[doc(hidden)]
macro_rules! __in_section_helper_macro_generic_reference {
(($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=reference) ; $($args)*)); }
}
#[macro_export]
#[doc(hidden)]
macro_rules! __in_section_helper_macro_no_generic {
(($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=untyped) ; $($args)*)); }
}
#[macro_export]
#[doc(hidden)]
#[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
macro_rules! __in_section_crate {
((@v=0 ; (source=$source:ident) ; (type = untyped) $(; (aux = $aux:ident))? ; (section = $section:tt) $(; (path = $path:path))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@untyped $section, $($aux)?, $($path)?, $meta $item);
};
((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) $(; (aux = $aux:ident))? ; (section = $section:tt) $(; (path = $path:path))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
$crate::__in_section_crate!(@typed[$section_type] $section, $($aux)?, $($path)?, $meta $item);
};
(@untyped $section:tt, $($aux:ident)?, $($path:path)?, ($($meta:tt)*) ($vis:vis fn $($rest:tt)*)) => {
$crate::__add_section_link_attribute!(
item code section $section $($aux)?
#[link_section = __]
$($meta)*
$vis fn $($rest)*
);
$(
const _: () = {
$crate::Section::__validate(&$path);
};
)?
};
(@untyped $section:tt, $($aux:ident)?, $($path:path)?, ($($meta:tt)*) ($($rest:tt)*)) => {
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[link_section = __]
$($meta)*
$($rest)*
);
$(
const _: () = {
$crate::Section::__validate(&$path);
};
)?
};
(@typed[$section_type:ident] $section:tt, $($aux:ident)?, $($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, $($aux)?, $($path)?, () (
const _: fn($($args)*) $(-> $ret)? = $ident_fn;
));
$($body)*
}
};
(@typed[$section_type:ident] $section:tt, $($aux:ident)?, , $meta:tt ($vis:vis $const_or_static:ident $name:tt : $ty:ty = $($rest:tt)*)) => {
$crate::__in_section_crate!(@typed[$section_type] $section, $($aux)?, $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, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident : $ty:ty = $value:expr;)) => {
#[cfg(not(target_family = "wasm"))]
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[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
};
);
#[cfg(target_family = "wasm")]
compile_error!("static items are not supported on WASM: use const items instead");
};
(@typed[mutable] $section:tt, $($aux:ident)?, $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 $($aux)?);
#[cfg(not(target_family = "wasm"))]
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[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, $($aux:ident)?, $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);
#[cfg(not(target_family = "wasm"))]
{
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[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 $($aux)?
#[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>(),
)
}
#[cfg(target_family = "wasm")]
{
$crate::__register_wasm_item!(
movable,
value=__LINK_SECTION_CONST_ITEM_VALUE,
slot=$crate::MovableRef::slot_ptr(&raw const $ident),
section=$section $($aux)?
);
$crate::MovableRef::new(::core::ptr::null())
}
};
};
(@typed[movable] $($rest:tt)*) => {
compile_error!("Only static items are supported in movable sections");
};
(@typed[$section_type:ident] $section:tt, $($aux:ident)?, $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!($section_type, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section $($aux)?);
#[cfg(not(target_family = "wasm"))]
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[link_section = __]
static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
);
__LINK_SECTION_CONST_ITEM_VALUE
};
};
(@typed[reference] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
#[cfg(target_family="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 $($aux)?);
$crate::reference::Ref::new()
};
#[cfg(not(target_family="wasm"))]
$crate::__add_section_link_attribute!(
item data section $section $($aux)?
#[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;