From c6c0f10143fbec44630bafa96c93d4744275b101 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 20 Dec 2022 20:34:03 +0100 Subject: [PATCH] Update mkoverlay with new overlay strategy --- lib/psexe.ld | 27 +---- src/Tools/mkoverlay/Cargo.toml | 2 +- src/Tools/mkoverlay/src/creator/ldscript.rs | 112 ++++++++++++++---- src/Tools/mkoverlay/src/creator/makefile.rs | 16 ++- .../mkoverlay/src/types/json_reader/mod.rs | 27 +++-- src/Tools/mkoverlay/src/types/mod.rs | 34 +++++- 6 files changed, 152 insertions(+), 66 deletions(-) diff --git a/lib/psexe.ld b/lib/psexe.ld index cff77471..4190335d 100644 --- a/lib/psexe.ld +++ b/lib/psexe.ld @@ -49,8 +49,6 @@ __fdata_len = (__planschi_end - __fdata_start); __stack_start = ORIGIN(ram) + LENGTH(ram); -__heap_base = __planschi_end; - SECTIONS { /DISCARD/ : { *(.MIPS.abiflags) } @@ -61,30 +59,7 @@ SECTIONS { /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.*) *(.comment) } } -SECTIONS { - __boot_loader_start = .; - __planschi_start = .; - OVERLAY __bss_end : NOCROSSREFS SUBALIGN(4) - { - .planschi - { - *libJabyEngine.a:*_boot.o(.text.startup._GLOBAL__*) - *libJabyEngine.a:*_boot.o(.ctors) - - *libJabyEngine.a:*_boot.o(.text.*) - *libJabyEngine.a:*_boot.o(.rodata*) - *libJabyEngine.a:*_boot.o(.sdata*) - *libJabyEngine.a::*_boot.o(.data*) - *libJabyEngine.a::*_boot.o(.sbss*) - *libJabyEngine.a::*_boot.o(.bss*) - *libJabyEngine.a::*_boot.o(*) - } - } - __boot_loader_end = .; - /*Only needed for the PSX BIOS to load the entire game*/ - . = ALIGN(2048); - __planschi_end = .; -} +/*Overlay sections created by mkoverlay*/ SECTIONS { .PSX_EXE_Header : { diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index 5ea17c2a..5ae6d8a8 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mkoverlay" -version = "1.0.0" +version = "1.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/mkoverlay/src/creator/ldscript.rs b/src/Tools/mkoverlay/src/creator/ldscript.rs index 7207471b..e8bac266 100644 --- a/src/Tools/mkoverlay/src/creator/ldscript.rs +++ b/src/Tools/mkoverlay/src/creator/ldscript.rs @@ -1,14 +1,23 @@ -use super::super::types::OverlaySlot; +use super::super::types::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot}; use tool_helper::{Error, format_if_error, Output}; use std::io::Write; -const OVERLAY_DEFAULT_START:&'static str = "__boot_loader_end"; // < will probably be "__boot_loader_start" later +const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later -pub fn write(output: &mut Output, overlay_desc: &Vec) -> Result<(), Error> { - fn create_heap_base(overlay_desc: &Vec) -> String { - let mut heap_start = format!("MAX({}, __{}_end)", OVERLAY_DEFAULT_START, overlay_desc[0].name); +pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> { + fn create_heap_base(overlay_desc: &OverlayDesc) -> String { + let (first_entry,additional_slots_iter) = { + if overlay_desc.boot_section.is_empty() { + (&overlay_desc.additional_slots[0].name, overlay_desc.additional_slots.iter().skip(1)) + } - for slot in overlay_desc.iter().skip(1) { + else { + (&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 { heap_start = format!("MAX(__{}_end, {})", slot.name, heap_start); } heap_start @@ -24,39 +33,94 @@ pub fn write(output: &mut Output, overlay_desc: &Vec) -> Result<(), } } - if overlay_desc.is_empty() { - return write_heap_base(output, OVERLAY_DEFAULT_START); + if overlay_desc.additional_slots.is_empty() && overlay_desc.boot_section.is_empty() { + write_heap_base(output, OVERLAY_DEFAULT_START)?; + } + + else { + write_heap_base(output, &create_heap_base(&overlay_desc))?; } - write_heap_base(output, &create_heap_base(overlay_desc))?; writeln!(output, "")?; writeln!(output, "SECTIONS {{")?; - for slot in overlay_desc { + writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?; + write_planschi_section(output, &overlay_desc.boot_section)?; + for slot in &overlay_desc.additional_slots { 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__{}_lbas = .;", section.name)?; - section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\tKEEP({}(.header.lbas))", patr))?; - writeln!(output, "\t\t\t__{}_ctor = .;", section.name)?; - - 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}}")?; - } + write_section(output, &slot.sections, false)?; writeln!(output, "\t}}")?; writeln!(output, "\t__{}_end = .;", slot.name)?; writeln!(output, "")?; } - writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?; writeln!(output, "}}")?; return Ok(()); } fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> { format_if_error!(writeln!(output, "__heap_base = {};", heap_base), "Writing default LD Script failed with: {error_text}")?; + Ok(()) +} + +fn write_planschi_section(output: &mut Output, boot_overlay: &BootOverlaySection) -> Result<(), Error> { + writeln!(output, "\tOVERLAY __bss_end : NOCROSSREFS SUBALIGN(4) {{")?; + writeln!(output, "\t\t.planschi {{")?; + writeln!(output, "\t\t\t__planschi_start = .;")?; + writeln!(output, "\t\t\t__boot_loader_start = .;")?; + writeln!(output, "")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.text.startup._GLOBAL__*)")?; + writeln!(output, "\t\t\t*_boot.o(.text.startup._GLOBAL__*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.ctors)")?; + writeln!(output, "\t\t\t*_boot.o(.ctors)")?; + writeln!(output, "")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.text.*)")?; + writeln!(output, "\t\t\t*_boot.o(.text.*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.rodata*)")?; + writeln!(output, "\t\t\t*_boot.o(.rodata*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.sdata*)")?; + writeln!(output, "\t\t\t*_boot.o(.sdata*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.data*)")?; + writeln!(output, "\t\t\t*_boot.o(.data*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.sbss*)")?; + writeln!(output, "\t\t\t*_boot.o(.sbss*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(.bss*)")?; + writeln!(output, "\t\t\t*_boot.o(.bss*)")?; + writeln!(output, "\t\t\t*libJabyEngine.a:*_boot.o(*)")?; + writeln!(output, "\t\t\t*_boot.o(*)")?; + writeln!(output, "")?; + writeln!(output, "\t\t\t__boot_loader_end = .;")?; + writeln!(output, "\t\t\t/*Only needed for the PSX BIOS to load the entire game*/")?; + writeln!(output, "\t\t\t. = ALIGN(2048);")?; + writeln!(output, "\t\t\t__planschi_end = .;")?; + writeln!(output, "\t\t}}")?; + writeln!(output, "")?; + writeln!(output, "\t\t/*{}*/", boot_overlay.name)?; + write_section(output, &boot_overlay.sections, true)?; + writeln!(output, "\t}}")?; + writeln!(output, "\t__{}_end = .;", boot_overlay.name)?; + writeln!(output, "")?; + + Ok(()) +} + +fn write_section(output: &mut Output, sections: &Vec, add_end_name: bool) -> Result<(), Error> { + for section in 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__{}_lbas = .;", section.name)?; + section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\tKEEP({}(.header.lbas))", patr))?; + writeln!(output, "\t\t\t__{}_ctor = .;", section.name)?; + + 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))?; + } + + if add_end_name { + writeln!(output, "\t\t\t__{}_end = .;", section.name)?; + } + writeln!(output, "\t\t}}")?; + } + Ok(()) } \ No newline at end of file diff --git a/src/Tools/mkoverlay/src/creator/makefile.rs b/src/Tools/mkoverlay/src/creator/makefile.rs index 8a648ebe..e2296abe 100644 --- a/src/Tools/mkoverlay/src/creator/makefile.rs +++ b/src/Tools/mkoverlay/src/creator/makefile.rs @@ -1,13 +1,17 @@ -use super::super::types::OverlaySlot; +use super::super::types::OverlayDesc; use tool_helper::{Error, Output}; -pub fn write(output: &mut Output, overlay_desc: &Vec) -> Result<(), Error> { - if !overlay_desc.is_empty() { +pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> { + if !overlay_desc.boot_section.is_empty() || !overlay_desc.additional_slots.is_empty() { write!(output, "OVERLAYSECTION = ")?; - for slot in overlay_desc { - for overlay in &slot.sections { - write!(output, ".{} ", overlay.name)?; + for section in &overlay_desc.boot_section.sections { + write!(output, ".{} ", section.name)?; + } + + for slot in &overlay_desc.additional_slots { + for section in &slot.sections { + write!(output, ".{} ", section.name)?; } } diff --git a/src/Tools/mkoverlay/src/types/json_reader/mod.rs b/src/Tools/mkoverlay/src/types/json_reader/mod.rs index 6006c880..1e2f1d1f 100644 --- a/src/Tools/mkoverlay/src/types/json_reader/mod.rs +++ b/src/Tools/mkoverlay/src/types/json_reader/mod.rs @@ -1,25 +1,38 @@ -use super::{OverlaySection, OverlaySlot}; +use super::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot}; use tool_helper::{Error, format_if_error, Input}; const FOLLOW_KEYWORD:&'static str = "following"; -pub fn read_config(input: Input) -> Result, Error> { +pub fn read_config(input: Input) -> Result { let json_reader:serde_json::Value = format_if_error!(serde_json::from_reader(input), "Parsing JSON failed with: {error_text}")?; - let mut overlay_slots = Vec::::new(); + let mut overlay_desc = OverlayDesc::new(); if let Some(objects) = json_reader.as_object() { for object in objects { let mut slot = read_as_slot(object)?; if slot.start_adr.is_none() { - if let Some(prev_slot) = overlay_slots.last() { - slot.set_start_adr_as_end_of(prev_slot.name.as_ref()); + 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("planschi"); + } + overlay_desc.additional_slots.push(slot); } } - overlay_slots.push(slot); + else { + overlay_desc.additional_slots.push(slot); + } } - Ok(overlay_slots) + Ok(overlay_desc) } else { diff --git a/src/Tools/mkoverlay/src/types/mod.rs b/src/Tools/mkoverlay/src/types/mod.rs index c68b459a..b240c8dc 100644 --- a/src/Tools/mkoverlay/src/types/mod.rs +++ b/src/Tools/mkoverlay/src/types/mod.rs @@ -1,6 +1,37 @@ pub mod json_reader; -#[derive(Debug)] +pub struct OverlayDesc { + pub(super) boot_section: BootOverlaySection, + pub(super) additional_slots: Vec +} + +impl OverlayDesc { + pub fn new() -> OverlayDesc { + OverlayDesc{boot_section: BootOverlaySection::default(), additional_slots: Vec::new()} + } +} + +pub struct BootOverlaySection { + pub(super) name: String, + pub(super) sections: Vec, +} + +impl BootOverlaySection { + pub fn new(name: String, sections: Vec) -> BootOverlaySection { + BootOverlaySection{name, sections} + } + + pub fn is_empty(&self) -> bool { + self.sections.is_empty() + } +} + +impl std::default::Default for BootOverlaySection { + fn default() -> Self { + BootOverlaySection{name: String::new(), sections: Vec::new()} + } +} + pub struct OverlaySection { pub(super) name: String, pub(super) file_pattern: Vec @@ -16,7 +47,6 @@ impl OverlaySection { } } -#[derive(Debug)] pub struct OverlaySlot { pub(super) name: String, pub(super) start_adr: Option,