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