Write LD file

This commit is contained in:
Jaby 2022-12-01 04:02:38 +01:00 committed by Jaby
parent e4ac622a34
commit 837f431547
3 changed files with 54 additions and 15 deletions

View File

@ -2,20 +2,59 @@ use super::super::types::OverlaySlot;
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 DEFAULT_LD_SCRIPT:&'static str = r#" const OVERLAY_DEFAULT_START:&'static str = "__boot_loader_end"; // < will probably be "__boot_loader_start" later
__heap_base = __bss_end;
"#;
pub fn write(output: &mut Output, overlay_desc: &Vec<OverlaySlot>) -> Result<(), Error> { pub fn write(output: &mut Output, overlay_desc: &Vec<OverlaySlot>) -> Result<(), Error> {
if overlay_desc.is_empty() { fn create_heap_base(overlay_desc: &Vec<OverlaySlot>) -> String {
return write_default(output); let mut heap_start = format!("MAX({}, {}_end)", OVERLAY_DEFAULT_START, overlay_desc[0].name);
for slot in overlay_desc.iter().skip(1) {
heap_start = format!("MAX({}_end, {})", slot.name, heap_start);
}
heap_start
} }
format_if_error!(write!(output, "Dino\n"), "Writing test output failed with: {error_text}")?; fn get_slot_start_adr(slot: &OverlaySlot) -> &str {
if let Some(slot_adr) = &slot.start_adr {
slot_adr.as_ref()
}
else {
OVERLAY_DEFAULT_START
}
}
if overlay_desc.is_empty() {
return write_heap_base(output, OVERLAY_DEFAULT_START);
}
write_heap_base(output, &create_heap_base(overlay_desc))?;
writeln!(output, "")?;
writeln!(output, "SECTION {{")?;
for slot in overlay_desc {
writeln!(output, "\t// {}", slot.name)?;
writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", get_slot_start_adr(slot))?;
for section in &slot.sections {
writeln!(output, "\t\t.{} {{", section.name)?;
writeln!(output, "\t\t\t__{}_start = .;", section.name)?;
section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\tKEEP({}(.header)", patr))?;
writeln!(output, "\t\t\t__main_area_ctor = .;")?;
for section_type in [".text.startup._GLOBAL__*", ".ctors", ".text.*", ".rodata*", ".sdata*", ".data*", ".sbss*", ".bss*"] {
section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\t{}({})", patr, section_type))?;
}
writeln!(output, "\t\t}}")?;
}
writeln!(output, "\t}}")?;
writeln!(output, "\t{}_end = .;", slot.name)?;
writeln!(output, "")?;
}
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
writeln!(output, "}}")?;
return Ok(()); return Ok(());
} }
fn write_default(output: &mut Output) -> Result<(), Error> { fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> {
format_if_error!(output.write(DEFAULT_LD_SCRIPT.as_bytes()), "Writing default LD Script failed with: {error_text}")?; format_if_error!(writeln!(output, "__heap_base = {};", heap_base), "Writing default LD Script failed with: {error_text}")?;
Ok(()) Ok(())
} }

View File

@ -3,7 +3,7 @@ use tool_helper::{Error, open_output};
fn generate_file() -> Vec<OverlaySlot> { fn generate_file() -> Vec<OverlaySlot> {
let mut slots = Vec::new(); let mut slots = Vec::new();
let mut slot = OverlaySlot::new("slot_0".to_owned(), String::new()); let mut slot = OverlaySlot::new("slot_0".to_owned(), None);
let mut section = OverlaySection::new("main_area".to_owned()); let mut section = OverlaySection::new("main_area".to_owned());
section.add_file_pattern("bin/PSX-release/src/*.o".to_owned()); section.add_file_pattern("bin/PSX-release/src/*.o".to_owned());

View File

@ -1,7 +1,7 @@
#[derive(Debug)] #[derive(Debug)]
pub struct OverlaySection { pub struct OverlaySection {
name: String, pub(super) name: String,
file_pattern: Vec<String> pub(super) file_pattern: Vec<String>
} }
impl OverlaySection { impl OverlaySection {
@ -16,13 +16,13 @@ impl OverlaySection {
#[derive(Debug)] #[derive(Debug)]
pub struct OverlaySlot { pub struct OverlaySlot {
name: String, pub(super) name: String,
start_adr: String, pub(super) start_adr: Option<String>,
sections: Vec<OverlaySection> pub(super) sections: Vec<OverlaySection>
} }
impl OverlaySlot { impl OverlaySlot {
pub fn new(name: String, start_adr: String) -> OverlaySlot { pub fn new(name: String, start_adr: Option<String>) -> OverlaySlot {
OverlaySlot{name, start_adr, sections: Vec::new()} OverlaySlot{name, start_adr, sections: Vec::new()}
} }