diff --git a/Cargo.lock b/Cargo.lock index 2328126..ddfb5c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,7 +214,7 @@ dependencies = [ [[package]] name = "decomp-toolkit" -version = "0.3.3" +version = "0.3.4" dependencies = [ "anyhow", "ar", diff --git a/Cargo.toml b/Cargo.toml index 5b4bf56..6b770cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "decomp-toolkit" description = "Yet another GameCube/Wii decompilation toolkit." authors = ["Luke Street "] license = "MIT OR Apache-2.0" -version = "0.3.3" +version = "0.3.4" edition = "2021" publish = false build = "build.rs" diff --git a/assets/ldscript.lcf b/assets/ldscript.lcf index 69be224..43d3253 100644 --- a/assets/ldscript.lcf +++ b/assets/ldscript.lcf @@ -26,4 +26,5 @@ FORCEFILES FORCEACTIVE { + $FORCEACTIVE } diff --git a/src/cmd/dol.rs b/src/cmd/dol.rs index 530bb15..ef017a8 100644 --- a/src/cmd/dol.rs +++ b/src/cmd/dol.rs @@ -119,6 +119,7 @@ pub struct ProjectConfig { /// Version of the MW `.comment` section format. /// If not present, no `.comment` sections will be written. pub mw_comment_version: Option, + #[serde(default)] pub modules: Vec, // Analysis options #[serde(default = "bool_true")] @@ -258,6 +259,14 @@ fn split(args: SplitArgs) -> Result<()> { if let Some((symbol_index, symbol)) = obj.symbols.for_relocation(target, rel_reloc.kind)? { + if symbol.flags.is_local() { + bail!( + "Module {} relocation to {:#010X} found local symbol {}", + module_id, + symbol.address, + symbol.name + ); + } let addend = target as i64 - symbol.address as i64; if addend != 0 { bail!( @@ -268,7 +277,7 @@ fn split(args: SplitArgs) -> Result<()> { addend ); } - obj.symbols.set_externally_referenced(symbol_index, true); + obj.symbols.flags(symbol_index).set_force_active(true); } else { // Add label let target_section = obj.section_at(target)?; @@ -577,6 +586,10 @@ fn diff(args: DiffArgs) -> Result<()> { apply_map_file(&args.map_file, &mut linked_obj)?; for orig_sym in obj.symbols.iter() { + if orig_sym.kind == ObjSymbolKind::Section || orig_sym.section.is_none() { + continue; + } + let linked_sym = linked_obj .symbols .at_address(orig_sym.address as u32) diff --git a/src/obj/mod.rs b/src/obj/mod.rs index c4f83bf..49a3cd6 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -34,8 +34,6 @@ flags! { Common, Hidden, ForceActive, - // Same as ForceActive, but used internally - ExternallyReferenced, } } @@ -74,11 +72,6 @@ impl ObjSymbolFlagSet { #[inline] pub fn is_force_active(&self) -> bool { self.0.contains(ObjSymbolFlags::ForceActive) } - #[inline] - pub fn is_externally_referenced(&self) -> bool { - self.0.contains(ObjSymbolFlags::ExternallyReferenced) - } - #[inline] pub fn set_scope(&mut self, scope: ObjSymbolScope) { match scope { @@ -101,11 +94,11 @@ impl ObjSymbolFlagSet { } #[inline] - pub fn set_externally_referenced(&mut self, value: bool) { + pub fn set_force_active(&mut self, value: bool) { if value { - self.0 |= ObjSymbolFlags::ExternallyReferenced; + self.0 |= ObjSymbolFlags::ForceActive; } else { - self.0 &= !ObjSymbolFlags::ExternallyReferenced; + self.0 &= !ObjSymbolFlags::ForceActive; } } } @@ -562,8 +555,9 @@ impl ObjSymbols { Ok(result) } - pub fn set_externally_referenced(&mut self, idx: SymbolIndex, value: bool) { - self.symbols[idx].flags.set_externally_referenced(value); + #[inline] + pub fn flags(&mut self, idx: SymbolIndex) -> &mut ObjSymbolFlagSet { + &mut self.symbols[idx].flags } } @@ -629,6 +623,18 @@ impl ObjInfo { pub fn section_data(&self, start: u32, end: u32) -> Result<(&ObjSection, &[u8])> { let section = self.section_at(start)?; + ensure!( + section.contains_range(start..end), + "Range {:#010X}-{:#010X} outside of section {}: {:#010X}-{:#010X}", + start, + end, + section.name, + section.address, + section.address + section.size + ); + if section.kind == ObjSectionKind::Bss { + return Ok((section, &[])); + } let data = if end == 0 { §ion.data[(start as u64 - section.address) as usize..] } else { diff --git a/src/obj/split.rs b/src/obj/split.rs index 93feecf..b811878 100644 --- a/src/obj/split.rs +++ b/src/obj/split.rs @@ -97,7 +97,7 @@ fn split_ctors_dtors(obj: &mut ObjInfo, section_start: u32, section_end: u32) -> // Hack to avoid deadstripping for symbol_idx in referenced_symbols { - obj.symbols.set_externally_referenced(symbol_idx, true); + obj.symbols.flags(symbol_idx).set_force_active(true); } Ok(()) diff --git a/src/util/comment.rs b/src/util/comment.rs index 009dbd0..de34abd 100644 --- a/src/util/comment.rs +++ b/src/util/comment.rs @@ -196,7 +196,7 @@ impl CommentSym { vis_flags |= 0xD; } let mut active_flags = 0; - if symbol.flags.is_force_active() || symbol.flags.is_externally_referenced() { + if symbol.flags.is_force_active() { active_flags |= 0x8; // TODO what is 0x10? } Self { align, vis_flags, active_flags } diff --git a/src/util/config.rs b/src/util/config.rs index c29014d..ee7cb8b 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -200,9 +200,9 @@ fn write_symbol(w: &mut W, obj: &ObjInfo, symbol: &ObjSymbol) -> Resul if symbol.flags.is_hidden() { write!(w, " hidden")?; } - if symbol.flags.is_force_active() { - write!(w, " force_active")?; - } + // if symbol.flags.is_force_active() { + // write!(w, " force_active")?; + // } if obj.blocked_ranges.contains_key(&(symbol.address as u32)) { write!(w, " noreloc")?; } diff --git a/src/util/lcf.rs b/src/util/lcf.rs index 9cf84ea..ba03974 100644 --- a/src/util/lcf.rs +++ b/src/util/lcf.rs @@ -23,6 +23,13 @@ pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result Result