Parse JSON into linker script
This commit is contained in:
parent
268642fb6b
commit
897969467f
|
@ -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]
|
||||
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\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<OverlaySlot>) -> 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)}}")?;
|
||||
|
|
|
@ -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<OverlaySlot> {
|
||||
fn _generate_file() -> Vec<OverlaySlot> {
|
||||
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<OverlaySlot> {
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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)]
|
||||
pub struct OverlaySection {
|
||||
pub(super) name: String,
|
||||
|
@ -22,7 +24,16 @@ pub struct 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()}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue