1#![doc = include_str!("../docs/BUILD.md")]
2#![doc = include_str!("../docs/PREAMBLE.md")]
4#![allow(unsafe_code)]
5#![no_std]
6#![recursion_limit = "256"]
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 item::SectionItemLocation;
19pub use sections::{
20 MovableBackref, MovableRef, Ref, Section, TypedMovableSection, TypedMutableSection,
21 TypedReferenceSection, TypedSection,
22};
23
24#[deprecated(since = "0.17.1", note = "Use [`Ref`] from the crate root instead.")]
26pub mod reference {
27 pub use crate::sections::Ref;
28}
29
30__declare_features!(
31 section: __section_features;
32
33 @default: type;
34
35 aux {
38 attr: [(aux(main = $($aux_name:tt)*)) => (($($aux_name)*))];
39 example: "aux(main = path::to::MAIN_SECTION)";
40 validate: [(($aux_name:path))];
41 };
42 crate_path {
45 attr: [(crate_path = $path:pat) => (($path))];
46 example: "crate_path = ::path::to::link_section";
47 };
48 name {
59 attr: [(name = $($name_path:tt)*) => (($($name_path)*))];
60 example: "name = my_crate::SECTION_NAME";
61 validate: [(($name_path:path))];
62 };
63 proc_macro {
65 feature: "proc_macro";
66 };
67 type {
69 attr: [
70 (type = $section_type:ident) => ($section_type)
71 ];
72 example: "untyped | typed | mutable | movable | reference";
73 validate: [(untyped), (typed), (mutable), (movable), (reference)];
74 };
75 unsafe {
77 attr: [(unsafe) => (unsafe)];
78 };
79);
80
81#[cfg(doc)]
82__generate_docs!(__section_features);
83
84__declare_features!(
85 in_section: __in_section_features;
86
87 @default: section;
88
89 aux {
92 attr: [(aux(main = $($aux_name:tt)*)) => (($($aux_name)*))];
93 example: "aux(main = my_crate::SECTION_NAME)";
94 validate: [(($aux_name:path))];
95 };
96 name {
102 attr: [(name = $($name_path:tt)*) => (($($name_path)*))];
103 example: "name = my_crate::SECTION_NAME";
104 validate: [(($name_is_path:path))];
105 };
106 section {
109 attr: [(section = $($section_path:tt)*) => (($($section_path)*))];
110 example: "[section = ] ::path::to::SECTION";
111 validate: [(($section_path:path))];
112 };
113 section_type {
115 attr: [(type = $section_type_name:ident) => ($section_type_name)];
116 example: "type = untyped | typed | mutable | movable | reference";
117 validate: [(untyped), (typed), (mutable), (movable), (reference)];
118 };
119 unsafe {
120 attr: [(unsafe) => (unsafe)];
121 };
122);
123
124#[cfg(target_family = "wasm")]
125extern crate alloc;
126
127pub mod declarative {
134 pub use crate::__in_section_parse as in_section;
135 pub use crate::__section_parse as section;
136}
137
138#[doc(hidden)]
139pub mod __support {
140 pub use crate::__add_section_link_attribute as add_section_link_attribute;
141 pub use crate::__in_section_crate as in_section_crate;
142 pub use crate::__in_section_parse as in_section_parse;
143 pub use crate::__section_parse as section_parse;
144
145 pub use crate::sections::IsUntypedSection;
146 pub use crate::{item::*, platform::*};
147
148 #[cfg(feature = "proc_macro")]
149 pub use linktime_proc_macro::combine;
150
151 #[doc(hidden)]
152 #[macro_export]
153 macro_rules! __hash_no_proc_macro {
154 (unsafe (($($__prefix:literal)*)) (($($name:ident)::*) $($literal2:literal ($($name2:ident)::*))?) (($($__suffix:literal)*)) $__hash_length:literal $__max_length:literal $__valid_section_chars:literal) => {
155 concat!($($__prefix,)* $(stringify!($name)),* $( ,$literal2 $(, stringify!($name2))* )? $(,$__suffix)*)
156 };
157 ($($rest:tt)*) => {
158 compile_error!(concat!("link-section: No proc_macro feature enabled: `unsafe` is required", stringify!($($rest)*)));
159 };
160 }
161
162 #[doc(hidden)]
163 #[macro_export]
164 macro_rules! __hash_proc_macro {
165 (unsafe $prefix:tt $name:tt $suffix:tt $hash_length:literal $max_length:literal $valid_section_chars:literal) => {
168 $crate::__support::combine!(output=string input=(
169 __IF__(
170 test=(
171 __LE__(
172 a=(__LENGTH__(string=(
173 __TOIDENT__(input=(__RAW__(input=($name))))
174 )))
175 b=$max_length
176 )
177 )
178 then=(
179 $prefix
180 __TOIDENT__(input=(__RAW__(input=($name))))
181 $suffix
182 )
183 else=(
184 $prefix
185 __SUBSTRING__(input=(
186 __TOIDENT__(input=(__RAW__(input=($name))))
187 ) end=(__SUB__(a=$max_length b=$hash_length)))
188 __SUBSTRING__(input=(
189 __HASH__(string=(__RAW__(input=($name))))
190 ) length=$hash_length)
191 $suffix
192 )
193 )
194 ))
195 };
196 ($definition:tt $prefix:tt $name:tt $suffix:tt $hash_length:literal $max_length:literal $valid_section_chars:literal) => {
198 $crate::__support::combine!(output=string input=(
199 $prefix
200 __SUBSTRING__(input=(
201 __SUBSTRING__(input=(
202 __TOIDENT__(input=(__RAW__(input=($name))))
203 ) end=(__SUB__(a=$max_length b=$hash_length)))
204 __LOCATIONHASH__(of=($definition $name) alphabet=[_0-9a-zA-Z])
207 ) length=$max_length)
208 $suffix
209 ))
210 };
211 }
212
213 #[cfg(feature = "proc_macro")]
214 pub use __hash_proc_macro as hash;
215
216 #[cfg(not(feature = "proc_macro"))]
217 pub use __hash_no_proc_macro as hash;
218
219 #[cfg(miri)]
220 #[doc(hidden)]
221 #[macro_export]
222 macro_rules! __address_of_symbol {
223 ($ref_or_item:ident $section:ident $type:ident $name:tt) => {
224 ::core::ptr::null() as *const ()
227 };
228 }
229
230 #[cfg(not(miri))]
231 #[doc(hidden)]
232 #[macro_export]
233 macro_rules! __address_of_symbol {
234 ($ref_or_item:ident $section:ident $type:ident $name:tt) => {
235 {
236 $crate::__add_linktime_attributes_to_static!(
239 extern "C" {
240 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
241 static __SYMBOL: u8;
242 }
243 );
244 unsafe { ::core::ptr::addr_of!(__SYMBOL) as *const () }
248 }
249 }
250 }
251
252 #[doc(hidden)]
253 #[macro_export]
254 macro_rules! __add_section_link_attribute(
255 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
256 $(#[$meta:meta])*
257 $vis:vis static $($static:tt)*
258 ) => {
259 $crate::__add_linktime_attributes_to_static!(
260 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
261 $(#[$meta])*
262 $vis static $($static)*
263 );
264 };
265 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
266 extern "C" {
267 $(#[$meta:meta])*
268 $vis:vis static $($static:tt)*
269 }
270 ) => {
271 $crate::__add_linktime_attributes_to_static!(
272 extern "C" {
273 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
274 $(#[$meta])*
275 $vis static $($static)*
276 }
277 );
278 };
279 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
280 $($item:tt)*) => {
281 $crate::__add_linktime_attributes_to_static!(
282 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
283 $($item)*
284 );
285 };
286 );
287
288 #[cfg(target_family = "wasm")]
289 #[macro_export]
290 #[doc(hidden)]
291 macro_rules! __if_wasm {
292 (($($true:tt)*) ($($false:tt)*)) => {
293 $($true)*
294 };
295 }
296
297 #[cfg(not(target_family = "wasm"))]
298 #[macro_export]
299 #[doc(hidden)]
300 macro_rules! __if_wasm {
301 (($($true:tt)*) ($($false:tt)*)) => {
302 $($false)*
303 };
304 }
305
306 #[macro_export]
307 #[doc(hidden)]
308 #[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
309 macro_rules! __in_section_crate {
310 ((@v=0 ; (source=$source:ident) ; (type = untyped) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
311 $crate::__in_section_crate!(@untyped (($name)()), , $path, $meta $item);
312 };
313 ((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
314 $crate::__in_section_crate!(@typed[$section_type] (($name)()), , $path, $meta $item);
315 };
316 ((@v=0 ; (source=$source:ident) ; (type = untyped) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
317 $crate::__in_section_crate!(@untyped $section, , $($path)?, $meta $item);
318 };
319 ((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
320 $crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, $meta $item);
321 };
322
323 (@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $($rest:tt)*)) => {
325 $crate::__add_section_link_attribute!(
326 item code section $section
327 #[link_section = __]
328 $($meta)*
329 $vis fn $($rest)*
330 );
331 $(
332 const _: () = {
333 $crate::Section::__validate(&$path);
334 };
335 )?
336 };
337 (@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($($rest:tt)*)) => {
338 $crate::__add_section_link_attribute!(
339 item data section $section
340 #[link_section = __]
341 $($meta)*
342 $($rest)*
343 );
344 $(
345 const _: () = {
346 $crate::Section::__validate(&$path);
347 };
348 )?
349 };
350
351 (@typed[$section_type:ident] $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? { $($body:tt)* })) => {
353 $($meta)*
354 $vis fn $ident_fn($($args)*) $(-> $ret)? {
355 $crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, () (
356 const _: fn($($args)*) $(-> $ret)? = $ident_fn;
357 ));
358
359 $($body)*
360 }
361 };
362
363 (@typed[$section_type:ident] $section:tt, , , $meta:tt ($vis:vis $const_or_static:ident $name:tt : $ty:ty = $($rest:tt)*)) => {
365 $crate::__in_section_crate!(@typed[$section_type] $section, , $crate::TypedSection::<$ty>, $meta (
366 $vis $const_or_static $name: $ty = $($rest)*
367 ));
368 };
369
370 (@type_select $path:path) => {
371 <$path as $crate::__support::SectionItemType>::Item
372 };
373
374 (@typed[typed] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident : $ty:ty = $value:expr;)) => {
376 $crate::__if_wasm!(
377 (
378 compile_error!("static items are not supported on WASM: use const items instead");
379 )
380 (
381 $crate::__add_section_link_attribute!(
382 item data section $section
383 #[link_section = __]
384 $($meta)*
385 $vis static $ident: $crate::__in_section_crate!(@type_select $path) = const {
386 const _: () = {
387 let _: *const <$path as $crate::__support::SectionItemTyped<$ty>>::Item = ::core::ptr::null();
388 };
389
390 $value
391 };
392 );
393 )
394 );
395 };
396
397 (@typed[mutable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
399 $($meta)*
400 $vis const $ident: $ty = const {
401 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
402 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
403
404 $crate::__register_wasm_item!(mutable, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
405
406 $crate::__if_wasm!(() (
407 $crate::__add_section_link_attribute!(
408 item data section $section
409 #[link_section = __]
410 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> = $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
411 );
412 ));
413
414 __LINK_SECTION_CONST_ITEM_VALUE
415 };
416 };
417
418 (@typed[mutable] $($rest:tt)*) => {
419 compile_error!("Only const items are supported in mutable sections");
420 };
421
422 (@typed[movable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
424 $($meta)*
425 $vis static $ident: $crate::MovableRef<$crate::__in_section_crate!(@type_select $path)> = const {
426 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
427 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
428
429 $crate::__if_wasm!((
430 {
431 $crate::__register_wasm_item!(
432 movable,
433 value=__LINK_SECTION_CONST_ITEM_VALUE,
434 slot=$crate::MovableRef::slot_ptr(&raw const $ident),
435 section=$section
436 );
437
438 $crate::MovableRef::new(::core::ptr::null())
439 }
440 )(
441 {
442 $crate::__add_section_link_attribute!(
443 item data section $section
444 #[link_section = __]
445 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> =
446 $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
447 );
448
449 $crate::__add_section_link_attribute!(
450 backref data section $section
451 #[link_section = __]
452 static __LINK_SECTION_MOVABLE_BACKREF: $crate::__support::SyncUnsafeCell<
453 $crate::MovableBackref<__InSecStoredTy>
454 > = $crate::__support::SyncUnsafeCell::new(
455 $crate::MovableBackref::new(
456 $crate::MovableRef::slot_ptr(&raw const $ident),
457 )
458 );
459 );
460
461 $crate::MovableRef::new(
462 (&raw const __LINK_SECTION_CONST_ITEM)
463 .cast::<__InSecStoredTy>(),
464 )
465 }
466 ))
467 };
468 };
469
470 (@typed[movable] $($rest:tt)*) => {
471 compile_error!("Only static items are supported in movable sections");
472 };
473
474 (@typed[$section_type:ident] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
476 $($meta)*
477 $vis const $ident: $ty = const {
478 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
479 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
480
481 $crate::__if_wasm!((
482 $crate::__register_wasm_item!($section_type, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
483 ) (
484 $crate::__add_section_link_attribute!(
485 item data section $section
486 #[link_section = __]
487 static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
488 );
489 ));
490
491 __LINK_SECTION_CONST_ITEM_VALUE
492 };
493 };
494
495 (@typed[reference] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
496 $crate::__if_wasm!(
497 (
498 $($meta)*
499 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = {
500 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
501 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
502 $crate::__register_wasm_item!(reference, value=__LINK_SECTION_CONST_ITEM_VALUE, ref=$ident, section=$section);
503 $crate::reference::Ref::new()
504 };
505 )
506 (
507 #[cfg(not(target_family="wasm"))]
509 $crate::__add_section_link_attribute!(
510 item data section $section
511 #[link_section = __]
512 $($meta)*
513 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = $crate::reference::Ref::new($value);
514 );
515 )
516 );
517 };
518
519 ($($input:tt)*) => {
520 compile_error!(concat!("Unexpected input to __in_section_crate: ", stringify!($($input)*)));
521 };
522 }
523}
524
525#[cfg(feature = "proc_macro")]
552pub use ::linktime_proc_macro::section;
553
554#[cfg(feature = "proc_macro")]
568pub use ::linktime_proc_macro::in_section;