mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-06-06 22:53:30 +00:00
Auto-split and padding symbol fixes
A few issues were causing linker errors: - Auto-splits could contain symbols that have a higher alignment than the split itself. Detect this and create a new auto-split at these symbols. - The analyzer can miss objects in between other objects if there are no direct relocations to them. In these cases, non-zero data could just get totally lost. Detect and create symbols for these.
This commit is contained in:
parent
7e15810af1
commit
bb18a4b253
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -339,16 +339,16 @@ checksum = "c2e06f9bce634a3c898eb1e5cb949ff63133cbb218af93cc9b38b31d6f3ea285"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cwextab"
|
name = "cwextab"
|
||||||
version = "1.0.2"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5aa7f13cc2fcb2bcfd3abc51bdbbf8f1fb729a69ed8c05ecbaa1a42197d1842"
|
checksum = "003567b96ff9d8ac3275831650385891bca370092937be625157778b1e58f755"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decomp-toolkit"
|
name = "decomp-toolkit"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -3,7 +3,7 @@ name = "decomp-toolkit"
|
|||||||
description = "Yet another GameCube/Wii decompilation toolkit."
|
description = "Yet another GameCube/Wii decompilation toolkit."
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
repository = "https://github.com/encounter/decomp-toolkit"
|
repository = "https://github.com/encounter/decomp-toolkit"
|
||||||
|
@ -385,6 +385,20 @@ fn create_gap_splits(obj: &mut ObjInfo) -> Result<()> {
|
|||||||
new_split_end.address = symbol.address as u32;
|
new_split_end.address = symbol.address as u32;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Create a new split if we need to adjust the alignment
|
||||||
|
if let Some(align) = symbol.align {
|
||||||
|
if current_address & (align - 1) != 0 {
|
||||||
|
log::debug!(
|
||||||
|
"Auto split {:#010X}..{:#010X} for symbol {} with alignment {}",
|
||||||
|
current_address,
|
||||||
|
symbol.address,
|
||||||
|
symbol.name,
|
||||||
|
align
|
||||||
|
);
|
||||||
|
new_split_end.address = symbol.address as u32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure!(
|
ensure!(
|
||||||
@ -614,20 +628,54 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> {
|
|||||||
if let Some(&(_, next_symbol)) = iter.peek() {
|
if let Some(&(_, next_symbol)) = iter.peek() {
|
||||||
(
|
(
|
||||||
next_symbol.name.as_str(),
|
next_symbol.name.as_str(),
|
||||||
next_symbol.address,
|
next_symbol.address as u32,
|
||||||
next_symbol.address + next_symbol.size,
|
(next_symbol.address + next_symbol.size) as u32,
|
||||||
next_symbol.align.unwrap_or(1),
|
next_symbol.align.unwrap_or(1),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
section.name.as_str(),
|
section.name.as_str(),
|
||||||
section.address + section.size,
|
(section.address + section.size) as u32,
|
||||||
section.address + section.size,
|
(section.address + section.size) as u32,
|
||||||
1,
|
1,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let aligned_end = align_up((symbol.address + symbol.size) as u32, next_align);
|
|
||||||
match aligned_end.cmp(&(next_address as u32)) {
|
// Check if symbol is missing data between the end of the symbol and the next symbol
|
||||||
|
let symbol_end = (symbol.address + symbol.size) as u32;
|
||||||
|
if section.kind != ObjSectionKind::Code && next_address > symbol_end {
|
||||||
|
let data = section.data_range(symbol_end, next_address)?;
|
||||||
|
if data.iter().any(|&x| x != 0) {
|
||||||
|
log::debug!(
|
||||||
|
"Non-zero data between {:#010X}..{:#010X}, creating new symbol",
|
||||||
|
symbol_end,
|
||||||
|
next_address
|
||||||
|
);
|
||||||
|
let name = if obj.module_id == 0 {
|
||||||
|
format!("lbl_{:08X}", symbol_end)
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"lbl_{}_{}_{:X}",
|
||||||
|
obj.module_id,
|
||||||
|
section.name.trim_start_matches('.'),
|
||||||
|
symbol_end
|
||||||
|
)
|
||||||
|
};
|
||||||
|
to_add.push(ObjSymbol {
|
||||||
|
name,
|
||||||
|
address: symbol_end as u64,
|
||||||
|
section: Some(section_index),
|
||||||
|
size: (next_address - symbol_end) as u64,
|
||||||
|
size_known: true,
|
||||||
|
kind: ObjSymbolKind::Object,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let aligned_end = align_up(symbol_end, next_align);
|
||||||
|
match aligned_end.cmp(&next_address) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
let symbol_name = format!(
|
let symbol_name = format!(
|
||||||
"gap_{:02}_{:08X}_{}",
|
"gap_{:02}_{:08X}_{}",
|
||||||
@ -640,7 +688,7 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> {
|
|||||||
name: symbol_name,
|
name: symbol_name,
|
||||||
address: aligned_end as u64,
|
address: aligned_end as u64,
|
||||||
section: Some(section_index),
|
section: Some(section_index),
|
||||||
size: next_address - aligned_end as u64,
|
size: (next_address - aligned_end) as u64,
|
||||||
size_known: true,
|
size_known: true,
|
||||||
flags: ObjSymbolFlagSet(
|
flags: ObjSymbolFlagSet(
|
||||||
ObjSymbolFlags::Global
|
ObjSymbolFlags::Global
|
||||||
|
Loading…
x
Reference in New Issue
Block a user