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