Parse JSON into linker script
This commit is contained in:
parent
837f431547
commit
da2fb45442
|
@ -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/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,3 +7,4 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tool_helper = {path = "../tool_helper"}
|
tool_helper = {path = "../tool_helper"}
|
||||||
|
serde_json = "*"
|
|
@ -38,7 +38,7 @@ pub fn write(output: &mut Output, overlay_desc: &Vec<OverlaySlot>) -> Result<(),
|
||||||
writeln!(output, "\t\t.{} {{", section.name)?;
|
writeln!(output, "\t\t.{} {{", section.name)?;
|
||||||
writeln!(output, "\t\t\t__{}_start = .;", 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))?;
|
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*"] {
|
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))?;
|
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<OverlaySlot>) -> Result<(),
|
||||||
writeln!(output, "\t\t}}")?;
|
writeln!(output, "\t\t}}")?;
|
||||||
}
|
}
|
||||||
writeln!(output, "\t}}")?;
|
writeln!(output, "\t}}")?;
|
||||||
writeln!(output, "\t{}_end = .;", slot.name)?;
|
writeln!(output, "\t__{}_end = .;", slot.name)?;
|
||||||
writeln!(output, "")?;
|
writeln!(output, "")?;
|
||||||
}
|
}
|
||||||
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
|
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use mkoverlay::types::{OverlaySection, OverlaySlot};
|
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<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(), None);
|
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());
|
||||||
|
@ -15,7 +16,7 @@ fn generate_file() -> Vec<OverlaySlot> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_main() -> Result<(), Error> {
|
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)?;
|
let mut output = open_output(None)?;
|
||||||
|
|
||||||
mkoverlay::creator::ldscript::write(&mut output, &input)
|
mkoverlay::creator::ldscript::write(&mut output, &input)
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
use super::{OverlaySection, OverlaySlot};
|
||||||
|
use tool_helper::{Error, format_if_error, Input};
|
||||||
|
|
||||||
|
pub fn read_config(input: Input) -> Result<Vec<OverlaySlot>, 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<OverlaySlot, Error> {
|
||||||
|
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<OverlaySection, Error> {
|
||||||
|
fn create_pattern_error<T>(section_name: &String) -> Result<T, Error> {
|
||||||
|
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<String, Error> {
|
||||||
|
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)))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod json_reader;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OverlaySection {
|
pub struct OverlaySection {
|
||||||
pub(super) name: String,
|
pub(super) name: String,
|
||||||
|
@ -22,7 +24,16 @@ pub struct OverlaySlot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlaySlot {
|
impl OverlaySlot {
|
||||||
pub fn new(name: String, start_adr: Option<String>) -> 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()}
|
OverlaySlot{name, start_adr, sections: Vec::new()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue