Fix and improve mkoverlay

This commit is contained in:
Jaby 2023-01-24 22:12:37 +01:00 committed by Jaby
parent dfc8c94213
commit e59139f565
4 changed files with 35 additions and 117 deletions

View File

@ -1,33 +1,27 @@
use super::super::types::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot}; use super::super::types::{OverlayDesc, OverlaySection};
use tool_helper::{Error, format_if_error, Output}; use tool_helper::{Error, format_if_error, Output};
use std::io::Write; use std::io::Write;
const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later
macro_rules! section_end_name_template {
() => {
"__{}_end"
};
}
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> { pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
fn create_heap_base(overlay_desc: &OverlayDesc) -> String { fn create_heap_base(overlay_desc: &OverlayDesc) -> String {
let (first_entry,additional_slots_iter) = { let (first_entry, additional_slots_iter) = (&overlay_desc[0].name, overlay_desc.iter().skip(1));
if overlay_desc.boot_section.is_empty() {
(&overlay_desc.additional_slots[0].name, overlay_desc.additional_slots.iter().skip(1))
}
else { let mut heap_start = format!(concat!("MAX({}, ", section_end_name_template!(), ")"), OVERLAY_DEFAULT_START, first_entry);
(&overlay_desc.boot_section.name, overlay_desc.additional_slots.iter().skip(0))
}
};
let mut heap_start = format!("MAX({}, __{}_end)", OVERLAY_DEFAULT_START, first_entry);
for slot in additional_slots_iter { for slot in additional_slots_iter {
heap_start = format!("MAX(__{}_end, {})", slot.name, heap_start); heap_start = format!(concat!("MAX(", section_end_name_template!(), ", {})"), slot.name, heap_start);
} }
heap_start heap_start
} }
fn get_slot_start_adr(slot: &OverlaySlot) -> &str { if overlay_desc.is_empty() {
slot.start_adr.as_ref()
}
if overlay_desc.additional_slots.is_empty() && overlay_desc.boot_section.is_empty() {
write_heap_base(output, OVERLAY_DEFAULT_START)?; write_heap_base(output, OVERLAY_DEFAULT_START)?;
} }
@ -35,18 +29,21 @@ pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Erro
write_heap_base(output, &create_heap_base(&overlay_desc))?; write_heap_base(output, &create_heap_base(&overlay_desc))?;
} }
let mut slot_start_adr = format!(section_end_name_template!(), "bss");
writeln!(output, "")?; writeln!(output, "")?;
writeln!(output, "SECTIONS {{")?; writeln!(output, "SECTIONS {{")?;
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?; writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
write_first_section(output, &overlay_desc.boot_section)?; for slot in overlay_desc {
for slot in &overlay_desc.additional_slots {
writeln!(output, "\t/*{}*/", slot.name)?; writeln!(output, "\t/*{}*/", slot.name)?;
writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", get_slot_start_adr(slot))?; writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", slot_start_adr)?;
write_section(output, &slot.sections, false)?; write_section(output, &slot.sections, false)?;
writeln!(output, "\t}}")?; writeln!(output, "\t}}")?;
writeln!(output, "\t. = ALIGN(4);")?; writeln!(output, "\t. = ALIGN(4);")?;
writeln!(output, "\t__{}_end = .;", slot.name)?; writeln!(output, concat!("\t", section_end_name_template!(), " = .;"), slot.name)?;
writeln!(output, "")?; writeln!(output, "")?;
slot_start_adr = format!(section_end_name_template!(), slot.name);
} }
writeln!(output, "}}")?; writeln!(output, "}}")?;
return Ok(()); return Ok(());
@ -57,18 +54,6 @@ fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn write_first_section(output: &mut Output, boot_overlay: &BootOverlaySection) -> Result<(), Error> {
writeln!(output, "\tOVERLAY __bss_end : NOCROSSREFS SUBALIGN(4) {{")?;
writeln!(output, "\t\t/*{}*/", boot_overlay.name)?;
write_section(output, &boot_overlay.sections, true)?;
writeln!(output, "\t}}")?;
writeln!(output, "\t. = ALIGN(4);")?;
writeln!(output, "\t__{}_end = .;", boot_overlay.name)?;
writeln!(output, "")?;
Ok(())
}
fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_name: bool) -> Result<(), Error> { fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_name: bool) -> Result<(), Error> {
for section in sections { for section in sections {
writeln!(output, "\t\t.{} {{", section.name)?; writeln!(output, "\t\t.{} {{", section.name)?;
@ -83,7 +68,7 @@ fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_na
} }
if add_end_name { if add_end_name {
writeln!(output, "\t\t\t__{}_end = .;", section.name)?; writeln!(output, concat!("\t\t\t", section_end_name_template!(), " = .;"), section.name)?;
} }
writeln!(output, "\t\t}}")?; writeln!(output, "\t\t}}")?;
} }

View File

@ -2,14 +2,10 @@ use super::super::types::OverlayDesc;
use tool_helper::{Error, Output}; use tool_helper::{Error, Output};
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> { pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
if !overlay_desc.boot_section.is_empty() || !overlay_desc.additional_slots.is_empty() { if !overlay_desc.is_empty() {
write!(output, "OVERLAYSECTION = ")?; write!(output, "OVERLAYSECTION = ")?;
for section in &overlay_desc.boot_section.sections { for slot in overlay_desc {
write!(output, ".{} ", section.name)?;
}
for slot in &overlay_desc.additional_slots {
for section in &slot.sections { for section in &slot.sections {
write!(output, ".{} ", section.name)?; write!(output, ".{} ", section.name)?;
} }

View File

@ -1,29 +1,13 @@
use super::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot}; use super::{OverlayDesc, OverlaySection, OverlaySlot};
use tool_helper::{Error, format_if_error, Input}; use tool_helper::{Error, format_if_error, Input};
const FOLLOW_KEYWORD:&'static str = "following";
pub fn read_config(input: Input) -> Result<OverlayDesc, Error> { pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
let json_reader:serde_json::Value = format_if_error!(serde_json::from_reader(input), "Parsing JSON failed with: {error_text}")?; let json_reader:serde_json::Value = format_if_error!(serde_json::from_reader(input), "Parsing JSON failed with: {error_text}")?;
let mut overlay_desc = OverlayDesc::new(); let mut overlay_desc = OverlayDesc::new();
if let Some(objects) = json_reader.as_object() { if let Some(objects) = json_reader.as_object() {
for object in objects { for object in objects {
let mut slot = read_as_slot(object)?; overlay_desc.push(read_as_slot(object)?);
if overlay_desc.boot_section.is_empty() {
overlay_desc.boot_section = BootOverlaySection::new(slot.name, slot.sections);
}
else {
if let Some(prev_slot) = overlay_desc.additional_slots.last() {
slot.set_start_adr_as_end_of(prev_slot.name.as_ref());
}
else {
slot.set_start_adr_as_end_of("bss");
}
overlay_desc.additional_slots.push(slot);
}
} }
Ok(overlay_desc) Ok(overlay_desc)
@ -36,23 +20,11 @@ pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result<OverlaySlot, Error> { fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result<OverlaySlot, Error> {
let (slot_name, json_value) = json_value; let (slot_name, json_value) = json_value;
let mut slot = OverlaySlot::new(slot_name.clone(), "bss"); let mut slot = OverlaySlot::new(slot_name.clone());
if let Some(json_value) = json_value.as_object() { if let Some(json_value) = json_value.as_object() {
for (name, json_value) in json_value { for (name, json_value) in json_value {
if name == FOLLOW_KEYWORD { slot.add_section(read_as_section(name.clone(), json_value)?);
if let Some(start_adr) = json_value.as_str() {
slot.set_start_adr_as_end_of(start_adr);
}
else {
return Err(Error::from_text(format!("\"{}\" option of {} must be a string", FOLLOW_KEYWORD, slot_name)));
}
}
else {
slot.add_section(read_as_section(name.clone(), json_value)?);
}
} }
} }

View File

@ -1,34 +1,19 @@
pub mod json_reader; pub mod json_reader;
pub struct OverlayDesc { pub type OverlayDesc = Vec<OverlaySlot>;
pub(super) boot_section: BootOverlaySection,
pub(super) additional_slots: Vec<OverlaySlot> pub struct OverlaySlot {
pub(super) name: String,
pub(super) sections: Vec<OverlaySection>
} }
impl OverlayDesc { impl OverlaySlot {
pub fn new() -> OverlayDesc { pub fn new(name: String) -> OverlaySlot {
OverlayDesc{boot_section: BootOverlaySection::default(), additional_slots: Vec::new()} OverlaySlot{name, sections: Vec::new()}
}
}
pub struct BootOverlaySection {
pub(super) name: String,
pub(super) sections: Vec<OverlaySection>,
}
impl BootOverlaySection {
pub fn new(name: String, sections: Vec<OverlaySection>) -> BootOverlaySection {
BootOverlaySection{name, sections}
} }
pub fn is_empty(&self) -> bool { pub fn add_section(&mut self, section: OverlaySection) {
self.sections.is_empty() self.sections.push(section);
}
}
impl std::default::Default for BootOverlaySection {
fn default() -> Self {
BootOverlaySection{name: String::new(), sections: Vec::new()}
} }
} }
@ -45,24 +30,4 @@ impl OverlaySection {
pub fn add_file_pattern(&mut self, file_pattern: String) { pub fn add_file_pattern(&mut self, file_pattern: String) {
self.file_pattern.push(file_pattern); self.file_pattern.push(file_pattern);
} }
}
pub struct OverlaySlot {
pub(super) name: String,
pub(super) start_adr: String,
pub(super) sections: Vec<OverlaySection>
}
impl OverlaySlot {
pub fn new(name: String, start_adr: &str) -> OverlaySlot {
OverlaySlot{name, start_adr: String::from(start_adr), sections: Vec::new()}
}
pub fn set_start_adr_as_end_of(&mut self, end: &str) {
self.start_adr = format!("__{}_end", end);
}
pub fn add_section(&mut self, section: OverlaySection) {
self.sections.push(section);
}
} }