Skip to content

Commit cad9b70

Browse files
committed
Support protobuf format for reports
This migrates to using protobuf to define the "report" and "changes" formats in objdiff-cli. The JSON output now uses the Proto3 "JSON Mapping", which is slightly incompatible with the existing JSON format. Mainly, 64-bit numbers are represented as strings, and addresses are decimal strings instead of hex. However, the older JSON format is still accepted by "report changes" to ease migration.
1 parent cf937b0 commit cad9b70

File tree

10 files changed

+526
-157
lines changed

10 files changed

+526
-157
lines changed

Cargo.lock

Lines changed: 132 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objdiff-cli/Cargo.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "objdiff-cli"
3-
version = "2.0.0-beta.3"
3+
version = "2.0.0-beta.4"
44
edition = "2021"
55
rust-version = "1.70"
66
authors = ["Luke Street <[email protected]>"]
@@ -18,7 +18,10 @@ anyhow = "1.0.82"
1818
argp = "0.3.0"
1919
crossterm = "0.27.0"
2020
enable-ansi-support = "0.2.1"
21+
memmap2 = "0.9.4"
2122
objdiff-core = { path = "../objdiff-core", features = ["all"] }
23+
pbjson = "0.7.0"
24+
prost = "0.13.1"
2225
ratatui = "0.26.2"
2326
rayon = "1.10.0"
2427
serde = { version = "1", features = ["derive"] }
@@ -27,3 +30,8 @@ supports-color = "3.0.0"
2730
time = { version = "0.3.36", features = ["formatting", "local-offset"] }
2831
tracing = "0.1.40"
2932
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
33+
34+
[build-dependencies]
35+
prost-build = "0.13.1"
36+
pbjson-build = "0.7.0"
37+

objdiff-cli/build.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::PathBuf;
2+
13
fn main() {
24
let output = std::process::Command::new("git")
35
.args(["rev-parse", "HEAD"])
@@ -6,4 +8,28 @@ fn main() {
68
let rev = String::from_utf8(output.stdout).expect("Failed to parse git output");
79
println!("cargo:rustc-env=GIT_COMMIT_SHA={rev}");
810
println!("cargo:rustc-rerun-if-changed=.git/HEAD");
11+
12+
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("protos");
13+
let proto_files = vec![root.join("report.proto")];
14+
15+
// Tell cargo to recompile if any of these proto files are changed
16+
for proto_file in &proto_files {
17+
println!("cargo:rerun-if-changed={}", proto_file.display());
18+
}
19+
20+
let descriptor_path =
21+
PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("proto_descriptor.bin");
22+
23+
prost_build::Config::new()
24+
.file_descriptor_set_path(&descriptor_path)
25+
.compile_protos(&proto_files, &[root])
26+
.expect("Failed to compile protos");
27+
28+
let descriptor_set = std::fs::read(descriptor_path).expect("Failed to read descriptor set");
29+
pbjson_build::Builder::new()
30+
.register_descriptors(&descriptor_set)
31+
.expect("Failed to register descriptors")
32+
.preserve_proto_field_names()
33+
.build(&[".objdiff"])
34+
.expect("Failed to build pbjson");
935
}

objdiff-cli/protos/report.proto

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
syntax = "proto3";
2+
3+
package objdiff.report;
4+
5+
message Report {
6+
float fuzzy_match_percent = 1;
7+
uint64 total_code = 2;
8+
uint64 matched_code = 3;
9+
float matched_code_percent = 4;
10+
uint64 total_data = 5;
11+
uint64 matched_data = 6;
12+
float matched_data_percent = 7;
13+
uint32 total_functions = 8;
14+
uint32 matched_functions = 9;
15+
float matched_functions_percent = 10;
16+
repeated ReportUnit units = 11;
17+
}
18+
19+
message ReportUnit {
20+
string name = 1;
21+
float fuzzy_match_percent = 2;
22+
uint64 total_code = 3;
23+
uint64 matched_code = 4;
24+
uint64 total_data = 5;
25+
uint64 matched_data = 6;
26+
uint32 total_functions = 7;
27+
uint32 matched_functions = 8;
28+
optional bool complete = 9;
29+
optional string module_name = 10;
30+
optional uint32 module_id = 11;
31+
repeated ReportItem sections = 12;
32+
repeated ReportItem functions = 13;
33+
}
34+
35+
message ReportItem {
36+
string name = 1;
37+
uint64 size = 2;
38+
float fuzzy_match_percent = 3;
39+
optional string demangled_name = 4;
40+
optional uint64 address = 5;
41+
}
42+
43+
// Used as stdin for the changes command
44+
message ChangesInput {
45+
Report from = 1;
46+
Report to = 2;
47+
}
48+
49+
message Changes {
50+
ChangeInfo from = 1;
51+
ChangeInfo to = 2;
52+
repeated ChangeUnit units = 3;
53+
}
54+
55+
message ChangeInfo {
56+
float fuzzy_match_percent = 1;
57+
uint64 total_code = 2;
58+
uint64 matched_code = 3;
59+
float matched_code_percent = 4;
60+
uint64 total_data = 5;
61+
uint64 matched_data = 6;
62+
float matched_data_percent = 7;
63+
uint32 total_functions = 8;
64+
uint32 matched_functions = 9;
65+
float matched_functions_percent = 10;
66+
}
67+
68+
message ChangeUnit {
69+
string name = 1;
70+
optional ChangeInfo from = 2;
71+
optional ChangeInfo to = 3;
72+
repeated ChangeItem sections = 4;
73+
repeated ChangeItem functions = 5;
74+
}
75+
76+
message ChangeItem {
77+
string name = 1;
78+
optional ChangeItemInfo from = 2;
79+
optional ChangeItemInfo to = 3;
80+
}
81+
82+
message ChangeItemInfo {
83+
float fuzzy_match_percent = 1;
84+
uint64 size = 2;
85+
}

0 commit comments

Comments
 (0)