mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-12-16 08:27:02 +00:00
Analyzer fixes galore
- Transparent NLZSS decompression (add `:nlzss` to path) - Overhaul portions of the analyzer to support more games - Reject some invalid data relocations automatically - Jump table analysis fixes
This commit is contained in:
@@ -69,8 +69,8 @@ pub struct ObjInfo {
|
||||
pub link_order: Vec<ObjUnit>,
|
||||
pub blocked_ranges: BTreeMap<SectionAddress, u32>, // start -> end
|
||||
|
||||
// From extab
|
||||
pub known_functions: BTreeMap<SectionAddress, u32>,
|
||||
// From .ctors, .dtors and extab
|
||||
pub known_functions: BTreeMap<SectionAddress, Option<u32>>,
|
||||
|
||||
// REL
|
||||
/// Module ID (0 for main)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use std::{collections::BTreeMap, ops::RangeBounds};
|
||||
use std::{cmp::max, collections::BTreeMap, ops::RangeBounds};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::util::nested::NestedVec;
|
||||
use crate::{
|
||||
obj::{ObjInfo, ObjSection},
|
||||
util::{nested::NestedVec, split::default_section_align},
|
||||
};
|
||||
|
||||
/// Marks a split point within a section.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
@@ -21,6 +24,30 @@ pub struct ObjSplit {
|
||||
pub rename: Option<String>,
|
||||
}
|
||||
|
||||
impl ObjSplit {
|
||||
pub fn alignment(
|
||||
&self,
|
||||
obj: &ObjInfo,
|
||||
section_index: usize,
|
||||
section: &ObjSection,
|
||||
split_addr: u32,
|
||||
) -> u32 {
|
||||
self.align.unwrap_or_else(|| {
|
||||
let default_align = default_section_align(section) as u32;
|
||||
max(
|
||||
// Maximum alignment of any symbol in this split
|
||||
obj.symbols
|
||||
.for_section_range(section_index, split_addr..self.end)
|
||||
.filter(|&(_, s)| s.size_known && s.size > 0)
|
||||
.filter_map(|(_, s)| s.align)
|
||||
.max()
|
||||
.unwrap_or(default_align),
|
||||
default_align,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits within a section.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ObjSplits {
|
||||
@@ -46,6 +73,13 @@ impl ObjSplits {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn at_mut(&mut self, address: u32) -> Option<&mut ObjSplit> {
|
||||
match self.for_range_mut(..=address).next_back() {
|
||||
Some((_, split)) if split.end == 0 || split.end > address => Some(split),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Locate existing splits within the given address range.
|
||||
pub fn for_range<R>(&self, range: R) -> impl DoubleEndedIterator<Item = (u32, &ObjSplit)>
|
||||
where R: RangeBounds<u32> {
|
||||
|
||||
@@ -112,6 +112,15 @@ impl ObjSymbolFlagSet {
|
||||
self.0 &= !ObjSymbolFlags::ForceActive;
|
||||
}
|
||||
}
|
||||
|
||||
/// Special flags to keep when merging symbols.
|
||||
#[inline]
|
||||
pub fn keep_flags(&self) -> FlagSet<ObjSymbolFlags> {
|
||||
self.0
|
||||
& (ObjSymbolFlags::ForceActive
|
||||
| ObjSymbolFlags::NoWrite
|
||||
| ObjSymbolFlags::RelocationIgnore)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
@@ -213,8 +222,7 @@ impl ObjSymbols {
|
||||
let replace = replace || (is_auto_symbol(existing) && !is_auto_symbol(&in_symbol));
|
||||
let size =
|
||||
if existing.size_known && in_symbol.size_known && existing.size != in_symbol.size {
|
||||
// TODO fix and promote back to warning
|
||||
log::debug!(
|
||||
log::warn!(
|
||||
"Conflicting size for {}: was {:#X}, now {:#X}",
|
||||
existing.name,
|
||||
existing.size,
|
||||
@@ -248,7 +256,7 @@ impl ObjSymbols {
|
||||
section: in_symbol.section,
|
||||
size,
|
||||
size_known: existing.size_known || in_symbol.size != 0,
|
||||
flags: in_symbol.flags,
|
||||
flags: ObjSymbolFlagSet(in_symbol.flags.0 | existing.flags.keep_flags()),
|
||||
kind: in_symbol.kind,
|
||||
align: in_symbol.align.or(existing.align),
|
||||
data_kind: match in_symbol.data_kind {
|
||||
@@ -511,7 +519,8 @@ impl ObjSymbol {
|
||||
ObjSymbolKind::Unknown => true,
|
||||
ObjSymbolKind::Function => !matches!(reloc_kind, ObjRelocKind::PpcEmbSda21),
|
||||
ObjSymbolKind::Object => {
|
||||
!matches!(reloc_kind, ObjRelocKind::PpcRel14 | ObjRelocKind::PpcRel24)
|
||||
// !matches!(reloc_kind, ObjRelocKind::PpcRel14 | ObjRelocKind::PpcRel24)
|
||||
true // SADX has bugged relocations that jump from .text to .bss, how awful
|
||||
}
|
||||
ObjSymbolKind::Section => {
|
||||
matches!(
|
||||
|
||||
Reference in New Issue
Block a user