Skip to content

Commit

Permalink
Add symbol mapping feature (#118)
Browse files Browse the repository at this point in the history
This allows users to "map" (or "link") symbols with different names so that they can be compared without having to update either the target or base objects. Symbol mappings are persisted in objdiff.json, so generators will need to ensure that they're preserved when updating. (Example: encounter/dtk-template@d1334bb)

Resolves #117
  • Loading branch information
encounter authored Oct 10, 2024
1 parent 603dbd6 commit 741d93e
Show file tree
Hide file tree
Showing 26 changed files with 2,257 additions and 926 deletions.
16 changes: 13 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ strip = "debuginfo"
codegen-units = 1

[workspace.package]
version = "2.2.2"
version = "2.3.0"
authors = ["Luke Street <[email protected]>"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down
7 changes: 7 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@
},
"metadata": {
"ref": "#/$defs/metadata"
},
"symbol_mappings": {
"type": "object",
"description": "Manual symbol mappings from target to base.",
"additionalProperties": {
"type": "string"
}
}
}
},
Expand Down
52 changes: 32 additions & 20 deletions objdiff-cli/src/cmd/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,34 +102,46 @@ pub fn run(args: Args) -> Result<()> {
let unit_path =
PathBuf::from_str(u).ok().and_then(|p| fs::canonicalize(p).ok());

let Some(object) = project_config.objects.iter_mut().find_map(|obj| {
if obj.name.as_deref() == Some(u) {
resolve_paths(obj);
return Some(obj);
}
let Some(object) = project_config
.units
.as_deref_mut()
.unwrap_or_default()
.iter_mut()
.find_map(|obj| {
if obj.name.as_deref() == Some(u) {
resolve_paths(obj);
return Some(obj);
}

let up = unit_path.as_deref()?;
let up = unit_path.as_deref()?;

resolve_paths(obj);
resolve_paths(obj);

if [&obj.base_path, &obj.target_path]
.into_iter()
.filter_map(|p| p.as_ref().and_then(|p| p.canonicalize().ok()))
.any(|p| p == up)
{
return Some(obj);
}
if [&obj.base_path, &obj.target_path]
.into_iter()
.filter_map(|p| p.as_ref().and_then(|p| p.canonicalize().ok()))
.any(|p| p == up)
{
return Some(obj);
}

None
}) else {
None
})
else {
bail!("Unit not found: {}", u)
};

object
} else if let Some(symbol_name) = &args.symbol {
let mut idx = None;
let mut count = 0usize;
for (i, obj) in project_config.objects.iter_mut().enumerate() {
for (i, obj) in project_config
.units
.as_deref_mut()
.unwrap_or_default()
.iter_mut()
.enumerate()
{
resolve_paths(obj);

if obj
Expand All @@ -148,7 +160,7 @@ pub fn run(args: Args) -> Result<()> {
}
match (count, idx) {
(0, None) => bail!("Symbol not found: {}", symbol_name),
(1, Some(i)) => &mut project_config.objects[i],
(1, Some(i)) => &mut project_config.units_mut()[i],
(2.., Some(_)) => bail!(
"Multiple instances of {} were found, try specifying a unit",
symbol_name
Expand Down Expand Up @@ -303,7 +315,7 @@ fn find_function(obj: &ObjInfo, name: &str) -> Option<SymbolRef> {
None
}

#[allow(dead_code)]
#[expect(dead_code)]
struct FunctionDiffUi {
relax_reloc_diffs: bool,
left_highlight: HighlightKind,
Expand Down Expand Up @@ -758,7 +770,7 @@ impl FunctionDiffUi {
self.scroll_y += self.per_page / if half { 2 } else { 1 };
}

#[allow(clippy::too_many_arguments)]
#[expect(clippy::too_many_arguments)]
fn print_sym(
&self,
out: &mut Text<'static>,
Expand Down
10 changes: 6 additions & 4 deletions objdiff-cli/src/cmd/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn generate(args: GenerateArgs) -> Result<()> {
};
info!(
"Generating report for {} units (using {} threads)",
project.objects.len(),
project.units().len(),
if args.deduplicate { 1 } else { rayon::current_num_threads() }
);

Expand All @@ -103,7 +103,7 @@ fn generate(args: GenerateArgs) -> Result<()> {
let mut existing_functions: HashSet<String> = HashSet::new();
if args.deduplicate {
// If deduplicating, we need to run single-threaded
for object in &mut project.objects {
for object in project.units.as_deref_mut().unwrap_or_default() {
if let Some(unit) = report_object(
object,
project_dir,
Expand All @@ -116,7 +116,9 @@ fn generate(args: GenerateArgs) -> Result<()> {
}
} else {
let vec = project
.objects
.units
.as_deref_mut()
.unwrap_or_default()
.par_iter_mut()
.map(|object| {
report_object(
Expand All @@ -132,7 +134,7 @@ fn generate(args: GenerateArgs) -> Result<()> {
}
let measures = units.iter().flat_map(|u| u.measures.into_iter()).collect();
let mut categories = Vec::new();
for category in &project.progress_categories {
for category in project.progress_categories() {
categories.push(ReportCategory {
id: category.id.clone(),
name: category.name.clone(),
Expand Down
5 changes: 3 additions & 2 deletions objdiff-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ crate-type = ["cdylib", "rlib"]

[features]
all = ["config", "dwarf", "mips", "ppc", "x86", "arm", "bindings"]
any-arch = [] # Implicit, used to check if any arch is enabled
config = ["globset", "semver", "serde_json", "serde_yaml"]
any-arch = ["bimap"] # Implicit, used to check if any arch is enabled
config = ["bimap", "globset", "semver", "serde_json", "serde_yaml"]
dwarf = ["gimli"]
mips = ["any-arch", "rabbitizer"]
ppc = ["any-arch", "cwdemangle", "cwextab", "ppc750cl"]
Expand All @@ -32,6 +32,7 @@ features = ["all"]

[dependencies]
anyhow = "1.0"
bimap = { version = "0.6", features = ["serde"], optional = true }
byteorder = "1.5"
filetime = "0.2"
flagset = "0.4"
Expand Down
Loading

0 comments on commit 741d93e

Please sign in to comment.