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:
cadmic 2025-06-04 20:01:05 -07:00 committed by GitHub
parent 9cafb77d3f
commit 5e33fea49f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 16 deletions

4
Cargo.lock generated
View File

@ -339,9 +339,9 @@ checksum = "c2e06f9bce634a3c898eb1e5cb949ff63133cbb218af93cc9b38b31d6f3ea285"
[[package]]
name = "cwextab"
version = "1.1.0"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "701f6867c92e1b64ddcc4b416194be3121b8f7ba5352a70ed5fd3295a7d8e0e1"
checksum = "9dd95393b8cc20937e4757d9c22b89d016613e934c60dcb073bd8a5aade79fcf"
dependencies = [
"thiserror 2.0.12",
]

View File

@ -838,7 +838,7 @@ fn load_dol_module(
};
if config.clean_extab.unwrap_or(false) {
log::debug!("Cleaning extab for {}", config.name());
clean_extab(&mut obj)?;
clean_extab(&mut obj, std::iter::empty())?;
}
Ok((obj, object_path))
}

View File

@ -30,15 +30,18 @@ enum SubCommand {
}
#[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")]
pub struct CleanArgs {
#[argp(positional, from_str_fn(native_path))]
/// path to input file
/// Path to input file
input: Utf8NativePathBuf,
#[argp(positional, from_str_fn(native_path))]
/// path to output file
/// Path to output file
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<()> {
@ -56,7 +59,13 @@ fn clean_extab(args: CleanArgs) -> Result<()> {
let name = args.input.file_stem().unwrap_or_default();
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");
let mut out = buf_writer(&args.output)?;
if is_elf {

View File

@ -3,7 +3,7 @@ use itertools::Itertools;
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
.sections
.iter_mut()
@ -27,19 +27,25 @@ pub fn clean_extab(obj: &mut ObjInfo) -> Result<usize> {
})?;
let mut updated = false;
for action in &decoded.exception_actions {
let section_offset =
(symbol.address - extab_section.address) as usize + action.action_offset as usize;
let clean_data = action.get_exaction_bytes(true);
let orig_data =
&mut extab_section.data[section_offset..section_offset + clean_data.len()];
if orig_data != clean_data {
updated = true;
// Check if the current action has padding
if let Some(padding_offset) = action.get_struct_padding_offset() {
let index = padding_offset as usize;
let section_offset = (symbol.address - extab_section.address) as usize
+ action.action_offset as usize;
let mut clean_data: Vec<u8> = action.get_exaction_bytes(false);
// 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);
updated = true;
}
}
if updated {
tracing::debug!(
"Removed uninitialized bytes in {} (extab {:#010X}..{:#010X})",
"Replaced uninitialized bytes in {} (extab {:#010X}..{:#010X})",
symbol.name,
symbol.address,
symbol.address + symbol.size