Updates & initial MIPS support

This commit is contained in:
2022-09-11 13:52:55 -04:00
parent 7bbdba5566
commit b55c919f4d
13 changed files with 874 additions and 239 deletions

View File

@@ -1,85 +1,124 @@
use std::sync::{Arc, RwLock};
use crate::{
app::{AppConfig, ViewState},
jobs::build::queue_build,
app::{AppConfig, DiffKind, ViewState},
jobs::{bindiff::queue_bindiff, build::queue_build},
};
pub fn config_ui(ui: &mut egui::Ui, config: &Arc<RwLock<AppConfig>>, view_state: &mut ViewState) {
let mut config_guard = config.write().unwrap();
let AppConfig { project_dir, project_dir_change, build_asm_dir, build_src_dir, build_obj } =
&mut *config_guard;
let AppConfig {
project_dir,
project_dir_change,
build_asm_dir,
build_src_dir,
build_obj,
left_obj,
right_obj,
} = &mut *config_guard;
if ui.button("Select project dir").clicked() {
if let Some(path) = rfd::FileDialog::new().pick_folder() {
*project_dir = Some(path);
*project_dir_change = true;
*build_asm_dir = None;
*build_src_dir = None;
*build_obj = None;
}
}
if let Some(dir) = project_dir {
ui.label(dir.to_string_lossy());
}
ui.separator();
if let Some(project_dir) = project_dir {
if ui.button("Select asm build dir").clicked() {
if let Some(path) = rfd::FileDialog::new().set_directory(&project_dir).pick_folder() {
*build_asm_dir = Some(path);
if view_state.diff_kind == DiffKind::SplitObj {
if ui.button("Select project dir").clicked() {
if let Some(path) = rfd::FileDialog::new().pick_folder() {
*project_dir = Some(path);
*project_dir_change = true;
*build_asm_dir = None;
*build_src_dir = None;
*build_obj = None;
}
}
if let Some(dir) = build_asm_dir {
if let Some(dir) = project_dir {
ui.label(dir.to_string_lossy());
}
ui.separator();
if ui.button("Select src build dir").clicked() {
if let Some(path) = rfd::FileDialog::new().set_directory(&project_dir).pick_folder() {
*build_src_dir = Some(path);
*build_obj = None;
if let Some(project_dir) = project_dir {
if ui.button("Select asm build dir").clicked() {
if let Some(path) = rfd::FileDialog::new().set_directory(&project_dir).pick_folder()
{
*build_asm_dir = Some(path);
*build_obj = None;
}
}
}
if let Some(dir) = build_src_dir {
ui.label(dir.to_string_lossy());
if let Some(dir) = build_asm_dir {
ui.label(dir.to_string_lossy());
}
ui.separator();
if ui.button("Select src build dir").clicked() {
if let Some(path) = rfd::FileDialog::new().set_directory(&project_dir).pick_folder()
{
*build_src_dir = Some(path);
*build_obj = None;
}
}
if let Some(dir) = build_src_dir {
ui.label(dir.to_string_lossy());
}
ui.separator();
}
ui.separator();
}
if let Some(build_src_dir) = build_src_dir {
if ui.button("Select obj").clicked() {
if let Some(path) = rfd::FileDialog::new()
.set_directory(&build_src_dir)
.add_filter("Object file", &["o"])
.pick_file()
{
let mut new_build_obj: Option<String> = None;
if let Ok(obj_path) = path.strip_prefix(&build_src_dir) {
new_build_obj = Some(obj_path.display().to_string());
} else if let Some(build_asm_dir) = build_asm_dir {
if let Ok(obj_path) = path.strip_prefix(&build_asm_dir) {
if let Some(build_src_dir) = build_src_dir {
if ui.button("Select obj").clicked() {
if let Some(path) = rfd::FileDialog::new()
.set_directory(&build_src_dir)
.add_filter("Object file", &["o", "elf"])
.pick_file()
{
let mut new_build_obj: Option<String> = None;
if let Ok(obj_path) = path.strip_prefix(&build_src_dir) {
new_build_obj = Some(obj_path.display().to_string());
} else if let Some(build_asm_dir) = build_asm_dir {
if let Ok(obj_path) = path.strip_prefix(&build_asm_dir) {
new_build_obj = Some(obj_path.display().to_string());
}
}
if let Some(new_build_obj) = new_build_obj {
*build_obj = Some(new_build_obj.clone());
view_state.jobs.push(queue_build(new_build_obj, config.clone()));
}
}
if let Some(new_build_obj) = new_build_obj {
*build_obj = Some(new_build_obj.clone());
view_state.jobs.push(queue_build(new_build_obj, config.clone()));
}
if let Some(build_obj) = build_obj {
ui.label(&*build_obj);
if ui.button("Build").clicked() {
view_state.jobs.push(queue_build(build_obj.clone(), config.clone()));
}
}
ui.separator();
}
if let Some(build_obj) = build_obj {
ui.label(&*build_obj);
if ui.button("Build").clicked() {
view_state.jobs.push(queue_build(build_obj.clone(), config.clone()));
} else if view_state.diff_kind == DiffKind::WholeBinary {
if ui.button("Select left obj").clicked() {
if let Some(path) =
rfd::FileDialog::new().add_filter("Object file", &["o", "elf"]).pick_file()
{
*left_obj = Some(path);
}
}
if let Some(obj) = left_obj {
ui.label(obj.to_string_lossy());
}
ui.separator();
if ui.button("Select right obj").clicked() {
if let Some(path) =
rfd::FileDialog::new().add_filter("Object file", &["o", "elf"]).pick_file()
{
*right_obj = Some(path);
}
}
if let Some(obj) = right_obj {
ui.label(obj.to_string_lossy());
}
if let (Some(_), Some(_)) = (left_obj, right_obj) {
if ui.button("Build").clicked() {
view_state.jobs.push(queue_bindiff(config.clone()));
}
}
}
ui.checkbox(&mut view_state.reverse_fn_order, "Reverse function order (deferred)");

View File

@@ -25,13 +25,39 @@ fn write_text(str: &str, color: Color32, job: &mut LayoutJob) {
fn write_reloc(reloc: &ObjReloc, job: &mut LayoutJob) {
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
write_text(name, Color32::LIGHT_GRAY, job);
match reloc.kind {
ObjRelocKind::PpcAddr16Lo => write_text("@l", Color32::GRAY, job),
ObjRelocKind::PpcAddr16Hi => write_text("@h", Color32::GRAY, job),
ObjRelocKind::PpcAddr16Ha => write_text("@ha", Color32::GRAY, job),
ObjRelocKind::PpcEmbSda21 => write_text("@sda21", Color32::GRAY, job),
_ => {}
ObjRelocKind::PpcAddr16Lo => {
write_text(name, Color32::LIGHT_GRAY, job);
write_text("@l", Color32::GRAY, job);
}
ObjRelocKind::PpcAddr16Hi => {
write_text(name, Color32::LIGHT_GRAY, job);
write_text("@h", Color32::GRAY, job);
}
ObjRelocKind::PpcAddr16Ha => {
write_text(name, Color32::LIGHT_GRAY, job);
write_text("@ha", Color32::GRAY, job);
}
ObjRelocKind::PpcEmbSda21 => {
write_text(name, Color32::LIGHT_GRAY, job);
write_text("@sda21", Color32::GRAY, job);
}
ObjRelocKind::MipsHi16 => {
write_text("%hi(", Color32::GRAY, job);
write_text(name, Color32::LIGHT_GRAY, job);
write_text(")", Color32::GRAY, job);
}
ObjRelocKind::MipsLo16 => {
write_text("%lo(", Color32::GRAY, job);
write_text(name, Color32::LIGHT_GRAY, job);
write_text(")", Color32::GRAY, job);
}
ObjRelocKind::Absolute
| ObjRelocKind::PpcRel24
| ObjRelocKind::PpcRel14
| ObjRelocKind::Mips26 => {
write_text(name, Color32::LIGHT_GRAY, job);
}
};
}
@@ -51,7 +77,7 @@ fn write_ins(
ObjInsDiffKind::Insert => Color32::GREEN,
};
write_text(
&ins.mnemonic,
&format!("{:<11}", ins.mnemonic),
match diff_kind {
ObjInsDiffKind::OpMismatch => Color32::LIGHT_BLUE,
_ => base_color,
@@ -72,17 +98,13 @@ fn write_ins(
base_color
};
match arg {
ObjInsArg::Arg(arg) => match arg {
ObjInsArg::PpcArg(arg) => match arg {
Argument::Offset(val) => {
write_text(&format!("{}", val), color, job);
write_text("(", base_color, job);
writing_offset = true;
continue;
}
Argument::BranchDest(dest) => {
let addr = dest.0 + ins.ins.addr as i32 - base_addr as i32;
write_text(&format!("{:x}", addr), color, job);
}
Argument::Uimm(_) | Argument::Simm(_) => {
write_text(&format!("{}", arg), color, job);
}
@@ -93,12 +115,19 @@ fn write_ins(
ObjInsArg::Reloc => {
write_reloc(ins.reloc.as_ref().unwrap(), job);
}
ObjInsArg::RelocOffset => {
ObjInsArg::RelocWithBase => {
write_reloc(ins.reloc.as_ref().unwrap(), job);
write_text("(", base_color, job);
writing_offset = true;
continue;
}
ObjInsArg::MipsArg(str) => {
write_text(str.strip_prefix('$').unwrap_or(str), color, job);
}
ObjInsArg::BranchOffset(offset) => {
let addr = offset + ins.address as i32 - base_addr as i32;
write_text(&format!("{:x}", addr), color, job);
}
}
if writing_offset {
write_text(")", base_color, job);
@@ -112,10 +141,10 @@ fn ins_hover_ui(ui: &mut egui::Ui, ins: &ObjIns) {
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
ui.style_mut().wrap = Some(false);
ui.label(format!("{:02X?}", ins.ins.code.to_be_bytes()));
ui.label(format!("{:02X?}", ins.code.to_be_bytes()));
for arg in &ins.args {
if let ObjInsArg::Arg(arg) = arg {
if let ObjInsArg::PpcArg(arg) = arg {
match arg {
Argument::Uimm(v) => {
ui.label(format!("{} == {}", v, v.0));
@@ -153,7 +182,7 @@ fn ins_context_menu(ui: &mut egui::Ui, ins: &ObjIns) {
// if ui.button("Copy hex").clicked() {}
for arg in &ins.args {
if let ObjInsArg::Arg(arg) = arg {
if let ObjInsArg::PpcArg(arg) = arg {
match arg {
Argument::Uimm(v) => {
if ui.button(format!("Copy \"{}\"", v)).clicked() {
@@ -236,7 +265,7 @@ fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol) {
ObjInsDiffKind::Insert => Color32::GREEN,
};
write_text(
&format!("{:<6}", format!("{:x}:", ins.ins.addr - symbol.address as u32)),
&format!("{:<6}", format!("{:x}:", ins.address - symbol.address as u32)),
base_color,
&mut job,
);

View File

@@ -66,21 +66,28 @@ fn symbol_ui(
..Default::default()
});
}
job.append("] (", 0.0, TextFormat {
font_id: font_id.clone(),
color: Color32::GRAY,
..Default::default()
});
job.append(&format!("{:.0}%", symbol.match_percent), 0.0, TextFormat {
font_id: font_id.clone(),
color: match_color_for_symbol(symbol),
..Default::default()
});
job.append(") ", 0.0, TextFormat {
job.append("] ", 0.0, TextFormat {
font_id: font_id.clone(),
color: Color32::GRAY,
..Default::default()
});
if symbol.match_percent > 0.0 {
job.append("(", 0.0, TextFormat {
font_id: font_id.clone(),
color: Color32::GRAY,
..Default::default()
});
job.append(&format!("{:.0}%", symbol.match_percent), 0.0, TextFormat {
font_id: font_id.clone(),
color: match_color_for_symbol(symbol),
..Default::default()
});
job.append(") ", 0.0, TextFormat {
font_id: font_id.clone(),
color: Color32::GRAY,
..Default::default()
});
}
job.append(name, 0.0, TextFormat { font_id, color: Color32::WHITE, ..Default::default() });
let response = SelectableLabel::new(selected, job).ui(ui);
if response.clicked() {