mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-06-12 09:33:30 +00:00
Allow specifying replacement bytes in dtk extab clean (#103)
* Allow specifying replacement bytes in dtk extab clean * Simplify extab padding replacement * Reword log message * clippy has bad taste * Don't specify revision number for cwextab --------- Co-authored-by: Amber Brault <celestialamber1@gmail.com>
This commit is contained in:
parent
9cafb77d3f
commit
5e33fea49f
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -339,9 +339,9 @@ checksum = "c2e06f9bce634a3c898eb1e5cb949ff63133cbb218af93cc9b38b31d6f3ea285"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cwextab"
|
name = "cwextab"
|
||||||
version = "1.1.0"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "701f6867c92e1b64ddcc4b416194be3121b8f7ba5352a70ed5fd3295a7d8e0e1"
|
checksum = "9dd95393b8cc20937e4757d9c22b89d016613e934c60dcb073bd8a5aade79fcf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
@ -838,7 +838,7 @@ fn load_dol_module(
|
|||||||
};
|
};
|
||||||
if config.clean_extab.unwrap_or(false) {
|
if config.clean_extab.unwrap_or(false) {
|
||||||
log::debug!("Cleaning extab for {}", config.name());
|
log::debug!("Cleaning extab for {}", config.name());
|
||||||
clean_extab(&mut obj)?;
|
clean_extab(&mut obj, std::iter::empty())?;
|
||||||
}
|
}
|
||||||
Ok((obj, object_path))
|
Ok((obj, object_path))
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,18 @@ enum SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||||
/// Rewrites extab data in a DOL or ELF file, zeroing out any uninitialized padding bytes.
|
/// Rewrites extab data in a DOL or ELF file, replacing any uninitialized padding bytes.
|
||||||
#[argp(subcommand, name = "clean")]
|
#[argp(subcommand, name = "clean")]
|
||||||
pub struct CleanArgs {
|
pub struct CleanArgs {
|
||||||
#[argp(positional, from_str_fn(native_path))]
|
#[argp(positional, from_str_fn(native_path))]
|
||||||
/// path to input file
|
/// Path to input file
|
||||||
input: Utf8NativePathBuf,
|
input: Utf8NativePathBuf,
|
||||||
#[argp(positional, from_str_fn(native_path))]
|
#[argp(positional, from_str_fn(native_path))]
|
||||||
/// path to output file
|
/// Path to output file
|
||||||
output: Utf8NativePathBuf,
|
output: Utf8NativePathBuf,
|
||||||
|
#[argp(option, short = 'p')]
|
||||||
|
/// Data to replace padding bytes with, encoded as a hexadecimal string. If not specified, padding bytes will be zeroed instead.
|
||||||
|
padding: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(args: Args) -> Result<()> {
|
pub fn run(args: Args) -> Result<()> {
|
||||||
@ -56,7 +59,13 @@ fn clean_extab(args: CleanArgs) -> Result<()> {
|
|||||||
let name = args.input.file_stem().unwrap_or_default();
|
let name = args.input.file_stem().unwrap_or_default();
|
||||||
process_dol(file.map()?, name)?
|
process_dol(file.map()?, name)?
|
||||||
};
|
};
|
||||||
let num_cleaned = util::extab::clean_extab(&mut obj)?;
|
let padding: Vec<u8> = match args.padding {
|
||||||
|
None => Vec::new(),
|
||||||
|
Some(padding_str) => {
|
||||||
|
hex::decode(padding_str).context("Failed to decode padding bytes from hex")?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let num_cleaned = util::extab::clean_extab(&mut obj, padding.iter().copied())?;
|
||||||
tracing::debug!("Cleaned {num_cleaned} extab symbols");
|
tracing::debug!("Cleaned {num_cleaned} extab symbols");
|
||||||
let mut out = buf_writer(&args.output)?;
|
let mut out = buf_writer(&args.output)?;
|
||||||
if is_elf {
|
if is_elf {
|
||||||
|
@ -3,7 +3,7 @@ use itertools::Itertools;
|
|||||||
|
|
||||||
use crate::obj::ObjInfo;
|
use crate::obj::ObjInfo;
|
||||||
|
|
||||||
pub fn clean_extab(obj: &mut ObjInfo) -> Result<usize> {
|
pub fn clean_extab(obj: &mut ObjInfo, mut padding: impl Iterator<Item = u8>) -> Result<usize> {
|
||||||
let (extab_section_index, extab_section) = obj
|
let (extab_section_index, extab_section) = obj
|
||||||
.sections
|
.sections
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
@ -27,19 +27,25 @@ pub fn clean_extab(obj: &mut ObjInfo) -> Result<usize> {
|
|||||||
})?;
|
})?;
|
||||||
let mut updated = false;
|
let mut updated = false;
|
||||||
for action in &decoded.exception_actions {
|
for action in &decoded.exception_actions {
|
||||||
let section_offset =
|
// Check if the current action has padding
|
||||||
(symbol.address - extab_section.address) as usize + action.action_offset as usize;
|
if let Some(padding_offset) = action.get_struct_padding_offset() {
|
||||||
let clean_data = action.get_exaction_bytes(true);
|
let index = padding_offset as usize;
|
||||||
let orig_data =
|
let section_offset = (symbol.address - extab_section.address) as usize
|
||||||
&mut extab_section.data[section_offset..section_offset + clean_data.len()];
|
+ action.action_offset as usize;
|
||||||
if orig_data != clean_data {
|
let mut clean_data: Vec<u8> = action.get_exaction_bytes(false);
|
||||||
updated = true;
|
// Write the two padding bytes
|
||||||
|
clean_data[index] = padding.next().unwrap_or(0);
|
||||||
|
clean_data[index + 1] = padding.next().unwrap_or(0);
|
||||||
|
|
||||||
|
let orig_data =
|
||||||
|
&mut extab_section.data[section_offset..section_offset + clean_data.len()];
|
||||||
orig_data.copy_from_slice(&clean_data);
|
orig_data.copy_from_slice(&clean_data);
|
||||||
|
updated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if updated {
|
if updated {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
"Removed uninitialized bytes in {} (extab {:#010X}..{:#010X})",
|
"Replaced uninitialized bytes in {} (extab {:#010X}..{:#010X})",
|
||||||
symbol.name,
|
symbol.name,
|
||||||
symbol.address,
|
symbol.address,
|
||||||
symbol.address + symbol.size
|
symbol.address + symbol.size
|
||||||
|
Loading…
x
Reference in New Issue
Block a user