Compare commits

..

19 Commits

Author SHA1 Message Date
Luke Street 809e2ffddc cargo fmt 2025-03-11 21:43:32 -06:00
Luke Street 87fa29e8b0 objdiff-wasm: Fix symbol filtering
regex crate needed the `unicode-case` feature
2025-03-11 21:42:14 -06:00
Luke Street 42d4c38079 mips: Ignore .NON_MATCHING functions from INLINE_ASM macros 2025-03-11 21:39:17 -06:00
Luke Street fa26200ed7 Silence warning 2025-03-10 22:22:05 -06:00
Luke Street a0e7f9bc37 Fix x86 mov relocations with uint32 2025-03-10 22:09:58 -06:00
Luke Street 5898d7aebf Fix section ordering with many same-named sections
Before, this was comparing, for example, `.text-2`
with `.text-10` with standard string comparison,
yielding `.text-10` before `.text-2`.

Instead, this simply uses a stable sort by name,
which preserves the relative ordering of sections.
2025-03-10 21:51:54 -06:00
Luke Street ffb38d1bb0 Fix cargo deny advisories 2025-03-09 22:59:42 -06:00
Luke Street d56dda72f0 Version v3.0.0-beta.2 2025-03-09 22:56:28 -06:00
Luke Street c6971f3f2d Add initial support for x86-64 relocations 2025-03-09 22:51:43 -06:00
Luke Street 3965a035fa objdiff-cli diff: Show build errors/log 2025-03-09 22:51:43 -06:00
Luke Street f1fc29f77e Split report changes into separate proto 2025-03-08 14:39:15 -07:00
Luke Street 7c4f1c5d13 Fix left/right arch mismatches in diff code 2025-03-08 10:44:44 -07:00
Luke Street fa4a6cadbb Downgrade objdiff-wasm Rust edition temporarily 2025-03-04 23:27:17 -07:00
Luke Street 799971d54e Migrate to Rust edition 2024 2025-03-04 22:31:38 -07:00
Luke Street 8eef37e8df Version v3.0.0-beta.1 2025-03-04 22:24:55 -07:00
Luke Street 5f36916087 Fix unintended unwrap in load_font_if_needed 2025-03-04 22:24:20 -07:00
Luke Street ee667a2dde Update config-schema.json: PPC -> PowerPC 2025-03-04 22:23:45 -07:00
LagoLunatic cf5fc54cfa PPC: Reimplement pooled data reference calculation (#167)
* PPC: Calculate pooled relocations

Reimplements #140

The relocations are now generated when the object is first read in `parse`, right after the real relocations are read.

`resolve_relocation` was changed to take `obj.symbols` instead of `obj` as an argument, because `obj` itself doesn't exist yet at the time the relocations are being read.

* Improve readability of PPC pool relocs code

* Fix regression causing extern pool relocs to be ignored

* Fix showing incorrect diff when diffing weak stripped symbol with an addend

This is a regression that was introduced by #158 diffing addends in addition to symbol names. But it's not really a bug in that PR, rather it seems like I simply never added the offset into the addend when creating a fake pool relocation for an extern symbol. So this commit fixes that root issue instead.

* Add PPC "Calculate pooled data references" option

* Fix objdiff-wasm compilation errors

* Update PPC test snapshots
2025-03-04 20:40:34 -07:00
Luke Street 1cdfa1e857 Update rabbitizer & utilize use_dollar option 2025-03-04 09:38:59 -07:00
78 changed files with 3544 additions and 736 deletions
Generated
+52 -32
View File
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "ab_glyph"
@@ -450,6 +450,18 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "auditable-serde"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7bf8143dfc3c0258df908843e169b5cc5fcf76c7718bd66135ef4a9cd558c5"
dependencies = [
"semver",
"serde",
"serde_json",
"topological-sort",
]
[[package]]
name = "autocfg"
version = "1.4.0"
@@ -3268,7 +3280,7 @@ dependencies = [
[[package]]
name = "objdiff-cli"
version = "3.0.0-alpha.3"
version = "3.0.0-beta.3"
dependencies = [
"anyhow",
"argp",
@@ -3291,7 +3303,7 @@ dependencies = [
[[package]]
name = "objdiff-core"
version = "3.0.0-alpha.3"
version = "3.0.0-beta.3"
dependencies = [
"anyhow",
"arm-attr",
@@ -3344,13 +3356,12 @@ dependencies = [
[[package]]
name = "objdiff-gui"
version = "3.0.0-alpha.3"
version = "3.0.0-beta.3"
dependencies = [
"anyhow",
"cfg-if",
"const_format",
"cwdemangle",
"cwextab",
"dirs 6.0.0",
"eframe",
"egui",
@@ -3370,8 +3381,6 @@ dependencies = [
"rlwinmdec",
"ron",
"serde",
"serde_json",
"shell-escape",
"tauri-winres",
"time",
"tracing-subscriber",
@@ -3383,7 +3392,7 @@ dependencies = [
[[package]]
name = "objdiff-wasm"
version = "3.0.0-alpha.3"
version = "3.0.0-beta.3"
dependencies = [
"log",
"objdiff-core",
@@ -3897,7 +3906,7 @@ dependencies = [
[[package]]
name = "rabbitizer"
version = "2.0.0-dev0"
source = "git+https://github.com/Decompollaborate/rabbitizer.git?branch=🦀#706fd145b788ec3d068d55904dd112c7989e0412"
source = "git+https://github.com/Decompollaborate/rabbitizer.git?branch=%F0%9F%A6%80#06dc8b6c826c3d60e112d4c2cd70aa54e308be12"
dependencies = [
"bitflags 2.9.0",
]
@@ -4208,9 +4217,9 @@ dependencies = [
[[package]]
name = "ring"
version = "0.17.11"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
dependencies = [
"cc",
"cfg-if",
@@ -4477,6 +4486,9 @@ name = "semver"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
dependencies = [
"serde",
]
[[package]]
name = "serde"
@@ -5168,6 +5180,12 @@ dependencies = [
"winnow 0.7.3",
]
[[package]]
name = "topological-sort"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d"
[[package]]
name = "tower"
version = "0.5.2"
@@ -5540,9 +5558,9 @@ dependencies = [
[[package]]
name = "wasm-encoder"
version = "0.225.0"
version = "0.227.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f7eac0445cac73bcf09e6a97f83248d64356dccf9f2b100199769b6b42464e5"
checksum = "80bb72f02e7fbf07183443b27b0f3d4144abf8c114189f2e088ed95b696a7822"
dependencies = [
"leb128fmt",
"wasmparser",
@@ -5550,11 +5568,13 @@ dependencies = [
[[package]]
name = "wasm-metadata"
version = "0.225.0"
version = "0.227.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1d20d0bf2c73c32a5114cf35a5c10ccf9f9aa37a3a2c0114b3e11cbf6faac12"
checksum = "ce1ef0faabbbba6674e97a56bee857ccddf942785a336c8b47b42373c922a91d"
dependencies = [
"anyhow",
"auditable-serde",
"flate2",
"indexmap",
"serde",
"serde_derive",
@@ -5580,9 +5600,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.225.0"
version = "0.227.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36e5456165f81e64cb9908a0fe9b9d852c2c74582aa3fe2be3c2da57f937d3ae"
checksum = "0f51cad774fb3c9461ab9bccc9c62dfb7388397b5deda31bf40e8108ccd678b2"
dependencies = [
"bitflags 2.9.0",
"hashbrown",
@@ -6303,19 +6323,19 @@ dependencies = [
[[package]]
name = "wit-bindgen"
version = "0.39.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4dd9a372b25d6f35456b0a730d2adabeb0c4878066ba8f8089800349be6ecb5"
checksum = "8e7091ed6c9abfa4e0a2ef3b39d0539da992d841fcf32c255f64fb98764ffee5"
dependencies = [
"wit-bindgen-rt 0.39.0",
"wit-bindgen-rt 0.40.0",
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.39.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f108fa9b77a346372858b30c11ea903680e7e2b9d820b1a5883e9d530bf51c7e"
checksum = "398c650cec1278cfb72e214ba26ef3440ab726e66401bd39c04f465ee3979e6b"
dependencies = [
"anyhow",
"heck",
@@ -6333,18 +6353,18 @@ dependencies = [
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
checksum = "68faed92ae696b93ea9a7b67ba6c37bf09d72c6d9a70fa824a743c3020212f11"
dependencies = [
"bitflags 2.9.0",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.39.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ba5b852e976d35dbf6cb745746bf1bd4fc26782bab1e0c615fc71a7d8aac05"
checksum = "83903c8dcd8084a8a67ae08190122cf0e25dc37bdc239070a00f47e22d3f0aae"
dependencies = [
"anyhow",
"heck",
@@ -6358,9 +6378,9 @@ dependencies = [
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.39.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "401529c9af9304a20ed99fa01799e467b7d37727126f0c9a958895471268ad7a"
checksum = "a7bf7f20495bcc7dc9f24c5fbcac9e919ca5ebdb7a1b1841d74447d3c8dd0c60"
dependencies = [
"anyhow",
"prettyplease",
@@ -6373,9 +6393,9 @@ dependencies = [
[[package]]
name = "wit-component"
version = "0.225.0"
version = "0.227.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2505c917564c1d74774563bbcd3e4f8c216a6508050862fd5f449ee56e3c5125"
checksum = "635c3adc595422cbf2341a17fb73a319669cc8d33deed3a48368a841df86b676"
dependencies = [
"anyhow",
"bitflags 2.9.0",
@@ -6417,9 +6437,9 @@ dependencies = [
[[package]]
name = "wit-parser"
version = "0.225.0"
version = "0.227.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebefaa234e47224f10ce60480c5bfdece7497d0f3b87a12b41ff39e5c8377a78"
checksum = "ddf445ed5157046e4baf56f9138c124a0824d4d1657e7204d71886ad8ce2fc11"
dependencies = [
"anyhow",
"id-arena",
+4 -4
View File
@@ -5,7 +5,7 @@ members = [
"objdiff-gui",
"objdiff-wasm",
]
resolver = "2"
resolver = "3"
[profile.release-lto]
inherits = "release"
@@ -14,9 +14,9 @@ strip = "debuginfo"
codegen-units = 1
[workspace.package]
version = "3.0.0-alpha.3"
version = "3.0.0-beta.3"
authors = ["Luke Street <luke@street.dev>"]
edition = "2021"
edition = "2024"
license = "MIT OR Apache-2.0"
repository = "https://github.com/encounter/objdiff"
rust-version = "1.82"
rust-version = "1.85"
+1
View File
@@ -73,6 +73,7 @@ ignore = [
#{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" },
#"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish
#{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" },
{ id = "RUSTSEC-2024-0436", reason = "Unmaintained paste crate is an indirect dependency" },
]
# If this is true, then cargo deny will use the git executable to fetch advisory database.
# If this is false, then it uses a built-in git library.
+1 -1
View File
@@ -4,7 +4,7 @@
//! For now, this only adds a --version/-V option which causes early-exit.
use std::ffi::OsStr;
use argp::{parser::ParseGlobalOptions, EarlyExit, FromArgs, TopLevelCommand};
use argp::{EarlyExit, FromArgs, TopLevelCommand, parser::ParseGlobalOptions};
struct ArgsOrVersion<T>(T)
where T: FromArgs;
+25 -18
View File
@@ -3,40 +3,39 @@ use std::{
mem,
str::FromStr,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
atomic::{AtomicBool, Ordering},
},
task::{Wake, Waker},
time::Duration,
};
use anyhow::{anyhow, bail, Context, Result};
use anyhow::{Context, Result, anyhow, bail};
use argp::FromArgs;
use crossterm::{
event,
event::{DisableMouseCapture, EnableMouseCapture},
terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, SetTitle,
EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode,
},
};
use objdiff_core::{
bindings::diff::DiffResult,
build::{
watcher::{create_watcher, Watcher},
BuildConfig,
BuildConfig, BuildStatus,
watcher::{Watcher, create_watcher},
},
config::{
build_globset,
ProjectConfig, ProjectObject, ProjectObjectMetadata, build_globset,
path::{check_path_buf, platform_path, platform_path_serde_option},
ProjectConfig, ProjectObject, ProjectObjectMetadata,
},
diff::{
self, ConfigEnum, ConfigPropertyId, ConfigPropertyKind, DiffObjConfig, MappingConfig,
ObjectDiff,
},
jobs::{
objdiff::{start_build, ObjDiffConfig},
Job, JobQueue, JobResult,
objdiff::{ObjDiffConfig, start_build},
},
obj::{self, Object},
};
@@ -45,10 +44,10 @@ use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
use crate::{
util::{
output::{write_output, OutputFormat},
output::{OutputFormat, write_output},
term::crossterm_panic_handler,
},
views::{function_diff::FunctionDiffUi, EventControlFlow, EventResult, UiView},
views::{EventControlFlow, EventResult, UiView, function_diff::FunctionDiffUi},
};
#[derive(FromArgs, PartialEq, Debug)]
@@ -252,6 +251,8 @@ pub struct AppState {
pub project_config: Option<ProjectConfig>,
pub target_path: Option<Utf8PlatformPathBuf>,
pub base_path: Option<Utf8PlatformPathBuf>,
pub left_status: Option<BuildStatus>,
pub right_status: Option<BuildStatus>,
pub left_obj: Option<(Object, ObjectDiff)>,
pub right_obj: Option<(Object, ObjectDiff)>,
pub prev_obj: Option<(Object, ObjectDiff)>,
@@ -349,6 +350,8 @@ impl AppState {
JobResult::None => unreachable!("Unexpected JobResult::None"),
JobResult::ObjDiff(result) => {
let result = result.unwrap();
self.left_status = Some(result.first_status);
self.right_status = Some(result.second_status);
self.left_obj = result.first_obj;
self.right_obj = result.second_obj;
self.reload_time = Some(result.time);
@@ -389,6 +392,8 @@ fn run_interactive(
project_config,
target_path,
base_path,
left_status: None,
right_status: None,
left_obj: None,
right_obj: None,
prev_obj: None,
@@ -426,15 +431,17 @@ fn run_interactive(
let mut result = EventResult { redraw: true, ..Default::default() };
'outer: loop {
if result.redraw {
terminal.draw(|f| loop {
result.redraw = false;
view.draw(&state, f, &mut result);
result.click_xy = None;
if !result.redraw {
break;
terminal.draw(|f| {
loop {
result.redraw = false;
view.draw(&state, f, &mut result);
result.click_xy = None;
if !result.redraw {
break;
}
// Clear buffer on redraw
f.buffer_mut().reset();
}
// Clear buffer on redraw
f.buffer_mut().reset();
})?;
}
loop {
+7 -15
View File
@@ -1,12 +1,11 @@
use std::{collections::HashSet, fs::File, io::Read, time::Instant};
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use argp::FromArgs;
use objdiff_core::{
bindings::report::{
ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, Report,
ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata,
REPORT_VERSION,
ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, REPORT_VERSION,
Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata,
},
config::path::platform_path,
diff, obj,
@@ -19,7 +18,7 @@ use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
use crate::{
cmd::diff::ObjectConfig,
util::output::{write_output, OutputFormat},
util::output::{OutputFormat, write_output},
};
#[derive(FromArgs, PartialEq, Debug)]
@@ -206,11 +205,7 @@ fn report_object(
let section_match_percent = section_diff.match_percent.unwrap_or_else(|| {
// Support cases where we don't have a target object,
// assume complete means 100% match
if object.complete.unwrap_or(false) {
100.0
} else {
0.0
}
if object.complete.unwrap_or(false) { 100.0 } else { 0.0 }
});
sections.push(ReportItem {
name: section.name.clone(),
@@ -237,6 +232,7 @@ fn report_object(
if symbol.section != Some(section_idx)
|| symbol.size == 0
|| symbol.flags.contains(SymbolFlag::Hidden)
|| symbol.flags.contains(SymbolFlag::Ignored)
{
continue;
}
@@ -251,11 +247,7 @@ fn report_object(
let match_percent = symbol_diff.match_percent.unwrap_or_else(|| {
// Support cases where we don't have a target object,
// assume complete means 100% match
if object.complete.unwrap_or(false) {
100.0
} else {
0.0
}
if object.complete.unwrap_or(false) { 100.0 } else { 0.0 }
});
measures.fuzzy_match_percent += match_percent * symbol.size as f32;
measures.total_code += symbol.size;
+1 -1
View File
@@ -17,7 +17,7 @@ use anyhow::{Error, Result};
use argp::{FromArgValue, FromArgs};
use enable_ansi_support::enable_ansi_support;
use supports_color::Stream;
use tracing_subscriber::{filter::LevelFilter, EnvFilter};
use tracing_subscriber::{EnvFilter, filter::LevelFilter};
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
enum LogLevel {
+1 -1
View File
@@ -5,7 +5,7 @@ use std::{
path::Path,
};
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use tracing::info;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
+1 -1
View File
@@ -3,7 +3,7 @@ use std::{io::stdout, panic};
use crossterm::{
cursor::Show,
event::DisableMouseCapture,
terminal::{disable_raw_mode, LeaveAlternateScreen},
terminal::{LeaveAlternateScreen, disable_raw_mode},
};
pub fn crossterm_panic_handler() {
+27 -4
View File
@@ -1,18 +1,19 @@
use core::cmp::Ordering;
use anyhow::{bail, Result};
use anyhow::Result;
use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers, MouseButton, MouseEventKind};
use objdiff_core::{
build::BuildStatus,
diff::{
display::{display_row, DiffText, DiffTextColor, HighlightKind},
DiffObjConfig, FunctionRelocDiffs, InstructionDiffKind, ObjectDiff, SymbolDiff,
display::{DiffText, DiffTextColor, HighlightKind, display_row},
},
obj::Object,
};
use ratatui::{
Frame,
prelude::*,
widgets::{Block, Borders, Clear, Paragraph, Scrollbar, ScrollbarOrientation, ScrollbarState},
Frame,
};
use super::{EventControlFlow, EventResult, UiView};
@@ -126,6 +127,11 @@ impl UiView for FunctionDiffUi {
);
max_width = max_width.max(text.width());
left_text = Some(text);
} else if let Some(status) = &state.left_status {
let mut text = Text::default();
self.print_build_status(&mut text, status);
max_width = max_width.max(text.width());
left_text = Some(text);
}
let mut right_text = None;
@@ -155,6 +161,11 @@ impl UiView for FunctionDiffUi {
let rect = content_chunks[1].inner(Margin::new(1, 1));
self.print_margin(&mut text, symbol_diff, rect);
margin_text = Some(text);
} else if let Some(status) = &state.right_status {
let mut text = Text::default();
self.print_build_status(&mut text, status);
max_width = max_width.max(text.width());
right_text = Some(text);
}
let mut prev_text = None;
@@ -453,7 +464,7 @@ impl UiView for FunctionDiffUi {
}
(Some((_l, _ls, ld)), None) => ld.instruction_rows.len(),
(None, Some((_r, _rs, rd))) => rd.instruction_rows.len(),
(None, None) => bail!("Symbol not found: {}", self.symbol_name),
(None, None) => 0,
};
self.left_sym = left_sym;
self.right_sym = right_sym;
@@ -596,6 +607,18 @@ impl FunctionDiffUi {
}
}
}
fn print_build_status<'a>(&self, out: &mut Text<'a>, status: &'a BuildStatus) {
if !status.cmdline.is_empty() {
out.lines.push(Line::styled(status.cmdline.clone(), Style::new().fg(Color::LightBlue)));
}
for line in status.stdout.lines() {
out.lines.push(Line::styled(line, Style::new().fg(Color::White)));
}
for line in status.stderr.lines() {
out.lines.push(Line::styled(line, Style::new().fg(Color::Red)));
}
}
}
pub const COLOR_ROTATION: [Color; 7] = [
+9 -1
View File
@@ -19,7 +19,15 @@ fn compile_protos() {
.map(|m| m.modified().unwrap())
.unwrap_or(std::time::SystemTime::UNIX_EPOCH);
let mut run_protoc = false;
let proto_files = vec![root.join("report.proto")];
let proto_files = root
.read_dir()
.unwrap()
.filter_map(|e| {
let e = e.unwrap();
let path = e.path();
(path.extension() == Some(std::ffi::OsStr::new("proto"))).then_some(path)
})
.collect::<Vec<_>>();
for proto_file in &proto_files {
println!("cargo:rerun-if-changed={}", proto_file.display());
let mtime = match std::fs::metadata(proto_file) {
+14
View File
@@ -194,6 +194,13 @@
"name": "Register '$' prefix",
"description": "Display MIPS register names with a '$' prefix."
},
{
"id": "ppc.calculatePoolRelocations",
"type": "boolean",
"default": true,
"name": "Calculate pooled data references",
"description": "Display pooled data references in functions as fake relocations."
},
{
"id": "x86.formatter",
"type": "choice",
@@ -253,6 +260,13 @@
"mips.registerPrefix"
]
},
{
"id": "ppc",
"name": "PowerPC",
"properties": [
"ppc.calculatePoolRelocations"
]
},
{
"id": "x86",
"name": "x86",
+59
View File
@@ -0,0 +1,59 @@
syntax = "proto3";
import "report.proto";
package objdiff.report;
// A pair of reports to compare and generate changes
message ChangesInput {
// The previous report
Report from = 1;
// The current report
Report to = 2;
}
// Changes between two reports
message Changes {
// The progress info for the previous report
Measures from = 1;
// The progress info for the current report
Measures to = 2;
// Units that changed
repeated ChangeUnit units = 3;
}
// A changed unit
message ChangeUnit {
// The name of the unit
string name = 1;
// The previous progress info (omitted if new)
optional Measures from = 2;
// The current progress info (omitted if removed)
optional Measures to = 3;
// Sections that changed
repeated ChangeItem sections = 4;
// Functions that changed
repeated ChangeItem functions = 5;
// Extra metadata for this unit
optional ReportUnitMetadata metadata = 6;
}
// A changed section or function
message ChangeItem {
// The name of the item
string name = 1;
// The previous progress info (omitted if new)
optional ChangeItemInfo from = 2;
// The current progress info (omitted if removed)
optional ChangeItemInfo to = 3;
// Extra metadata for this item
optional ReportItemMetadata metadata = 4;
}
// Progress info for a section or function
message ChangeItemInfo {
// The overall match percent for this item
float fuzzy_match_percent = 1;
// The size of the item in bytes
uint64 size = 2;
}
Binary file not shown.
+12 -66
View File
@@ -2,6 +2,18 @@ syntax = "proto3";
package objdiff.report;
// Project progress report
message Report {
// Overall progress info
Measures measures = 1;
// Units within this report
repeated ReportUnit units = 2;
// Report version
uint32 version = 3;
// Progress categories
repeated ReportCategory categories = 4;
}
// Progress info for a report or unit
message Measures {
// Overall match percent, including partially matched functions and data
@@ -38,18 +50,6 @@ message Measures {
uint32 complete_units = 16;
}
// Project progress report
message Report {
// Overall progress info
Measures measures = 1;
// Units within this report
repeated ReportUnit units = 2;
// Report version
uint32 version = 3;
// Progress categories
repeated ReportCategory categories = 4;
}
message ReportCategory {
// The ID of the category
string id = 1;
@@ -108,57 +108,3 @@ message ReportItemMetadata {
// The virtual address of the function or section
optional uint64 virtual_address = 2;
}
// A pair of reports to compare and generate changes
message ChangesInput {
// The previous report
Report from = 1;
// The current report
Report to = 2;
}
// Changes between two reports
message Changes {
// The progress info for the previous report
Measures from = 1;
// The progress info for the current report
Measures to = 2;
// Units that changed
repeated ChangeUnit units = 3;
}
// A changed unit
message ChangeUnit {
// The name of the unit
string name = 1;
// The previous progress info (omitted if new)
optional Measures from = 2;
// The current progress info (omitted if removed)
optional Measures to = 3;
// Sections that changed
repeated ChangeItem sections = 4;
// Functions that changed
repeated ChangeItem functions = 5;
// Extra metadata for this unit
optional ReportUnitMetadata metadata = 6;
}
// A changed section or function
message ChangeItem {
// The name of the item
string name = 1;
// The previous progress info (omitted if new)
optional ChangeItemInfo from = 2;
// The current progress info (omitted if removed)
optional ChangeItemInfo to = 3;
// Extra metadata for this item
optional ReportItemMetadata metadata = 4;
}
// Progress info for a section or function
message ChangeItemInfo {
// The overall match percent for this item
float fuzzy_match_percent = 1;
// The size of the item in bytes
uint64 size = 2;
}
+6 -14
View File
@@ -5,14 +5,14 @@ use alloc::{
vec::Vec,
};
use anyhow::{bail, Result};
use arm_attr::{enums::CpuArch, tag::Tag, BuildAttrs};
use object::{elf, Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _};
use anyhow::{Result, bail};
use arm_attr::{BuildAttrs, enums::CpuArch, tag::Tag};
use object::{Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _, elf};
use unarm::{args, arm, thumb};
use crate::{
arch::Arch,
diff::{display::InstructionPart, ArmArchVersion, ArmR9Usage, DiffObjConfig},
diff::{ArmArchVersion, ArmR9Usage, DiffObjConfig, display::InstructionPart},
obj::{
InstructionRef, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
ScannedInstruction, SymbolFlag, SymbolFlagSet, SymbolKind,
@@ -58,11 +58,7 @@ impl ArchArm {
}
// Only checking first CpuArch tag. Others may exist, but that's very unlikely.
let cpu_arch = subsection.into_public_tag_iter()?.find_map(|(_, tag)| {
if let Tag::CpuArch(cpu_arch) = tag {
Some(cpu_arch)
} else {
None
}
if let Tag::CpuArch(cpu_arch) = tag { Some(cpu_arch) } else { None }
});
match cpu_arch {
Some(CpuArch::V4T) => return Ok(Some(unarm::ArmVersion::V4T)),
@@ -358,11 +354,7 @@ impl Arch for ArchArm {
}
fn symbol_address(&self, address: u64, kind: SymbolKind) -> u64 {
if kind == SymbolKind::Function {
address & !1
} else {
address
}
if kind == SymbolKind::Function { address & !1 } else { address }
}
fn extra_symbol_flags(&self, symbol: &object::Symbol) -> SymbolFlagSet {
+5 -17
View File
@@ -5,7 +5,7 @@ use alloc::{
};
use core::cmp::Ordering;
use anyhow::{bail, Result};
use anyhow::{Result, bail};
use object::elf;
use yaxpeax_arch::{Arch as YaxpeaxArch, Decoder, Reader, U8Reader};
use yaxpeax_arm::armv8::a64::{
@@ -15,7 +15,7 @@ use yaxpeax_arm::armv8::a64::{
use crate::{
arch::Arch,
diff::{display::InstructionPart, DiffObjConfig},
diff::{DiffObjConfig, display::InstructionPart},
obj::{
InstructionRef, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
ScannedInstruction,
@@ -216,11 +216,7 @@ where Cb: FnMut(InstructionPart<'static>) {
unreachable!("movn operand 1 is always ImmShift");
};
let imm = if let Operand::Register(size, _) = ins.operands[0] {
if size == SizeCode::W {
imm as u32 as u64
} else {
imm
}
if size == SizeCode::W { imm as u32 as u64 } else { imm }
} else {
unreachable!("movn operand 0 is always Register");
};
@@ -237,11 +233,7 @@ where Cb: FnMut(InstructionPart<'static>) {
unreachable!("movz operand is always ImmShift");
};
let imm = if let Operand::Register(size, _) = ins.operands[0] {
if size == SizeCode::W {
imm as u32 as u64
} else {
imm
}
if size == SizeCode::W { imm as u32 as u64 } else { imm }
} else {
unreachable!("movz operand 0 is always Register");
};
@@ -574,11 +566,7 @@ where Cb: FnMut(InstructionPart<'static>) {
{
if immr < imms {
let size = if let Operand::Register(size, _) = ins.operands[0] {
if size == SizeCode::W {
32
} else {
64
}
if size == SizeCode::W { 32 } else { 64 }
} else {
unreachable!("operand 0 is always a register");
};
+52 -29
View File
@@ -1,21 +1,25 @@
use alloc::{collections::BTreeMap, string::ToString, vec::Vec};
use alloc::{
collections::{BTreeMap, BTreeSet},
string::ToString,
vec::Vec,
};
use core::ops::Range;
use anyhow::{bail, Result};
use object::{elf, Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _};
use anyhow::{Result, bail};
use object::{Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _, elf};
use rabbitizer::{
abi::Abi,
operands::{ValuedOperand, IU16},
registers_meta::Register,
IsaExtension, IsaVersion, Vram,
abi::Abi,
operands::{IU16, ValuedOperand},
registers_meta::Register,
};
use crate::{
arch::Arch,
diff::{display::InstructionPart, DiffObjConfig, MipsAbi, MipsInstrCategory},
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart},
obj::{
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
ResolvedInstructionRef, ResolvedRelocation, ScannedInstruction,
ResolvedInstructionRef, ResolvedRelocation, ScannedInstruction, SymbolFlag, SymbolFlagSet,
},
};
@@ -26,6 +30,7 @@ pub struct ArchMips {
pub isa_extension: Option<IsaExtension>,
pub ri_gp_value: i32,
pub paired_relocations: Vec<BTreeMap<u64, i64>>,
pub ignored_symbols: BTreeSet<usize>,
}
const EF_MIPS_ABI: u32 = 0x0000F000;
@@ -118,7 +123,25 @@ impl ArchMips {
paired_relocations[section_index] = addends;
}
Ok(Self { endianness, abi, isa_extension, ri_gp_value, paired_relocations })
let mut ignored_symbols = BTreeSet::new();
for obj_symbol in object.symbols() {
let Ok(name) = obj_symbol.name() else { continue };
if let Some(prefix) = name.strip_suffix(".NON_MATCHING") {
ignored_symbols.insert(obj_symbol.index().0);
if let Some(target_symbol) = object.symbol_by_name(prefix) {
ignored_symbols.insert(target_symbol.index().0);
}
}
}
Ok(Self {
endianness,
abi,
isa_extension,
ri_gp_value,
paired_relocations,
ignored_symbols,
})
}
fn instruction_flags(&self, diff_config: &DiffObjConfig) -> rabbitizer::InstructionFlags {
@@ -144,9 +167,11 @@ impl ArchMips {
fn instruction_display_flags(
&self,
_diff_config: &DiffObjConfig,
diff_config: &DiffObjConfig,
) -> rabbitizer::InstructionDisplayFlags {
rabbitizer::InstructionDisplayFlags::default().with_unknown_instr_comment(false)
rabbitizer::InstructionDisplayFlags::default()
.with_unknown_instr_comment(false)
.with_use_dollar(diff_config.mips_register_prefix)
}
fn parse_ins_ref(
@@ -207,7 +232,6 @@ impl Arch for ArchMips {
function_range,
resolved.section_index,
&display_flags,
diff_config,
cb,
)?;
Ok(())
@@ -293,6 +317,14 @@ impl Arch for ArchMips {
_ => 1,
}
}
fn extra_symbol_flags(&self, symbol: &object::Symbol) -> SymbolFlagSet {
let mut flags = SymbolFlagSet::default();
if self.ignored_symbols.contains(&symbol.index().0) {
flags |= SymbolFlag::Ignored;
}
flags
}
}
fn push_args(
@@ -301,7 +333,6 @@ fn push_args(
function_range: Range<u64>,
section_index: usize,
display_flags: &rabbitizer::InstructionDisplayFlags,
diff_config: &DiffObjConfig,
mut arg_cb: impl FnMut(InstructionPart) -> Result<()>,
) -> Result<()> {
let operands = instruction.valued_operands_iter();
@@ -361,14 +392,11 @@ fn push_args(
})))?;
}
arg_cb(InstructionPart::basic("("))?;
let mut value =
base.either_name(instruction.flags().abi(), display_flags.named_gpr());
if !diff_config.mips_register_prefix {
if let Some(trimmed) = value.strip_prefix('$') {
value = trimmed;
}
}
arg_cb(InstructionPart::opaque(value))?;
arg_cb(InstructionPart::opaque(base.either_name(
instruction.flags().abi(),
display_flags.named_gpr(),
!display_flags.use_dollar(),
)))?;
arg_cb(InstructionPart::basic(")"))?;
}
// ValuedOperand::r5900_immediate15(..) => match relocation {
@@ -382,14 +410,9 @@ fn push_args(
// }
// },
_ => {
let value = op.display(instruction, display_flags, None::<&str>).to_string();
if !diff_config.mips_register_prefix {
if let Some(value) = value.strip_prefix('$') {
arg_cb(InstructionPart::opaque(value))?;
continue;
}
}
arg_cb(InstructionPart::opaque(value))?;
arg_cb(InstructionPart::opaque(
op.display(instruction, display_flags, None::<&str>).to_string(),
))?;
}
}
}
+18 -5
View File
@@ -1,17 +1,17 @@
use alloc::{borrow::Cow, boxed::Box, format, string::String, vec::Vec};
use core::{ffi::CStr, fmt, fmt::Debug};
use anyhow::{bail, Result};
use anyhow::{Result, bail};
use object::Endian as _;
use crate::{
diff::{
display::{ContextItem, HoverItem, InstructionPart},
DiffObjConfig,
display::{ContextItem, HoverItem, InstructionPart},
},
obj::{
InstructionArg, Object, ParsedInstruction, RelocationFlags, ResolvedInstructionRef,
ScannedInstruction, SymbolFlagSet, SymbolKind,
InstructionArg, Object, ParsedInstruction, Relocation, RelocationFlags,
ResolvedInstructionRef, ScannedInstruction, Symbol, SymbolFlagSet, SymbolKind,
},
util::ReallySigned,
};
@@ -66,7 +66,9 @@ impl DataType {
pub fn display_literals(&self, endian: object::Endianness, bytes: &[u8]) -> Vec<String> {
let mut strs = Vec::new();
if self.required_len().is_some_and(|l| bytes.len() < l) {
log::warn!("Failed to display a symbol value for a symbol whose size is too small for instruction referencing it.");
log::warn!(
"Failed to display a symbol value for a symbol whose size is too small for instruction referencing it."
);
return strs;
}
let mut bytes = bytes;
@@ -212,6 +214,17 @@ pub trait Arch: Send + Sync + Debug {
cb: &mut dyn FnMut(InstructionPart) -> Result<()>,
) -> Result<()>;
/// Generate a list of fake relocations from the given code that represent pooled data accesses.
fn generate_pooled_relocations(
&self,
_address: u64,
_code: &[u8],
_relocations: &[Relocation],
_symbols: &[Symbol],
) -> Vec<Relocation> {
Vec::new()
}
fn implcit_addend(
&self,
file: &object::File<'_>,
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More