From 897969467ff661300dc6ae950b90c94604b2a3a4 Mon Sep 17 00:00:00 2001 From: Jaby Date: Sat, 3 Dec 2022 02:55:12 +0100 Subject: [PATCH] Parse JSON into linker script --- src/Tools/Tests/Overlay.json | 16 ++++ src/Tools/mkoverlay/Cargo.toml | 3 +- src/Tools/mkoverlay/src/creator/ldscript.rs | 4 +- src/Tools/mkoverlay/src/main.rs | 7 +- .../mkoverlay/src/types/json_reader/mod.rs | 84 +++++++++++++++++++ src/Tools/mkoverlay/src/types/mod.rs | 13 ++- 6 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 src/Tools/Tests/Overlay.json create mode 100644 src/Tools/mkoverlay/src/types/json_reader/mod.rs diff --git a/src/Tools/Tests/Overlay.json b/src/Tools/Tests/Overlay.json new file mode 100644 index 00000000..58fd7144 --- /dev/null +++ b/src/Tools/Tests/Overlay.json @@ -0,0 +1,16 @@ +{ + "slot_0": { + "main_area": { + "pattern": ["bin/PSX-release/src/*.o"] + }, + "main_area2": { + "pattern": ["Wuffi/*", "Knuffi/*"] + } + }, + "slot_1": { + "following": "slot_0", + "blubb": { + "pattern": ["cody/*"] + } + } +} \ No newline at end of file diff --git a/src/Tools/mkoverlay/Cargo.toml b/src/Tools/mkoverlay/Cargo.toml index f5e04de4..f9eea239 100644 --- a/src/Tools/mkoverlay/Cargo.toml +++ b/src/Tools/mkoverlay/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tool_helper = {path = "../tool_helper"} \ No newline at end of file +tool_helper = {path = "../tool_helper"} +serde_json = "*" \ No newline at end of file diff --git a/src/Tools/mkoverlay/src/creator/ldscript.rs b/src/Tools/mkoverlay/src/creator/ldscript.rs index 4a2592fa..43cf4fed 100644 --- a/src/Tools/mkoverlay/src/creator/ldscript.rs +++ b/src/Tools/mkoverlay/src/creator/ldscript.rs @@ -38,7 +38,7 @@ pub fn write(output: &mut Output, overlay_desc: &Vec) -> Result<(), 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 = .;")?; + 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))?; @@ -46,7 +46,7 @@ pub fn write(output: &mut Output, overlay_desc: &Vec) -> Result<(), writeln!(output, "\t\t}}")?; } writeln!(output, "\t}}")?; - writeln!(output, "\t{}_end = .;", slot.name)?; + writeln!(output, "\t__{}_end = .;", slot.name)?; writeln!(output, "")?; } writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?; diff --git a/src/Tools/mkoverlay/src/main.rs b/src/Tools/mkoverlay/src/main.rs index 3f91e7e0..680d2827 100644 --- a/src/Tools/mkoverlay/src/main.rs +++ b/src/Tools/mkoverlay/src/main.rs @@ -1,7 +1,8 @@ use mkoverlay::types::{OverlaySection, OverlaySlot}; -use tool_helper::{Error, open_output}; +use tool_helper::{Error, open_input, open_output}; +use std::path::PathBuf; -fn generate_file() -> Vec { +fn _generate_file() -> Vec { let mut slots = Vec::new(); let mut slot = OverlaySlot::new("slot_0".to_owned(), None); let mut section = OverlaySection::new("main_area".to_owned()); @@ -15,7 +16,7 @@ fn generate_file() -> Vec { } fn run_main() -> Result<(), Error> { - let input = generate_file(); + let input = mkoverlay::types::json_reader::read_config(open_input(Some(PathBuf::from("../Tests/Overlay.json")))?)?; let mut output = open_output(None)?; mkoverlay::creator::ldscript::write(&mut output, &input) diff --git a/src/Tools/mkoverlay/src/types/json_reader/mod.rs b/src/Tools/mkoverlay/src/types/json_reader/mod.rs new file mode 100644 index 00000000..fc18adf0 --- /dev/null +++ b/src/Tools/mkoverlay/src/types/json_reader/mod.rs @@ -0,0 +1,84 @@ +use super::{OverlaySection, OverlaySlot}; +use tool_helper::{Error, format_if_error, Input}; + +pub fn read_config(input: Input) -> Result, Error> { + 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(); + + if let Some(objects) = json_reader.as_object() { + for object in objects { + overlay_slots.push(read_as_slot(object)?); + } + + Ok(overlay_slots) + } + + else { + Err(Error::from_str("JSON must start with an object")) + } +} + +fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result { + let (slot_name, json_value) = json_value; + let mut slot = OverlaySlot::new(slot_name.clone(), None); + + if let Some(json_value) = json_value.as_object() { + for (name, json_value) in json_value { + if name == "following" { + if let Some(start_adr) = json_value.as_str() { + slot.start_adr = Some(format!("__{}_end", start_adr)); + } + + else { + return Err(Error::from_text(format!("\"following\" option of {} must be a string", slot_name))); + } + } + + else { + slot.add_section(read_as_section(name.clone(), json_value)?); + } + } + } + + Ok(slot) +} + +fn read_as_section(section_name: String, json_value: &serde_json::Value) -> Result { + fn create_pattern_error(section_name: &String) -> Result { + Err(Error::from_text(format!("Pattern element of section declaration \"{}\" must contain only strings", section_name))) + } + + fn read_pattern(section_name: &String, json_value: &serde_json::Value) -> Result { + if let Some(pattern) = json_value.as_str() { + Ok(pattern.to_owned()) + } + + else { + create_pattern_error(section_name) + } + } + + let mut section = OverlaySection::new(section_name); + + if let Some(pattern_json) = json_value.get("pattern") { + if let Some(pattern) = pattern_json.as_array() { + for cur_pattern in pattern { + section.add_file_pattern(read_pattern(§ion.name, cur_pattern)?); + } + Ok(section) + } + + else if let Some(pattern) = pattern_json.as_str() { + section.add_file_pattern(pattern.to_owned()); + Ok(section) + } + + else { + create_pattern_error(§ion.name) + } + } + + else { + Err(Error::from_text(format!("Section declaration \"{}\" does not contain any pattern!", section.name))) + } +} \ No newline at end of file diff --git a/src/Tools/mkoverlay/src/types/mod.rs b/src/Tools/mkoverlay/src/types/mod.rs index d72cf54f..cd637cdc 100644 --- a/src/Tools/mkoverlay/src/types/mod.rs +++ b/src/Tools/mkoverlay/src/types/mod.rs @@ -1,3 +1,5 @@ +pub mod json_reader; + #[derive(Debug)] pub struct OverlaySection { pub(super) name: String, @@ -22,7 +24,16 @@ pub struct OverlaySlot { } impl OverlaySlot { - pub fn new(name: String, start_adr: Option) -> OverlaySlot { + pub fn new(name: String, start_adr: Option<&str>) -> OverlaySlot { + let start_adr = { + if let Some(str) = start_adr { + Some(str.to_owned()) + } + + else { + None + } + }; OverlaySlot{name, start_adr, sections: Vec::new()} }