Skip to content

Commit 5e33fea

Browse files
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 <[email protected]>
1 parent 9cafb77 commit 5e33fea

File tree

4 files changed

+31
-16
lines changed

4 files changed

+31
-16
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/dol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ fn load_dol_module(
838838
};
839839
if config.clean_extab.unwrap_or(false) {
840840
log::debug!("Cleaning extab for {}", config.name());
841-
clean_extab(&mut obj)?;
841+
clean_extab(&mut obj, std::iter::empty())?;
842842
}
843843
Ok((obj, object_path))
844844
}

src/cmd/extab.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ enum SubCommand {
3030
}
3131

3232
#[derive(FromArgs, PartialEq, Eq, Debug)]
33-
/// Rewrites extab data in a DOL or ELF file, zeroing out any uninitialized padding bytes.
33+
/// Rewrites extab data in a DOL or ELF file, replacing any uninitialized padding bytes.
3434
#[argp(subcommand, name = "clean")]
3535
pub struct CleanArgs {
3636
#[argp(positional, from_str_fn(native_path))]
37-
/// path to input file
37+
/// Path to input file
3838
input: Utf8NativePathBuf,
3939
#[argp(positional, from_str_fn(native_path))]
40-
/// path to output file
40+
/// Path to output file
4141
output: Utf8NativePathBuf,
42+
#[argp(option, short = 'p')]
43+
/// Data to replace padding bytes with, encoded as a hexadecimal string. If not specified, padding bytes will be zeroed instead.
44+
padding: Option<String>,
4245
}
4346

4447
pub fn run(args: Args) -> Result<()> {
@@ -56,7 +59,13 @@ fn clean_extab(args: CleanArgs) -> Result<()> {
5659
let name = args.input.file_stem().unwrap_or_default();
5760
process_dol(file.map()?, name)?
5861
};
59-
let num_cleaned = util::extab::clean_extab(&mut obj)?;
62+
let padding: Vec<u8> = match args.padding {
63+
None => Vec::new(),
64+
Some(padding_str) => {
65+
hex::decode(padding_str).context("Failed to decode padding bytes from hex")?
66+
}
67+
};
68+
let num_cleaned = util::extab::clean_extab(&mut obj, padding.iter().copied())?;
6069
tracing::debug!("Cleaned {num_cleaned} extab symbols");
6170
let mut out = buf_writer(&args.output)?;
6271
if is_elf {

src/util/extab.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use itertools::Itertools;
33

44
use crate::obj::ObjInfo;
55

6-
pub fn clean_extab(obj: &mut ObjInfo) -> Result<usize> {
6+
pub fn clean_extab(obj: &mut ObjInfo, mut padding: impl Iterator<Item = u8>) -> Result<usize> {
77
let (extab_section_index, extab_section) = obj
88
.sections
99
.iter_mut()
@@ -27,19 +27,25 @@ pub fn clean_extab(obj: &mut ObjInfo) -> Result<usize> {
2727
})?;
2828
let mut updated = false;
2929
for action in &decoded.exception_actions {
30-
let section_offset =
31-
(symbol.address - extab_section.address) as usize + action.action_offset as usize;
32-
let clean_data = action.get_exaction_bytes(true);
33-
let orig_data =
34-
&mut extab_section.data[section_offset..section_offset + clean_data.len()];
35-
if orig_data != clean_data {
36-
updated = true;
30+
// Check if the current action has padding
31+
if let Some(padding_offset) = action.get_struct_padding_offset() {
32+
let index = padding_offset as usize;
33+
let section_offset = (symbol.address - extab_section.address) as usize
34+
+ action.action_offset as usize;
35+
let mut clean_data: Vec<u8> = action.get_exaction_bytes(false);
36+
// Write the two padding bytes
37+
clean_data[index] = padding.next().unwrap_or(0);
38+
clean_data[index + 1] = padding.next().unwrap_or(0);
39+
40+
let orig_data =
41+
&mut extab_section.data[section_offset..section_offset + clean_data.len()];
3742
orig_data.copy_from_slice(&clean_data);
43+
updated = true;
3844
}
3945
}
4046
if updated {
4147
tracing::debug!(
42-
"Removed uninitialized bytes in {} (extab {:#010X}..{:#010X})",
48+
"Replaced uninitialized bytes in {} (extab {:#010X}..{:#010X})",
4349
symbol.name,
4450
symbol.address,
4551
symbol.address + symbol.size

0 commit comments

Comments
 (0)