mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 07:03:39 +00:00
Reimplement colorized data relocation hover diffs (#182)
* Reimplement colorized data relocation hover diffs * Fix objdiff-wasm build Data diffing doesn't seem to be fully implemented in objdiff-wasm yet, so just putting placeholders in so it compiles. * Reloc hover: Add separators, override special color too
This commit is contained in:
parent
7b00a9e9f2
commit
196c003a92
@ -325,10 +325,14 @@ pub enum SymbolNavigationKind {
|
|||||||
Extab,
|
Extab,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
||||||
pub enum HoverItemColor {
|
pub enum HoverItemColor {
|
||||||
Normal, // Gray
|
#[default]
|
||||||
|
Normal, // Gray
|
||||||
Emphasized, // White
|
Emphasized, // White
|
||||||
Special, // Blue
|
Special, // Blue
|
||||||
|
Delete, // Red
|
||||||
|
Insert, // Green
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum HoverItem {
|
pub enum HoverItem {
|
||||||
@ -355,7 +359,12 @@ pub fn symbol_context(obj: &Object, symbol_index: usize) -> Vec<ContextItem> {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_hover(obj: &Object, symbol_index: usize, addend: i64) -> Vec<HoverItem> {
|
pub fn symbol_hover(
|
||||||
|
obj: &Object,
|
||||||
|
symbol_index: usize,
|
||||||
|
addend: i64,
|
||||||
|
override_color: Option<HoverItemColor>,
|
||||||
|
) -> Vec<HoverItem> {
|
||||||
let symbol = &obj.symbols[symbol_index];
|
let symbol = &obj.symbols[symbol_index];
|
||||||
let addend_str = match addend.cmp(&0i64) {
|
let addend_str = match addend.cmp(&0i64) {
|
||||||
Ordering::Greater => format!("+{:x}", addend),
|
Ordering::Greater => format!("+{:x}", addend),
|
||||||
@ -366,51 +375,51 @@ pub fn symbol_hover(obj: &Object, symbol_index: usize, addend: i64) -> Vec<Hover
|
|||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Name".into(),
|
label: "Name".into(),
|
||||||
value: format!("{}{}", symbol.name, addend_str),
|
value: format!("{}{}", symbol.name, addend_str),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
if let Some(demangled_name) = &symbol.demangled_name {
|
if let Some(demangled_name) = &symbol.demangled_name {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Demangled".into(),
|
label: "Demangled".into(),
|
||||||
value: demangled_name.into(),
|
value: demangled_name.into(),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(section) = symbol.section {
|
if let Some(section) = symbol.section {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Section".into(),
|
label: "Section".into(),
|
||||||
value: obj.sections[section].name.clone(),
|
value: obj.sections[section].name.clone(),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Address".into(),
|
label: "Address".into(),
|
||||||
value: format!("{:x}{}", symbol.address, addend_str),
|
value: format!("{:x}{}", symbol.address, addend_str),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
if symbol.flags.contains(SymbolFlag::SizeInferred) {
|
if symbol.flags.contains(SymbolFlag::SizeInferred) {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Size".into(),
|
label: "Size".into(),
|
||||||
value: format!("{:x} (inferred)", symbol.size),
|
value: format!("{:x} (inferred)", symbol.size),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Size".into(),
|
label: "Size".into(),
|
||||||
value: format!("{:x}", symbol.size),
|
value: format!("{:x}", symbol.size),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(align) = symbol.align {
|
if let Some(align) = symbol.align {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Alignment".into(),
|
label: "Alignment".into(),
|
||||||
value: align.get().to_string(),
|
value: align.get().to_string(),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(address) = symbol.virtual_address {
|
if let Some(address) = symbol.virtual_address {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Virtual address".into(),
|
label: "Virtual address".into(),
|
||||||
value: format!("{:x}", address),
|
value: format!("{:x}", address),
|
||||||
color: HoverItemColor::Special,
|
color: override_color.clone().unwrap_or(HoverItemColor::Special),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -443,22 +452,31 @@ pub fn relocation_context(
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relocation_hover(obj: &Object, reloc: ResolvedRelocation) -> Vec<HoverItem> {
|
pub fn relocation_hover(
|
||||||
|
obj: &Object,
|
||||||
|
reloc: ResolvedRelocation,
|
||||||
|
override_color: Option<HoverItemColor>,
|
||||||
|
) -> Vec<HoverItem> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
if let Some(name) = obj.arch.reloc_name(reloc.relocation.flags) {
|
if let Some(name) = obj.arch.reloc_name(reloc.relocation.flags) {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Relocation".into(),
|
label: "Relocation".into(),
|
||||||
value: name.to_string(),
|
value: name.to_string(),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
out.push(HoverItem::Text {
|
out.push(HoverItem::Text {
|
||||||
label: "Relocation".into(),
|
label: "Relocation".into(),
|
||||||
value: format!("<{:?}>", reloc.relocation.flags),
|
value: format!("<{:?}>", reloc.relocation.flags),
|
||||||
color: HoverItemColor::Normal,
|
color: override_color.clone().unwrap_or_default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
out.append(&mut symbol_hover(obj, reloc.relocation.target_symbol, reloc.relocation.addend));
|
out.append(&mut symbol_hover(
|
||||||
|
obj,
|
||||||
|
reloc.relocation.target_symbol,
|
||||||
|
reloc.relocation.addend,
|
||||||
|
override_color,
|
||||||
|
));
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,7 +563,7 @@ pub fn instruction_hover(
|
|||||||
}
|
}
|
||||||
if let Some(reloc) = resolved.relocation {
|
if let Some(reloc) = resolved.relocation {
|
||||||
out.push(HoverItem::Separator);
|
out.push(HoverItem::Separator);
|
||||||
out.append(&mut relocation_hover(obj, reloc));
|
out.append(&mut relocation_hover(obj, reloc, None));
|
||||||
if let Some(ty) = obj.arch.guess_data_type(resolved) {
|
if let Some(ty) = obj.arch.guess_data_type(resolved) {
|
||||||
let literals = display_ins_data_literals(obj, resolved);
|
let literals = display_ins_data_literals(obj, resolved);
|
||||||
if !literals.is_empty() {
|
if !literals.is_empty() {
|
||||||
|
@ -5,7 +5,7 @@ use objdiff_core::{
|
|||||||
diff::{
|
diff::{
|
||||||
DataDiff, DataDiffKind, DataRelocationDiff,
|
DataDiff, DataDiffKind, DataRelocationDiff,
|
||||||
data::resolve_relocation,
|
data::resolve_relocation,
|
||||||
display::{ContextItem, HoverItem, relocation_context, relocation_hover},
|
display::{ContextItem, HoverItem, HoverItemColor, relocation_context, relocation_hover},
|
||||||
},
|
},
|
||||||
obj::Object,
|
obj::Object,
|
||||||
};
|
};
|
||||||
@ -19,6 +19,7 @@ fn data_row_hover(obj: &Object, diffs: &[(DataDiff, Vec<DataRelocationDiff>)]) -
|
|||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let reloc_diffs = diffs.iter().flat_map(|(_, reloc_diffs)| reloc_diffs);
|
let reloc_diffs = diffs.iter().flat_map(|(_, reloc_diffs)| reloc_diffs);
|
||||||
let mut prev_reloc = None;
|
let mut prev_reloc = None;
|
||||||
|
let mut first = true;
|
||||||
for reloc_diff in reloc_diffs {
|
for reloc_diff in reloc_diffs {
|
||||||
let reloc = &reloc_diff.reloc;
|
let reloc = &reloc_diff.reloc;
|
||||||
if prev_reloc == Some(reloc) {
|
if prev_reloc == Some(reloc) {
|
||||||
@ -29,11 +30,16 @@ fn data_row_hover(obj: &Object, diffs: &[(DataDiff, Vec<DataRelocationDiff>)]) -
|
|||||||
}
|
}
|
||||||
prev_reloc = Some(reloc);
|
prev_reloc = Some(reloc);
|
||||||
|
|
||||||
// TODO: Change hover text color depending on Insert/Delete/Replace kind
|
if first {
|
||||||
// let color = get_color_for_diff_kind(reloc_diff.kind, appearance);
|
first = false;
|
||||||
|
} else {
|
||||||
|
out.push(HoverItem::Separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
let color = get_hover_item_color_for_diff_kind(reloc_diff.kind);
|
||||||
|
|
||||||
let reloc = resolve_relocation(&obj.symbols, reloc);
|
let reloc = resolve_relocation(&obj.symbols, reloc);
|
||||||
out.append(&mut relocation_hover(obj, reloc));
|
out.append(&mut relocation_hover(obj, reloc, Some(color)));
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
@ -97,6 +103,15 @@ fn get_color_for_diff_kind(diff_kind: DataDiffKind, appearance: &Appearance) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_hover_item_color_for_diff_kind(diff_kind: DataDiffKind) -> HoverItemColor {
|
||||||
|
match diff_kind {
|
||||||
|
DataDiffKind::None => HoverItemColor::Normal,
|
||||||
|
DataDiffKind::Replace => HoverItemColor::Special,
|
||||||
|
DataDiffKind::Delete => HoverItemColor::Delete,
|
||||||
|
DataDiffKind::Insert => HoverItemColor::Insert,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn data_row_ui(
|
pub(crate) fn data_row_ui(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
obj: Option<&Object>,
|
obj: Option<&Object>,
|
||||||
|
@ -795,6 +795,8 @@ pub fn hover_items_ui(ui: &mut Ui, items: Vec<HoverItem>, appearance: &Appearanc
|
|||||||
if !label.is_empty() {
|
if !label.is_empty() {
|
||||||
let label_color = match color {
|
let label_color = match color {
|
||||||
HoverItemColor::Special => appearance.replace_color,
|
HoverItemColor::Special => appearance.replace_color,
|
||||||
|
HoverItemColor::Delete => appearance.delete_color,
|
||||||
|
HoverItemColor::Insert => appearance.insert_color,
|
||||||
_ => appearance.highlight_color,
|
_ => appearance.highlight_color,
|
||||||
};
|
};
|
||||||
write_text(&label, label_color, &mut job, appearance.code_font.clone());
|
write_text(&label, label_color, &mut job, appearance.code_font.clone());
|
||||||
|
@ -512,7 +512,7 @@ pub fn symbol_hover_ui(
|
|||||||
ui.scope(|ui| {
|
ui.scope(|ui| {
|
||||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||||
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Wrap);
|
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Wrap);
|
||||||
hover_items_ui(ui, symbol_hover(ctx.obj, symbol_idx, 0), appearance);
|
hover_items_ui(ui, symbol_hover(ctx.obj, symbol_idx, 0, None), appearance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +230,9 @@ impl GuestDisplay for Component {
|
|||||||
) -> Vec<HoverItem> {
|
) -> Vec<HoverItem> {
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
diff::display::symbol_hover(obj, symbol_display.symbol as usize, 0 /* TODO */)
|
// TODO: colorize replaced/deleted/inserted relocations
|
||||||
|
let override_color = None;
|
||||||
|
diff::display::symbol_hover(obj, symbol_display.symbol as usize, 0, override_color)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| HoverItem::from(item))
|
.map(|item| HoverItem::from(item))
|
||||||
.collect()
|
.collect()
|
||||||
@ -501,6 +503,8 @@ impl From<diff::display::HoverItemColor> for HoverItemColor {
|
|||||||
diff::display::HoverItemColor::Normal => HoverItemColor::Normal,
|
diff::display::HoverItemColor::Normal => HoverItemColor::Normal,
|
||||||
diff::display::HoverItemColor::Emphasized => HoverItemColor::Emphasized,
|
diff::display::HoverItemColor::Emphasized => HoverItemColor::Emphasized,
|
||||||
diff::display::HoverItemColor::Special => HoverItemColor::Special,
|
diff::display::HoverItemColor::Special => HoverItemColor::Special,
|
||||||
|
diff::display::HoverItemColor::Delete => HoverItemColor::Delete,
|
||||||
|
diff::display::HoverItemColor::Insert => HoverItemColor::Insert,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,8 @@ interface display {
|
|||||||
normal,
|
normal,
|
||||||
emphasized,
|
emphasized,
|
||||||
special,
|
special,
|
||||||
|
delete,
|
||||||
|
insert,
|
||||||
}
|
}
|
||||||
|
|
||||||
record hover-item-text {
|
record hover-item-text {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user