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) => {
199 $crate::__support::combine!(output=string input=(
200 $prefix
201 __SUBSTRING__(input=(
202 __SUBSTRING__(input=(
203 __TOIDENT__(input=(__RAW__(input=($name))))
204 ) end=(__SUB__(a=$max_length b=$hash_length)))
205 __LOCATIONHASH__(of=($definition $name) alphabet=[_0-9a-zA-Z] ignore_base=("src/lib.rs"))
206 ) length=$max_length)
207 $suffix
208 ))
209 };
210 }
211
212 #[cfg(feature = "proc_macro")]
213 pub use __hash_proc_macro as hash;
214
215 #[cfg(not(feature = "proc_macro"))]
216 pub use __hash_no_proc_macro as hash;
217
218 #[cfg(miri)]
219 #[doc(hidden)]
220 #[macro_export]
221 macro_rules! __address_of_symbol {
222 ($ref_or_item:ident $section:ident $type:ident $name:tt) => {
223 ::core::ptr::null() as *const ()
226 };
227 }
228
229 #[cfg(not(miri))]
230 #[doc(hidden)]
231 #[macro_export]
232 macro_rules! __address_of_symbol {
233 ($ref_or_item:ident $section:ident $type:ident $name:tt) => {
234 {
235 $crate::__add_linktime_attributes_to_static!(
238 extern "C" {
239 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
240 static __SYMBOL: u8;
241 }
242 );
243 unsafe { ::core::ptr::addr_of!(__SYMBOL) as *const () }
247 }
248 }
249 }
250
251 #[doc(hidden)]
252 #[macro_export]
253 macro_rules! __add_section_link_attribute(
254 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
255 $(#[$meta:meta])*
256 $vis:vis static $($static:tt)*
257 ) => {
258 $crate::__add_linktime_attributes_to_static!(
259 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
260 $(#[$meta])*
261 $vis static $($static)*
262 );
263 };
264 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
265 extern "C" {
266 $(#[$meta:meta])*
267 $vis:vis static $($static:tt)*
268 }
269 ) => {
270 $crate::__add_linktime_attributes_to_static!(
271 extern "C" {
272 #[link_name = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
273 $(#[$meta])*
274 $vis static $($static)*
275 }
276 );
277 };
278 ($ref_or_item:ident $section:ident $type:ident $name:tt #[$attr:ident = __]
279 $($item:tt)*) => {
280 $crate::__add_linktime_attributes_to_static!(
281 #[$attr = $crate::__support::section_name!(string $ref_or_item $section $type $name)]
282 $($item)*
283 );
284 };
285 );
286
287 #[cfg(target_family = "wasm")]
288 #[macro_export]
289 #[doc(hidden)]
290 macro_rules! __if_wasm {
291 (($($true:tt)*) ($($false:tt)*)) => {
292 $($true)*
293 };
294 }
295
296 #[cfg(not(target_family = "wasm"))]
297 #[macro_export]
298 #[doc(hidden)]
299 macro_rules! __if_wasm {
300 (($($true:tt)*) ($($false:tt)*)) => {
301 $($false)*
302 };
303 }
304
305 #[macro_export]
306 #[doc(hidden)]
307 #[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
308 macro_rules! __in_section_crate {
309 ((@v=0 ; (source=$source:ident) ; (type = untyped) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
310 $crate::__in_section_crate!(@untyped (($name)()), , $path, $meta $item);
311 };
312 ((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (path = $path:path) ; (name = $name:ident) ; (meta = $meta:tt) ; (item = $item:tt))) => {
313 $crate::__in_section_crate!(@typed[$section_type] (($name)()), , $path, $meta $item);
314 };
315 ((@v=0 ; (source=$source:ident) ; (type = untyped) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
316 $crate::__in_section_crate!(@untyped $section, , $($path)?, $meta $item);
317 };
318 ((@v=0 ; (source=$source:ident) ; (type = $section_type:ident) ; (section = $section:tt) $(; (path = $path:path) ; (name = $name:ident))? ; (meta = $meta:tt) ; (item = $item:tt))) => {
319 $crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, $meta $item);
320 };
321
322 (@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $($rest:tt)*)) => {
324 $crate::__add_section_link_attribute!(
325 item code section $section
326 #[link_section = __]
327 $($meta)*
328 $vis fn $($rest)*
329 );
330 $(
331 const _: () = {
332 $crate::Section::__validate(&$path);
333 };
334 )?
335 };
336 (@untyped $section:tt, , $($path:path)?, ($($meta:tt)*) ($($rest:tt)*)) => {
337 $crate::__add_section_link_attribute!(
338 item data section $section
339 #[link_section = __]
340 $($meta)*
341 $($rest)*
342 );
343 $(
344 const _: () = {
345 $crate::Section::__validate(&$path);
346 };
347 )?
348 };
349
350 (@typed[$section_type:ident] $section:tt, , $($path:path)?, ($($meta:tt)*) ($vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? { $($body:tt)* })) => {
352 $($meta)*
353 $vis fn $ident_fn($($args)*) $(-> $ret)? {
354 $crate::__in_section_crate!(@typed[$section_type] $section, , $($path)?, () (
355 const _: fn($($args)*) $(-> $ret)? = $ident_fn;
356 ));
357
358 $($body)*
359 }
360 };
361
362 (@typed[$section_type:ident] $section:tt, , , $meta:tt ($vis:vis $const_or_static:ident $name:tt : $ty:ty = $($rest:tt)*)) => {
364 $crate::__in_section_crate!(@typed[$section_type] $section, , $crate::TypedSection::<$ty>, $meta (
365 $vis $const_or_static $name: $ty = $($rest)*
366 ));
367 };
368
369 (@type_select $path:path) => {
370 <$path as $crate::__support::SectionItemType>::Item
371 };
372
373 (@typed[typed] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident : $ty:ty = $value:expr;)) => {
375 $crate::__if_wasm!(
376 (
377 compile_error!("static items are not supported on WASM: use const items instead");
378 )
379 (
380 $crate::__add_section_link_attribute!(
381 item data section $section
382 #[link_section = __]
383 $($meta)*
384 $vis static $ident: $crate::__in_section_crate!(@type_select $path) = const {
385 const _: () = {
386 let _: *const <$path as $crate::__support::SectionItemTyped<$ty>>::Item = ::core::ptr::null();
387 };
388
389 $value
390 };
391 );
392 )
393 );
394 };
395
396 (@typed[mutable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
398 $($meta)*
399 $vis const $ident: $ty = const {
400 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
401 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
402
403 $crate::__register_wasm_item!(mutable, type=__InSecStoredTy, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
404
405 $crate::__if_wasm!(() (
406 $crate::__add_section_link_attribute!(
407 item data section $section
408 #[link_section = __]
409 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> = $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
410 );
411 ));
412
413 __LINK_SECTION_CONST_ITEM_VALUE
414 };
415 };
416
417 (@typed[mutable] $($rest:tt)*) => {
418 compile_error!("Only const items are supported in mutable sections");
419 };
420
421 (@typed[movable] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
423 $($meta)*
424 $vis static $ident: $crate::MovableRef<$crate::__in_section_crate!(@type_select $path)> = const {
425 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
426 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
427
428 $crate::__if_wasm!((
429 {
430 $crate::__register_wasm_item!(
431 movable,
432 type=__InSecStoredTy,
433 value=__LINK_SECTION_CONST_ITEM_VALUE,
434 slot=$crate::MovableRef::slot_ptr(&raw const $ident),
435 section=$section
436 );
437
438 $crate::__import_section_info!(
440 $crate::__support::wasm::LinkSectionMovableInfo,
441 __LINK_SECTION_MOVABLE_INFO,
442 $section
443 );
444
445 $crate::MovableRef::new($crate::__support::MovableRefStorage::new(::core::ptr::null(), &raw const __LINK_SECTION_MOVABLE_INFO))
446 }
447 )(
448 {
449 $crate::__add_section_link_attribute!(
450 item data section $section
451 #[link_section = __]
452 static __LINK_SECTION_CONST_ITEM: $crate::__support::SyncUnsafeCell<__InSecStoredTy> =
453 $crate::__support::SyncUnsafeCell::new(__LINK_SECTION_CONST_ITEM_VALUE);
454 );
455
456 $crate::__add_section_link_attribute!(
457 backref data section $section
458 #[link_section = __]
459 static __LINK_SECTION_MOVABLE_BACKREF: $crate::__support::SyncUnsafeCell<
460 $crate::MovableBackref<__InSecStoredTy>
461 > = $crate::__support::SyncUnsafeCell::new(
462 $crate::MovableBackref::new(
463 $crate::MovableRef::slot_ptr(&raw const $ident),
464 )
465 );
466 );
467
468 $crate::MovableRef::new($crate::__support::MovableRefStorage::new(
469 (&raw const __LINK_SECTION_CONST_ITEM)
470 .cast::<__InSecStoredTy>(),
471 ))
472 }
473 ))
474 };
475 };
476
477 (@typed[movable] $($rest:tt)*) => {
478 compile_error!("Only static items are supported in movable sections");
479 };
480
481 (@typed[$section_type:ident] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis const $ident:tt: $ty:ty = $value:expr;)) => {
483 $($meta)*
484 $vis const $ident: $ty = const {
485 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
486 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
487
488 $crate::__if_wasm!((
489 $crate::__register_wasm_item!($section_type, type=__InSecStoredTy, value=__LINK_SECTION_CONST_ITEM_VALUE, section=$section);
490 ) (
491 $crate::__add_section_link_attribute!(
492 item data section $section
493 #[link_section = __]
494 static __LINK_SECTION_CONST_ITEM: __InSecStoredTy = __LINK_SECTION_CONST_ITEM_VALUE;
495 );
496 ));
497
498 __LINK_SECTION_CONST_ITEM_VALUE
499 };
500 };
501
502 (@typed[reference] $section:tt, , $path:path, ($($meta:tt)*) ($vis:vis static $ident:ident: $ty:ty = $value:expr;)) => {
503 $crate::__if_wasm!(
504 (
505 $($meta)*
506 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = {
507 type __InSecStoredTy = $crate::__in_section_crate!(@type_select $path);
508 const __LINK_SECTION_CONST_ITEM_VALUE: __InSecStoredTy = $value;
509 $crate::__register_wasm_item!(reference, type=__InSecStoredTy, value=__LINK_SECTION_CONST_ITEM_VALUE, ref=$ident, section=$section);
510 $crate::__import_section_info!(
512 $crate::__support::wasm::LinkSectionInfo,
513 __LINK_SECTION_REF_INFO,
514 $section
515 );
516 $crate::reference::Ref::new($crate::__support::RefStorage::new(&raw const __LINK_SECTION_REF_INFO))
517 };
518 )
519 (
520 #[cfg(not(target_family="wasm"))]
522 $crate::__add_section_link_attribute!(
523 item data section $section
524 #[link_section = __]
525 $($meta)*
526 $vis static $ident: $crate::reference::Ref<$crate::__in_section_crate!(@type_select $path)> = $crate::reference::Ref::new($crate::__support::RefStorage::new($value));
527 );
528 )
529 );
530 };
531
532 ($($input:tt)*) => {
533 compile_error!(concat!("Unexpected input to __in_section_crate: ", stringify!($($input)*)));
534 };
535 }
536}
537
538#[cfg(feature = "proc_macro")]
565pub use ::linktime_proc_macro::section;
566
567#[cfg(feature = "proc_macro")]
581pub use ::linktime_proc_macro::in_section;