1#![doc = include_str!("../README.md")]
2#![allow(unsafe_code)]
3
4pub mod declarative {
11 pub use crate::__in_section_parse as in_section;
12 pub use crate::__section_parse as section;
13}
14
15#[doc(hidden)]
16pub mod __support {
17 pub use crate::__add_section_link_attribute as add_section_link_attribute;
18 pub use crate::__def_section_name as def_section_name;
19 pub use crate::__in_section_crate as in_section_crate;
20 pub use crate::__in_section_parse as in_section_parse;
21 pub use crate::__section_parse as section_parse;
22
23 #[cfg(feature = "proc_macro")]
24 pub use link_section_proc_macro::hash;
25 #[cfg(feature = "proc_macro")]
26 pub use link_section_proc_macro::ident_concat;
27
28 #[macro_export]
30 #[doc(hidden)]
31 macro_rules! __def_section_name {
32 (
33 {$(
34 $__section:ident $__type:ident => $__prefix:tt __ $__suffix:tt;
35 )*}
36
37 MAX_LENGTH = $__max_length:literal;
38 HASH_LENGTH = $__hash_length:literal;
39 VALID_SECTION_CHARS = $__valid_section_chars:literal;
40 ) => {
41 #[macro_export]
43 #[doc(hidden)]
44 macro_rules! __section_name {
45 $(
46 (raw $__section $__type $name:ident) => {
47 concat!(concat! $__prefix, stringify!($name), concat! $__suffix);
48 };
49 ($pattern:tt $__section $__type $name:ident) => {
50 $crate::__support::hash!($pattern $name ($__prefix) ($__suffix) $__hash_length $__max_length $__valid_section_chars);
51 };
52 )*
53 ($pattern:tt $unknown_section:ident $unknown_type:ident $name:ident) => {
54 const _: () = {
55 compile_error!("Unknown section type: `{}`/`{}`", stringify!($unknown_section), stringify!($unknown_type));
56 };
57 };
58 }
59 };
60 }
61
62 #[cfg(feature = "proc_macro")]
63 #[doc(hidden)]
64 #[macro_export]
65 macro_rules! __add_section_link_attribute(
66 ($section:ident $type:ident $name:ident #[$attr:ident = __] $item:item) => {
67 $crate::__section_name!(
68 (#[$attr = __] #[allow(unsafe_code)] $item)
69 $section $type $name
70 );
71 }
72 );
73
74 #[cfg(not(feature = "proc_macro"))]
75 #[doc(hidden)]
76 #[macro_export]
77 macro_rules! __add_section_link_attribute(
78 ($section:ident $type:ident $name:ident #[$attr:ident = __] $item:item) => {
79 #[$attr = $crate::__section_name!(
80 raw $section $type $name
81 )] $item
82 }
83 );
84
85 #[cfg(target_vendor = "apple")]
87 def_section_name! {
88 {
89 data bare => ("__DATA,") __ ();
90 code bare => ("__TEXT,") __ ();
91 data section => ("__DATA,") __ (",regular,no_dead_strip");
92 code section => ("__TEXT,") __ (",regular,no_dead_strip");
93 data start => ("\x01section$start$__DATA$") __ ();
94 data end => ("\x01section$end$__DATA$") __ ();
95 }
96 MAX_LENGTH = 16;
97 HASH_LENGTH = 6;
98 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
99 }
100
101 #[cfg(target_family = "wasm")]
102 def_section_name! {
103 {
104 data bare => (".data", ".link_section.") __ ();
105 data section => (".data", ".link_section.") __ ();
106 code bare => (".text", ".link_section.") __ ();
107 code section => (".text", ".link_section.") __ ();
108 }
109 MAX_LENGTH = 16;
110 HASH_LENGTH = 6;
111 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
112 }
113
114 #[cfg(all(
115 not(target_vendor = "apple"),
116 not(target_vendor = "pc"),
117 not(target_family = "wasm")
118 ))]
119 def_section_name! {
120 {
121 data bare => ("_data", "_link_section_") __ ();
122 data section => ("_data", "_link_section_") __ ();
123 data start => ("__start_", "_data", "_link_section_") __ ();
124 data end => ("__stop_", "_data", "_link_section_") __ ();
125 code bare => ("_text", "_link_section_") __ ();
126 code section => ("_text", "_link_section_") __ ();
127 code start => ("__start_", "_text", "_link_section_") __ ();
128 code end => ("__stop_", "_text", "_link_section_") __ ();
129 }
130 MAX_LENGTH = 64;
131 HASH_LENGTH = 10;
132 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
133 }
134
135 #[cfg(target_vendor = "pc")]
136 def_section_name! {
137 {
138 data bare => (".data", "$") __ ();
139 data section => (".data", "$") __ ("$b");
140 data start => (".data", "$") __ ("$a");
141 data end => (".data", "$") __ ("$c");
142 code bare => (".text", "$") __ ();
143 code section => (".text", "$") __ ("$b");
144 code start => (".text", "$") __ ("$a");
145 code end => (".text", "$") __ ("$c");
146 }
147 MAX_LENGTH = 64;
148 HASH_LENGTH = 10;
149 VALID_SECTION_CHARS = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
150 }
151
152 #[macro_export]
154 #[doc(hidden)]
155 macro_rules! __section_parse {
156 (#[section] $(#[$meta:meta])* $vis:vis static $ident:ident : $(:: $path_prefix:ident ::)? $($path:ident)::* < $($generic:tt)*) => {
158 $crate::__section_parse!(@parsed #[section] $(#[$meta])* $vis static $ident: ( $(:: $path_prefix ::)? $($path)::* < $($generic)*) ( $($generic)* ) __in_section_helper_macro_generic);
159 };
160 (#[section] $(#[$meta:meta])* $vis:vis static $ident:ident : $(:: $path_prefix:ident ::)? $($path:ident)::* ;) => {
162 $crate::__section_parse!(@parsed #[section] $(#[$meta])* $vis static $ident: ( $(:: $path_prefix ::)? $($path)::* ;) ( () > ; ) __in_section_helper_macro_no_generic);
163 };
164 (@parsed #[section] $(#[$meta:meta])* $vis:vis static $ident:ident : ($ty:ty ;) ( $generic_ty:ty > ; ) $generic_macro:ident) => {
166 #[doc(hidden)]
169 $vis use $crate::$generic_macro as $ident;
170
171 $crate::__section_parse!(@generate #[section] $(#[$meta])* $vis static $ident: $ty, $generic_ty, $generic_macro);
172 };
173 (@generate #[section] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, __in_section_helper_macro_generic) => {
174 $crate::__section_parse!(@generate #[section] $(#[$meta])* $vis static $ident: $ty, $generic_ty, __base_case__);
175
176 impl ::core::iter::IntoIterator for $ident {
177 type Item = &'static $generic_ty;
178 type IntoIter = ::core::slice::Iter<'static, $generic_ty>;
179 fn into_iter(self) -> Self::IntoIter {
180 $ident.as_slice().iter()
181 }
182 }
183 };
184 (@generate #[section] $(#[$meta:meta])* $vis:vis static $ident:ident : $ty:ty, $generic_ty:ty, $generic_macro:ident) => {
185 $(#[$meta])*
186 #[allow(non_camel_case_types)]
187 $vis struct $ident;
188
189 impl $crate::__support::SectionFactory for $ident {
190 type SectionType = $crate::__support::Section< $ty, $generic_ty >;
191 type ItemType = $generic_ty;
192 }
193
194 impl $crate::__support::SectionItemType for $ident {
195 type Item = $generic_ty;
196 }
197
198 impl ::core::fmt::Debug for $ident {
199 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
200 ::core::ops::Deref::deref(self).fmt(f)
201 }
202 }
203
204 impl ::core::ops::Deref for $ident {
205 type Target = $ty;
206 fn deref(&self) -> &Self::Target {
207 #[cfg(miri)]
209 static SECTION: $crate::__support::Section< $ty, $generic_ty > = {
210 $crate::__support::Section::new(
211 {
212 let name = $crate::__section_name!(
213 raw data bare $ident
214 );
215 name
216 },
217 std::ptr::null_mut(),
218 std::ptr::null_mut(),
219 )
220 };
221
222 #[cfg(all(not(miri), target_family = "wasm"))]
223 static SECTION: $crate::__support::Section< $ty, $generic_ty > = {
224 static __START: ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>> = unsafe {
225 ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>>::new(::core::ptr::null_mut())
226 };
227 static __END: ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>> = unsafe {
228 ::core::sync::atomic::AtomicPtr::<::core::marker::PhantomData<$generic_ty>>::new(::core::ptr::null_mut())
229 };
230
231 $crate::__support::ident_concat!((#[no_mangle]pub extern "C" fn) (register_link_section_ $ident) ((data_ptr: *const u8, data_len: usize) {
232 unsafe {
233 __START.store(data_ptr as *mut ::core::marker::PhantomData<$generic_ty>, ::core::sync::atomic::Ordering::Relaxed);
234 __END.store(data_ptr.add(data_len) as *mut ::core::marker::PhantomData<$generic_ty>, ::core::sync::atomic::Ordering::Relaxed);
235 }
236 }));
237
238 $crate::__support::Section::new(
239 {
240 let name = $crate::__section_name!(
241 raw data bare $ident
242 );
243 name
244 },
245 &__START,
246 &__END,
247 )
248 };
249
250 #[cfg(all(not(miri), not(target_family = "wasm")))]
251 static SECTION: $crate::__support::Section< $ty, $generic_ty > = $crate::__support::Section::new(
252 {
253 let name = $crate::__section_name!(
254 raw data bare $ident
255 );
256 name
257 },
258 {
259 #[cfg(not(target_vendor = "pc"))]
260 extern "C" {
261 $crate::__support::add_section_link_attribute!(
262 data start $ident
263 #[link_name = __]
264 static __START: $crate::__support::SectionPtr<$generic_ty>;
265 );
266 }
267
268 #[cfg(target_vendor = "pc")]
270 $crate::__support::add_section_link_attribute!(
271 data start $ident
272 #[link_section = __]
273 static __START: [$generic_ty; 0] = [];
274 );
275
276 unsafe { &raw const __START as $crate::__support::SectionPtr<$generic_ty> }
277 },
278 {
279 #[cfg(not(target_vendor = "pc"))]
280 extern "C" {
281 $crate::__support::add_section_link_attribute!(
282 data end $ident
283 #[link_name = __]
284 static __END: $crate::__support::SectionPtr<$generic_ty>;
285 );
286 }
287
288 #[cfg(target_vendor = "pc")]
289 $crate::__support::add_section_link_attribute!(
290 data end $ident
291 #[link_section = __]
292 static __END: [$generic_ty; 0] = [];
293 );
294
295 unsafe { &raw const __END as $crate::__support::SectionPtr<$generic_ty> }
296 },
297 );
298
299 &SECTION
300 }
301 }
302
303 };
304 }
305
306 #[macro_export]
308 #[doc(hidden)]
309 macro_rules! __in_section_parse {
310 (#[in_section( $($path:tt)* )] $($item:tt)*) => {
317 $crate::__support::in_section_parse!(path=[$($path)*] #[in_section($($path)*)] $($item)*);
318 };
319 (path=[$orig_path:path] #[in_section($name:ident)] $($item:tt)*) => {
320 $orig_path ! (
321 v=0 (name=$name (path=[$orig_path] (item=($($item)*) ())))
322 );
323 };
324 (path=[$orig_path:path] #[in_section(:: $($path:ident)::*)] $($item:tt)*) => {
325 $crate::__support::in_section_parse!(path=[$orig_path] #[in_section($($path)::*)] $($item)*);
326 };
327 (path=[$orig_path:path] #[in_section($prefix:ident :: $($path:ident)::*)] $($item:tt)*) => {
328 $crate::__support::in_section_parse!(path=[$orig_path] #[in_section($($path)::*)] $($item)*);
329 };
330 }
331
332 #[macro_export]
333 #[doc(hidden)]
334 macro_rules! __in_section_helper_macro_generic {
335 (v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) => {
336 $crate::__support::in_section_crate!($ident, $path, generic, $item);
337 };
338 (v=$v:literal $rest:tt) => {
339 const _: () = {
340 compile_error!(concat!(
341 "link-section: Unsupported version: `",
342 stringify!($v),
343 "`: ",
344 stringify!($rest)
345 ));
346 };
347 };
348 }
349
350 #[macro_export]
351 #[doc(hidden)]
352 macro_rules! __in_section_helper_macro_no_generic {
353 (v=0 (name=$ident:ident (path=[$path:path] (item=$item:tt $rest:tt)))) => {
354 $crate::__support::in_section_crate!($ident, $path, no_generic, $item);
355 };
356 (v=$v:literal $rest:tt) => {
357 const _: () = {
358 compile_error!(concat!(
359 "link-section: Unsupported version: `",
360 stringify!($v),
361 "`: ",
362 stringify!($rest)
363 ));
364 };
365 };
366 }
367
368 #[macro_export]
369 #[doc(hidden)]
370 #[allow(unknown_lints, edition_2024_expr_fragment_specifier)]
371 macro_rules! __in_section_crate {
372 ($ident:ident, $path:path, generic, ($(#[$meta:meta])* $vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? $body:block)) => {
373 $crate::__add_section_link_attribute!(
374 data section $ident
375 #[link_section = __]
376 $(#[$meta])*
378 #[used]
379 #[allow(non_upper_case_globals)]
380 $vis static $ident_fn: <$path as $crate::__support::SectionItemType>::Item =
381 {
382 fn $ident_fn($($args)*) $(-> $ret)? $body
383 $ident_fn as _
384 };
385 );
386 };
387 ($ident:ident, $path:path, generic, ($(#[$meta:meta])* $vis:vis static _ : $ty:ty = $value:expr;)) => {
388 const _: () = {
389 $crate::__add_section_link_attribute!(
390 data section $ident
391 #[link_section = __]
392 $(#[$meta])* #[used] $vis static ANONYMOUS: <$path as $crate::__support::SectionItemType>::Item = $value;
393 );
394 };
395 };
396 ($ident:ident, $path:path, generic, ($(#[$meta:meta])* $vis:vis static $ident_static:ident : $ty:ty = $value:expr;)) => {
397 $crate::__add_section_link_attribute!(
398 data section $ident
399 #[link_section = __]
400 $(#[$meta])* #[used] $vis static $ident_static: <$path as $crate::__support::SectionItemType>::Item = $value;
401 );
402 };
403 ($ident:ident, $path:path, no_generic, ($(#[$meta:meta])* $vis:vis fn $ident_fn:ident($($args:tt)*) $(-> $ret:ty)? $body:block)) => {
404 $crate::__add_section_link_attribute!(
405 data section $ident
406 #[link_section = __]
407 $(#[$meta])*
408 #[used]
409 #[allow(non_upper_case_globals)]
410 $vis static $ident_fn: fn($($args)*) $(-> $ret)? =
411 {
412 $crate::__section_name!(
413 (#[link_section = __] fn $ident_fn($($args)*) $(-> $ret)? $body)
414 code section $ident
415 );
416 $ident_fn
417 };
418 );
419 };
420 ($ident:ident, $path:path, no_generic, ($(#[$meta:meta])* $item:item)) => {
421 $crate::__add_section_link_attribute!(
422 data section $ident
423 #[link_section = __]
424 $(#[$meta])* #[used] $item
425 );
426 };
427 }
428
429 pub trait SectionItemType {
430 type Item;
431 }
432
433 pub trait SectionFactory {
434 type SectionType;
435 type ItemType;
436 }
437
438 #[repr(C)]
439 pub struct Section<T: sealed::FromRawSection, S: 'static> {
440 name: &'static str,
441 start: SectionPtr<S>,
442 end: SectionPtr<S>,
443 _t: ::core::marker::PhantomData<T>,
444 }
445
446 impl<T> SectionItemType for super::TypedSection<T> {
447 type Item = T;
448 }
449
450 impl<T: sealed::FromRawSection, S> Section<T, S> {
451 pub const fn new(name: &'static str, start: SectionPtr<S>, end: SectionPtr<S>) -> Self {
452 Self {
453 name,
454 start,
455 end,
456 _t: ::core::marker::PhantomData,
457 }
458 }
459 }
460
461 impl<'a, T: sealed::FromRawSection, S> ::core::iter::IntoIterator for &'a Section<T, S>
462 where
463 for<'b> &'b T: ::core::iter::IntoIterator,
464 {
465 type Item = <&'a T as ::core::iter::IntoIterator>::Item;
466 type IntoIter = <&'a T as ::core::iter::IntoIterator>::IntoIter;
467 fn into_iter(self) -> Self::IntoIter {
468 ::core::ops::Deref::deref(self).into_iter()
469 }
470 }
471
472 impl<T: sealed::FromRawSection, S> ::core::ops::Deref for Section<T, S> {
473 type Target = T;
474 fn deref(&self) -> &Self::Target {
475 unsafe { ::core::mem::transmute(self) }
477 }
478 }
479
480 impl<T: sealed::FromRawSection + ::core::fmt::Debug, S> ::core::fmt::Debug for Section<T, S> {
481 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
482 ::core::fmt::Debug::fmt(::core::ops::Deref::deref(self), f)
483 }
484 }
485
486 unsafe impl<T: sealed::FromRawSection, S> Sync for Section<T, S> {}
487 unsafe impl<T: sealed::FromRawSection, S> Send for Section<T, S> {}
488
489 #[cfg(all(not(target_vendor = "pc"), not(target_family = "wasm")))]
492 pub type SectionPtr<T> = *const ::core::marker::PhantomData<T>;
493 #[cfg(target_vendor = "pc")]
497 pub type SectionPtr<T> = *const [T; 0];
498 #[cfg(target_family = "wasm")]
500 pub type SectionPtr<T> =
501 &'static ::core::sync::atomic::AtomicPtr<::core::marker::PhantomData<T>>;
502
503 mod sealed {
504 pub trait FromRawSection {}
505
506 impl FromRawSection for crate::Section {}
507
508 impl<T> FromRawSection for crate::TypedSection<T> {}
509 }
510}
511
512#[cfg(feature = "proc_macro")]
527pub use ::link_section_proc_macro::section;
528
529#[cfg(feature = "proc_macro")]
536pub use ::link_section_proc_macro::in_section;
537
538#[repr(C)]
541pub struct Section {
542 name: &'static str,
543 start: __support::SectionPtr<()>,
544 end: __support::SectionPtr<()>,
545}
546
547#[cfg(target_family = "wasm")]
548impl Section {
549 pub fn start_ptr(&self) -> *const () {
551 let ptr = self.start.load(::core::sync::atomic::Ordering::Relaxed) as *const ();
552 if ptr.is_null() {
553 panic!(
554 "Section {} was not initialized by the host environment",
555 self.name
556 );
557 }
558 ptr
559 }
560 pub fn end_ptr(&self) -> *const () {
562 let ptr = self.end.load(::core::sync::atomic::Ordering::Relaxed) as *const ();
563 if ptr.is_null() {
564 panic!(
565 "Section {} was not initialized by the host environment",
566 self.name
567 );
568 }
569 ptr
570 }
571 pub fn byte_len(&self) -> usize {
573 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
574 }
575}
576
577#[cfg(not(target_family = "wasm"))]
578impl Section {
579 pub const fn start_ptr(&self) -> *const () {
581 self.start as *const ()
582 }
583 pub const fn end_ptr(&self) -> *const () {
585 self.end as *const ()
586 }
587 pub const fn byte_len(&self) -> usize {
589 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
590 }
591}
592
593impl ::core::fmt::Debug for Section {
594 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
595 f.debug_struct("Section")
596 .field("name", &self.name)
597 .field("start", &self.start_ptr())
598 .field("end", &self.end_ptr())
599 .field("byte_len", &self.byte_len())
600 .finish()
601 }
602}
603
604unsafe impl Sync for Section {}
605unsafe impl Send for Section {}
606
607#[repr(C)]
610pub struct TypedSection<T: 'static> {
611 name: &'static str,
612 start: __support::SectionPtr<T>,
613 end: __support::SectionPtr<T>,
614 _phantom: ::core::marker::PhantomData<T>,
615}
616
617#[cfg(target_family = "wasm")]
618impl<T: 'static> TypedSection<T> {
619 pub const fn stride(&self) -> usize {
621 assert!(
622 ::core::mem::size_of::<T>() > 0
623 && ::core::mem::size_of::<T>() * 2 == ::core::mem::size_of::<[T; 2]>()
624 );
625 ::core::mem::size_of::<T>()
626 }
627
628 pub fn start_ptr(&self) -> *const T {
630 let ptr = self.start.load(::core::sync::atomic::Ordering::Relaxed) as *const T;
631 if ptr.is_null() {
632 panic!(
633 "TypedSection {} was not initialized by the host environment",
634 self.name
635 );
636 }
637 ptr
638 }
639
640 pub fn end_ptr(&self) -> *const T {
642 let ptr = self.end.load(::core::sync::atomic::Ordering::Relaxed) as *const T;
643 if ptr.is_null() {
644 panic!(
645 "TypedSection {} was not initialized by the host environment",
646 self.name
647 );
648 }
649 ptr
650 }
651
652 pub fn byte_len(&self) -> usize {
654 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
655 }
656
657 pub fn len(&self) -> usize {
659 self.byte_len() / self.stride()
660 }
661
662 pub fn is_empty(&self) -> bool {
664 self.len() == 0
665 }
666
667 pub fn as_slice(&self) -> &[T] {
669 if self.is_empty() {
670 &[]
671 } else {
672 unsafe { ::core::slice::from_raw_parts(self.start_ptr(), self.len()) }
673 }
674 }
675}
676
677#[cfg(not(target_family = "wasm"))]
678impl<T: 'static> TypedSection<T> {
679 pub const fn stride(&self) -> usize {
681 assert!(
682 ::core::mem::size_of::<T>() > 0
683 && ::core::mem::size_of::<T>() * 2 == ::core::mem::size_of::<[T; 2]>()
684 );
685 ::core::mem::size_of::<T>()
686 }
687
688 pub const fn start_ptr(&self) -> *const T {
690 self.start as *const T
691 }
692
693 pub const fn end_ptr(&self) -> *const T {
695 self.end as *const T
696 }
697
698 pub const fn byte_len(&self) -> usize {
700 unsafe { (self.end_ptr() as *const u8).offset_from(self.start_ptr() as *const u8) as usize }
701 }
702
703 pub const fn len(&self) -> usize {
705 self.byte_len() / self.stride()
706 }
707
708 pub const fn is_empty(&self) -> bool {
710 self.len() == 0
711 }
712
713 pub const fn as_slice(&self) -> &[T] {
715 if self.is_empty() {
716 &[]
717 } else {
718 unsafe { ::core::slice::from_raw_parts(self.start_ptr(), self.len()) }
719 }
720 }
721
722 #[allow(clippy::mut_from_ref)]
729 pub unsafe fn as_mut_slice(&self) -> &mut [T] {
730 if self.is_empty() {
731 &mut []
732 } else {
733 unsafe { ::core::slice::from_raw_parts_mut(self.start_ptr() as *mut T, self.len()) }
734 }
735 }
736}
737
738impl<'a, T> ::core::iter::IntoIterator for &'a TypedSection<T> {
739 type Item = &'a T;
740 type IntoIter = ::core::slice::Iter<'a, T>;
741 fn into_iter(self) -> Self::IntoIter {
742 self.as_slice().iter()
743 }
744}
745
746impl<T> ::core::ops::Deref for TypedSection<T> {
747 type Target = [T];
748 fn deref(&self) -> &Self::Target {
749 self.as_slice()
750 }
751}
752
753impl<T> ::core::fmt::Debug for TypedSection<T> {
754 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
755 f.debug_struct("TypedSection")
756 .field("name", &self.name)
757 .field("start", &self.start_ptr())
758 .field("end", &self.end_ptr())
759 .field("len", &self.len())
760 .field("stride", &self.stride())
761 .finish()
762 }
763}
764
765unsafe impl<T> Sync for TypedSection<T> where T: Sync {}
766unsafe impl<T> Send for TypedSection<T> where T: Send {}