mirror of https://github.com/encounter/objdiff.git
Add simple symbol search & handle symbol relocation addends
This commit is contained in:
parent
b7b177af4c
commit
1e44f73b2f
|
@ -181,6 +181,10 @@ fn resolve_branches(vec: &mut [ObjInsDiff]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn address_eq(left: &ObjSymbol, right: &ObjSymbol) -> bool {
|
||||
left.address as i64 + left.addend == right.address as i64 + right.addend
|
||||
}
|
||||
|
||||
fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bool {
|
||||
if let (Some(left), Some(right)) = (left_reloc, right_reloc) {
|
||||
if left.kind != right.kind {
|
||||
|
@ -190,7 +194,7 @@ fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bo
|
|||
match (&left.target_section, &right.target_section) {
|
||||
(Some(sl), Some(sr)) => {
|
||||
// Match if section and name or address match
|
||||
sl == sr && (name_matches || left.target.address == right.target.address)
|
||||
sl == sr && (name_matches || address_eq(&left.target, &right.target))
|
||||
}
|
||||
(Some(_), None) => false,
|
||||
(None, Some(_)) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ fn to_obj_section_kind(kind: SectionKind) -> ObjSectionKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_obj_symbol(obj_file: &File<'_>, symbol: &Symbol<'_, '_>) -> Result<ObjSymbol> {
|
||||
fn to_obj_symbol(obj_file: &File<'_>, symbol: &Symbol<'_, '_>, addend: i64) -> Result<ObjSymbol> {
|
||||
let mut name = symbol.name().context("Failed to process symbol name")?;
|
||||
if name.is_empty() {
|
||||
println!("Found empty sym: {:?}", symbol);
|
||||
|
@ -56,6 +56,7 @@ fn to_obj_symbol(obj_file: &File<'_>, symbol: &Symbol<'_, '_>) -> Result<ObjSymb
|
|||
size: symbol.size(),
|
||||
size_known: symbol.size() != 0,
|
||||
flags,
|
||||
addend,
|
||||
diff_symbol: None,
|
||||
instructions: vec![],
|
||||
match_percent: 0.0,
|
||||
|
@ -118,7 +119,7 @@ fn symbols_by_section(obj_file: &File<'_>, section: &ObjSection) -> Result<Vec<O
|
|||
continue;
|
||||
}
|
||||
}
|
||||
result.push(to_obj_symbol(obj_file, &symbol)?);
|
||||
result.push(to_obj_symbol(obj_file, &symbol, 0)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +141,7 @@ fn common_symbols(obj_file: &File<'_>) -> Result<Vec<ObjSymbol>> {
|
|||
let mut result = Vec::<ObjSymbol>::new();
|
||||
for symbol in obj_file.symbols() {
|
||||
if symbol.is_common() {
|
||||
result.push(to_obj_symbol(obj_file, &symbol)?);
|
||||
result.push(to_obj_symbol(obj_file, &symbol, 0)?);
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
|
@ -169,7 +170,7 @@ fn find_section_symbol(
|
|||
}
|
||||
continue;
|
||||
}
|
||||
return to_obj_symbol(obj_file, &symbol);
|
||||
return to_obj_symbol(obj_file, &symbol, 0);
|
||||
}
|
||||
let (name, offset) = closest_symbol
|
||||
.and_then(|s| s.name().map(|n| (n, s.address())).ok())
|
||||
|
@ -177,13 +178,14 @@ fn find_section_symbol(
|
|||
.unwrap_or(("<unknown>", 0));
|
||||
let offset_addr = address - offset;
|
||||
Ok(ObjSymbol {
|
||||
name: if offset_addr > 0 { format!("{}+{:#X}", name, address) } else { name.to_string() },
|
||||
name: name.to_string(),
|
||||
demangled_name: None,
|
||||
address,
|
||||
section_address: address - section.address(),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
addend: offset_addr as i64,
|
||||
diff_symbol: None,
|
||||
instructions: vec![],
|
||||
match_percent: 0.0,
|
||||
|
@ -257,7 +259,7 @@ fn relocations_by_section(
|
|||
// println!("Reloc: {:?}, symbol: {:?}", reloc, symbol);
|
||||
let target = match symbol.kind() {
|
||||
SymbolKind::Text | SymbolKind::Data | SymbolKind::Unknown => {
|
||||
to_obj_symbol(obj_file, &symbol)
|
||||
to_obj_symbol(obj_file, &symbol, reloc.addend())
|
||||
}
|
||||
SymbolKind::Section => {
|
||||
let addend = if reloc.has_implicit_addend() {
|
||||
|
|
|
@ -101,6 +101,7 @@ pub struct ObjSymbol {
|
|||
pub size: u64,
|
||||
pub size_known: bool,
|
||||
pub flags: ObjSymbolFlagSet,
|
||||
pub addend: i64,
|
||||
|
||||
// Diff
|
||||
pub diff_symbol: Option<String>,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::default::Default;
|
||||
|
||||
use cwdemangle::demangle;
|
||||
use egui::{text::LayoutJob, Color32, FontFamily, FontId, Label, Sense, TextFormat};
|
||||
use egui::{text::LayoutJob, Color32, Label, Sense};
|
||||
use egui_extras::{Size, StripBuilder, TableBuilder};
|
||||
use ppc750cl::Argument;
|
||||
|
||||
|
@ -11,52 +11,50 @@ use crate::{
|
|||
ObjInfo, ObjIns, ObjInsArg, ObjInsArgDiff, ObjInsDiff, ObjInsDiffKind, ObjReloc,
|
||||
ObjRelocKind, ObjSymbol,
|
||||
},
|
||||
views::symbol_diff::match_color_for_symbol,
|
||||
views::{symbol_diff::match_color_for_symbol, write_text, COLOR_RED, FONT_SIZE},
|
||||
};
|
||||
|
||||
const FONT_SIZE: f32 = 14.0;
|
||||
const FONT_ID: FontId = FontId::new(FONT_SIZE, FontFamily::Monospace);
|
||||
|
||||
const COLOR_RED: Color32 = Color32::from_rgb(200, 40, 41);
|
||||
|
||||
fn write_text(str: &str, color: Color32, job: &mut LayoutJob) {
|
||||
job.append(str, 0.0, TextFormat { font_id: FONT_ID, color, ..Default::default() });
|
||||
fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob) {
|
||||
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
if reloc.target.addend != 0 {
|
||||
write_text(&format!("+{:X}", reloc.target.addend), color, job);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_reloc(reloc: &ObjReloc, job: &mut LayoutJob) {
|
||||
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
|
||||
fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob) {
|
||||
match reloc.kind {
|
||||
ObjRelocKind::PpcAddr16Lo => {
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text("@l", Color32::GRAY, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text("@l", color, job);
|
||||
}
|
||||
ObjRelocKind::PpcAddr16Hi => {
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text("@h", Color32::GRAY, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text("@h", color, job);
|
||||
}
|
||||
ObjRelocKind::PpcAddr16Ha => {
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text("@ha", Color32::GRAY, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text("@ha", color, job);
|
||||
}
|
||||
ObjRelocKind::PpcEmbSda21 => {
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text("@sda21", Color32::GRAY, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text("@sda21", color, job);
|
||||
}
|
||||
ObjRelocKind::MipsHi16 => {
|
||||
write_text("%hi(", Color32::GRAY, job);
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text(")", Color32::GRAY, job);
|
||||
write_text("%hi(", color, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text(")", color, job);
|
||||
}
|
||||
ObjRelocKind::MipsLo16 => {
|
||||
write_text("%lo(", Color32::GRAY, job);
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_text(")", Color32::GRAY, job);
|
||||
write_text("%lo(", color, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
write_text(")", color, job);
|
||||
}
|
||||
ObjRelocKind::Absolute
|
||||
| ObjRelocKind::PpcRel24
|
||||
| ObjRelocKind::PpcRel14
|
||||
| ObjRelocKind::Mips26 => {
|
||||
write_text(name, Color32::LIGHT_GRAY, job);
|
||||
write_reloc_name(reloc, color, job);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -113,10 +111,10 @@ fn write_ins(
|
|||
}
|
||||
},
|
||||
ObjInsArg::Reloc => {
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), job);
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), base_color, job);
|
||||
}
|
||||
ObjInsArg::RelocWithBase => {
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), job);
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), base_color, job);
|
||||
write_text("(", base_color, job);
|
||||
writing_offset = true;
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
use egui::{text::LayoutJob, Color32, FontFamily, FontId, TextFormat};
|
||||
|
||||
pub(crate) mod config;
|
||||
pub(crate) mod function_diff;
|
||||
pub(crate) mod jobs;
|
||||
pub(crate) mod symbol_diff;
|
||||
|
||||
const FONT_SIZE: f32 = 14.0;
|
||||
const FONT_ID: FontId = FontId::new(FONT_SIZE, FontFamily::Monospace);
|
||||
|
||||
const COLOR_RED: Color32 = Color32::from_rgb(200, 40, 41);
|
||||
|
||||
fn write_text(str: &str, color: Color32, job: &mut LayoutJob) {
|
||||
job.append(str, 0.0, TextFormat { font_id: FONT_ID, color, ..Default::default() });
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use egui::{
|
||||
text::LayoutJob, CollapsingHeader, Color32, FontFamily, FontId, Rgba, ScrollArea,
|
||||
SelectableLabel, TextFormat, Ui, Widget,
|
||||
text::LayoutJob, CollapsingHeader, Color32, Rgba, ScrollArea,
|
||||
SelectableLabel, Ui, Widget,
|
||||
};
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||
app::{View, ViewState},
|
||||
jobs::objdiff::BuildStatus,
|
||||
obj::{ObjInfo, ObjSymbol, ObjSymbolFlags},
|
||||
views::write_text,
|
||||
};
|
||||
|
||||
pub fn match_color_for_symbol(symbol: &ObjSymbol) -> Color32 {
|
||||
|
@ -20,13 +21,6 @@ pub fn match_color_for_symbol(symbol: &ObjSymbol) -> Color32 {
|
|||
}
|
||||
}
|
||||
|
||||
const FONT_SIZE: f32 = 14.0;
|
||||
const FONT_ID: FontId = FontId::new(FONT_SIZE, FontFamily::Monospace);
|
||||
|
||||
fn write_text(str: &str, color: Color32, job: &mut LayoutJob) {
|
||||
job.append(str, 0.0, TextFormat { font_id: FONT_ID, color, ..Default::default() });
|
||||
}
|
||||
|
||||
fn symbol_context_menu_ui(ui: &mut Ui, symbol: &ObjSymbol) {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
|
@ -104,6 +98,16 @@ fn symbol_ui(
|
|||
}
|
||||
}
|
||||
|
||||
fn symbol_matches_search(symbol: &ObjSymbol, search_str: &str) -> bool {
|
||||
search_str.is_empty()
|
||||
|| symbol.name.contains(search_str)
|
||||
|| symbol
|
||||
.demangled_name
|
||||
.as_ref()
|
||||
.map(|s| s.to_ascii_lowercase().contains(search_str))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn symbol_list_ui(
|
||||
ui: &mut Ui,
|
||||
obj: &ObjInfo,
|
||||
|
@ -111,7 +115,11 @@ fn symbol_list_ui(
|
|||
selected_symbol: &mut Option<String>,
|
||||
current_view: &mut View,
|
||||
reverse_function_order: bool,
|
||||
search: &mut String,
|
||||
) {
|
||||
ui.text_edit_singleline(search);
|
||||
let lower_search = search.to_ascii_lowercase();
|
||||
|
||||
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
|
@ -131,6 +139,9 @@ fn symbol_list_ui(
|
|||
.show(ui, |ui| {
|
||||
if section.name == ".text" && reverse_function_order {
|
||||
for symbol in section.symbols.iter().rev() {
|
||||
if !symbol_matches_search(symbol, &lower_search) {
|
||||
continue;
|
||||
}
|
||||
symbol_ui(
|
||||
ui,
|
||||
symbol,
|
||||
|
@ -141,6 +152,9 @@ fn symbol_list_ui(
|
|||
}
|
||||
} else {
|
||||
for symbol in §ion.symbols {
|
||||
if !symbol_matches_search(symbol, &lower_search) {
|
||||
continue;
|
||||
}
|
||||
symbol_ui(
|
||||
ui,
|
||||
symbol,
|
||||
|
@ -168,11 +182,12 @@ fn build_log_ui(ui: &mut Ui, status: &BuildStatus) {
|
|||
}
|
||||
|
||||
pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) {
|
||||
if let (Some(result), highlighted_symbol, selected_symbol, current_view) = (
|
||||
if let (Some(result), highlighted_symbol, selected_symbol, current_view, search) = (
|
||||
&view_state.build,
|
||||
&mut view_state.highlighted_symbol,
|
||||
&mut view_state.selected_symbol,
|
||||
&mut view_state.current_view,
|
||||
&mut view_state.search,
|
||||
) {
|
||||
StripBuilder::new(ui).size(Size::exact(40.0)).size(Size::remainder()).vertical(
|
||||
|mut strip| {
|
||||
|
@ -223,6 +238,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) {
|
|||
selected_symbol,
|
||||
current_view,
|
||||
view_state.reverse_fn_order,
|
||||
search,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -241,6 +257,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) {
|
|||
selected_symbol,
|
||||
current_view,
|
||||
view_state.reverse_fn_order,
|
||||
search,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue