Include the debug info in the rom (optionally)

This commit is contained in:
Gwilym Inzani 2024-04-03 13:33:50 +01:00
parent 4144a2be0a
commit 2475b5676a
4 changed files with 158 additions and 3 deletions

105
agb-gbafix/Cargo.lock generated
View file

@ -9,6 +9,7 @@ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"elf", "elf",
"rmp-serde",
] ]
[[package]] [[package]]
@ -65,6 +66,18 @@ version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
[[package]]
name = "autocfg"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.3" version = "4.5.3"
@ -104,12 +117,104 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rmp"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
dependencies = [
"byteorder",
"num-traits",
"paste",
]
[[package]]
name = "rmp-serde"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
dependencies = [
"byteorder",
"rmp",
"serde",
]
[[package]]
name = "serde"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "syn"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
version = "0.2.1" version = "0.2.1"

View file

@ -11,6 +11,7 @@ repository = "https://github.com/agbrs/agb"
elf = "0.7" elf = "0.7"
anyhow = "1" anyhow = "1"
clap = "4" clap = "4"
rmp-serde = "1"
[profile.dev] [profile.dev]
opt-level = 3 opt-level = 3

View file

@ -1,5 +1,5 @@
use anyhow::{anyhow, bail, ensure, Result}; use anyhow::{anyhow, bail, ensure, Result};
use std::io::Write; use std::{collections::HashMap, io::Write};
const GBA_HEADER_SIZE: usize = 192; const GBA_HEADER_SIZE: usize = 192;
@ -71,6 +71,7 @@ pub fn write_gba_file<W: Write>(
input: &[u8], input: &[u8],
mut header: GbaHeader, mut header: GbaHeader,
padding_behaviour: PaddingBehaviour, padding_behaviour: PaddingBehaviour,
include_debug: bool,
output: &mut W, output: &mut W,
) -> Result<()> { ) -> Result<()> {
let elf_file = elf::ElfBytes::<elf::endian::AnyEndian>::minimal_parse(input)?; let elf_file = elf::ElfBytes::<elf::endian::AnyEndian>::minimal_parse(input)?;
@ -80,7 +81,7 @@ pub fn write_gba_file<W: Write>(
.ok_or_else(|| anyhow!("Failed to parse as elf file"))?; .ok_or_else(|| anyhow!("Failed to parse as elf file"))?;
let mut bytes_written = 0; let mut bytes_written = 0;
for section_header in section_headers.iter() { for section_header in section_headers {
const SHT_NOBITS: u32 = 8; const SHT_NOBITS: u32 = 8;
const SHT_NULL: u32 = 0; const SHT_NULL: u32 = 0;
const SHF_ALLOC: u64 = 2; const SHF_ALLOC: u64 = 2;
@ -123,6 +124,10 @@ pub fn write_gba_file<W: Write>(
bytes_written += data.len() as u64; bytes_written += data.len() as u64;
} }
if include_debug {
bytes_written += write_debug(&elf_file, output)?;
}
if !bytes_written.is_power_of_two() && padding_behaviour == PaddingBehaviour::Pad { if !bytes_written.is_power_of_two() && padding_behaviour == PaddingBehaviour::Pad {
let required_padding = bytes_written.next_power_of_two() - bytes_written; let required_padding = bytes_written.next_power_of_two() - bytes_written;
@ -133,3 +138,38 @@ pub fn write_gba_file<W: Write>(
Ok(()) Ok(())
} }
fn write_debug<W: Write>(
elf_file: &elf::ElfBytes<'_, elf::endian::AnyEndian>,
output: &mut W,
) -> Result<u64> {
let (Some(section_headers), Some(string_table)) = elf_file.section_headers_with_strtab()?
else {
bail!("Could not find either the section headers or the string table");
};
let mut debug_sections = HashMap::new();
for section_header in section_headers {
let section_name = string_table.get(section_header.sh_name as usize)?;
if !section_name.starts_with(".debug") {
continue;
}
let (data, compression) = elf_file.section_data(&section_header)?;
if compression.is_some() {
bail!("Do not support compression in elf files, section {section_name} was compressed");
}
debug_sections.insert(section_name.to_owned(), data);
}
let mut debug_data = vec![];
rmp_serde::encode::write(&mut debug_data, &debug_sections)?;
output.write_all(&debug_data)?;
output.write_all(&(debug_data.len() as u32).to_le_bytes())?;
output.write_all(&(1u32).to_le_bytes())?;
Ok(debug_data.len() as u64 + 4)
}

View file

@ -19,6 +19,7 @@ fn main() -> Result<()> {
.arg(arg!(-m --makercode <MAKER_CODE> "Set the maker code, 2 bytes")) .arg(arg!(-m --makercode <MAKER_CODE> "Set the maker code, 2 bytes"))
.arg(arg!(-r --gameversion <VERSION> "Set the version of the game, 0-255").value_parser(value_parser!(u8))) .arg(arg!(-r --gameversion <VERSION> "Set the version of the game, 0-255").value_parser(value_parser!(u8)))
.arg(arg!(-p --padding "Pad the ROM to the next power of 2 in size")) .arg(arg!(-p --padding "Pad the ROM to the next power of 2 in size"))
.arg(arg!(-g --debug "Include debug information directly in the ROM"))
.get_matches(); .get_matches();
let input = matches.get_one::<PathBuf>("INPUT").unwrap(); let input = matches.get_one::<PathBuf>("INPUT").unwrap();
@ -70,6 +71,8 @@ fn main() -> Result<()> {
} }
} }
let include_debug = matches.get_flag("debug");
let pad = matches.get_flag("padding"); let pad = matches.get_flag("padding");
let pad = if pad { let pad = if pad {
PaddingBehaviour::Pad PaddingBehaviour::Pad
@ -80,7 +83,13 @@ fn main() -> Result<()> {
let mut output = BufWriter::new(fs::File::create(output)?); let mut output = BufWriter::new(fs::File::create(output)?);
let file_data = fs::read(input)?; let file_data = fs::read(input)?;
write_gba_file(file_data.as_slice(), header, pad, &mut output)?; write_gba_file(
file_data.as_slice(),
header,
pad,
include_debug,
&mut output,
)?;
output.flush()?; output.flush()?;