diff --git a/objdiff-cli/src/cmd/report.rs b/objdiff-cli/src/cmd/report.rs index 5aef191..c6cc8fd 100644 --- a/objdiff-cli/src/cmd/report.rs +++ b/objdiff-cli/src/cmd/report.rs @@ -228,6 +228,7 @@ fn report_object( demangled_name: None, virtual_address: section.virtual_address, }), + address: None, }); match section.kind { @@ -273,6 +274,7 @@ fn report_object( demangled_name: symbol.demangled_name.clone(), virtual_address: symbol.virtual_address, }), + address: symbol.address.checked_sub(section.address), }); if match_percent == 100.0 { measures.matched_functions += 1; @@ -280,6 +282,16 @@ fn report_object( measures.total_functions += 1; } } + sections.sort_by(|a, b| a.name.cmp(&b.name)); + let reverse_fn_order = object.metadata.reverse_fn_order.unwrap_or(false); + functions.sort_by(|a, b| { + if reverse_fn_order { + b.address.unwrap_or(0).cmp(&a.address.unwrap_or(0)) + } else { + a.address.unwrap_or(u64::MAX).cmp(&b.address.unwrap_or(u64::MAX)) + } + .then_with(|| a.size.cmp(&b.size)) + }); if metadata.complete.unwrap_or(false) { measures.complete_code = measures.total_code; measures.complete_data = measures.total_data; diff --git a/objdiff-core/protos/proto_descriptor.bin b/objdiff-core/protos/proto_descriptor.bin index c281ade..3004765 100644 Binary files a/objdiff-core/protos/proto_descriptor.bin and b/objdiff-core/protos/proto_descriptor.bin differ diff --git a/objdiff-core/protos/report.proto b/objdiff-core/protos/report.proto index 279bbb0..9b65dfb 100644 --- a/objdiff-core/protos/report.proto +++ b/objdiff-core/protos/report.proto @@ -99,6 +99,8 @@ message ReportItem { float fuzzy_match_percent = 3; // Extra metadata for this item optional ReportItemMetadata metadata = 4; + // Address of the item (section-relative offset) + optional uint64 address = 5; } // Extra metadata for an item diff --git a/objdiff-core/src/bindings/report.rs b/objdiff-core/src/bindings/report.rs index 02bf34a..923a42a 100644 --- a/objdiff-core/src/bindings/report.rs +++ b/objdiff-core/src/bindings/report.rs @@ -434,6 +434,7 @@ impl From for ReportItem { demangled_name: value.demangled_name, virtual_address: value.address, }), + address: None, } } } diff --git a/objdiff-core/src/diff/display.rs b/objdiff-core/src/diff/display.rs index bbac421..a35834a 100644 --- a/objdiff-core/src/diff/display.rs +++ b/objdiff-core/src/diff/display.rs @@ -687,19 +687,20 @@ pub fn display_sections( continue; } let section_diff = &diff.sections[section_idx]; - if section.kind == SectionKind::Code && reverse_fn_order { - symbols.sort_by(|a, b| { - let a_symbol = &obj.symbols[a.symbol]; - let b_symbol = &obj.symbols[b.symbol]; - symbol_sort_reverse(a_symbol, b_symbol) - }); - } else { - symbols.sort_by(|a, b| { - let a_symbol = &obj.symbols[a.symbol]; - let b_symbol = &obj.symbols[b.symbol]; - symbol_sort(a_symbol, b_symbol) - }); - } + let reverse_fn_order = section.kind == SectionKind::Code && reverse_fn_order; + symbols.sort_by(|a, b| { + let a = &obj.symbols[a.symbol]; + let b = &obj.symbols[b.symbol]; + section_symbol_sort(a, b) + .then_with(|| { + if reverse_fn_order { + b.address.cmp(&a.address) + } else { + a.address.cmp(&b.address) + } + }) + .then_with(|| a.size.cmp(&b.size)) + }); sections.push(SectionDisplay { id: section.id.clone(), name: if section.flags.contains(SectionFlag::Combined) { @@ -737,14 +738,6 @@ fn section_symbol_sort(a: &Symbol, b: &Symbol) -> Ordering { Ordering::Equal } -fn symbol_sort(a: &Symbol, b: &Symbol) -> Ordering { - section_symbol_sort(a, b).then(a.address.cmp(&b.address)).then(a.size.cmp(&b.size)) -} - -fn symbol_sort_reverse(a: &Symbol, b: &Symbol) -> Ordering { - section_symbol_sort(a, b).then(b.address.cmp(&a.address)).then(b.size.cmp(&a.size)) -} - pub fn display_ins_data_labels(obj: &Object, resolved: ResolvedInstructionRef) -> Vec { let Some(reloc) = resolved.relocation else { return Vec::new();