Compare commits
5 Commits
9249fa67b8
...
a156c3697f
Author | SHA1 | Date |
---|---|---|
Luke Street | a156c3697f | |
Luke Street | 3497d38ea3 | |
Luke Street | d0f39f1d82 | |
Luke Street | ccfbfd1a5a | |
Luke Street | e9a9ed0453 |
|
@ -269,7 +269,7 @@ checksum = "c2e06f9bce634a3c898eb1e5cb949ff63133cbb218af93cc9b38b31d6f3ea285"
|
|||
|
||||
[[package]]
|
||||
name = "decomp-toolkit"
|
||||
version = "0.7.5"
|
||||
version = "0.7.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ar",
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "decomp-toolkit"
|
|||
description = "Yet another GameCube/Wii decompilation toolkit."
|
||||
authors = ["Luke Street <luke@street.dev>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
version = "0.7.5"
|
||||
version = "0.7.6"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
repository = "https://github.com/encounter/decomp-toolkit"
|
||||
|
|
|
@ -248,8 +248,12 @@ impl AnalyzerState {
|
|||
}
|
||||
if self.functions.iter().any(|(_, i)| i.is_unfinalized()) {
|
||||
log::error!("Failed to finalize functions:");
|
||||
for (addr, _) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
|
||||
log::error!(" {:#010X}", addr);
|
||||
for (addr, info) in self.functions.iter().filter(|(_, i)| i.is_unfinalized()) {
|
||||
log::error!(
|
||||
" {:#010X}: blocks [{:?}]",
|
||||
addr,
|
||||
info.slices.as_ref().unwrap().possible_blocks.keys()
|
||||
);
|
||||
}
|
||||
bail!("Failed to finalize functions");
|
||||
}
|
||||
|
@ -298,11 +302,15 @@ impl AnalyzerState {
|
|||
&self.functions,
|
||||
Some(vm),
|
||||
)?;
|
||||
// Start at the beginning of the function again
|
||||
current = SectionAddress::new(addr.section, 0);
|
||||
}
|
||||
TailCallResult::Is => {
|
||||
log::trace!("Finalized tail call @ {:#010X}", block);
|
||||
slices.possible_blocks.remove(&block);
|
||||
slices.function_references.insert(block);
|
||||
// Start at the beginning of the function again
|
||||
current = SectionAddress::new(addr.section, 0);
|
||||
}
|
||||
TailCallResult::Possible => {
|
||||
if finalize {
|
||||
|
|
|
@ -328,7 +328,7 @@ impl FunctionSlices {
|
|||
function_end.or_else(|| self.end()),
|
||||
)?;
|
||||
log::debug!("-> size {}: {:?}", size, entries);
|
||||
if entries.contains(&next_address)
|
||||
if (entries.contains(&next_address) || self.blocks.contains_key(&next_address))
|
||||
&& !entries.iter().any(|&addr| {
|
||||
self.is_known_function(known_functions, addr)
|
||||
.is_some_and(|fn_addr| fn_addr != function_start)
|
||||
|
|
|
@ -295,7 +295,7 @@ fn make(args: MakeArgs) -> Result<()> {
|
|||
for (module_id, (module, path)) in modules.iter().enumerate() {
|
||||
let _span = info_span!("file", path = %path.display()).entered();
|
||||
for symbol in module.symbols() {
|
||||
if symbol.is_definition() && symbol.scope() == object::SymbolScope::Dynamic {
|
||||
if symbol.scope() == object::SymbolScope::Dynamic {
|
||||
symbol_map.entry(symbol.name_bytes()?).or_insert((module_id, symbol.index()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,11 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
|
|||
use crate::{
|
||||
analysis::cfa::SectionAddress,
|
||||
obj::{ObjKind, ObjRelocKind},
|
||||
util::{config::is_auto_symbol, nested::NestedVec, split::is_linker_generated_label},
|
||||
util::{
|
||||
config::{is_auto_jump_table, is_auto_label, is_auto_symbol},
|
||||
nested::NestedVec,
|
||||
split::is_linker_generated_label,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize, Default)]
|
||||
|
@ -242,7 +246,11 @@ impl ObjSymbols {
|
|||
bail!("ABS symbol in relocatable object: {:?}", in_symbol);
|
||||
};
|
||||
let target_symbol_idx = if let Some((symbol_idx, existing)) = opt {
|
||||
let replace = replace || (is_auto_symbol(existing) && !is_auto_symbol(&in_symbol));
|
||||
let replace = replace
|
||||
// Replace auto symbols with known symbols
|
||||
|| (is_auto_symbol(existing) && !is_auto_symbol(&in_symbol))
|
||||
// Replace lbl_ with jumptable_
|
||||
|| (is_auto_label(existing) && is_auto_jump_table(&in_symbol));
|
||||
let size =
|
||||
if existing.size_known && in_symbol.size_known && existing.size != in_symbol.size {
|
||||
// TODO fix this and restore to warning
|
||||
|
|
|
@ -182,6 +182,10 @@ pub fn is_auto_symbol(symbol: &ObjSymbol) -> bool {
|
|||
|| symbol.name.starts_with("pad_")
|
||||
}
|
||||
|
||||
pub fn is_auto_label(symbol: &ObjSymbol) -> bool { symbol.name.starts_with("lbl_") }
|
||||
|
||||
pub fn is_auto_jump_table(symbol: &ObjSymbol) -> bool { symbol.name.starts_with("jumptable_") }
|
||||
|
||||
fn write_if_unchanged<P, Cb>(path: P, cb: Cb, cached_file: Option<FileReadInfo>) -> Result<()>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
|
|
|
@ -428,7 +428,7 @@ where P: AsRef<Path> {
|
|||
if path.as_ref().exists() {
|
||||
set_file_mtime(path, FileTime::now())
|
||||
} else {
|
||||
match OpenOptions::new().create(true).write(true).open(path) {
|
||||
match OpenOptions::new().create(true).truncate(true).write(true).open(path) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
|
|
|
@ -391,11 +391,7 @@ impl<'parent> Iterator for Nodes<'parent> {
|
|||
type Item = Node;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let Some(state) = self.stack.pop() else {
|
||||
return None;
|
||||
};
|
||||
|
||||
match state {
|
||||
match self.stack.pop()? {
|
||||
NodeState::Begin(name) => {
|
||||
self.stack.push(NodeState::File(name.clone(), 0));
|
||||
Some(Node::DirectoryBegin { name })
|
||||
|
|
Loading…
Reference in New Issue