From f06a6ffbdd0027a7498fe2001a2c1ef29a62abc7 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Thu, 3 Aug 2023 19:04:17 -0400 Subject: [PATCH] Ignore ABS symbols in ObjSymbols::for_range - Add ObjSymbols::iter_ordered for all symbols (including ABS) - Extract duplicated logic into ObjSymbols::for_relocation --- src/analysis/tracker.rs | 64 ++---------------------------------- src/cmd/dol.rs | 2 +- src/cmd/rel.rs | 64 ++---------------------------------- src/obj/mod.rs | 72 +++++++++++++++++++++++++++++++++++++++++ src/util/config.rs | 2 +- 5 files changed, 80 insertions(+), 124 deletions(-) diff --git a/src/analysis/tracker.rs b/src/analysis/tracker.rs index 6452ac6..afe0859 100644 --- a/src/analysis/tracker.rs +++ b/src/analysis/tracker.rs @@ -519,67 +519,9 @@ impl Tracker { Some(v) => v, None => continue, }; - // Try to find a previous sized symbol that encompasses the target - let target_symbol = { - let mut result = None; - for (_addr, symbol_idxs) in obj.symbols.indexes_for_range(..=target).rev() { - let symbol_idx = if symbol_idxs.len() == 1 { - symbol_idxs.first().cloned().unwrap() - } else { - let mut symbol_idxs = symbol_idxs.to_vec(); - symbol_idxs.sort_by_key(|&symbol_idx| { - let symbol = obj.symbols.at(symbol_idx); - let mut rank = match symbol.kind { - ObjSymbolKind::Function | ObjSymbolKind::Object => { - match reloc_kind { - ObjRelocKind::PpcAddr16Hi - | ObjRelocKind::PpcAddr16Ha - | ObjRelocKind::PpcAddr16Lo => 1, - ObjRelocKind::Absolute - | ObjRelocKind::PpcRel24 - | ObjRelocKind::PpcRel14 - | ObjRelocKind::PpcEmbSda21 => 2, - } - } - // Label - ObjSymbolKind::Unknown => match reloc_kind { - ObjRelocKind::PpcAddr16Hi - | ObjRelocKind::PpcAddr16Ha - | ObjRelocKind::PpcAddr16Lo - if !symbol.name.starts_with("..") => - { - 3 - } - _ => 1, - }, - ObjSymbolKind::Section => -1, - }; - if symbol.size > 0 { - rank += 1; - } - -rank - }); - match symbol_idxs.first().cloned() { - Some(v) => v, - None => continue, - } - }; - let symbol = obj.symbols.at(symbol_idx); - if symbol.address == target as u64 { - result = Some(symbol_idx); - break; - } - if symbol.size > 0 { - if symbol.address + symbol.size > target as u64 { - result = Some(symbol_idx); - } - break; - } - } - result - }; - if let Some(symbol_idx) = target_symbol { - let symbol = obj.symbols.at(symbol_idx); + if let Some((symbol_idx, symbol)) = + obj.symbols.for_relocation(target, reloc_kind)? + { let symbol_address = symbol.address; // TODO meh if data_kind != ObjDataKind::Unknown diff --git a/src/cmd/dol.rs b/src/cmd/dol.rs index d8bd594..ef2b2ad 100644 --- a/src/cmd/dol.rs +++ b/src/cmd/dol.rs @@ -109,7 +109,7 @@ fn info(args: InfoArgs) -> Result<()> { } println!("\nDiscovered symbols:"); println!("\t{: >23} | {: <10} | {: <10}", "Name", "Address", "Size"); - for (_, symbol) in obj.symbols.for_range(..) { + for (_, symbol) in obj.symbols.iter_ordered() { if symbol.name.starts_with('@') || symbol.name.starts_with("fn_") { continue; } diff --git a/src/cmd/rel.rs b/src/cmd/rel.rs index 88e453e..68a747e 100644 --- a/src/cmd/rel.rs +++ b/src/cmd/rel.rs @@ -161,67 +161,9 @@ fn merge(args: MergeArgs) -> Result<()> { let source_section_index = obj.section_at(source_addr)?.index; let target_section_index = obj.section_at(target_addr)?.index; - // Try to find a previous sized symbol that encompasses the target - let target_symbol = { - let mut result = None; - for (_addr, symbol_idxs) in obj.symbols.indexes_for_range(..=target_addr).rev() { - let symbol_idx = if symbol_idxs.len() == 1 { - symbol_idxs.first().cloned().unwrap() - } else { - let mut symbol_idxs = symbol_idxs.to_vec(); - symbol_idxs.sort_by_key(|&symbol_idx| { - let symbol = obj.symbols.at(symbol_idx); - let mut rank = match symbol.kind { - ObjSymbolKind::Function | ObjSymbolKind::Object => { - match rel_reloc.kind { - ObjRelocKind::PpcAddr16Hi - | ObjRelocKind::PpcAddr16Ha - | ObjRelocKind::PpcAddr16Lo => 1, - ObjRelocKind::Absolute - | ObjRelocKind::PpcRel24 - | ObjRelocKind::PpcRel14 - | ObjRelocKind::PpcEmbSda21 => 2, - } - } - // Label - ObjSymbolKind::Unknown => match rel_reloc.kind { - ObjRelocKind::PpcAddr16Hi - | ObjRelocKind::PpcAddr16Ha - | ObjRelocKind::PpcAddr16Lo - if !symbol.name.starts_with("..") => - { - 3 - } - _ => 1, - }, - ObjSymbolKind::Section => -1, - }; - if symbol.size > 0 { - rank += 1; - } - -rank - }); - match symbol_idxs.first().cloned() { - Some(v) => v, - None => continue, - } - }; - let symbol = obj.symbols.at(symbol_idx); - if symbol.address == target_addr as u64 { - result = Some(symbol_idx); - break; - } - if symbol.size > 0 { - if symbol.address + symbol.size > target_addr as u64 { - result = Some(symbol_idx); - } - break; - } - } - result - }; - let (symbol_idx, addend) = if let Some(symbol_idx) = target_symbol { - let symbol = obj.symbols.at(symbol_idx); + let (symbol_idx, addend) = if let Some((symbol_idx, symbol)) = + obj.symbols.for_relocation(target_addr, rel_reloc.kind)? + { (symbol_idx, target_addr as i64 - symbol.address as i64) } else { // Create a new label diff --git a/src/obj/mod.rs b/src/obj/mod.rs index 182de7a..5b095d3 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -341,6 +341,14 @@ impl ObjSymbols { Ok(result) } + // Iterate over all in address ascending order, including ABS symbols + pub fn iter_ordered(&self) -> impl DoubleEndedIterator { + self.symbols_by_address + .iter() + .flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u]))) + } + + // Iterate over range in address ascending order, excluding ABS symbols pub fn for_range( &self, range: R, @@ -351,6 +359,8 @@ impl ObjSymbols { self.symbols_by_address .range(range) .flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u]))) + // Ignore ABS symbols + .filter(move |(_, sym)| sym.section.is_some()) } pub fn indexes_for_range( @@ -421,6 +431,68 @@ impl ObjSymbols { *symbol_ref = symbol; Ok(()) } + + // Try to find a previous sized symbol that encompasses the target + pub fn for_relocation( + &self, + target_addr: u32, + reloc_kind: ObjRelocKind, + ) -> Result> { + let mut result = None; + for (_addr, symbol_idxs) in self.indexes_for_range(..=target_addr).rev() { + let symbol_idx = if symbol_idxs.len() == 1 { + symbol_idxs.first().cloned().unwrap() + } else { + let mut symbol_idxs = symbol_idxs.to_vec(); + symbol_idxs.sort_by_key(|&symbol_idx| { + let symbol = self.at(symbol_idx); + let mut rank = match symbol.kind { + ObjSymbolKind::Function | ObjSymbolKind::Object => match reloc_kind { + ObjRelocKind::PpcAddr16Hi + | ObjRelocKind::PpcAddr16Ha + | ObjRelocKind::PpcAddr16Lo => 1, + ObjRelocKind::Absolute + | ObjRelocKind::PpcRel24 + | ObjRelocKind::PpcRel14 + | ObjRelocKind::PpcEmbSda21 => 2, + }, + // Label + ObjSymbolKind::Unknown => match reloc_kind { + ObjRelocKind::PpcAddr16Hi + | ObjRelocKind::PpcAddr16Ha + | ObjRelocKind::PpcAddr16Lo + if !symbol.name.starts_with("..") => + { + 3 + } + _ => 1, + }, + ObjSymbolKind::Section => -1, + }; + if symbol.size > 0 { + rank += 1; + } + -rank + }); + match symbol_idxs.first().cloned() { + Some(v) => v, + None => continue, + } + }; + let symbol = self.at(symbol_idx); + if symbol.address == target_addr as u64 { + result = Some((symbol_idx, symbol)); + break; + } + if symbol.size > 0 { + if symbol.address + symbol.size > target_addr as u64 { + result = Some((symbol_idx, symbol)); + } + break; + } + } + Ok(result) + } } impl ObjInfo { diff --git a/src/util/config.rs b/src/util/config.rs index da806a0..7b7a899 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -106,7 +106,7 @@ fn is_skip_symbol(symbol: &ObjSymbol) -> bool { } pub fn write_symbols(w: &mut W, obj: &ObjInfo) -> Result<()> { - for (_, symbol) in obj.symbols.for_range(..) { + for (_, symbol) in obj.symbols.iter_ordered() { if symbol.kind == ObjSymbolKind::Section // Ignore absolute symbols for now (usually linker-generated) || symbol.section.is_none()