diff --git a/src/analysis/cfa.rs b/src/analysis/cfa.rs index 8f7f4f3..aea65a3 100644 --- a/src/analysis/cfa.rs +++ b/src/analysis/cfa.rs @@ -16,12 +16,15 @@ use crate::{ vm::{BranchTarget, GprValue, StepResult, VM}, RelocationTarget, }, - obj::{ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind}, + obj::{ + ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, + SectionIndex, + }, }; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SectionAddress { - pub section: usize, + pub section: SectionIndex, pub address: u32, } @@ -38,7 +41,7 @@ impl Display for SectionAddress { } impl SectionAddress { - pub fn new(section: usize, address: u32) -> Self { Self { section, address } } + pub fn new(section: SectionIndex, address: u32) -> Self { Self { section, address } } pub fn offset(self, offset: i32) -> Self { Self { section: self.section, address: self.address.wrapping_add_signed(offset) } @@ -116,7 +119,7 @@ pub struct AnalyzerState { pub functions: BTreeMap, pub jump_tables: BTreeMap, pub known_symbols: BTreeMap>, - pub known_sections: BTreeMap, + pub known_sections: BTreeMap, } impl AnalyzerState { diff --git a/src/analysis/executor.rs b/src/analysis/executor.rs index 5e0dc47..2c634d0 100644 --- a/src/analysis/executor.rs +++ b/src/analysis/executor.rs @@ -18,7 +18,7 @@ struct VisitedAddresses { impl VisitedAddresses { pub fn new(obj: &ObjInfo) -> Self { - let mut inner = Vec::with_capacity(obj.sections.len()); + let mut inner = Vec::with_capacity(obj.sections.len() as usize); for (_, section) in obj.sections.iter() { if section.kind == ObjSectionKind::Code { let size = (section.size / 4) as usize; @@ -32,11 +32,13 @@ impl VisitedAddresses { } pub fn contains(&self, section_address: u32, address: SectionAddress) -> bool { - self.inner[address.section].contains(Self::bit_for(section_address, address.address)) + self.inner[address.section as usize] + .contains(Self::bit_for(section_address, address.address)) } pub fn insert(&mut self, section_address: u32, address: SectionAddress) { - self.inner[address.section].insert(Self::bit_for(section_address, address.address)); + self.inner[address.section as usize] + .insert(Self::bit_for(section_address, address.address)); } #[inline] diff --git a/src/analysis/mod.rs b/src/analysis/mod.rs index c53d9a3..2ea8c9a 100644 --- a/src/analysis/mod.rs +++ b/src/analysis/mod.rs @@ -6,7 +6,9 @@ use ppc750cl::Ins; use crate::{ analysis::cfa::SectionAddress, array_ref, - obj::{ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind}, + obj::{ + ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind, SectionIndex, + }, }; pub mod cfa; @@ -36,11 +38,9 @@ fn read_unresolved_relocation_address( address: u32, reloc_kind: Option, ) -> Result> { - if let Some(reloc) = obj - .unresolved_relocations - .iter() - .find(|reloc| reloc.section as usize == section.elf_index && reloc.address == address) - { + if let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| { + reloc.section as SectionIndex == section.elf_index && reloc.address == address + }) { if reloc.module_id != obj.module_id { return Ok(Some(RelocationTarget::External)); } @@ -48,7 +48,7 @@ fn read_unresolved_relocation_address( ensure!(reloc.kind == reloc_kind); } let (target_section_index, target_section) = - obj.sections.get_elf_index(reloc.target_section as usize).ok_or_else(|| { + obj.sections.get_elf_index(reloc.target_section as SectionIndex).ok_or_else(|| { anyhow!( "Failed to find target section {} for unresolved relocation", reloc.target_section diff --git a/src/analysis/objects.rs b/src/analysis/objects.rs index 7a40382..e681392 100644 --- a/src/analysis/objects.rs +++ b/src/analysis/objects.rs @@ -1,7 +1,7 @@ use anyhow::Result; use crate::{ - obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind}, + obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind, SymbolIndex}, util::split::is_linker_generated_label, }; @@ -64,7 +64,7 @@ pub fn detect_objects(obj: &mut ObjInfo) -> Result<()> { } pub fn detect_strings(obj: &mut ObjInfo) -> Result<()> { - let mut symbols_set = Vec::<(usize, ObjDataKind, usize)>::new(); + let mut symbols_set = Vec::<(SymbolIndex, ObjDataKind, usize)>::new(); for (section_index, section) in obj .sections .iter() diff --git a/src/analysis/pass.rs b/src/analysis/pass.rs index 038355a..80ccdbd 100644 --- a/src/analysis/pass.rs +++ b/src/analysis/pass.rs @@ -7,7 +7,7 @@ use crate::{ analysis::cfa::{AnalyzerState, FunctionInfo, SectionAddress}, obj::{ ObjInfo, ObjKind, ObjRelocKind, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, - ObjSymbolFlags, ObjSymbolKind, + ObjSymbolFlags, ObjSymbolKind, SectionIndex, }, }; @@ -147,14 +147,14 @@ impl AnalysisPass for FindRelCtorsDtors { // And the section ends with a null pointer while let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| { reloc.module_id == obj.module_id - && reloc.section == section.elf_index as u8 + && reloc.section as SectionIndex == section.elf_index && reloc.address == current_address && reloc.kind == ObjRelocKind::Absolute }) { - let Some((target_section_index, target_section)) = obj - .sections - .iter() - .find(|(_, section)| section.elf_index == reloc.target_section as usize) + let Some((target_section_index, target_section)) = + obj.sections.iter().find(|(_, section)| { + section.elf_index == reloc.target_section as SectionIndex + }) else { return false; }; diff --git a/src/analysis/tracker.rs b/src/analysis/tracker.rs index 5e5fbee..9f381ac 100644 --- a/src/analysis/tracker.rs +++ b/src/analysis/tracker.rs @@ -19,7 +19,7 @@ use crate::{ }, obj::{ ObjDataKind, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, - ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, + ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, SectionIndex, SymbolIndex, }, }; @@ -298,7 +298,7 @@ impl Tracker { debug_assert_ne!( value, RelocationTarget::Address(SectionAddress::new( - usize::MAX, + SectionIndex::MAX, 0 )) ); @@ -359,7 +359,7 @@ impl Tracker { debug_assert_ne!( address, RelocationTarget::Address(SectionAddress::new( - usize::MAX, + SectionIndex::MAX, 0 )) ); @@ -380,7 +380,7 @@ impl Tracker { debug_assert_ne!( address, RelocationTarget::Address(SectionAddress::new( - usize::MAX, + SectionIndex::MAX, 0 )) ); @@ -464,7 +464,7 @@ impl Tracker { { (addr, is_function_addr(addr)) } else { - (SectionAddress::new(usize::MAX, 0), false) + (SectionAddress::new(SectionIndex::MAX, 0), false) }; if branch.link || !is_fn_addr { self.relocations.insert(ins_addr, match ins.op { @@ -549,7 +549,7 @@ impl Tracker { fn process_data( &mut self, obj: &ObjInfo, - section_index: usize, + section_index: SectionIndex, section: &ObjSection, ) -> Result<()> { let mut addr = SectionAddress::new(section_index, section.address as u32); @@ -602,7 +602,7 @@ impl Tracker { } else { // Check known relocations (function signature matching) if self.known_relocations.contains(&from) { - return Some(SectionAddress::new(usize::MAX, addr)); + return Some(SectionAddress::new(SectionIndex::MAX, addr)); } // Check special symbols if self.stack_address == Some(addr) @@ -613,7 +613,7 @@ impl Tracker { || self.sda2_base == Some(addr) || self.sda_base == Some(addr) { - return Some(SectionAddress::new(usize::MAX, addr)); + return Some(SectionAddress::new(SectionIndex::MAX, addr)); } // Not valid None @@ -625,7 +625,7 @@ impl Tracker { obj: &mut ObjInfo, addr: u32, reloc_kind: ObjRelocKind, - ) -> Option { + ) -> Option { if !matches!( reloc_kind, ObjRelocKind::PpcAddr16Ha | ObjRelocKind::PpcAddr16Lo @@ -641,7 +641,7 @@ impl Tracker { // return generate_special_symbol(obj, addr, &name).ok(); // } // } - let mut check_symbol = |opt: Option, name: &str| -> Option { + let mut check_symbol = |opt: Option, name: &str| -> Option { if let Some(value) = opt { if addr == value { return generate_special_symbol(obj, value, name).ok(); @@ -866,7 +866,7 @@ fn data_kind_from_op(op: Opcode) -> DataKind { } } -fn generate_special_symbol(obj: &mut ObjInfo, addr: u32, name: &str) -> Result { +fn generate_special_symbol(obj: &mut ObjInfo, addr: u32, name: &str) -> Result { obj.add_symbol( ObjSymbol { name: name.to_string(), diff --git a/src/cmd/dol.rs b/src/cmd/dol.rs index 0bf91d3..2398976 100644 --- a/src/cmd/dol.rs +++ b/src/cmd/dol.rs @@ -34,7 +34,7 @@ use crate::{ cmd::shasum::file_sha1_string, obj::{ best_match_for_reloc, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSectionKind, ObjSymbol, - ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SymbolIndex, + ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SectionIndex, SymbolIndex, }, util::{ asm::write_asm, @@ -402,7 +402,7 @@ pub fn run(args: Args) -> Result<()> { fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> { let rso = process_rso(&mut Cursor::new(buf))?; - for symbol in rso.symbols.iter() { + for (_, symbol) in rso.symbols.iter() { let dol_section_index = match symbol.section { Some(section) => section, None => bail!( @@ -411,15 +411,17 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> { symbol.address ), }; - let (section, address, section_kind) = if dol_section_index == DOL_SECTION_ABS as usize { + let (section, address, section_kind) = if dol_section_index + == DOL_SECTION_ABS as SectionIndex + { (None, symbol.address as u32, None) } else { - let dol_section_name = if dol_section_index == DOL_SECTION_ETI as usize { + let dol_section_name = if dol_section_index == DOL_SECTION_ETI as SectionIndex { "extabindex" } else { - DOL_SECTION_NAMES.get(dol_section_index).and_then(|&opt| opt).ok_or_else(|| { - anyhow!("Can't add symbol for unknown DOL section {}", dol_section_index) - })? + DOL_SECTION_NAMES.get(dol_section_index as usize).and_then(|&opt| opt).ok_or_else( + || anyhow!("Can't add symbol for unknown DOL section {}", dol_section_index), + )? }; let (dol_section_index, dol_section) = obj .sections @@ -577,7 +579,7 @@ fn update_symbols( if source_module_id == obj.module_id { // Skip if already resolved let (_, source_section) = - obj.sections.get_elf_index(rel_reloc.section as usize).ok_or_else(|| { + obj.sections.get_elf_index(rel_reloc.section as SectionIndex).ok_or_else(|| { anyhow!( "Failed to locate REL section {} in module ID {}: source module {}, {:?}", rel_reloc.section, @@ -591,8 +593,10 @@ fn update_symbols( } } - let (target_section_index, target_section) = - obj.sections.get_elf_index(rel_reloc.target_section as usize).ok_or_else(|| { + let (target_section_index, target_section) = obj + .sections + .get_elf_index(rel_reloc.target_section as SectionIndex) + .ok_or_else(|| { anyhow!( "Failed to locate REL section {} in module ID {}: source module {}, {:?}", rel_reloc.target_section, @@ -655,7 +659,7 @@ fn create_relocations( for rel_reloc in take(&mut obj.unresolved_relocations) { // Skip if already resolved let (_, source_section) = - obj.sections.get_elf_index(rel_reloc.section as usize).ok_or_else(|| { + obj.sections.get_elf_index(rel_reloc.section as SectionIndex).ok_or_else(|| { anyhow!( "Failed to locate REL section {} in module ID {}: {:?}", rel_reloc.section, @@ -683,7 +687,7 @@ fn create_relocations( anyhow!("Failed to locate DOL section at {:#010X}", rel_reloc.addend) })? } else { - target_obj.sections.get_elf_index(rel_reloc.target_section as usize).ok_or_else( + target_obj.sections.get_elf_index(rel_reloc.target_section as SectionIndex).ok_or_else( || { anyhow!( "Failed to locate module {} section {}", @@ -720,7 +724,7 @@ fn create_relocations( }, }; let (_, source_section) = - obj.sections.get_elf_index_mut(rel_reloc.section as usize).unwrap(); + obj.sections.get_elf_index_mut(rel_reloc.section as SectionIndex).unwrap(); source_section.relocations.insert(rel_reloc.address, reloc)?; } @@ -739,7 +743,7 @@ fn resolve_external_relocations( module_id: u32, symbol_index: SymbolIndex, } - let mut reloc_to_symbol = HashMap::::new(); + let mut reloc_to_symbol = HashMap::::new(); for (_section_index, section) in obj.sections.iter_mut() { for (_reloc_address, reloc) in section.relocations.iter_mut() { @@ -1572,7 +1576,7 @@ fn diff(args: DiffArgs) -> Result<()> { let linked_obj = process_elf(&args.elf_file)?; let common_bss = obj.sections.common_bss_start(); - for orig_sym in obj.symbols.iter().filter(|s| { + for (_, orig_sym) in obj.symbols.iter().filter(|(_, s)| { !matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) && !s.flags.is_stripped() }) { let Some(orig_section_index) = orig_sym.section else { continue }; @@ -1596,8 +1600,8 @@ fn diff(args: DiffArgs) -> Result<()> { if linked_sym.size != orig_sym.size && // TODO validate common symbol sizes // (need to account for inflation bug) - matches!(common_bss, Some((idx, addr)) if - orig_section_index == idx && orig_sym.address as u32 >= addr) + matches!(common_bss, Some(addr) if + orig_section_index == addr.section && orig_sym.address as u32 >= addr.address) { log::error!( "Expected {} (type {:?}) to have size {:#X}, but found {:#X}", @@ -1656,7 +1660,7 @@ fn diff(args: DiffArgs) -> Result<()> { } // Data diff - for orig_sym in obj.symbols.iter().filter(|s| { + for (_, orig_sym) in obj.symbols.iter().filter(|(_, s)| { s.size > 0 && !matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) }) { let Some(orig_section_index) = orig_sym.section else { continue }; @@ -1756,7 +1760,7 @@ fn apply(args: ApplyArgs) -> Result<()> { let linked_obj = process_elf(&args.elf_file)?; let mut replacements: Vec<(SymbolIndex, Option)> = vec![]; - for (orig_idx, orig_sym) in obj.symbols.iter().enumerate() { + for (orig_idx, orig_sym) in obj.symbols.iter() { // skip ABS for now if orig_sym.section.is_none() { continue; @@ -1832,7 +1836,7 @@ fn apply(args: ApplyArgs) -> Result<()> { } // Add symbols from the linked object that aren't in the original - for linked_sym in linked_obj.symbols.iter() { + for (_, linked_sym) in linked_obj.symbols.iter() { if matches!(linked_sym.kind, ObjSymbolKind::Section) || is_auto_symbol(linked_sym) || is_linker_generated_object(&linked_sym.name) diff --git a/src/cmd/rel.rs b/src/cmd/rel.rs index c9db8d6..19dbd2b 100644 --- a/src/cmd/rel.rs +++ b/src/cmd/rel.rs @@ -28,7 +28,10 @@ use crate::{ }, array_ref_mut, cmd::dol::{find_object_base, ModuleConfig, ObjectBase, ProjectConfig}, - obj::{ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol}, + obj::{ + ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol, + SectionIndex as ObjSectionIndex, + }, util::{ config::{is_auto_symbol, read_splits_sections, SectionDef}, dol::process_dol, @@ -499,7 +502,7 @@ fn merge(args: MergeArgs) -> Result<()> { } log::info!("Merging {} REL(s)", processed); - let mut section_map: BTreeMap> = BTreeMap::new(); + let mut section_map: BTreeMap> = BTreeMap::new(); let mut offset = align32(arena_lo + 0x2000); for module in module_map.values() { for (mod_section_index, mod_section) in module.sections.iter() { @@ -518,7 +521,7 @@ fn merge(args: MergeArgs) -> Result<()> { section_known: mod_section.section_known, splits: mod_section.splits.clone(), }); - section_map.nested_insert(module.module_id, mod_section.elf_index as u32, offset)?; + section_map.nested_insert(module.module_id, mod_section.elf_index, offset)?; for (_, mod_symbol) in module.symbols.for_section(mod_section_index) { obj.symbols.add_direct(ObjSymbol { name: mod_symbol.name.clone(), @@ -542,7 +545,8 @@ fn merge(args: MergeArgs) -> Result<()> { log::info!("Applying REL relocations"); for module in module_map.values() { for rel_reloc in &module.unresolved_relocations { - let source_addr = (section_map[&module.module_id][&(rel_reloc.section as u32)] + let source_addr = (section_map[&module.module_id] + [&(rel_reloc.section as ObjSectionIndex)] + rel_reloc.address) & !3; let target_addr = if rel_reloc.module_id == 0 { diff --git a/src/obj/mod.rs b/src/obj/mod.rs index e74fd53..7d703ab 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -13,7 +13,9 @@ use std::{ use anyhow::{anyhow, bail, ensure, Result}; use objdiff_core::obj::split_meta::SplitMeta; pub use relocations::{ObjReloc, ObjRelocKind, ObjRelocations}; -pub use sections::{section_kind_for_section, ObjSection, ObjSectionKind, ObjSections}; +pub use sections::{ + section_kind_for_section, ObjSection, ObjSectionKind, ObjSections, SectionIndex, +}; pub use splits::{ObjSplit, ObjSplits}; pub use symbols::{ best_match_for_reloc, ObjDataKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, @@ -132,7 +134,12 @@ impl ObjInfo { self.symbols.add(in_symbol, replace) } - pub fn add_split(&mut self, section_index: usize, address: u32, split: ObjSplit) -> Result<()> { + pub fn add_split( + &mut self, + section_index: SectionIndex, + address: u32, + split: ObjSplit, + ) -> Result<()> { let section = self .sections .get_mut(section_index) @@ -322,8 +329,8 @@ impl ObjInfo { // Include common symbols self.symbols .iter() - .filter(|&symbol| symbol.flags.is_common()) - .map(|s| s.size as u32), + .filter(|&(_, symbol)| symbol.flags.is_common()) + .map(|(_, s)| s.size as u32), ) .sum() } diff --git a/src/obj/sections.rs b/src/obj/sections.rs index b109cc4..6d366b5 100644 --- a/src/obj/sections.rs +++ b/src/obj/sections.rs @@ -7,7 +7,10 @@ use std::{ use anyhow::{anyhow, bail, ensure, Result}; use itertools::Itertools; -use crate::obj::{ObjKind, ObjRelocations, ObjSplit, ObjSplits, ObjSymbol}; +use crate::{ + analysis::cfa::SectionAddress, + obj::{ObjKind, ObjRelocations, ObjSplit, ObjSplits, ObjSymbol}, +}; #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum ObjSectionKind { @@ -26,7 +29,7 @@ pub struct ObjSection { pub data: Vec, pub align: u64, /// REL files reference the original ELF section indices - pub elf_index: usize, + pub elf_index: SectionIndex, pub relocations: ObjRelocations, pub virtual_address: Option, pub file_offset: u64, @@ -40,38 +43,45 @@ pub struct ObjSections { sections: Vec, } +pub type SectionIndex = u32; + impl ObjSections { pub fn new(obj_kind: ObjKind, sections: Vec) -> Self { Self { obj_kind, sections } } - pub fn iter(&self) -> impl DoubleEndedIterator { - self.sections.iter().enumerate() + pub fn iter(&self) -> impl DoubleEndedIterator { + self.sections.iter().enumerate().map(|(i, s)| (i as SectionIndex, s)) } - pub fn iter_mut(&mut self) -> impl DoubleEndedIterator { - self.sections.iter_mut().enumerate() + pub fn iter_mut(&mut self) -> impl DoubleEndedIterator { + self.sections.iter_mut().enumerate().map(|(i, s)| (i as SectionIndex, s)) } - pub fn len(&self) -> usize { self.sections.len() } + pub fn len(&self) -> SectionIndex { self.sections.len() as SectionIndex } pub fn is_empty(&self) -> bool { self.sections.is_empty() } - pub fn next_section_index(&self) -> usize { self.sections.len() } + pub fn next_section_index(&self) -> SectionIndex { self.sections.len() as SectionIndex } - pub fn get(&self, index: usize) -> Option<&ObjSection> { self.sections.get(index) } - - pub fn get_mut(&mut self, index: usize) -> Option<&mut ObjSection> { - self.sections.get_mut(index) + pub fn get(&self, index: SectionIndex) -> Option<&ObjSection> { + self.sections.get(index as usize) } - pub fn get_elf_index(&self, elf_index: usize) -> Option<(usize, &ObjSection)> { + pub fn get_mut(&mut self, index: SectionIndex) -> Option<&mut ObjSection> { + self.sections.get_mut(index as usize) + } + + pub fn get_elf_index(&self, elf_index: SectionIndex) -> Option<(SectionIndex, &ObjSection)> { self.iter().find(|&(_, s)| s.elf_index == elf_index) } - pub fn get_elf_index_mut(&mut self, elf_index: usize) -> Option<(usize, &mut ObjSection)> { + pub fn get_elf_index_mut( + &mut self, + elf_index: SectionIndex, + ) -> Option<(SectionIndex, &mut ObjSection)> { self.iter_mut().find(|(_, s)| s.elf_index == elf_index) } - pub fn at_address(&self, addr: u32) -> Result<(usize, &ObjSection)> { + pub fn at_address(&self, addr: u32) -> Result<(SectionIndex, &ObjSection)> { ensure!( self.obj_kind == ObjKind::Executable, "Use of ObjSections::at_address in relocatable object" @@ -81,7 +91,7 @@ impl ObjSections { .ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr)) } - pub fn at_address_mut(&mut self, addr: u32) -> Result<(usize, &mut ObjSection)> { + pub fn at_address_mut(&mut self, addr: u32) -> Result<(SectionIndex, &mut ObjSection)> { ensure!( self.obj_kind == ObjKind::Executable, "Use of ObjSections::at_address_mut in relocatable object" @@ -91,7 +101,7 @@ impl ObjSections { .ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr)) } - pub fn with_range(&self, range: Range) -> Result<(usize, &ObjSection)> { + pub fn with_range(&self, range: Range) -> Result<(SectionIndex, &ObjSection)> { ensure!( self.obj_kind == ObjKind::Executable, "Use of ObjSections::with_range in relocatable object" @@ -104,46 +114,52 @@ impl ObjSections { pub fn by_kind( &self, kind: ObjSectionKind, - ) -> impl DoubleEndedIterator { + ) -> impl DoubleEndedIterator { self.iter().filter(move |(_, s)| s.kind == kind) } - pub fn by_name(&self, name: &str) -> Result> { + pub fn by_name(&self, name: &str) -> Result> { self.iter() .filter(move |(_, s)| s.name == name) .at_most_one() .map_err(|_| anyhow!("Multiple sections with name {}", name)) } - pub fn push(&mut self, section: ObjSection) -> usize { + pub fn push(&mut self, section: ObjSection) -> SectionIndex { let index = self.sections.len(); self.sections.push(section); - index + index as SectionIndex } pub fn all_splits( &self, - ) -> impl DoubleEndedIterator { + ) -> impl DoubleEndedIterator { self.iter() .flat_map(|(idx, s)| s.splits.iter().map(move |(addr, split)| (idx, s, addr, split))) } - pub fn common_bss_start(&self) -> Option<(usize, u32)> { + pub fn common_bss_start(&self) -> Option { let Ok(Some((section_index, section))) = self.by_name(".bss") else { return None; }; - section.splits.iter().find(|(_, split)| split.common).map(|(addr, _)| (section_index, addr)) + section + .splits + .iter() + .find(|(_, split)| split.common) + .map(|(addr, _)| SectionAddress::new(section_index, addr)) } } -impl Index for ObjSections { +impl Index for ObjSections { type Output = ObjSection; - fn index(&self, index: usize) -> &Self::Output { &self.sections[index] } + fn index(&self, index: SectionIndex) -> &Self::Output { &self.sections[index as usize] } } -impl IndexMut for ObjSections { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.sections[index] } +impl IndexMut for ObjSections { + fn index_mut(&mut self, index: SectionIndex) -> &mut Self::Output { + &mut self.sections[index as usize] + } } impl ObjSection { diff --git a/src/obj/splits.rs b/src/obj/splits.rs index 6240d98..147255a 100644 --- a/src/obj/splits.rs +++ b/src/obj/splits.rs @@ -4,7 +4,7 @@ use anyhow::{anyhow, Result}; use itertools::Itertools; use crate::{ - obj::{ObjInfo, ObjSection}, + obj::{ObjInfo, ObjSection, SectionIndex}, util::{nested::NestedVec, split::default_section_align}, }; @@ -28,7 +28,7 @@ impl ObjSplit { pub fn alignment( &self, obj: &ObjInfo, - section_index: usize, + section_index: SectionIndex, section: &ObjSection, split_addr: u32, ) -> u32 { diff --git a/src/obj/symbols.rs b/src/obj/symbols.rs index cce02f7..46b2a4e 100644 --- a/src/obj/symbols.rs +++ b/src/obj/symbols.rs @@ -12,7 +12,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; use crate::{ analysis::cfa::SectionAddress, - obj::{ObjKind, ObjRelocKind, ObjSections}, + obj::{sections::SectionIndex, ObjKind, ObjRelocKind, ObjSections}, util::{ config::{is_auto_jump_table, is_auto_label, is_auto_symbol, parse_u32}, nested::NestedVec, @@ -187,7 +187,7 @@ pub struct ObjSymbol { pub name: String, pub demangled_name: Option, pub address: u64, - pub section: Option, + pub section: Option, pub size: u64, pub size_known: bool, pub flags: ObjSymbolFlagSet, @@ -199,7 +199,7 @@ pub struct ObjSymbol { pub demangled_name_hash: Option, } -pub type SymbolIndex = usize; +pub type SymbolIndex = u32; #[derive(Debug, Clone)] pub struct ObjSymbols { @@ -216,8 +216,10 @@ impl ObjSymbols { let mut symbols_by_section: Vec>> = vec![]; let mut symbols_by_name = HashMap::>::new(); for (idx, symbol) in symbols.iter().enumerate() { + let idx = idx as SymbolIndex; symbols_by_address.nested_push(symbol.address as u32, idx); if let Some(section_idx) = symbol.section { + let section_idx = section_idx as usize; if section_idx >= symbols_by_section.len() { symbols_by_section.resize_with(section_idx + 1, BTreeMap::new); } @@ -312,7 +314,7 @@ impl ObjSymbols { } symbol_idx } else { - let target_symbol_idx = self.symbols.len(); + let target_symbol_idx = self.symbols.len() as SymbolIndex; self.add_direct(ObjSymbol { name: in_symbol.name, demangled_name: in_symbol.demangled_name, @@ -333,9 +335,10 @@ impl ObjSymbols { } pub fn add_direct(&mut self, in_symbol: ObjSymbol) -> Result { - let symbol_idx = self.symbols.len(); + let symbol_idx = self.symbols.len() as SymbolIndex; self.symbols_by_address.nested_push(in_symbol.address as u32, symbol_idx); if let Some(section_idx) = in_symbol.section { + let section_idx = section_idx as usize; if section_idx >= self.symbols_by_section.len() { self.symbols_by_section.resize_with(section_idx + 1, BTreeMap::new); } @@ -355,28 +358,30 @@ impl ObjSymbols { Ok(symbol_idx) } - pub fn iter(&self) -> impl DoubleEndedIterator { self.symbols.iter() } + pub fn iter(&self) -> impl DoubleEndedIterator { + self.symbols.iter().enumerate().map(|(i, s)| (i as SymbolIndex, s)) + } - pub fn count(&self) -> usize { self.symbols.len() } + pub fn count(&self) -> SymbolIndex { self.symbols.len() as SymbolIndex } pub fn at_section_address( &self, - section_idx: usize, + section_idx: SectionIndex, addr: u32, ) -> impl DoubleEndedIterator { self.symbols_by_section - .get(section_idx) + .get(section_idx as usize) .and_then(|v| v.get(&addr)) .into_iter() .flatten() - .map(move |&idx| (idx, &self.symbols[idx])) + .map(move |&idx| (idx, &self.symbols[idx as usize])) // "Stripped" symbols don't actually exist at the address .filter(|(_, sym)| !sym.flags.is_stripped()) } pub fn kind_at_section_address( &self, - section_idx: usize, + section_idx: SectionIndex, addr: u32, kind: ObjSymbolKind, ) -> Result> { @@ -397,7 +402,7 @@ impl ObjSymbols { self.symbols_by_section .iter() .flat_map(|v| v.iter().map(|(_, v)| v)) - .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) + .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize]))) } // Iterate over all ABS symbols @@ -405,24 +410,24 @@ impl ObjSymbols { debug_assert!(self.obj_kind == ObjKind::Executable); self.symbols_by_address .iter() - .flat_map(|(_, v)| v.iter().map(|&u| (u, &self.symbols[u]))) + .flat_map(|(_, v)| v.iter().map(|&u| (u, &self.symbols[u as usize]))) .filter(|(_, s)| s.section.is_none()) } // Iterate over range in address ascending order, excluding ABS symbols pub fn for_section_range( &self, - section_index: usize, + section_index: SectionIndex, range: R, ) -> impl DoubleEndedIterator where R: RangeBounds + Clone, { self.symbols_by_section - .get(section_index) + .get(section_index as usize) .into_iter() .flat_map(move |v| v.range(range.clone())) - .flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u]))) + .flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u as usize]))) } pub fn indexes_for_range( @@ -438,13 +443,13 @@ impl ObjSymbols { pub fn for_section( &self, - section_idx: usize, + section_idx: SectionIndex, ) -> impl DoubleEndedIterator { self.symbols_by_section - .get(section_idx) + .get(section_idx as usize) .into_iter() .flat_map(|v| v.iter().map(|(_, v)| v)) - .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) + .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize]))) } pub fn for_name( @@ -454,7 +459,7 @@ impl ObjSymbols { self.symbols_by_name .get(name) .into_iter() - .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) + .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize]))) } pub fn by_name(&self, name: &str) -> Result> { @@ -515,11 +520,11 @@ impl ObjSymbols { &self, kind: ObjSymbolKind, ) -> impl DoubleEndedIterator { - self.symbols.iter().enumerate().filter(move |(_, sym)| sym.kind == kind) + self.iter().filter(move |(_, sym)| sym.kind == kind) } pub fn replace(&mut self, index: SymbolIndex, symbol: ObjSymbol) -> Result<()> { - let symbol_ref = &mut self.symbols[index]; + let symbol_ref = &mut self.symbols[index as usize]; ensure!(symbol_ref.address == symbol.address, "Can't modify address with replace_symbol"); ensure!(symbol_ref.section == symbol.section, "Can't modify section with replace_symbol"); if symbol_ref.name != symbol.name { @@ -545,7 +550,7 @@ impl ObjSymbols { for (_addr, symbol_idxs) in self.indexes_for_range(..=target_addr.address).rev() { let symbols = symbol_idxs .iter() - .map(|&idx| (idx, &self.symbols[idx])) + .map(|&idx| (idx, &self.symbols[idx as usize])) .filter(|(_, sym)| { (sym.section.is_none() || sym.section == Some(target_addr.section)) && sym.referenced_by(reloc_kind) @@ -570,14 +575,14 @@ impl ObjSymbols { #[inline] pub fn flags(&mut self, idx: SymbolIndex) -> &mut ObjSymbolFlagSet { - &mut self.symbols[idx].flags + &mut self.symbols[idx as usize].flags } } impl Index for ObjSymbols { type Output = ObjSymbol; - fn index(&self, index: usize) -> &Self::Output { &self.symbols[index] } + fn index(&self, index: SymbolIndex) -> &Self::Output { &self.symbols[index as usize] } } impl ObjSymbol { diff --git a/src/util/alf.rs b/src/util/alf.rs index 7b66489..dbac286 100644 --- a/src/util/alf.rs +++ b/src/util/alf.rs @@ -7,7 +7,7 @@ use anyhow::Result; use io::{Error, ErrorKind}; use crate::{ - obj::{ObjSymbol, ObjSymbolKind}, + obj::{ObjSymbol, ObjSymbolKind, SectionIndex}, util::{ dol::{DolLike, DolSection, DolSectionKind}, reader::{ @@ -55,7 +55,7 @@ impl FromReader for AlfFile { data_size: section.data_size, size: section.size, kind, - index: sections.len(), + index: sections.len() as SectionIndex, }); } for sym in &symtab.symbols { @@ -230,7 +230,7 @@ impl AlfSymbol { name, demangled_name, address: self.address as u64, - section: Some(self.section as usize - 1), + section: Some(self.section as SectionIndex - 1), size: self.size as u64, size_known: true, flags: Default::default(), diff --git a/src/util/asm.rs b/src/util/asm.rs index ac2df16..d54951b 100644 --- a/src/util/asm.rs +++ b/src/util/asm.rs @@ -11,7 +11,7 @@ use ppc750cl::{Argument, Ins, InsIter, Opcode}; use crate::{ obj::{ ObjDataKind, ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol, - ObjSymbolKind, + ObjSymbolKind, SymbolIndex, }, util::nested::NestedVec, }; @@ -25,7 +25,7 @@ enum SymbolEntryKind { #[derive(Debug, Copy, Clone, Eq, PartialEq)] struct SymbolEntry { - index: usize, + index: SymbolIndex, kind: SymbolEntryKind, } @@ -44,7 +44,7 @@ where W: Write + ?Sized { } // We'll append generated symbols to the end - let mut symbols: Vec = obj.symbols.iter().cloned().collect(); + let mut symbols: Vec = obj.symbols.iter().map(|(_, s)| s.clone()).collect(); let mut section_entries: Vec>> = vec![]; let mut section_relocations: Vec> = vec![]; for (section_idx, section) in obj.sections.iter() { @@ -90,7 +90,7 @@ where W: Write + ?Sized { .map(|e| e.index); if target_symbol_idx.is_none() { let display_address = address as u64 + section.virtual_address.unwrap_or(0); - let symbol_idx = symbols.len(); + let symbol_idx = symbols.len() as SymbolIndex; symbols.push(ObjSymbol { name: format!(".L_{display_address:08X}"), address: display_address, @@ -131,7 +131,7 @@ where W: Write + ?Sized { if reloc.addend == 0 { continue; } - let target = &symbols[reloc.target_symbol]; + let target = &symbols[reloc.target_symbol as usize]; let target_section_idx = match target.section { Some(v) => v, None => continue, @@ -140,7 +140,7 @@ where W: Write + ?Sized { anyhow!("Invalid relocation target section: {:#010X} {:?}", reloc_address, target) })?; let address = (target.address as i64 + reloc.addend) as u64; - let vec = match section_entries[target_section_idx].entry(address as u32) { + let vec = match section_entries[target_section_idx as usize].entry(address as u32) { btree_map::Entry::Occupied(e) => e.into_mut(), btree_map::Entry::Vacant(e) => e.insert(vec![]), }; @@ -149,7 +149,7 @@ where W: Write + ?Sized { .any(|e| e.kind == SymbolEntryKind::Label || e.kind == SymbolEntryKind::Start) { let display_address = address + target_section.virtual_address.unwrap_or(0); - let symbol_idx = symbols.len(); + let symbol_idx = symbols.len() as SymbolIndex; symbols.push(ObjSymbol { name: format!(".L_{display_address:08X}"), address: display_address, @@ -181,13 +181,17 @@ where W: Write + ?Sized { } for (section_index, section) in obj.sections.iter() { - let entries = §ion_entries[section_index]; - let relocations = §ion_relocations[section_index]; + let entries = §ion_entries[section_index as usize]; + let relocations = §ion_relocations[section_index as usize]; let mut current_address = section.address as u32; let section_end = (section.address + section.size) as u32; - let subsection = - obj.sections.iter().take(section_index).filter(|(_, s)| s.name == section.name).count(); + let subsection = obj + .sections + .iter() + .take(section_index as usize) + .filter(|(_, s)| s.name == section.name) + .count(); loop { if current_address >= section_end { @@ -369,7 +373,7 @@ fn write_symbol_entry( where W: Write + ?Sized, { - let symbol = &symbols[entry.index]; + let symbol = &symbols[entry.index as usize]; // Skip writing certain symbols if symbol.kind == ObjSymbolKind::Section { @@ -452,13 +456,13 @@ where } fn parse_extab(symbols: &[ObjSymbol], entry: &SymbolEntry, section: &ObjSection) -> Result { - let symbol = &symbols[entry.index]; + let symbol = &symbols[entry.index as usize]; let data = section.symbol_data(symbol)?; let decoded = cwextab::decode_extab(data)?; let function_names = section .relocations .range(symbol.address as u32..(symbol.address + symbol.size) as u32) - .map(|(_, reloc)| symbols[reloc.target_symbol].name.clone()) + .map(|(_, reloc)| symbols[reloc.target_symbol as usize].name.clone()) .collect_vec(); decoded.to_string(function_names).ok_or_else(|| anyhow!("Failed to print extab entry")) } @@ -504,7 +508,7 @@ where .with_context(|| format!("At address {:#010X}", sym_addr))?; entry = entry_iter.next(); } else if current_address > sym_addr { - let dbg_symbols = vec.iter().map(|e| &symbols[e.index]).collect_vec(); + let dbg_symbols = vec.iter().map(|e| &symbols[e.index as usize]).collect_vec(); bail!( "Unaligned symbol entry @ {:#010X}:\n\t{:?}", section.virtual_address.unwrap_or(0) as u32 + sym_addr, @@ -585,7 +589,7 @@ fn find_symbol_kind( for entry in entries { match entry.kind { SymbolEntryKind::Start => { - let new_kind = symbols[entry.index].kind; + let new_kind = symbols[entry.index as usize].kind; if !matches!(new_kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) { ensure!( !found || new_kind == kind, @@ -611,11 +615,11 @@ fn find_data_kind( for entry in entries { match entry.kind { SymbolEntryKind::Start => { - let new_kind = symbols[entry.index].data_kind; + let new_kind = symbols[entry.index as usize].data_kind; if !matches!(new_kind, ObjDataKind::Unknown) { if found && new_kind != kind { for entry in entries { - log::error!("Symbol {:?}", symbols[entry.index]); + log::error!("Symbol {:?}", symbols[entry.index as usize]); } bail!( "Conflicting data kinds found: {kind:?} and {new_kind:?}", @@ -806,14 +810,14 @@ where ObjRelocKind::Absolute => { // Attempt to use .rel macro for relative relocations if reloc.addend != 0 { - let target = &symbols[reloc.target_symbol]; + let target = &symbols[reloc.target_symbol as usize]; let target_addr = (target.address as i64 + reloc.addend) as u32; if let Some(entry) = target .section - .and_then(|section_idx| section_entries[section_idx].get(&target_addr)) + .and_then(|section_idx| section_entries[section_idx as usize].get(&target_addr)) .and_then(|entries| entries.iter().find(|e| e.kind == SymbolEntryKind::Label)) { - let symbol = &symbols[entry.index]; + let symbol = &symbols[entry.index as usize]; write!(w, "\t.rel ")?; write_symbol_name(w, &target.name)?; write!(w, ", ")?; @@ -959,7 +963,7 @@ fn write_reloc_symbol( where W: Write + ?Sized, { - write_symbol_name(w, &symbols[reloc.target_symbol].name)?; + write_symbol_name(w, &symbols[reloc.target_symbol as usize].name)?; match reloc.addend.cmp(&0i64) { Ordering::Greater => write!(w, "+{:#X}", reloc.addend), Ordering::Less => write!(w, "-{:#X}", -reloc.addend), diff --git a/src/util/config.rs b/src/util/config.rs index c35f736..e683335 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -18,7 +18,7 @@ use crate::{ analysis::cfa::SectionAddress, obj::{ ObjDataKind, ObjInfo, ObjKind, ObjSectionKind, ObjSplit, ObjSymbol, ObjSymbolFlagSet, - ObjSymbolFlags, ObjSymbolKind, ObjUnit, + ObjSymbolFlags, ObjSymbolKind, ObjUnit, SectionIndex, }, util::{ file::{buf_writer, FileReadInfo}, @@ -621,7 +621,7 @@ fn parse_section_line(captures: Captures, state: &SplitState) -> Result Result { dol.sections().iter().filter(|section| section.kind == DolSectionKind::Text).count(); let mut eti_entries: Vec = Vec::new(); let mut eti_init_info_range: Option<(u32, u32)> = None; - let mut extab_section: Option = None; - let mut extabindex_section: Option = None; + let mut extab_section: Option = None; + let mut extabindex_section: Option = None; 'outer: for dol_section in dol.sections().iter().filter(|section| section.kind == DolSectionKind::Data) { @@ -537,8 +537,9 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result { } // Apply section indices - let mut init_section_index = None; + let mut init_section_index: Option = None; for (idx, section) in sections.iter_mut().enumerate() { + let idx = idx as SectionIndex; match section.name.as_str() { ".init" => { init_section_index = Some(idx); diff --git a/src/util/elf.rs b/src/util/elf.rs index fbbd80d..7fa204a 100644 --- a/src/util/elf.rs +++ b/src/util/elf.rs @@ -26,6 +26,7 @@ use crate::{ obj::{ ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjUnit, + SectionIndex as ObjSectionIndex, SymbolIndex as ObjSymbolIndex, }, util::{ comment::{CommentSym, MWComment}, @@ -97,7 +98,7 @@ where P: AsRef { size: section.size(), data: section.uncompressed_data()?.to_vec(), align: section.align(), - elf_index: section.index().0, + elf_index: section.index().0 as ObjSectionIndex, relocations: Default::default(), virtual_address: None, // Loaded from section symbol file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(), @@ -151,7 +152,7 @@ where P: AsRef { }; let mut symbols: Vec = vec![]; - let mut symbol_indexes: Vec> = vec![None /* ELF null symbol */]; + let mut symbol_indexes: Vec> = vec![None /* ELF null symbol */]; let mut section_starts = IndexMap::>::new(); let mut name_to_index = HashMap::::new(); // for resolving duplicate names let mut boundary_state = BoundaryState::LookForFile(Default::default()); @@ -307,7 +308,7 @@ where P: AsRef { symbol_indexes.push(None); continue; } - symbol_indexes.push(Some(symbols.len())); + symbol_indexes.push(Some(symbols.len() as ObjSymbolIndex)); let align = mw_comment.as_ref().map(|(_, vec)| vec[symbol.index().0].align); symbols.push(to_obj_symbol(&obj_file, &symbol, §ion_indexes, align)?); } @@ -401,7 +402,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { } writer.reserve_null_section_index(); - let mut out_sections: Vec = Vec::with_capacity(obj.sections.len()); + let mut out_sections: Vec = Vec::with_capacity(obj.sections.len() as usize); for (_, section) in obj.sections.iter() { let name = writer.add_section_name(section.name.as_bytes()); let index = writer.reserve_section_index(); @@ -416,7 +417,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { }); } - let mut rela_names: Vec = vec![Default::default(); obj.sections.len()]; + let mut rela_names: Vec = vec![Default::default(); obj.sections.len() as usize]; for (((_, section), out_section), rela_name) in obj.sections.iter().zip(&mut out_sections).zip(&mut rela_names) { @@ -449,7 +450,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { }); // Generate .comment data - let mut comment_data = Vec::::with_capacity(0x2C + obj.symbols.count() * 8); + let mut comment_data = Vec::::with_capacity(0x2C + obj.symbols.count() as usize * 8); mw_comment.to_writer_static(&mut comment_data, Endian::Big)?; // Null symbol CommentSym { align: 0, vis_flags: 0, active_flags: 0 } @@ -485,8 +486,8 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { None }; - let mut out_symbols: Vec = Vec::with_capacity(obj.symbols.count()); - let mut symbol_map = vec![None; obj.symbols.count()]; + let mut out_symbols: Vec = Vec::with_capacity(obj.symbols.count() as usize); + let mut symbol_map = vec![None; obj.symbols.count() as usize]; let mut section_symbol_offset = 0; let mut num_local = 0; @@ -532,7 +533,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { // Add section symbols for relocatable objects if obj.kind == ObjKind::Relocatable { for (section_index, section) in obj.sections.iter() { - let out_section_index = out_sections.get(section_index).map(|s| s.index); + let out_section_index = out_sections.get(section_index as usize).map(|s| s.index); let index = writer.reserve_symbol_index(out_section_index); let sym = object::write::elf::Sym { name: None, @@ -561,19 +562,19 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { for (symbol_index, symbol) in obj .symbols .iter() - .enumerate() .filter(|&(_, s)| s.flags.is_local()) - .chain(obj.symbols.iter().enumerate().filter(|&(_, s)| !s.flags.is_local())) + .chain(obj.symbols.iter().filter(|&(_, s)| !s.flags.is_local())) { if obj.kind == ObjKind::Relocatable && symbol.kind == ObjSymbolKind::Section { // We wrote section symbols above, so skip them here let section_index = symbol.section.ok_or_else(|| anyhow!("section symbol without section index"))?; - symbol_map[symbol_index] = Some(section_symbol_offset + section_index as u32); + symbol_map[symbol_index as usize] = + Some(section_symbol_offset as ObjSectionIndex + section_index); continue; } - let section = symbol.section.and_then(|idx| out_sections.get(idx)); + let section = symbol.section.and_then(|idx| out_sections.get(idx as usize)); let section_index = section.map(|s| s.index); let index = writer.reserve_symbol_index(section_index); let name_index = if symbol.name.is_empty() { @@ -617,7 +618,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { num_local = writer.symbol_count(); } out_symbols.push(OutSymbol { index, sym }); - symbol_map[symbol_index] = Some(index.0); + symbol_map[symbol_index as usize] = Some(index.0); if let Some((comment_data, _)) = &mut comment_data { CommentSym::from(symbol, export_all).to_writer_static(comment_data, Endian::Big)?; } @@ -635,7 +636,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { writer.reserve_file_header(); if obj.kind == ObjKind::Executable { - writer.reserve_program_headers(obj.sections.len() as u32); + writer.reserve_program_headers(obj.sections.len()); } for ((_, section), out_section) in obj.sections.iter().zip(&mut out_sections) { @@ -734,7 +735,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { ensure!(writer.len() == out_section.rela_offset); for (addr, reloc) in section.relocations.iter() { let (r_offset, r_type) = reloc.to_elf(addr); - let r_sym = symbol_map[reloc.target_symbol] + let r_sym = symbol_map[reloc.target_symbol as usize] .ok_or_else(|| anyhow!("Relocation against stripped symbol"))?; writer.write_relocation(true, &Rel { r_offset, r_sym, r_type, r_addend: reloc.addend }); } @@ -893,7 +894,7 @@ fn to_obj_symbol( name: name.to_string(), demangled_name: demangle(name, &Default::default()), address: symbol.address(), - section: section_idx, + section: section_idx.map(|s| s as ObjSectionIndex), size: symbol.size(), size_known: true, flags, @@ -927,7 +928,7 @@ pub fn to_obj_reloc_kind(flags: RelocationFlags) -> Result { fn to_obj_reloc( obj_file: &object::File<'_>, - symbol_indexes: &[Option], + symbol_indexes: &[Option], section_data: &[u8], address: u64, reloc: Relocation, diff --git a/src/util/lcf.rs b/src/util/lcf.rs index 00c18f5..bc88256 100644 --- a/src/util/lcf.rs +++ b/src/util/lcf.rs @@ -37,7 +37,7 @@ pub fn generate_ldscript( } let mut force_active = force_active.to_vec(); - for symbol in obj.symbols.iter() { + for (_, symbol) in obj.symbols.iter() { if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { force_active.push(symbol.name.clone()); } @@ -86,7 +86,7 @@ pub fn generate_ldscript_partial( } let mut force_active = force_active.to_vec(); - for symbol in obj.symbols.iter() { + for (_, symbol) in obj.symbols.iter() { if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { force_active.push(symbol.name.clone()); } diff --git a/src/util/map.rs b/src/util/map.rs index 917711b..e681bb4 100644 --- a/src/util/map.rs +++ b/src/util/map.rs @@ -21,7 +21,7 @@ use crate::{ obj::{ section_kind_for_section, ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSections, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, - ObjSymbols, ObjUnit, + ObjSymbols, ObjUnit, SectionIndex, }, util::nested::NestedVec, vfs::open_file, @@ -770,7 +770,7 @@ pub fn apply_map(mut result: MapInfo, obj: &mut ObjInfo) -> Result<()> { && (s.address + s.size) <= (section.address + section.size) as u32 }) } else { - result.sections.iter().filter(|s| s.size > 0).nth(section_index) + result.sections.iter().filter(|s| s.size > 0).nth(section_index as usize) }; if let Some(info) = opt { if section.section_known && section.name != info.name { @@ -814,7 +814,7 @@ pub fn apply_map(mut result: MapInfo, obj: &mut ObjInfo) -> Result<()> { ".data" } } else if let Some(section_name) = - DEFAULT_REL_SECTIONS.get(section.elf_index) + DEFAULT_REL_SECTIONS.get(section.elf_index as usize) { section_name } else { @@ -1014,7 +1014,7 @@ pub fn create_obj(result: &MapInfo) -> Result { fn add_symbol( obj: &mut ObjInfo, symbol_entry: &SymbolEntry, - section: Option, + section: Option, ignore_alignment: bool, ) -> Result<()> { let demangled_name = demangle(&symbol_entry.name, &DemangleOptions::default()); diff --git a/src/util/rel.rs b/src/util/rel.rs index dc4864f..33b8e76 100644 --- a/src/util/rel.rs +++ b/src/util/rel.rs @@ -13,7 +13,7 @@ use crate::{ array_ref_mut, obj::{ ObjArchitecture, ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol, - ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, + ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, SectionIndex, }, util::{ align_up, @@ -418,7 +418,7 @@ where R: Read + Seek + ?Sized { _ => None, // determined later } .unwrap_or_default() as u64, - elf_index: idx, + elf_index: idx as SectionIndex, relocations: Default::default(), virtual_address: None, // TODO option to set? file_offset: offset as u64, @@ -440,7 +440,7 @@ where R: Read + Seek + ?Sized { let (section_index, _) = sections .iter() .enumerate() - .find(|&(_, section)| section.elf_index == rel_section_idx as usize) + .find(|&(_, section)| section.elf_index == rel_section_idx as SectionIndex) .ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?; log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}"); let mut flags = ObjSymbolFlagSet(ObjSymbolFlags::Global.into()); @@ -450,7 +450,7 @@ where R: Read + Seek + ?Sized { symbols.push(ObjSymbol { name: name.to_string(), address: offset as u64, - section: Some(section_index), + section: Some(section_index as SectionIndex), flags, kind: ObjSymbolKind::Function, ..Default::default() diff --git a/src/util/rso.rs b/src/util/rso.rs index bc78e6c..863e95f 100644 --- a/src/util/rso.rs +++ b/src/util/rso.rs @@ -9,7 +9,7 @@ use cwdemangle::{demangle, DemangleOptions}; use crate::{ obj::{ ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, - ObjSymbolFlags, ObjSymbolKind, + ObjSymbolFlags, ObjSymbolKind, SectionIndex, }, util::{ file::{read_c_string, read_string}, @@ -452,7 +452,7 @@ where R: Read + Seek + ?Sized { size: size as u64, data, align: 0, - elf_index: idx as usize, + elf_index: idx as SectionIndex, relocations: Default::default(), virtual_address: None, // TODO option to set? file_offset: offset as u64, @@ -476,13 +476,13 @@ where R: Read + Seek + ?Sized { let (section_index, _) = sections .iter() .enumerate() - .find(|&(_, section)| section.elf_index == rel_section_idx as usize) + .find(|&(_, section)| section.elf_index == rel_section_idx as SectionIndex) .ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?; log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}"); symbols.push(ObjSymbol { name: name.to_string(), address: offset as u64, - section: Some(section_index), + section: Some(section_index as SectionIndex), flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()), kind: ObjSymbolKind::Function, ..Default::default() @@ -526,7 +526,7 @@ where R: Read + Seek + ?Sized { let section = sections .iter() .enumerate() - .find(|&(_, section)| section.elf_index == symbol.section_index as usize) + .find(|&(_, section)| section.elf_index == symbol.section_index as SectionIndex) .map(|(idx, _)| idx) // HACK: selfiles won't have any sections .unwrap_or(symbol.section_index as usize); @@ -541,7 +541,7 @@ where R: Read + Seek + ?Sized { name, demangled_name, address: symbol.offset as u64, - section: Some(section), + section: Some(section as SectionIndex), ..Default::default() }); } diff --git a/src/util/signatures.rs b/src/util/signatures.rs index 043fd08..b4a305d 100644 --- a/src/util/signatures.rs +++ b/src/util/signatures.rs @@ -18,7 +18,7 @@ use crate::{ array_ref, obj::{ ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSymbol, ObjSymbolFlagSet, - ObjSymbolKind, + ObjSymbolKind, SectionIndex, SymbolIndex, }, util::elf::process_elf, }; @@ -36,13 +36,13 @@ pub struct OutSymbol { pub struct OutReloc { pub offset: u32, pub kind: ObjRelocKind, - pub symbol: usize, + pub symbol: u32, pub addend: i32, } #[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] pub struct FunctionSignature { - pub symbol: usize, + pub symbol: u32, pub hash: String, pub signature: String, pub symbols: Vec, @@ -92,12 +92,12 @@ pub fn check_signatures( let mut name = None; for signature in signatures { if name.is_none() { - name = Some(signature.symbols[signature.symbol].name.clone()); + name = Some(signature.symbols[signature.symbol as usize].name.clone()); } if check_signature(data, signature)? { log::debug!( "Found {} @ {:#010X} (hash {})", - signature.symbols[signature.symbol].name, + signature.symbols[signature.symbol as usize].name, addr, signature.hash ); @@ -114,9 +114,9 @@ pub fn apply_symbol( obj: &mut ObjInfo, target: SectionAddress, sig_symbol: &OutSymbol, -) -> Result { +) -> Result { let mut target_section_index = - if target.section == usize::MAX { None } else { Some(target.section) }; + if target.section == SectionIndex::MAX { None } else { Some(target.section) }; if let Some(target_section_index) = target_section_index { let target_section = &mut obj.sections[target_section_index]; if !target_section.section_known { @@ -154,7 +154,7 @@ pub fn apply_signature( addr: SectionAddress, signature: &FunctionSignature, ) -> Result<()> { - let in_symbol = &signature.symbols[signature.symbol]; + let in_symbol = &signature.symbols[signature.symbol as usize]; let symbol_idx = apply_symbol(obj, addr, in_symbol)?; let mut tracker = Tracker::new(obj); for reloc in &signature.relocations { @@ -185,7 +185,7 @@ pub fn apply_signature( } _ => bail!("Relocation mismatch: {:?} != {:?}", reloc, sig_reloc.kind), }; - let sig_symbol = &signature.symbols[sig_reloc.symbol]; + let sig_symbol = &signature.symbols[sig_reloc.symbol as usize]; // log::info!("Processing relocation {:#010X} {:?} -> {:#010X} {:?}", reloc_addr, reloc, target, sig_symbol); let target_symbol_idx = apply_symbol(obj, target, sig_symbol)?; let obj_reloc = ObjReloc { @@ -200,7 +200,7 @@ pub fn apply_signature( for reloc in &signature.relocations { let addr = addr + reloc.offset; if !tracker.relocations.contains_key(&addr) { - let sig_symbol = &signature.symbols[reloc.symbol]; + let sig_symbol = &signature.symbols[reloc.symbol as usize]; bail!("Missing relocation @ {:#010X}: {:?} -> {:?}", addr, reloc, sig_symbol); } } @@ -250,7 +250,7 @@ pub fn generate_signature

(path: P, symbol_name: &str) -> Result { let mut out_symbols: Vec = Vec::new(); let mut out_relocs: Vec = Vec::new(); - let mut symbol_map: BTreeMap = BTreeMap::new(); + let mut symbol_map: BTreeMap = BTreeMap::new(); let mut obj = process_elf(path)?; if obj.kind == ObjKind::Executable @@ -312,7 +312,7 @@ where P: AsRef { let symbol_idx = match symbol_map.entry(reloc.target_symbol) { btree_map::Entry::Vacant(e) => { let target = &obj.symbols[reloc.target_symbol]; - let symbol_idx = out_symbols.len(); + let symbol_idx = out_symbols.len() as u32; e.insert(symbol_idx); out_symbols.push(OutSymbol { kind: target.kind, diff --git a/src/util/split.rs b/src/util/split.rs index 44645af..4dfae4a 100644 --- a/src/util/split.rs +++ b/src/util/split.rs @@ -15,7 +15,7 @@ use crate::{ obj::{ ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocations, ObjSection, ObjSectionKind, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, - ObjUnit, + ObjUnit, SectionIndex, SymbolIndex, }, util::{align_up, comment::MWComment}, }; @@ -444,8 +444,8 @@ fn create_gap_splits(obj: &mut ObjInfo) -> Result<()> { /// Ensures that all .bss splits following a common split are also marked as common. fn update_common_splits(obj: &mut ObjInfo, common_start: Option) -> Result<()> { - let Some((bss_section_index, common_bss_start)) = (match common_start { - Some(addr) => Some(( + let Some(common_bss_start) = (match common_start { + Some(addr) => Some(SectionAddress::new( obj.sections.by_name(".bss")?.ok_or_else(|| anyhow!("Failed to find .bss section"))?.0, addr, )), @@ -454,8 +454,8 @@ fn update_common_splits(obj: &mut ObjInfo, common_start: Option) -> Result< return Ok(()); }; log::debug!("Found common BSS start at {:#010X}", common_bss_start); - let bss_section = &mut obj.sections[bss_section_index]; - for (addr, split) in bss_section.splits.for_range_mut(common_bss_start..) { + let bss_section = &mut obj.sections[common_bss_start.section]; + for (addr, split) in bss_section.splits.for_range_mut(common_bss_start.address..) { if !split.common { split.common = true; log::debug!("Added common flag to split {} at {:#010X}", split.unit, addr); @@ -593,8 +593,8 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> { .peekable(); while let Some((_, symbol)) = iter.next() { // Common BSS is allowed to have gaps and overlaps to accurately match the common BSS inflation bug - if matches!(common_bss, Some((idx, addr)) if - section_index == idx && symbol.address as u32 >= addr) + if matches!(common_bss, Some(addr) if + section_index == addr.section && symbol.address as u32 >= addr.address) { continue; } @@ -933,11 +933,11 @@ fn resolve_link_order(obj: &ObjInfo) -> Result> { #[instrument(level = "debug", skip(obj))] pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result> { let mut objects: Vec = vec![]; - let mut object_symbols: Vec>> = vec![]; + let mut object_symbols: Vec>> = vec![]; let mut name_to_obj: HashMap = HashMap::new(); for unit in &obj.link_order { name_to_obj.insert(unit.name.clone(), objects.len()); - object_symbols.push(vec![None; obj.symbols.count()]); + object_symbols.push(vec![None; obj.symbols.count() as usize]); let mut split_obj = ObjInfo::new( ObjKind::Relocatable, ObjArchitecture::PowerPc, @@ -1079,7 +1079,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result) -> Result) -> Result) -> Result { reloc.target_symbol = out_sym_idx; } @@ -1189,7 +1190,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result) -> Result) -> Result bool { } /// Locate the end address of a section when excluding linker generated objects -pub fn end_for_section(obj: &ObjInfo, section_index: usize) -> Result { +pub fn end_for_section(obj: &ObjInfo, section_index: SectionIndex) -> Result { let section = obj .sections .get(section_index)