Add dummy symbols to empty sections

Allows diffing sections without symbols

Resolves #87
This commit is contained in:
Luke Street 2024-08-11 14:27:27 -06:00
parent 177bd5e895
commit de74dfdba7
3 changed files with 55 additions and 26 deletions

View File

@ -612,6 +612,20 @@ fn matching_symbols(
Ok(matches) Ok(matches)
} }
fn unmatched_symbols<'section, 'used>(
section: &'section ObjSection,
section_idx: usize,
used: Option<&'used HashSet<SymbolRef>>,
) -> impl Iterator<Item = (usize, &'section ObjSymbol)> + 'used
where
'section: 'used,
{
section.symbols.iter().enumerate().filter(move |&(symbol_idx, _)| {
// Skip symbols that have already been matched
!used.map(|u| u.contains(&SymbolRef { section_idx, symbol_idx })).unwrap_or(false)
})
}
fn find_symbol( fn find_symbol(
obj: Option<&ObjInfo>, obj: Option<&ObjInfo>,
in_symbol: &ObjSymbol, in_symbol: &ObjSymbol,
@ -624,8 +638,8 @@ fn find_symbol(
if section.kind != in_section.kind { if section.kind != in_section.kind {
continue; continue;
} }
if let Some(symbol_idx) = if let Some((symbol_idx, _)) = unmatched_symbols(section, section_idx, used)
section.symbols.iter().position(|symbol| symbol.name == in_symbol.name) .find(|(_, symbol)| symbol.name == in_symbol.name)
{ {
return Some(SymbolRef { section_idx, symbol_idx }); return Some(SymbolRef { section_idx, symbol_idx });
} }
@ -638,9 +652,11 @@ fn find_symbol(
if let Some((section_idx, section)) = if let Some((section_idx, section)) =
obj.sections.iter().enumerate().find(|(_, s)| s.name == in_section.name) obj.sections.iter().enumerate().find(|(_, s)| s.name == in_section.name)
{ {
if let Some(symbol_idx) = section.symbols.iter().position(|symbol| { if let Some((symbol_idx, _)) =
symbol.address == in_symbol.address && symbol.name.starts_with('@') unmatched_symbols(section, section_idx, used).find(|(_, symbol)| {
}) { symbol.address == in_symbol.address && symbol.name.starts_with('@')
})
{
return Some(SymbolRef { section_idx, symbol_idx }); return Some(SymbolRef { section_idx, symbol_idx });
} }
} }
@ -655,13 +671,7 @@ fn find_symbol(
continue; continue;
} }
if let Some((symbol_idx, _)) = if let Some((symbol_idx, _)) =
section.symbols.iter().enumerate().find(|&(symbol_idx, symbol)| { unmatched_symbols(section, section_idx, used).find(|&(_, symbol)| {
if used
.map(|u| u.contains(&SymbolRef { section_idx, symbol_idx }))
.unwrap_or(false)
{
return false;
}
if let Some((p, s)) = symbol.name.split_once('$') { if let Some((p, s)) = symbol.name.split_once('$') {
prefix == p && s.chars().all(char::is_numeric) prefix == p && s.chars().all(char::is_numeric)
} else { } else {

View File

@ -160,6 +160,23 @@ fn symbols_by_section(
} }
} }
} }
if result.is_empty() {
// Dummy symbol for empty sections
result.push(ObjSymbol {
name: format!("[{}]", section.name),
demangled_name: None,
has_extab: false,
extab_name: None,
extabindex_name: None,
address: 0,
section_address: 0,
size: section.size,
size_known: true,
flags: Default::default(),
addend: 0,
virtual_address: None,
});
}
Ok(result) Ok(result)
} }

View File

@ -233,21 +233,23 @@ fn symbol_ui(
{ {
selected = symbol_diff.symbol_ref == sym_ref; selected = symbol_diff.symbol_ref == sym_ref;
} }
write_text("[", appearance.text_color, &mut job, appearance.code_font.clone()); if !symbol.flags.0.is_empty() {
if symbol.flags.0.contains(ObjSymbolFlags::Common) { write_text("[", appearance.text_color, &mut job, appearance.code_font.clone());
write_text("c", appearance.replace_color, &mut job, appearance.code_font.clone()); if symbol.flags.0.contains(ObjSymbolFlags::Common) {
} else if symbol.flags.0.contains(ObjSymbolFlags::Global) { write_text("c", appearance.replace_color, &mut job, appearance.code_font.clone());
write_text("g", appearance.insert_color, &mut job, appearance.code_font.clone()); } else if symbol.flags.0.contains(ObjSymbolFlags::Global) {
} else if symbol.flags.0.contains(ObjSymbolFlags::Local) { write_text("g", appearance.insert_color, &mut job, appearance.code_font.clone());
write_text("l", appearance.text_color, &mut job, appearance.code_font.clone()); } else if symbol.flags.0.contains(ObjSymbolFlags::Local) {
write_text("l", appearance.text_color, &mut job, appearance.code_font.clone());
}
if symbol.flags.0.contains(ObjSymbolFlags::Weak) {
write_text("w", appearance.text_color, &mut job, appearance.code_font.clone());
}
if symbol.flags.0.contains(ObjSymbolFlags::Hidden) {
write_text("h", appearance.deemphasized_text_color, &mut job, appearance.code_font.clone());
}
write_text("] ", appearance.text_color, &mut job, appearance.code_font.clone());
} }
if symbol.flags.0.contains(ObjSymbolFlags::Weak) {
write_text("w", appearance.text_color, &mut job, appearance.code_font.clone());
}
if symbol.flags.0.contains(ObjSymbolFlags::Hidden) {
write_text("h", appearance.deemphasized_text_color, &mut job, appearance.code_font.clone());
}
write_text("] ", appearance.text_color, &mut job, appearance.code_font.clone());
if let Some(match_percent) = symbol_diff.match_percent { if let Some(match_percent) = symbol_diff.match_percent {
write_text("(", appearance.text_color, &mut job, appearance.code_font.clone()); write_text("(", appearance.text_color, &mut job, appearance.code_font.clone());
write_text( write_text(