Write LD file
This commit is contained in:
parent
2bcb71d0d5
commit
268642fb6b
|
@ -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(())
|
||||||
}
|
}
|
|
@ -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());
|
||||||
|
|
|
@ -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()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue