#[derive(Debug, Copy, Clone)]
pub enum Section {
VectorTable,
Text,
Rodata,
Bss,
Data,
Uninit,
}
impl core::fmt::Display for Section {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.pad(match self {
Section::VectorTable => ".vector_table",
Section::Text => ".text",
Section::Rodata => ".rodata",
Section::Bss => ".bss",
Section::Data => ".data",
Section::Uninit => ".uninit",
})
}
}
impl Section {
pub fn iter() -> impl Iterator<Item = Section> {
SectionIter::new()
}
pub fn top(&self) -> *const u8 {
use core::ptr::addr_of;
unsafe extern "C" {
static __evector: u8;
static __etext: u8;
static __erodata: u8;
static __ebss: u8;
static __edata: u8;
static __euninit: u8;
}
match self {
Section::VectorTable => addr_of!(__evector),
Section::Text => addr_of!(__etext),
Section::Rodata => addr_of!(__erodata),
Section::Bss => addr_of!(__ebss),
Section::Data => addr_of!(__edata),
Section::Uninit => addr_of!(__euninit),
}
}
pub fn bottom(&self) -> *const u8 {
use core::ptr::addr_of;
unsafe extern "C" {
static __svector: u8;
static __stext: u8;
static __srodata: u8;
static __sbss: u8;
static __sdata: u8;
static __suninit: u8;
}
match self {
Section::VectorTable => addr_of!(__svector),
Section::Text => addr_of!(__stext),
Section::Rodata => addr_of!(__srodata),
Section::Bss => addr_of!(__sbss),
Section::Data => addr_of!(__sdata),
Section::Uninit => addr_of!(__suninit),
}
}
pub fn range(&self) -> Option<core::ops::Range<*const u8>> {
let bottom = self.bottom();
let top = self.top();
if bottom != top {
Some(bottom..top)
} else {
None
}
}
pub fn mpu_range(&self) -> Option<core::ops::RangeInclusive<*const u8>> {
let bottom = self.bottom();
let top = self.top();
let top_under = unsafe { top.offset(-1) };
if bottom != top {
Some(bottom..=top_under)
} else {
None
}
}
}
pub struct SectionIter {
next: Option<Section>,
}
impl SectionIter {
pub fn new() -> Self {
Self {
next: Some(Section::VectorTable),
}
}
}
impl Default for SectionIter {
fn default() -> Self {
SectionIter::new()
}
}
impl Iterator for SectionIter {
type Item = Section;
fn next(&mut self) -> Option<Self::Item> {
let current = self.next;
self.next = match self.next {
Some(Section::VectorTable) => Some(Section::Text),
Some(Section::Text) => Some(Section::Rodata),
Some(Section::Rodata) => Some(Section::Bss),
Some(Section::Bss) => Some(Section::Data),
Some(Section::Data) => Some(Section::Uninit),
Some(Section::Uninit) | None => None,
};
current
}
}