sel4_ctors_dtors/
lib.rs
1#![no_std]
12#![feature(linkage)]
13
14use core::mem;
15use core::ptr;
16use core::slice;
17
18type ArrayEntry = unsafe extern "C" fn();
19
20extern "C" {
21 static __preinit_array_start: ArrayEntry;
22 static __preinit_array_end: ArrayEntry;
23 static __init_array_start: ArrayEntry;
24 static __init_array_end: ArrayEntry;
25 static __fini_array_start: ArrayEntry;
26 static __fini_array_end: ArrayEntry;
27
28 fn _init();
29 fn _fini();
30}
31
32mod _weak {
33 #[linkage = "weak"]
34 #[no_mangle]
35 extern "C" fn _init() {}
36
37 #[linkage = "weak"]
38 #[no_mangle]
39 extern "C" fn _fini() {}
40}
41
42#[derive(Debug, Copy, Clone, Eq, PartialEq)]
43pub enum Error {
44 Misaligned { section_name: &'static str },
45}
46
47unsafe fn run_array(
48 start_addr: usize,
49 end_addr: usize,
50 section_name: &'static str,
51) -> Result<(), Error> {
52 if start_addr != end_addr {
53 if start_addr % mem::size_of::<ArrayEntry>() != 0
54 || end_addr % mem::size_of::<ArrayEntry>() != 0
55 {
56 return Err(Error::Misaligned { section_name });
57 }
58
59 let len = (end_addr - start_addr) / mem::size_of::<ArrayEntry>();
60 let array = slice::from_raw_parts(start_addr as *const ArrayEntry, len);
61 for entry in array {
62 (entry)();
63 }
64 }
65 Ok(())
66}
67
68fn run_preinit_array() -> Result<(), Error> {
69 unsafe {
70 run_array(
71 ptr::addr_of!(__preinit_array_start) as usize,
72 ptr::addr_of!(__preinit_array_end) as usize,
73 ".preinit_array",
74 )
75 }
76}
77
78fn run_init_array() -> Result<(), Error> {
79 unsafe {
80 run_array(
81 ptr::addr_of!(__init_array_start) as usize,
82 ptr::addr_of!(__init_array_end) as usize,
83 ".init_array",
84 )
85 }
86}
87
88fn run_fini_array() -> Result<(), Error> {
89 unsafe {
90 run_array(
91 ptr::addr_of!(__fini_array_start) as usize,
92 ptr::addr_of!(__fini_array_end) as usize,
93 ".fini_array",
94 )
95 }
96}
97
98fn run_init() {
99 unsafe { _init() }
100}
101
102fn run_fini() {
103 unsafe { _fini() }
104}
105
106pub fn run_ctors() -> Result<(), Error> {
107 run_preinit_array()?;
108 run_init();
109 run_init_array()?;
110 Ok(())
111}
112
113pub fn run_dtors() -> Result<(), Error> {
114 run_fini_array()?;
115 run_fini();
116 Ok(())
117}