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
7#[doc = include_str!("../docs/LIFE_BEFORE_MAIN.md")]
8pub mod life_before_main {}
9
10pub mod declarative {
17 pub use crate::__in_section_parse as in_section;
18 pub use crate::__section_parse as section;
19}
20
21#[doc(hidden)]
22pub mod __support {
23 pub use crate::__add_section_link_attribute as add_section_link_attribute;
24 pub use crate::__def_section_name as def_section_name;
25 pub use crate::__get_section as get_section;
26 pub use crate::__in_section_crate as in_section_crate;
27 pub use crate::__in_section_parse as in_section_parse;
28 pub use crate::__section_parse as section_parse;
29
30 #[cfg(feature = "proc_macro")]
31 pub use linktime_proc_macro::hash;
32 #[cfg(feature = "proc_macro")]
33 pub use linktime_proc_macro::ident_concat;
34
35 #[macro_export]
37 #[doc(hidden)]
38 macro_rules! __def_section_name {
39 (
40 {$(
41 $__section:ident $__type:ident => $__prefix:tt __ $__suffix:tt;
42 )*}
43 AUXILIARY = $__aux_sep:literal;
44 MAX_LENGTH = $__max_length:literal;
45 HASH_LENGTH = $__hash_length:literal;
46 VALID_SECTION_CHARS = $__valid_section_chars:literal;
47 ) => {
48 #[macro_export]
50 #[doc(hidden)]
51 macro_rules! __section_name {
52 $(
53 (raw $__section $__type $name:ident) => {
54 concat!(concat! $__prefix, stringify!($name), concat! $__suffix);
55 };
56 (raw $__section $__type $name:ident $aux:ident) => {
57 concat!(concat! $__prefix, stringify!($name), $__aux_sep, stringify!($aux), concat! $__suffix);
58 };
59 ($pattern:tt $__section $__type $name:ident) => {
60 $crate::__support::hash!($pattern ($__prefix) $name ($__suffix) $__hash_length $__max_length $__valid_section_chars);
61 };
62 ($pattern:tt $__section $__type $name:ident $aux:ident) => {
63 $crate::__support::hash!($pattern ($__prefix) ($name $__aux_sep $aux) ($__suffix) $__hash_length $__max_length $__valid_section_chars);
64 };
65 )*
66 ($pattern:tt $unknown_section:ident $unknown_type:ident $name:ident) => {
67 const _: () = {
68 compile_error!("Unknown section type: `{}`/`{}`", stringify!($unknown_section), stringify!($unknown_type));
69 };
70 };
71 }
72 };
73 }
74
75 #[cfg(not(linktime_used_linker))]
76 #[doc(hidden)]
77 #[macro_export]
78 macro_rules! __add_used {
79 (
80 $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
81 $(#[$meta:meta])*
82 $vis:vis static $($static:tt)*
83 ) => {
84 $crate::__add_section_link_attribute_impl!(
85 $section $type $name $($aux)? #[$attr = __]
86 $(#[$meta])*
87 #[used]
88 $vis static $($static)*
89 );
90 };
91 }
92
93 #[cfg(linktime_used_linker)]
94 #[doc(hidden)]
95 #[macro_export]
96 macro_rules! __add_used {
97 (
98 $section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
99 $(#[$meta:meta])*
100 $vis:vis static $($static:tt)*
101 ) => {
102 $crate::__add_section_link_attribute_impl!(
103 $section $type $name $($aux)? #[$attr = __]
104 $(#[$meta])*
105 #[used(linker)]
106 $vis static $($static)*
107 );
108 };
109 }
110
111 #[doc(hidden)]
112 #[macro_export]
113 macro_rules! __add_section_link_attribute(
114 ($section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
115 $(#[$meta:meta])*
116 $vis:vis static $($static:tt)*
117 ) => {
118 $crate::__add_used!(
119 $section $type $name $($aux)? #[$attr = __]
120 $(#[$meta])*
121 $vis static $($static)*
122 );
123 };
124 ($section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
125 extern "C" {
126 $(#[$meta:meta])*
127 $vis:vis static $($static:tt)*
128 }
129 ) => {
130 extern "C" {
131 $crate::__add_section_link_attribute_impl!(
132 $section $type $name $($aux)? #[$attr = __]
133 $(#[$meta])*
134 #[allow(unsafe_code)]
135 $vis static $($static)*
136 );
137 }
138 };
139 ($section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __]
140 $(#[$meta:meta])* $($item:tt)*) => {
141 $crate::__add_section_link_attribute_impl!(
142 $section $type $name $($aux)? #[$attr = __]
143 $(#[$meta])*
144 #[allow(unsafe_code)]
145 $($item)*
146 );
147 };
148 );
149
150 #[cfg(feature = "proc_macro")]
151 #[doc(hidden)]
152 #[macro_export]
153 macro_rules! __add_section_link_attribute_impl(
154 ($section:ident $type:ident $name:ident $($aux:ident)? #[$attr:ident = __] $($item:tt)*) => {
155 $crate::__section_name!(
156 (#[$attr = __] #[allow(unsafe_code)] $($item)*)
157 $section $type $name $($aux)?
158 );
159 }
160 );
161
162 #[cfg(not(feature = "proc_macro"))]
163 #[doc(hidden)]
164 #[macro_export]
165 macro_rules! __add_section_link_attribute_impl(
166 ($section:ident $type:ident $name:ident #[$attr:ident = __] $($item:tt)*) => {
167 #[$attr = $crate::__section_name!(
168 raw $section $type $name
169 )] $($item)*
170 }
171 );
172
173 #[cfg(target_vendor = "apple")]
175 def_section_name! {
176 {
177 data bare => ("__DATA,") __ ();
178 code bare => ("__TEXT,") __ ();
179 data section => ("__DATA,") __ (",regular,no_dead_strip");
180 code section => ("__TEXT,") __ (",regular,pure_instructions");
181 data start => ("\x01section$start$__DATA$") __ ();
182 data end => ("\x01section$end$__DATA$") __ ();
183 }
184 AUXILIARY = "_";
185 MAX_LENGTH = 16;
186 HASH_LENGTH = 6;
187 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
188 }
189
190 #[cfg(target_family = "wasm")]
191 def_section_name! {
192 {
193 data bare => (".data", ".link_section.") __ ();
194 data section => (".data", ".link_section.") __ ();
195 code bare => (".text", ".link_section.") __ ();
196 code section => (".text", ".link_section.") __ ();
197 }
198 AUXILIARY = ".";
199 MAX_LENGTH = 16;
200 HASH_LENGTH = 6;
201 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
202 }
203
204 #[cfg(all(
205 not(target_vendor = "apple"),
206 not(target_vendor = "pc"),
207 not(target_family = "wasm")
208 ))]
209 def_section_name! {
210 {
211 data bare => ("_data", "_link_section_") __ ();
212 data section => ("_data", "_link_section_") __ ();
213 data start => ("__start_", "_data", "_link_section_") __ ();
214 data end => ("__stop_", "_data", "_link_section_") __ ();
215 code bare => ("_text", "_link_section_") __ ();
216 code section => ("_text", "_link_section_") __ ();
217 code start => ("__start_", "_text", "_link_section_") __ ();
218 code end => ("__stop_", "_text", "_link_section_") __ ();
219 }
220 AUXILIARY = "_";
221 MAX_LENGTH = 64;
222 HASH_LENGTH = 10;
223 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
224 }
225
226 #[cfg(target_vendor = "pc")]
227 def_section_name! {
228 {
229 data bare => (".data", "$") __ ();
230 data section => (".data", "$") __ ("$b");
231 data start => (".data", "$") __ ("$a");
232 data end => (".data", "$") __ ("$c");
233 code bare => (".text", "$") __ ();
234 code section => (".text", "$") __ ("$b");
235 code start => (".text", "$") __ ("$a");
236 code end => (".text", "$") __ ("$c");
237 }
238 AUXILIARY = "$d$";
239 MAX_LENGTH = 64;
240 HASH_LENGTH = 10;
241 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
242 }
243
244 #[cfg(not(feature = "proc_macro"))]
245 #[doc(hidden)]
246 #[macro_export]
247 macro_rules! __declare_macro {
248 ($vis:vis $ident:ident $generic_macro:ident $args:tt) => {
249 #[doc(hidden)]
252 $vis use $crate::$generic_macro as $ident;
253 };
254 }
255
256 #[cfg(feature = "proc_macro")]
257 #[doc(hidden)]
258 #[macro_export]
259 macro_rules! __declare_macro {
260 ($vis:vis $ident:ident $generic_macro:ident $args:tt) => {
261 $crate::__support::ident_concat!(
262 (#[macro_export]
263 #[doc(hidden)]
264 macro_rules!) (__ $ident __link_section_private_macro__) ({
265 ($passthru:tt) => {
266 $crate::$generic_macro!($passthru $args);
267 };
268 })
269 );
270
271 $crate::__support::ident_concat!(
272 (#[doc(hidden)] pub use) (__ $ident __link_section_private_macro__) (as $ident;)
273 );
274 }
275 }
276
277 #[macro_export]
279 #[doc(hidden)]
280 macro_rules! __section_parse {
281 (#[section $($args:tt)*] $(#[$meta:meta])* $vis:vis static $ident:ident : $(:: $path_prefix:ident ::)? $($path:ident)::* < $($generic:tt)*) => {
283 $crate::__section_parse!(@parsed #[section $($args)*] $(#[$meta])* $vis static $ident: ( $(:: $path_prefix ::)? $($path)::* < $($generic)*) ( $($generic)* ) __in_section_helper_macro_generic);
284 };
285 (#[section $($args:tt)*] $(#[$meta:meta])* $vis:vis static $ident:ident : $(:: $path_prefix:ident ::)? $($path:ident)::* ;) => {
287 $crate::__section_parse!(@parsed #[section $($args)*] $(#[$meta])* $vis static $ident: ( $(:: $path_prefix ::)? $($path)::* ;) ( () > ; ) __in_section_helper_macro_no_generic);
288 };
289 (@parsed #[section(aux = $name:ident, no_macro)] $(#[$meta:meta])* $vis:vis static $ident:ident : ($ty:ty ;) ( $generic_ty:ty > ; ) $generic_macro:ident) => {
291 $crate::__section_parse!(@generate #[section(aux = $name)] $(#[$meta])* $vis static $ident: $ty, $generic_ty, $generic_macro);
292 };
293 (@parsed #[section(no_macro)] $(#[$meta:meta])* $vis:vis static $ident:ident : ($ty:ty ;) ( $generic_ty:ty > ; ) $generic_macro:ident) => {
294 $crate::__section_parse!(@generate #[section] $(#[$meta])* $vis static $ident: $ty, $generic_ty, $generic_macro);
295 };
296 (@parsed #[section $($args:tt)*] $(#[$meta:meta])* $vis:vis static $ident:ident : ($ty:ty ;) ( $generic_ty:ty > ; ) $generic_macro:ident) => {
297 $crate::__declare_macro!($vis $ident $generic_macro ($($args)*));
298 $crate::__section_parse!(@generate #[section $($args)*] $(#[$meta])* $vis static $ident: $ty, $generic_ty, $generic_macro);
299 };
300 (@generate #[section $($args:tt)*] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, __in_section_helper_macro_generic) => {
301 $crate::__section_parse!(@generate #[section $($args)*] $(#[$meta])* $vis static $ident: $ty, $generic_ty, __base_case__);
302
303 impl ::core::iter::IntoIterator for $ident {
304 type Item = &'static $generic_ty;
305 type IntoIter = ::core::slice::Iter<'static, $generic_ty>;
306 fn into_iter(self) -> Self::IntoIter {
307 $ident.as_slice().iter()
308 }
309 }
310 };
311 (@generate #[section $($args:tt)*] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, $generic_macro:ident) => {
312 $(#[$meta])*
313 #[allow(non_camel_case_types)]
314 $vis struct $ident;
315
316 impl $crate::__support::SectionItemType for $ident {
317 type Item = $generic_ty;
318 }
319
320 impl ::core::fmt::Debug for $ident {
321 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
322 ::core::ops::Deref::deref(self).fmt(f)
323 }
324 }
325
326 impl ::core::ops::Deref for $ident {
327 type Target = $ty;
328 fn deref(&self) -> &Self::Target {
329 self.const_deref()
330 }
331 }
332
333 $crate::__section_parse!(@deref #[section $($args)*] $(#[$meta])* $vis static $ident: $ty, $generic_ty, __base_case__);
334 };
335 (@deref #[section] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, __base_case__) => {
336 impl $ident {
337 pub const fn const_deref(&self) -> &$ty {
340 static SECTION: $ty = {
341 let section = $crate::__support::get_section!(name=$ident, type=$generic_ty, aux=);
342 let name = $crate::__section_name!(
343 raw data bare $ident
344 );
345 unsafe { <$ty>::new(name, section.0, section.1) }
346 };
347 &SECTION
348 }
349 }
350 };
351 (@deref #[section(aux=$aux:ident)] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, __base_case__) => {
352 impl $ident {
353 pub const fn const_deref(&self) -> &$ty {
356 static SECTION: $ty = {
357 let section = $crate::__support::get_section!(name=$ident, type=$generic_ty, aux=$aux);
358 let name = $crate::__section_name!(
359 raw data bare $aux $ident );
361 unsafe { <$ty>::new(name, section.0, section.1) }
362 };
363 &SECTION
364 }
365 }
366 };
367 }
368
369 #[cfg(miri)]
370 mod section {
371 #[doc(hidden)]
372 #[macro_export]
373 macro_rules! __get_section {
374 (name=$ident:ident, type=$generic_ty:ty, aux=$($aux:ident)?) => {{
375 (std::ptr::null_mut(), std::ptr::null_mut())
376 }};
377 }
378
379 pub type SectionPtr<T> = *const ::core::marker::PhantomData<T>;
382 }
383
384 #[cfg(all(not(miri), target_family = "wasm"))]
385 mod section {
386 #[doc(hidden)]
387 #[macro_export]
388 macro_rules! __get_section {
389 (name=$ident:ident, type=$generic_ty:ty, aux=$($aux:ident)?) => {
390 {
391 static __START: ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>> = unsafe {
392 ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>>::new(::core::ptr::null_mut())
393 };
394 static __END: ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>> = unsafe {
395 ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>>::new(::core::ptr::null_mut())
396 };
397
398 $crate::__support::ident_concat!((#[no_mangle]pub extern "C" fn) (register_link_section_ $ident) ((data_ptr: *const u8, data_len: usize) {
399 unsafe {
400 __START.store(data_ptr as *mut ::core::marker::PhantomData<$generic_ty>, ::core::sync::atomic::Ordering::Relaxed);
401 __END.store(data_ptr.add(data_len) as *mut ::core::marker::PhantomData<$generic_ty>, ::core::sync::atomic::Ordering::Relaxed);
402 }
403 }));
404
405 (&__START, &__END)
406 }
407 }
408 }
409
410 pub type SectionPtr<T> =
414 &'static ::core::sync::atomic::AtomicPtr<::core::marker::PhantomData<T>>;
415 }
416
417 #[cfg(all(not(miri), target_vendor = "pc"))]
418 mod section {
419 #[doc(hidden)]
420 #[macro_export]
421 macro_rules! __get_section {
422 (name=$ident:ident, type=$generic_ty:ty, aux=$($aux:ident)?) => {
423 {
424 $crate::__support::add_section_link_attribute!(
425 data start $ident $($aux)?
426 #[link_section = __]
427 static __START: [$generic_ty; 0] = [];
428 );
429 $crate::__support::add_section_link_attribute!(
430 data end $ident $($aux)?
431 #[link_section = __]
432 static __END: [$generic_ty; 0] = [];
433 );
434
435 (
436 unsafe { &raw const __START as $crate::__support::SectionPtr<$generic_ty> },
437 unsafe { &raw const __END as $crate::__support::SectionPtr<$generic_ty> },
438 )
439 }
440 }
441 }
442
443 pub type SectionPtr<T> = *const [T; 0];
447 }
448
449 #[cfg(all(not(miri), not(target_family = "wasm"), not(target_vendor = "pc")))]
450 mod section {
451 #[doc(hidden)]
452 #[macro_export]
453 macro_rules! __get_section {
454 (name=$ident:ident, type=$generic_ty:ty, aux=$($aux:ident)?) => {
455 {
456 $crate::__support::add_section_link_attribute!(
457 data start $ident $($aux)?
458 #[link_name = __]
459 extern "C" {
460 static __START: $crate::__support::SectionPtr<$generic_ty>;
461 }
462 );
463 $crate::__support::add_section_link_attribute!(
464 data end $ident $($aux)?
465 #[link_name = __]
466 extern "C" {
467 static __END: $crate::__support::SectionPtr<$generic_ty>;
468 }
469 );
470
471 (
472 unsafe { &raw const __START as $crate::__support::SectionPtr<$generic_ty> },
473 unsafe { &raw const __END as $crate::__support::SectionPtr<$generic_ty> },
474 )
475 }
476 }
477 }
478
479 pub type SectionPtr<T> = *const ::core::marker::PhantomData<T>;
482 }
483
484 #[macro_export]
486 #[doc(hidden)]
487 macro_rules! __in_section_parse {
488 (#[in_section(unsafe, type = $stored_ty:ty, name = $ident:ident $( , aux = $aux:ident)?)] $($item:tt)*) => {
495 $crate::__support::in_section_crate!((type = $stored_ty), $ident, $($aux)?, $ident, ($($item)*));
496 };
497 (#[in_section(unsafe, name = $ident:ident $( , aux = $aux:ident)?)] $($item:tt)*) => {
498 $crate::__support::in_section_crate!(data, $ident, $($aux)?, $ident, ($($item)*));
499 };
500 (#[in_section( $($path:tt)* )] $($item:tt)*) => {
501 $crate::__support::in_section_parse!(path=[$($path)*] #[in_section($($path)*)] $($item)*);
502 };
503 (path=[$orig_path:path] #[in_section($name:ident)] $($item:tt)*) => {
504 $orig_path ! (
505 (v=0 (name=$name (path=[$orig_path] (item=($($item)*) ()))))
506 );
507 };
508 (path=[$orig_path:path] #[in_section(:: $($path:ident)::*)] $($item:tt)*) => {
509 $crate::__support::in_section_parse!(path=[$orig_path] #[in_section($($path)::*)] $($item)*);
510 };
511 (path=[$orig_path:path] #[in_section($prefix:ident :: $($path:ident)::*)] $($item:tt)*) => {
512 $crate::__support::in_section_parse!(path=[$orig_path] #[in_section($($path)::*)] $($item)*);
513 };
514 }
515
516 #[macro_export]
517 #[doc(hidden)]
518 macro_rules! __in_section_helper_macro_generic {
519 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt))))) => {
520 $crate::__support::in_section_crate!(section, $ident,, $path, $item);
521 };
522 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) ((aux=$aux:ident)) )=> {
523 $crate::__support::in_section_crate!(section, $ident, $aux, $path, $item);
524 };
525 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) () )=> {
526 $crate::__support::in_section_crate!(section, $ident,, $path, $item);
527 };
528 (v=$v:literal $rest:tt) => {
529 const _: () = {
530 compile_error!(concat!(
531 "link-section: Unsupported version: `",
532 stringify!($v),
533 "`: ",
534 stringify!($rest)
535 ));
536 };
537 };
538 }
539
540 #[macro_export]
541 #[doc(hidden)]
542 macro_rules! __in_section_helper_macro_no_generic {
543 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt))))) => {
544 $crate::__support::in_section_crate!(data, $ident,, $path, $item);
545 };
546 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) ((aux=$aux:ident)) )=> {
547 $crate::__support::in_section_crate!(data, $ident, $aux, $path, $item);
548 };
549 ((v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) () )=> {
550 $crate::__support::in_section_crate!(data, $ident,, $path, $item);
551 };
552 (v=$v:literal $rest:tt) => {
553 const _: () = {
554 compile_error!(concat!(
555 "link-section: Unsupported version: `",
556 stringify!($v),
557 "`: ",
558 stringify!($rest)
559 ));
560 };
561 };
562 }
563
564 #[macro_export]
565 #[doc(hidden)]
566 #[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
567 macro_rules! __in_section_crate {
568 (@type_select section $path:path, $item_ty:ty) => {
569 <$path as $crate::__support::SectionItemType>::Item
570 };
571 (@type_select data $path:path, $item_ty:ty) => {
572 $item_ty
573 };
574 (@type_select (type = $stored_ty:ty) $path:path, $item_ty:ty) => {
575 $stored_ty
576 };
577 ($type_source:tt, $ident:ident, $($aux:ident)?, $path:path, ($(#[$meta:meta])* $vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? $body:block)) => {
578 const _: () = {
579 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $type_source $path, fn($($args)*) $(-> $ret)?);
580 $crate::__add_section_link_attribute!(
581 data section $ident $($aux)?
582 #[link_section = __]
583 $(#[$meta])*
584 #[allow(non_upper_case_globals)]
585 $vis static __LINK_SECTION_FN_ITEM: __InSecStoredTy = $ident_fn;
586 );
587 };
588
589 $crate::__add_section_link_attribute!(
590 code section $ident $($aux)?
591 #[link_section = __]
592 fn $ident_fn($($args)*) $(-> $ret)? $body
593 );
594 };
595 ($type_source:tt, $ident:ident, $($aux:ident)?, $path:path, ($(#[$meta:meta])* $vis:vis static _ : $ty:ty = $value:expr;)) => {
596 const _: () = {
597 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $type_source $path, $ty);
598 $crate::__add_section_link_attribute!(
599 data section $ident $($aux)?
600 #[link_section = __]
601 $(#[$meta])* $vis static ANONYMOUS: __InSecStoredTy = $value;
602 );
603 };
604 };
605 ($type_source:tt, $ident:ident, $($aux:ident)?, $path:path, ($(#[$meta:meta])* $vis:vis static $ident_static:ident : $ty:ty = $value:expr;)) => {
606 $crate::__add_section_link_attribute!(
607 data section $ident $($aux)?
608 #[link_section = __]
609 $(#[$meta])* $vis static $ident_static: $crate::__in_section_crate!(@type_select $type_source $path, $ty) = $value;
610 );
611 };
612 (data, $ident:ident, $($aux:ident)?, $path:path, ($(#[$meta:meta])* $item:item)) => {
613 $crate::__add_section_link_attribute!(
614 data section $ident $($aux)?
615 #[link_section = __]
616 $(#[$meta])* $item
617 );
618 };
619 }
620
621 pub trait SectionItemType {
622 type Item;
623 }
624
625 impl<T> SectionItemType for super::TypedSection<T> {
626 type Item = T;
627 }
628
629 pub use section::SectionPtr;
630}
631
632#[cfg(feature = "proc_macro")]
659pub use ::linktime_proc_macro::section;
660
661#[cfg(feature = "proc_macro")]
668pub use ::linktime_proc_macro::in_section;
669
670#[repr(C)]
673pub struct Section {
674 name: &'static str,
675 start: __support::SectionPtr<()>,
676 end: __support::SectionPtr<()>,
677}
678
679impl Section {
680 #[doc(hidden)]
681 pub const unsafe fn new(
682 name: &'static str,
683 start: __support::SectionPtr<()>,
684 end: __support::SectionPtr<()>,
685 ) -> Self {
686 Self { name, start, end }
687 }
688
689 pub fn byte_len(&self) -> usize {
691 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
692 }
693}
694
695#[cfg(target_family = "wasm")]
696impl Section {
697 pub fn start_ptr(&self) -> *const () {
699 let ptr = self.start.load(::core::sync::atomic::Ordering::Relaxed) as *const ();
700 if ptr.is_null() {
701 panic!(
702 "Section {} was not initialized by the host environment",
703 self.name
704 );
705 }
706 ptr
707 }
708 pub fn end_ptr(&self) -> *const () {
710 let ptr = self.end.load(::core::sync::atomic::Ordering::Relaxed) as *const ();
711 if ptr.is_null() {
712 panic!(
713 "Section {} was not initialized by the host environment",
714 self.name
715 );
716 }
717 ptr
718 }
719}
720
721#[cfg(not(target_family = "wasm"))]
722impl Section {
723 pub fn start_ptr(&self) -> *const () {
725 self.start as *const ()
726 }
727 pub fn end_ptr(&self) -> *const () {
729 self.end as *const ()
730 }
731}
732
733impl ::core::fmt::Debug for Section {
734 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
735 f.debug_struct("Section")
736 .field("name", &self.name)
737 .field("start", &self.start_ptr())
738 .field("end", &self.end_ptr())
739 .field("byte_len", &self.byte_len())
740 .finish()
741 }
742}
743
744unsafe impl Sync for Section {}
745unsafe impl Send for Section {}
746
747#[repr(C)]
750pub struct TypedSection<T: 'static> {
751 name: &'static str,
752 start: __support::SectionPtr<T>,
753 end: __support::SectionPtr<T>,
754 _phantom: ::core::marker::PhantomData<T>,
755}
756
757#[cfg(target_family = "wasm")]
758impl<T: 'static> TypedSection<T> {
759 pub fn start_ptr(&self) -> *const T {
761 let ptr = self.start.load(::core::sync::atomic::Ordering::Relaxed) as *const T;
762 if ptr.is_null() {
763 panic!(
764 "TypedSection {} was not initialized by the host environment",
765 self.name
766 );
767 }
768 ptr
769 }
770
771 pub fn end_ptr(&self) -> *const T {
773 let ptr = self.end.load(::core::sync::atomic::Ordering::Relaxed) as *const T;
774 if ptr.is_null() {
775 panic!(
776 "TypedSection {} was not initialized by the host environment",
777 self.name
778 );
779 }
780 ptr
781 }
782}
783
784#[cfg(not(target_family = "wasm"))]
785impl<T: 'static> TypedSection<T> {
786 #[inline(always)]
788 pub fn start_ptr(&self) -> *const T {
789 self.start as usize as *const T
790 }
791
792 #[inline(always)]
794 pub fn end_ptr(&self) -> *const T {
795 self.end as *const T
796 }
797}
798
799impl<T: 'static> TypedSection<T> {
801 #[doc(hidden)]
802 pub const unsafe fn new(
803 name: &'static str,
804 start: __support::SectionPtr<T>,
805 end: __support::SectionPtr<T>,
806 ) -> Self {
807 Self {
808 name,
809 start,
810 end,
811 _phantom: ::core::marker::PhantomData,
812 }
813 }
814
815 pub const fn stride(&self) -> usize {
817 assert!(
818 ::core::mem::size_of::<T>() > 0
819 && ::core::mem::size_of::<T>() * 2 == ::core::mem::size_of::<[T; 2]>()
820 );
821 ::core::mem::size_of::<T>()
822 }
823
824 pub fn byte_len(&self) -> usize {
826 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
827 }
828
829 pub fn len(&self) -> usize {
831 self.byte_len() / self.stride()
832 }
833
834 pub fn is_empty(&self) -> bool {
836 self.len() == 0
837 }
838
839 pub fn as_slice(&self) -> &[T] {
841 if self.is_empty() {
842 &[]
843 } else {
844 unsafe { ::core::slice::from_raw_parts(self.start_ptr(), self.len()) }
845 }
846 }
847
848 pub fn offset_of(&self, item: &T) -> Option<usize> {
850 let ptr = item as *const T;
851 if ptr < self.start_ptr() || ptr >= self.end_ptr() {
852 None
853 } else {
854 Some(unsafe { ptr.offset_from(self.start_ptr()) as usize })
855 }
856 }
857
858 #[allow(clippy::mut_from_ref)]
865 pub unsafe fn as_mut_slice(&self) -> &mut [T] {
866 if self.is_empty() {
867 &mut []
868 } else {
869 unsafe { ::core::slice::from_raw_parts_mut(self.start_ptr() as *mut T, self.len()) }
870 }
871 }
872
873 #[inline(always)]
875 pub fn start_ptr_mut(&self) -> *mut T {
876 self.start_ptr() as *mut T
877 }
878
879 #[inline(always)]
881 pub fn end_ptr_mut(&self) -> *mut T {
882 self.end_ptr() as *mut T
883 }
884}
885
886impl<'a, T> ::core::iter::IntoIterator for &'a TypedSection<T> {
887 type Item = &'a T;
888 type IntoIter = ::core::slice::Iter<'a, T>;
889 fn into_iter(self) -> Self::IntoIter {
890 self.as_slice().iter()
891 }
892}
893
894impl<T> ::core::ops::Deref for TypedSection<T> {
895 type Target = [T];
896 fn deref(&self) -> &Self::Target {
897 self.as_slice()
898 }
899}
900
901impl<T> ::core::fmt::Debug for TypedSection<T> {
902 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
903 f.debug_struct("TypedSection")
904 .field("name", &self.name)
905 .field("start", &self.start_ptr())
906 .field("end", &self.end_ptr())
907 .field("len", &self.len())
908 .field("stride", &self.stride())
909 .finish()
910 }
911}
912
913unsafe impl<T> Sync for TypedSection<T> where T: Sync {}
914unsafe impl<T> Send for TypedSection<T> where T: Send {}