Ignore ABS symbols in ObjSymbols::for_range

- Add ObjSymbols::iter_ordered for all symbols (including ABS)
- Extract duplicated logic into ObjSymbols::for_relocation
This commit is contained in:
Luke Street 2023-08-03 19:04:17 -04:00
parent 8f461b8e0a
commit f06a6ffbdd
5 changed files with 80 additions and 124 deletions

View File

@ -519,67 +519,9 @@ impl Tracker {
Some(v) => v, Some(v) => v,
None => continue, None => continue,
}; };
// Try to find a previous sized symbol that encompasses the target if let Some((symbol_idx, symbol)) =
let target_symbol = { obj.symbols.for_relocation(target, reloc_kind)?
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);
let symbol_address = symbol.address; let symbol_address = symbol.address;
// TODO meh // TODO meh
if data_kind != ObjDataKind::Unknown if data_kind != ObjDataKind::Unknown

View File

@ -109,7 +109,7 @@ fn info(args: InfoArgs) -> Result<()> {
} }
println!("\nDiscovered symbols:"); println!("\nDiscovered symbols:");
println!("\t{: >23} | {: <10} | {: <10}", "Name", "Address", "Size"); 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_") { if symbol.name.starts_with('@') || symbol.name.starts_with("fn_") {
continue; continue;
} }

View File

@ -161,67 +161,9 @@ fn merge(args: MergeArgs) -> Result<()> {
let source_section_index = obj.section_at(source_addr)?.index; let source_section_index = obj.section_at(source_addr)?.index;
let target_section_index = obj.section_at(target_addr)?.index; let target_section_index = obj.section_at(target_addr)?.index;
// Try to find a previous sized symbol that encompasses the target let (symbol_idx, addend) = if let Some((symbol_idx, symbol)) =
let target_symbol = { obj.symbols.for_relocation(target_addr, rel_reloc.kind)?
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);
(symbol_idx, target_addr as i64 - symbol.address as i64) (symbol_idx, target_addr as i64 - symbol.address as i64)
} else { } else {
// Create a new label // Create a new label

View File

@ -341,6 +341,14 @@ impl ObjSymbols {
Ok(result) Ok(result)
} }
// Iterate over all in address ascending order, including ABS symbols
pub fn iter_ordered(&self) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> {
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<R>( pub fn for_range<R>(
&self, &self,
range: R, range: R,
@ -351,6 +359,8 @@ impl ObjSymbols {
self.symbols_by_address self.symbols_by_address
.range(range) .range(range)
.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])))
// Ignore ABS symbols
.filter(move |(_, sym)| sym.section.is_some())
} }
pub fn indexes_for_range<R>( pub fn indexes_for_range<R>(
@ -421,6 +431,68 @@ impl ObjSymbols {
*symbol_ref = symbol; *symbol_ref = symbol;
Ok(()) Ok(())
} }
// Try to find a previous sized symbol that encompasses the target
pub fn for_relocation(
&self,
target_addr: u32,
reloc_kind: ObjRelocKind,
) -> Result<Option<(SymbolIndex, &ObjSymbol)>> {
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 { impl ObjInfo {

View File

@ -106,7 +106,7 @@ fn is_skip_symbol(symbol: &ObjSymbol) -> bool {
} }
pub fn write_symbols<W: Write>(w: &mut W, obj: &ObjInfo) -> Result<()> { pub fn write_symbols<W: Write>(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 if symbol.kind == ObjSymbolKind::Section
// Ignore absolute symbols for now (usually linker-generated) // Ignore absolute symbols for now (usually linker-generated)
|| symbol.section.is_none() || symbol.section.is_none()