parent
85e044463e
commit
58b6d7c7d5
|
@ -295,7 +295,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decomp-toolkit"
|
name = "decomp-toolkit"
|
||||||
version = "0.6.5"
|
version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
|
|
|
@ -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 = "0.6.5"
|
version = "0.7.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
repository = "https://github.com/encounter/decomp-toolkit"
|
repository = "https://github.com/encounter/decomp-toolkit"
|
||||||
|
|
|
@ -65,18 +65,10 @@ fn split_ctors_dtors(obj: &mut ObjInfo, start: SectionAddress, end: SectionAddre
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctors_split.is_none() || function_split.is_none() {
|
if ctors_split.is_none() || function_split.is_none() {
|
||||||
let unit = expected_unit.unwrap_or_else(|| {
|
let unit = match expected_unit {
|
||||||
let section_name = function_symbol
|
Some(unit) => unit,
|
||||||
.section
|
None => auto_unit_name(obj, function_symbol, &new_splits)?,
|
||||||
.and_then(|idx| obj.sections.get(idx).map(|s| s.name.clone()))
|
};
|
||||||
.unwrap_or_else(|| "unknown".to_string());
|
|
||||||
let name =
|
|
||||||
sanitize_with_options(&function_symbol.name, &sanitise_file_name::Options {
|
|
||||||
length_limit: 20,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
format!("auto_{}_{}", name, section_name.trim_start_matches('.'))
|
|
||||||
});
|
|
||||||
log::debug!("Adding splits to unit {}", unit);
|
log::debug!("Adding splits to unit {}", unit);
|
||||||
|
|
||||||
if ctors_split.is_none() {
|
if ctors_split.is_none() {
|
||||||
|
@ -251,13 +243,10 @@ fn split_extabindex(obj: &mut ObjInfo, start: SectionAddress) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if extabindex_split.is_none() || extab_split.is_none() || function_split.is_none() {
|
if extabindex_split.is_none() || extab_split.is_none() || function_split.is_none() {
|
||||||
let unit = expected_unit.unwrap_or_else(|| {
|
let unit = match expected_unit {
|
||||||
let section_name = function_symbol
|
Some(unit) => unit,
|
||||||
.section
|
None => auto_unit_name(obj, function_symbol, &new_splits)?,
|
||||||
.and_then(|idx| obj.sections.get(idx).map(|s| s.name.clone()))
|
};
|
||||||
.unwrap_or_else(|| "unknown".to_string());
|
|
||||||
format!("auto_{}_{}", function_symbol.name, section_name.trim_start_matches('.'))
|
|
||||||
});
|
|
||||||
log::debug!("Adding splits to unit {}", unit);
|
log::debug!("Adding splits to unit {}", unit);
|
||||||
|
|
||||||
if extabindex_split.is_none() {
|
if extabindex_split.is_none() {
|
||||||
|
@ -384,6 +373,14 @@ fn create_gap_splits(obj: &mut ObjInfo) -> Result<()> {
|
||||||
symbol.name,
|
symbol.name,
|
||||||
symbol.address
|
symbol.address
|
||||||
);
|
);
|
||||||
|
if symbol.address & 3 != 0 {
|
||||||
|
bail!(
|
||||||
|
"Need to split at {:#010X} for duplicate symbol name {}, \
|
||||||
|
but it is not 4-byte aligned. Please split manually.",
|
||||||
|
symbol.address,
|
||||||
|
symbol.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
new_split_end.address = symbol.address as u32;
|
new_split_end.address = symbol.address as u32;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1340,3 +1337,50 @@ pub fn end_for_section(obj: &ObjInfo, section_index: usize) -> Result<SectionAdd
|
||||||
}
|
}
|
||||||
Ok(SectionAddress::new(section_index, section_end))
|
Ok(SectionAddress::new(section_index, section_end))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a unit name for an autogenerated split.
|
||||||
|
/// The name is based on the symbol name and section name.
|
||||||
|
/// If the name is not unique, a number is appended to the end.
|
||||||
|
fn auto_unit_name(
|
||||||
|
obj: &ObjInfo,
|
||||||
|
symbol: &ObjSymbol,
|
||||||
|
new_splits: &BTreeMap<SectionAddress, ObjSplit>,
|
||||||
|
) -> Result<String> {
|
||||||
|
let section_name = symbol
|
||||||
|
.section
|
||||||
|
.and_then(|idx| obj.sections.get(idx).map(|s| s.name.clone()))
|
||||||
|
.unwrap_or_else(|| "unknown".to_string());
|
||||||
|
let name = sanitize_with_options(&symbol.name, &sanitise_file_name::Options {
|
||||||
|
length_limit: 20,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let mut unit_name = format!("auto_{}_{}", name, section_name.trim_start_matches('.'));
|
||||||
|
// Ensure the name is unique
|
||||||
|
if unit_exists(&unit_name, obj, new_splits) {
|
||||||
|
let mut i = 1;
|
||||||
|
loop {
|
||||||
|
let new_unit_name = format!("{}_{}", unit_name, i);
|
||||||
|
if !unit_exists(&new_unit_name, obj, new_splits) {
|
||||||
|
unit_name = new_unit_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(unit_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if a unit name exists in the object or pending splits.
|
||||||
|
fn unit_exists(
|
||||||
|
unit_name: &str,
|
||||||
|
obj: &ObjInfo,
|
||||||
|
new_splits: &BTreeMap<SectionAddress, ObjSplit>,
|
||||||
|
) -> bool {
|
||||||
|
obj.link_order.iter().any(|u| u.name.eq_ignore_ascii_case(unit_name))
|
||||||
|
|| obj
|
||||||
|
.sections
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, s)| s.splits.iter())
|
||||||
|
.any(|(_, split)| split.unit.eq_ignore_ascii_case(unit_name))
|
||||||
|
|| new_splits.values().any(|split| split.unit.eq_ignore_ascii_case(unit_name))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue