Skip to content

Commit cf5fc54

Browse files
authored
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
1 parent 1cdfa1e commit cf5fc54

File tree

10 files changed

+429
-295
lines changed

10 files changed

+429
-295
lines changed

objdiff-core/config-schema.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@
194194
"name": "Register '$' prefix",
195195
"description": "Display MIPS register names with a '$' prefix."
196196
},
197+
{
198+
"id": "ppc.calculatePoolRelocations",
199+
"type": "boolean",
200+
"default": true,
201+
"name": "Calculate pooled data references",
202+
"description": "Display pooled data references in functions as fake relocations."
203+
},
197204
{
198205
"id": "x86.formatter",
199206
"type": "choice",
@@ -253,6 +260,13 @@
253260
"mips.registerPrefix"
254261
]
255262
},
263+
{
264+
"id": "ppc",
265+
"name": "PPC",
266+
"properties": [
267+
"ppc.calculatePoolRelocations"
268+
]
269+
},
256270
{
257271
"id": "x86",
258272
"name": "x86",

objdiff-core/src/arch/mod.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::{
1010
DiffObjConfig,
1111
},
1212
obj::{
13-
InstructionArg, Object, ParsedInstruction, RelocationFlags, ResolvedInstructionRef,
14-
ScannedInstruction, SymbolFlagSet, SymbolKind,
13+
InstructionArg, Object, ParsedInstruction, Relocation, RelocationFlags,
14+
ResolvedInstructionRef, ScannedInstruction, Symbol, SymbolFlagSet, SymbolKind,
1515
},
1616
util::ReallySigned,
1717
};
@@ -212,6 +212,17 @@ pub trait Arch: Send + Sync + Debug {
212212
cb: &mut dyn FnMut(InstructionPart) -> Result<()>,
213213
) -> Result<()>;
214214

215+
/// Generate a list of fake relocations from the given code that represent pooled data accesses.
216+
fn generate_pooled_relocations(
217+
&self,
218+
_address: u64,
219+
_code: &[u8],
220+
_relocations: &[Relocation],
221+
_symbols: &[Symbol],
222+
) -> Vec<Relocation> {
223+
Vec::new()
224+
}
225+
215226
fn implcit_addend(
216227
&self,
217228
file: &object::File<'_>,

objdiff-core/src/arch/ppc.rs

Lines changed: 276 additions & 261 deletions
Large diffs are not rendered by default.

objdiff-core/src/diff/code.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -502,17 +502,3 @@ fn diff_instruction(
502502

503503
Ok(InstructionDiffResult::new(InstructionDiffKind::None))
504504
}
505-
506-
// TODO
507-
// fn find_symbol_matching_fake_symbol_in_sections(
508-
// fake_symbol: &ObjSymbol,
509-
// sections: &[ObjSection],
510-
// ) -> Option<ObjSymbol> {
511-
// let orig_section_index = fake_symbol.orig_section_index?;
512-
// let section = sections.iter().find(|s| s.orig_index == orig_section_index)?;
513-
// let real_symbol = section
514-
// .symbols
515-
// .iter()
516-
// .find(|s| s.size > 0 && (s.address..s.address + s.size).contains(&fake_symbol.address))?;
517-
// Some(real_symbol.clone())
518-
// }

objdiff-core/src/diff/data.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use super::{
88
code::{address_eq, section_name_eq},
99
DataDiff, DataDiffKind, DataRelocationDiff, ObjectDiff, SectionDiff, SymbolDiff,
1010
};
11-
use crate::obj::{Object, Relocation, ResolvedRelocation, SymbolFlag, SymbolKind};
11+
use crate::obj::{Object, Relocation, ResolvedRelocation, Symbol, SymbolFlag, SymbolKind};
1212

1313
pub fn diff_bss_symbol(
1414
left_obj: &Object,
@@ -64,10 +64,10 @@ fn reloc_eq(
6464

6565
#[inline]
6666
pub fn resolve_relocation<'obj>(
67-
obj: &'obj Object,
67+
symbols: &'obj [Symbol],
6868
reloc: &'obj Relocation,
6969
) -> ResolvedRelocation<'obj> {
70-
let symbol = &obj.symbols[reloc.target_symbol];
70+
let symbol = &symbols[reloc.target_symbol];
7171
ResolvedRelocation { relocation: reloc, symbol }
7272
}
7373

@@ -88,7 +88,7 @@ fn diff_data_relocs_for_range<'left, 'right>(
8888
continue;
8989
}
9090
let left_offset = left_reloc.address as usize - left_range.start;
91-
let left_reloc = resolve_relocation(left_obj, left_reloc);
91+
let left_reloc = resolve_relocation(&left_obj.symbols, left_reloc);
9292
let Some(right_reloc) = right_section.relocations.iter().find(|r| {
9393
if !right_range.contains(&(r.address as usize)) {
9494
return false;
@@ -99,7 +99,7 @@ fn diff_data_relocs_for_range<'left, 'right>(
9999
diffs.push((DataDiffKind::Delete, Some(left_reloc), None));
100100
continue;
101101
};
102-
let right_reloc = resolve_relocation(right_obj, right_reloc);
102+
let right_reloc = resolve_relocation(&right_obj.symbols, right_reloc);
103103
if reloc_eq(left_obj, right_obj, left_reloc, right_reloc) {
104104
diffs.push((DataDiffKind::None, Some(left_reloc), Some(right_reloc)));
105105
} else {
@@ -111,7 +111,7 @@ fn diff_data_relocs_for_range<'left, 'right>(
111111
continue;
112112
}
113113
let right_offset = right_reloc.address as usize - right_range.start;
114-
let right_reloc = resolve_relocation(right_obj, right_reloc);
114+
let right_reloc = resolve_relocation(&right_obj.symbols, right_reloc);
115115
let Some(_) = left_section.relocations.iter().find(|r| {
116116
if !left_range.contains(&(r.address as usize)) {
117117
return false;

objdiff-core/src/obj/read.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use alloc::{
66
};
77
use core::cmp::Ordering;
88

9-
use anyhow::{bail, ensure, Context, Result};
9+
use anyhow::{anyhow, bail, ensure, Context, Result};
1010
use object::{Object as _, ObjectSection as _, ObjectSymbol as _};
1111

1212
use crate::{
@@ -421,6 +421,44 @@ fn map_relocations(
421421
Ok(())
422422
}
423423

424+
fn calculate_pooled_relocations(
425+
arch: &dyn Arch,
426+
sections: &mut [Section],
427+
symbols: &[Symbol],
428+
) -> Result<()> {
429+
for (section_index, section) in sections.iter_mut().enumerate() {
430+
if section.kind != SectionKind::Code {
431+
continue;
432+
}
433+
let mut fake_pool_relocs = Vec::new();
434+
for symbol in symbols {
435+
if symbol.section != Some(section_index) {
436+
continue;
437+
}
438+
if symbol.kind != SymbolKind::Function {
439+
continue;
440+
}
441+
let code =
442+
section.data_range(symbol.address, symbol.size as usize).ok_or_else(|| {
443+
anyhow!(
444+
"Symbol data out of bounds: {:#x}..{:#x}",
445+
symbol.address,
446+
symbol.address + symbol.size
447+
)
448+
})?;
449+
fake_pool_relocs.append(&mut arch.generate_pooled_relocations(
450+
symbol.address,
451+
code,
452+
&section.relocations,
453+
symbols,
454+
));
455+
}
456+
section.relocations.append(&mut fake_pool_relocs);
457+
section.relocations.sort_by_key(|r| r.address);
458+
}
459+
Ok(())
460+
}
461+
424462
fn parse_line_info(
425463
obj_file: &object::File,
426464
sections: &mut [Section],
@@ -812,6 +850,9 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<Object> {
812850
let (mut symbols, symbol_indices) =
813851
map_symbols(arch.as_ref(), &obj_file, &sections, &section_indices, split_meta.as_ref())?;
814852
map_relocations(arch.as_ref(), &obj_file, &mut sections, &section_indices, &symbol_indices)?;
853+
if config.ppc_calculate_pool_relocations {
854+
calculate_pooled_relocations(arch.as_ref(), &mut sections, &symbols)?;
855+
}
815856
parse_line_info(&obj_file, &mut sections, &section_indices, data)?;
816857
if config.combine_data_sections || config.combine_text_sections {
817858
combine_sections(&mut sections, &mut symbols, config)?;

objdiff-core/tests/snapshots/arch_ppc__diff_ppc.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
source: objdiff-core/tests/arch_ppc.rs
3+
assertion_line: 70
34
expression: sections_display
45
---
56
[
@@ -46,7 +47,7 @@ expression: sections_display
4647
name: ".text",
4748
size: 3060,
4849
match_percent: Some(
49-
59.02353,
50+
58.662746,
5051
),
5152
symbols: [
5253
SectionDisplaySymbol {

0 commit comments

Comments
 (0)