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)
}
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(
obj: Option<&ObjInfo>,
in_symbol: &ObjSymbol,
@ -624,8 +638,8 @@ fn find_symbol(
if section.kind != in_section.kind {
continue;
}
if let Some(symbol_idx) =
section.symbols.iter().position(|symbol| symbol.name == in_symbol.name)
if let Some((symbol_idx, _)) = unmatched_symbols(section, section_idx, used)
.find(|(_, symbol)| symbol.name == in_symbol.name)
{
return Some(SymbolRef { section_idx, symbol_idx });
}
@ -638,9 +652,11 @@ fn find_symbol(
if let Some((section_idx, section)) =
obj.sections.iter().enumerate().find(|(_, s)| s.name == in_section.name)
{
if let Some(symbol_idx) = section.symbols.iter().position(|symbol| {
symbol.address == in_symbol.address && symbol.name.starts_with('@')
}) {
if let Some((symbol_idx, _)) =
unmatched_symbols(section, section_idx, used).find(|(_, symbol)| {
symbol.address == in_symbol.address && symbol.name.starts_with('@')
})
{
return Some(SymbolRef { section_idx, symbol_idx });
}
}
@ -655,13 +671,7 @@ fn find_symbol(
continue;
}
if let Some((symbol_idx, _)) =
section.symbols.iter().enumerate().find(|&(symbol_idx, symbol)| {
if used
.map(|u| u.contains(&SymbolRef { section_idx, symbol_idx }))
.unwrap_or(false)
{
return false;
}
unmatched_symbols(section, section_idx, used).find(|&(_, symbol)| {
if let Some((p, s)) = symbol.name.split_once('$') {
prefix == p && s.chars().all(char::is_numeric)
} 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)
}

View File

@ -233,21 +233,23 @@ fn symbol_ui(
{
selected = symbol_diff.symbol_ref == sym_ref;
}
write_text("[", appearance.text_color, &mut job, appearance.code_font.clone());
if symbol.flags.0.contains(ObjSymbolFlags::Common) {
write_text("c", appearance.replace_color, &mut job, appearance.code_font.clone());
} else if symbol.flags.0.contains(ObjSymbolFlags::Global) {
write_text("g", appearance.insert_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.is_empty() {
write_text("[", appearance.text_color, &mut job, appearance.code_font.clone());
if symbol.flags.0.contains(ObjSymbolFlags::Common) {
write_text("c", appearance.replace_color, &mut job, appearance.code_font.clone());
} else if symbol.flags.0.contains(ObjSymbolFlags::Global) {
write_text("g", appearance.insert_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 {
write_text("(", appearance.text_color, &mut job, appearance.code_font.clone());
write_text(