1#![doc = include_str!("../docs/BUILD.md")]
2#![doc = include_str!("../docs/PREAMBLE.md")]
4#![allow(unsafe_code)]
5#![cfg_attr(linktime_used_linker, doc(test(attr(feature(used_with_arg)))))]
6#![no_std]
7
8#[doc = include_str!("../docs/LIFE_BEFORE_MAIN.md")]
9pub mod life_before_main {}
10
11mod item;
12mod macros;
13mod meta;
14mod platform;
15mod section_parse;
16mod sections;
17
18pub use sections::{
19 MovableBackref, MovableRef, Section, TypedMovableSection, TypedMutableSection,
20 TypedReferenceSection, TypedSection,
21};
22
23pub mod reference {
25 pub use crate::sections::Ref;
26}
27
28__declare_features!(
29 section: __section_features;
30
31 @default: type;
32
33 aux {
36 attr: [(aux(main = $($aux_name:tt)*)) => (($($aux_name)*))];
37 example: "aux(main = path::to::MAIN_SECTION)";
38 validate: [(($aux_name:path))];
39 };
40 crate_path {
43 attr: [(crate_path = $path:pat) => (($path))];
44 example: "crate_path = ::path::to::link_section";
45 };
46 macro_unique_name {
49 attr: [(macro_unique_name = $macro_unique_name_str:ident) => (($macro_unique_name_str))];
50 example: "macro_unique_name = my_unique_name_1234";
51 };
52 no_macro {
54 attr: [(no_macro) => (no_macro)];
55 };
56 proc_macro {
58 feature: "proc_macro";
59 };
60 type {
62 attr: [
63 (type = $section_type:ident) => ($section_type)
64 ];
65 example: "untyped | typed | mutable | movable | reference";
66 validate: [(untyped), (typed), (mutable), (movable), (reference)];
67 };
68);
69
70#[cfg(doc)]
71__generate_docs!(__section_features);
72
73__declare_features!(
74 in_section: __in_section_features;
75
76 @default: section;
77
78 section {
79 attr: [(section = $($section_path:tt)*) => (($($section_path)*))];
80 example: "[section = ] ::path::to::SECTION";
81 validate: [(($section_path:path))];
82 };
83 aux {
84 attr: [(aux = $aux_str:ident) => ($aux_str)];
85 example: "aux = MAIN_SECTION";
86 };
87 name {
88 attr: [(name = $name_str:ident) => ($name_str)];
89 example: "name = SECTION";
90 };
91 section_type {
92 attr: [(type = $section_type_name:ident) => ($section_type_name)];
93 example: "type = untyped | typed | mutable | movable | reference";
94 validate: [(untyped), (typed), (mutable), (movable), (reference)];
95 };
96 unsafe {
97 attr: [(unsafe) => (unsafe)];
98 };
99);
100
101#[cfg(target_family = "wasm")]
102extern crate alloc;
103
104pub mod declarative {
111 pub use crate::__in_section_parse as in_section;
112 pub use crate::__section_parse as section;
113}
114
115#[doc(hidden)]
116pub mod __support {
117 pub use crate::__add_section_link_attribute as add_section_link_attribute;
118 pub use crate::__in_section_crate as in_section_crate;
119 pub use crate::__in_section_parse as in_section_parse;
120 pub use crate::__section_parse as section_parse;
121
122 pub use crate::sections::IsUntypedSection;
123 pub use crate::{item::*, platform::*};
124
125 #[cfg(feature = "proc_macro")]
126 pub use linktime_proc_macro::hash;
127 #[cfg(feature = "proc_macro")]
128 pub use linktime_proc_macro::ident_concat;
129
130 #[doc(hidden)]
131 #[macro_export]
132 macro_rules! __hash_no_proc_macro {
133 ((__) (($($__prefix:literal $(,)?)*)) ($($name:tt)*) (($($__suffix:literal $(,)?)*)) $__hash_length:literal $__max_length:literal $__valid_section_chars:literal) => {
134 concat!($($__prefix,)* $(stringify!($name)),* $(,$__suffix)*);
135 };
136 }
137 #[cfg(not(feature = "proc_macro"))]
138 pub use __hash_no_proc_macro as hash;
139
140 #[cfg(miri)]
141 #[doc(hidden)]
142 #[macro_export]
143 macro_rules! __address_of_symbol {
144 ($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)?) => {
145 ::core::ptr::null() as *const ()
148 };
149 }
150
151 #[cfg(not(miri))]
152 #[doc(hidden)]
153 #[macro_export]
154 macro_rules! __address_of_symbol {
155 ($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)?) => {
156 {
157 $crate::__add_linktime_attributes_to_static!(
160 extern "C" {
161 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
162 static __SYMBOL: u8;
163 }
164 );
165 unsafe { ::core::ptr::addr_of!(__SYMBOL) as *const () }
169 }
170 };
171 }
172
173 #[doc(hidden)]
174 #[macro_export]
175 macro_rules! __add_section_link_attribute(
176 ($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
177 $(#[$meta:meta])*
178 $vis:vis static $($static:tt)*
179 ) => {
180 $crate::__add_linktime_attributes_to_static!(
181 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
182 $(#[$meta])*
183 $vis static $($static)*
184 );
185 };
186 ($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
187 extern "C" {
188 $(#[$meta:meta])*
189 $vis:vis static $($static:tt)*
190 }
191 ) => {
192 $crate::__add_linktime_attributes_to_static!(
193 extern "C" {
194 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
195 $(#[$meta])*
196 $vis static $($static)*
197 }
198 );
199 };
200 ($ref_or_item:ident $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
201 $($item:tt)*) => {
202 $crate::__add_linktime_attributes_to_static!(
203 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name $($aux)?)]
204 $($item)*
205 );
206 };
207 );
208
209 #[doc(hidden)]
211 #[macro_export]
212 macro_rules! __declare_macro {
213 ($vis:vis $ident:ident $generic_macro:ident) => {
214 #[doc(hidden)]
217 $vis use $crate::$generic_macro as $ident;
218 };
219 }
220
221 #[macro_export]
222 #[doc(hidden)]
223 macro_rules! __in_section_helper_macro_generic {
224 (($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=typed) ; $($args)*)); }
225 }
226
227 #[macro_export]
228 #[doc(hidden)]
229 macro_rules! __in_section_helper_macro_generic_mutable {
230 (($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=mutable) ; $($args)*)); }
231 }
232
233 #[macro_export]
234 #[doc(hidden)]
235 macro_rules! __in_section_helper_macro_generic_movable {
236 (($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=movable) ; $($args)*)); }
237 }
238
239 #[macro_export]
240 #[doc(hidden)]
241 macro_rules! __in_section_helper_macro_generic_reference {
242 (($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=reference) ; $($args)*)); }
243 }
244
245 #[macro_export]
246 #[doc(hidden)]
247 macro_rules! __in_section_helper_macro_no_generic {
248 (($($args:tt)*)) => { $crate::__support::in_section_crate!((@v=0 ; (source=section) ; (type=untyped) ; $($args)*)); }
249 }
250
251 #[macro_export]
252 #[doc(hidden)]
253 #[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
254 macro_rules! __in_section_crate {
255 ((@v=0 ; (source=$source:ident) ; (type = untyped) $(; (aux = $aux:ident))? ; (section = $section:tt) $(; (path = $path:path))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
256 $crate::__in_section_crate!(@untyped $section, $($aux)?, $($path)?, $meta $item);
257 };
258 ((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) $(; (aux = $aux:ident))? ; (section = $section:tt) $(; (path = $path:path))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
259 $crate::__in_section_crate!(@typed[$section_type] $section, $($aux)?, $($path)?, $meta $item);
260 };
261
262 (@untyped $section:tt, $($aux:ident)?, $($path:path)?, ($($meta:tt)*) ($vis:vis fn $($rest:tt)*)) => {
264 $crate::__add_section_link_attribute!(
265 item code section $section $($aux)?
266 #[link_section = __]
267 $($meta)*
268 $vis fn $($rest)*
269 );
270 $(
271 const _: () = {
272 $crate::Section::__validate(&$path);
273 };
274 )?
275 };
276 (@untyped $section:tt, $($aux:ident)?, $($path:path)?, ($($meta:tt)*) ($($rest:tt)*)) => {
277 $crate::__add_section_link_attribute!(
278 item data section $section $($aux)?
279 #[link_section = __]
280 $($meta)*
281 $($rest)*
282 );
283 $(
284 const _: () = {
285 $crate::Section::__validate(&$path);
286 };
287 )?
288 };
289
290 (@typed[$section_type:ident] $section:tt, $($aux:ident)?, $($path:path)?, ($($meta:tt)*) ($vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? { $($body:tt)* })) => {
292 $($meta)*
293 $vis fn $ident_fn($($args)*) $(-> $ret)? {
294 $crate::__in_section_crate!(@typed[$section_type] $section, $($aux)?, $($path)?, () (
295 const _: fn($($args)*) $(-> $ret)? = $ident_fn;
296 ));
297
298 $($body)*
299 }
300 };
301
302 (@typed[$section_type:ident] $section:tt, $($aux:ident)?, , $meta:tt ($vis:vis $const_or_static:ident $name:tt : $ty:ty = $($rest:tt)*)) => {
304 $crate::__in_section_crate!(@typed[$section_type] $section, $($aux)?, $crate::TypedSection::<$ty>, $meta (
305 $vis $const_or_static $name: $ty = $($rest)*
306 ));
307 };
308
309 (@type_select $path:path) => {
310 <$path as $crate::__support::SectionItemType>::Item
311 };
312
313 (@typed[typed] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident : $ty:ty = $value:expr;)) => {
315 #[cfg(not(target_family = "wasm"))]
316 $crate::__add_section_link_attribute!(
317 item data section $section $($aux)?
318 #[link_section = __]
319 $($meta)*
320 $vis static $ident: $crate::__in_section_crate!(@type_select $path) = const {
321 const _: () = {
322 let _: *const <$path as $crate::__support::SectionItemTyped<$ty>>::Item = ::core::ptr::null();
323 };
324
325 $value
326 };
327 );
328
329 #[cfg(target_family = "wasm")]
330 compile_error!("static items are not supported on WASM: use const items instead");
331 };
332
333 (@typed[mutable] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
335 $($meta)*
336 $vis const $ident: $ty = const {
337 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
338 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
339
340 $crate::__register_wasm_item!(mutable, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section $($aux)?);
341
342 #[cfg(not(target_family = "wasm"))]
343 $crate::__add_section_link_attribute!(
344 item data section $section $($aux)?
345 #[link_section = __]
346 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> = $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
347 );
348
349 __LINK_SECTION_CONST_ITEM_VALUE
350 };
351 };
352
353 (@typed[mutable] $($rest:tt)*) => {
354 compile_error!("Only const items are supported in mutable sections");
355 };
356
357 (@typed[movable] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
359 $($meta)*
360 $vis static $ident: $crate::MovableRef<$crate::__in_section_crate!(@type_select $path)> = const {
361 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
362 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
363 #[cfg(not(target_family = "wasm"))]
364 {
365 $crate::__add_section_link_attribute!(
366 item data section $section $($aux)?
367 #[link_section = __]
368 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> =
369 $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
370 );
371
372 $crate::__add_section_link_attribute!(
373 backref data section $section $($aux)?
374 #[link_section = __]
375 static __LINK_SECTION_MOVABLE_BACKREF: $crate::__support::SyncUnsafeCell<
376 $crate::MovableBackref<__InSecStoredTy>
377 > = $crate::__support::SyncUnsafeCell::new(
378 $crate::MovableBackref::new(
379 $crate::MovableRef::slot_ptr(&raw const $ident),
380 )
381 );
382 );
383
384 $crate::MovableRef::new(
385 (&raw const __LINK_SECTION_CONST_ITEM)
386 .cast::<__InSecStoredTy>(),
387 )
388 }
389
390 #[cfg(target_family = "wasm")]
391 {
392 $crate::__register_wasm_item!(
393 movable,
394 value=__LINK_SECTION_CONST_ITEM_VALUE,
395 slot=$crate::MovableRef::slot_ptr(&raw const $ident),
396 section=$section $($aux)?
397 );
398
399 $crate::MovableRef::new(::core::ptr::null())
400 }
401 };
402 };
403
404 (@typed[movable] $($rest:tt)*) => {
405 compile_error!("Only static items are supported in movable sections");
406 };
407
408 (@typed[$section_type:ident] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
410 $($meta)*
411 $vis const $ident: $ty = const {
412 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
413 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
414
415 $crate::__register_wasm_item!($section_type, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section $($aux)?);
416
417 #[cfg(not(target_family = "wasm"))]
418 $crate::__add_section_link_attribute!(
419 item data section $section $($aux)?
420 #[link_section = __]
421 static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
422 );
423
424 __LINK_SECTION_CONST_ITEM_VALUE
425 };
426 };
427
428 (@typed[reference] $section:tt, $($aux:ident)?, $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
429 #[cfg(target_family="wasm")]
430 $($meta)*
431 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = {
432 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
433 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
434 $crate::__register_wasm_item!(reference, value=__LINK_SECTION_CONST_ITEM_VALUE, ref=$ident, section=$section $($aux)?);
435 $crate::reference::Ref::new()
436 };
437
438 #[cfg(not(target_family="wasm"))]
440 $crate::__add_section_link_attribute!(
441 item data section $section $($aux)?
442 #[link_section = __]
443 $($meta)*
444 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = $crate::reference::Ref::new($value);
445 );
446 };
447
448 ($($input:tt)*) => {
449 compile_error!(concat!("Unexpected input to __in_section_crate: ", stringify!($($input)*)));
450 };
451 }
452}
453
454#[cfg(feature = "proc_macro")]
481pub use ::linktime_proc_macro::section;
482
483#[cfg(feature = "proc_macro")]
490pub use ::linktime_proc_macro::in_section;