1#[derive(Debug, Copy, Clone)]
7pub enum Section {
8 VectorTable,
12 Text,
16 Rodata,
20 Bss,
24 Data,
28 Uninit,
32}
33
34impl core::fmt::Display for Section {
35 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
36 f.pad(match self {
37 Section::VectorTable => ".vector_table",
38 Section::Text => ".text",
39 Section::Rodata => ".rodata",
40 Section::Bss => ".bss",
41 Section::Data => ".data",
42 Section::Uninit => ".uninit",
43 })
44 }
45}
46
47impl Section {
48 pub fn iter() -> impl Iterator<Item = Section> {
50 SectionIter::new()
51 }
52
53 pub fn top(&self) -> *const u8 {
57 use core::ptr::addr_of;
58 unsafe extern "C" {
59 static __evector: u8;
60 static __etext: u8;
61 static __erodata: u8;
62 static __ebss: u8;
63 static __edata: u8;
64 static __euninit: u8;
65 }
66 match self {
67 Section::VectorTable => addr_of!(__evector),
68 Section::Text => addr_of!(__etext),
69 Section::Rodata => addr_of!(__erodata),
70 Section::Bss => addr_of!(__ebss),
71 Section::Data => addr_of!(__edata),
72 Section::Uninit => addr_of!(__euninit),
73 }
74 }
75
76 pub fn bottom(&self) -> *const u8 {
78 use core::ptr::addr_of;
79 unsafe extern "C" {
80 static __svector: u8;
81 static __stext: u8;
82 static __srodata: u8;
83 static __sbss: u8;
84 static __sdata: u8;
85 static __suninit: u8;
86 }
87 match self {
88 Section::VectorTable => addr_of!(__svector),
89 Section::Text => addr_of!(__stext),
90 Section::Rodata => addr_of!(__srodata),
91 Section::Bss => addr_of!(__sbss),
92 Section::Data => addr_of!(__sdata),
93 Section::Uninit => addr_of!(__suninit),
94 }
95 }
96
97 pub fn range(&self) -> Option<core::ops::Range<*const u8>> {
99 let bottom = self.bottom();
100 let top = self.top();
101 if bottom != top {
102 Some(bottom..top)
103 } else {
104 None
105 }
106 }
107
108 pub fn mpu_range(&self) -> Option<core::ops::RangeInclusive<*const u8>> {
112 let bottom = self.bottom();
113 let top = self.top();
114 let top_under = unsafe { top.offset(-1) };
115 if bottom != top {
116 Some(bottom..=top_under)
117 } else {
118 None
119 }
120 }
121}
122
123pub struct SectionIter {
125 next: Option<Section>,
126}
127
128impl SectionIter {
129 pub fn new() -> Self {
131 Self {
132 next: Some(Section::VectorTable),
133 }
134 }
135}
136
137impl Default for SectionIter {
138 fn default() -> Self {
139 SectionIter::new()
140 }
141}
142
143impl Iterator for SectionIter {
144 type Item = Section;
145
146 fn next(&mut self) -> Option<Self::Item> {
147 let current = self.next;
148 self.next = match self.next {
149 Some(Section::VectorTable) => Some(Section::Text),
150 Some(Section::Text) => Some(Section::Rodata),
151 Some(Section::Rodata) => Some(Section::Bss),
152 Some(Section::Bss) => Some(Section::Data),
153 Some(Section::Data) => Some(Section::Uninit),
154 Some(Section::Uninit) | None => None,
155 };
156 current
157 }
158}