Skip to content

Commit 6764884

Browse files
committed
Fix resolving symbols for section-relative relocations
Also fixes MIPS `j` handling when jumping within the function. Reworks `ObjReloc` struct to be a little more sensible.
1 parent 83de98b commit 6764884

File tree

11 files changed

+198
-140
lines changed

11 files changed

+198
-140
lines changed

Cargo.lock

+15-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ strip = "debuginfo"
1313
codegen-units = 1
1414

1515
[workspace.package]
16-
version = "2.3.1"
16+
version = "2.3.2"
1717
authors = ["Luke Street <luke@street.dev>"]
1818
edition = "2021"
1919
license = "MIT OR Apache-2.0"

deny.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ feature-depth = 1
7070
# A list of advisory IDs to ignore. Note that ignored advisories will still
7171
# output a note when they are encountered.
7272
ignore = [
73-
"RUSTSEC-2024-0370",
7473
#{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" },
7574
#"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish
7675
#{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" },
@@ -240,7 +239,7 @@ allow-git = []
240239

241240
[sources.allow-org]
242241
# github.com organizations to allow git sources for
243-
github = ["encounter"]
242+
github = ["notify-rs"]
244243
# gitlab.com organizations to allow git sources for
245244
gitlab = []
246245
# bitbucket.org organizations to allow git sources for

objdiff-core/src/arch/mips.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl ObjArch for ObjArchMips {
8383
&self,
8484
address: u64,
8585
code: &[u8],
86-
_section_index: usize,
86+
section_index: usize,
8787
relocations: &[ObjReloc],
8888
line_info: &BTreeMap<u64, u32>,
8989
config: &DiffObjConfig,
@@ -140,11 +140,18 @@ impl ObjArch for ObjArchMips {
140140
| OperandType::cpu_label
141141
| OperandType::cpu_branch_target_label => {
142142
if let Some(reloc) = reloc {
143-
if matches!(&reloc.target_section, Some(s) if s == ".text")
144-
&& reloc.target.address > start_address
145-
&& reloc.target.address < end_address
143+
// If the relocation target is within the current function, we can
144+
// convert it into a relative branch target. Note that we check
145+
// target_address > start_address instead of >= so that recursive
146+
// tail calls are not considered branch targets.
147+
let target_address =
148+
reloc.target.address.checked_add_signed(reloc.addend);
149+
if reloc.target.orig_section_index == Some(section_index)
150+
&& matches!(target_address, Some(addr) if addr > start_address && addr < end_address)
146151
{
147-
args.push(ObjInsArg::BranchDest(reloc.target.address));
152+
let target_address = target_address.unwrap();
153+
args.push(ObjInsArg::BranchDest(target_address));
154+
branch_dest = Some(target_address);
148155
} else {
149156
push_reloc(&mut args, reloc)?;
150157
branch_dest = None;

objdiff-core/src/bindings/diff.rs

+46-45
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ impl FunctionDiff {
7070
// let (_section, symbol) = object.section_symbol(symbol_ref);
7171
// Symbol::from(symbol)
7272
// });
73-
let instructions = symbol_diff.instructions.iter().map(InstructionDiff::from).collect();
73+
let instructions = symbol_diff
74+
.instructions
75+
.iter()
76+
.map(|ins_diff| InstructionDiff::new(object, ins_diff))
77+
.collect();
7478
Self {
75-
symbol: Some(Symbol::from(symbol)),
79+
symbol: Some(Symbol::new(symbol)),
7680
// diff_symbol,
7781
instructions,
7882
match_percent: symbol_diff.match_percent,
@@ -90,8 +94,8 @@ impl DataDiff {
9094
}
9195
}
9296

93-
impl<'a> From<&'a ObjSymbol> for Symbol {
94-
fn from(value: &'a ObjSymbol) -> Self {
97+
impl Symbol {
98+
pub fn new(value: &ObjSymbol) -> Self {
9599
Self {
96100
name: value.name.to_string(),
97101
demangled_name: value.demangled_name.clone(),
@@ -122,38 +126,38 @@ fn symbol_flags(value: ObjSymbolFlagSet) -> u32 {
122126
flags
123127
}
124128

125-
impl<'a> From<&'a ObjIns> for Instruction {
126-
fn from(value: &'a ObjIns) -> Self {
129+
impl Instruction {
130+
pub fn new(object: &ObjInfo, instruction: &ObjIns) -> Self {
127131
Self {
128-
address: value.address,
129-
size: value.size as u32,
130-
opcode: value.op as u32,
131-
mnemonic: value.mnemonic.clone(),
132-
formatted: value.formatted.clone(),
133-
arguments: value.args.iter().map(Argument::from).collect(),
134-
relocation: value.reloc.as_ref().map(Relocation::from),
135-
branch_dest: value.branch_dest,
136-
line_number: value.line,
137-
original: value.orig.clone(),
132+
address: instruction.address,
133+
size: instruction.size as u32,
134+
opcode: instruction.op as u32,
135+
mnemonic: instruction.mnemonic.clone(),
136+
formatted: instruction.formatted.clone(),
137+
arguments: instruction.args.iter().map(Argument::new).collect(),
138+
relocation: instruction.reloc.as_ref().map(|reloc| Relocation::new(object, reloc)),
139+
branch_dest: instruction.branch_dest,
140+
line_number: instruction.line,
141+
original: instruction.orig.clone(),
138142
}
139143
}
140144
}
141145

142-
impl<'a> From<&'a ObjInsArg> for Argument {
143-
fn from(value: &'a ObjInsArg) -> Self {
146+
impl Argument {
147+
pub fn new(value: &ObjInsArg) -> Self {
144148
Self {
145149
value: Some(match value {
146150
ObjInsArg::PlainText(s) => argument::Value::PlainText(s.to_string()),
147-
ObjInsArg::Arg(v) => argument::Value::Argument(ArgumentValue::from(v)),
151+
ObjInsArg::Arg(v) => argument::Value::Argument(ArgumentValue::new(v)),
148152
ObjInsArg::Reloc => argument::Value::Relocation(ArgumentRelocation {}),
149153
ObjInsArg::BranchDest(dest) => argument::Value::BranchDest(*dest),
150154
}),
151155
}
152156
}
153157
}
154158

155-
impl From<&ObjInsArgValue> for ArgumentValue {
156-
fn from(value: &ObjInsArgValue) -> Self {
159+
impl ArgumentValue {
160+
pub fn new(value: &ObjInsArgValue) -> Self {
157161
Self {
158162
value: Some(match value {
159163
ObjInsArgValue::Signed(v) => argument_value::Value::Signed(*v),
@@ -164,42 +168,39 @@ impl From<&ObjInsArgValue> for ArgumentValue {
164168
}
165169
}
166170

167-
impl<'a> From<&'a ObjReloc> for Relocation {
168-
fn from(value: &ObjReloc) -> Self {
171+
impl Relocation {
172+
pub fn new(object: &ObjInfo, reloc: &ObjReloc) -> Self {
169173
Self {
170-
r#type: match value.flags {
174+
r#type: match reloc.flags {
171175
object::RelocationFlags::Elf { r_type } => r_type,
172176
object::RelocationFlags::MachO { r_type, .. } => r_type as u32,
173177
object::RelocationFlags::Coff { typ } => typ as u32,
174178
object::RelocationFlags::Xcoff { r_rtype, .. } => r_rtype as u32,
175179
_ => unreachable!(),
176180
},
177-
type_name: String::new(), // TODO
178-
target: Some(RelocationTarget::from(&value.target)),
181+
type_name: object.arch.display_reloc(reloc.flags).into_owned(),
182+
target: Some(RelocationTarget {
183+
symbol: Some(Symbol::new(&reloc.target)),
184+
addend: reloc.addend,
185+
}),
179186
}
180187
}
181188
}
182189

183-
impl<'a> From<&'a ObjSymbol> for RelocationTarget {
184-
fn from(value: &'a ObjSymbol) -> Self {
185-
Self { symbol: Some(Symbol::from(value)), addend: value.addend }
186-
}
187-
}
188-
189-
impl<'a> From<&'a ObjInsDiff> for InstructionDiff {
190-
fn from(value: &'a ObjInsDiff) -> Self {
190+
impl InstructionDiff {
191+
pub fn new(object: &ObjInfo, instruction_diff: &ObjInsDiff) -> Self {
191192
Self {
192-
instruction: value.ins.as_ref().map(Instruction::from),
193-
diff_kind: DiffKind::from(value.kind) as i32,
194-
branch_from: value.branch_from.as_ref().map(InstructionBranchFrom::from),
195-
branch_to: value.branch_to.as_ref().map(InstructionBranchTo::from),
196-
arg_diff: value.arg_diff.iter().map(ArgumentDiff::from).collect(),
193+
instruction: instruction_diff.ins.as_ref().map(|ins| Instruction::new(object, ins)),
194+
diff_kind: DiffKind::from(instruction_diff.kind) as i32,
195+
branch_from: instruction_diff.branch_from.as_ref().map(InstructionBranchFrom::new),
196+
branch_to: instruction_diff.branch_to.as_ref().map(InstructionBranchTo::new),
197+
arg_diff: instruction_diff.arg_diff.iter().map(ArgumentDiff::new).collect(),
197198
}
198199
}
199200
}
200201

201-
impl From<&Option<ObjInsArgDiff>> for ArgumentDiff {
202-
fn from(value: &Option<ObjInsArgDiff>) -> Self {
202+
impl ArgumentDiff {
203+
pub fn new(value: &Option<ObjInsArgDiff>) -> Self {
203204
Self { diff_index: value.as_ref().map(|v| v.idx as u32) }
204205
}
205206
}
@@ -228,17 +229,17 @@ impl From<ObjDataDiffKind> for DiffKind {
228229
}
229230
}
230231

231-
impl<'a> From<&'a ObjInsBranchFrom> for InstructionBranchFrom {
232-
fn from(value: &'a ObjInsBranchFrom) -> Self {
232+
impl InstructionBranchFrom {
233+
pub fn new(value: &ObjInsBranchFrom) -> Self {
233234
Self {
234235
instruction_index: value.ins_idx.iter().map(|&x| x as u32).collect(),
235236
branch_index: value.branch_idx as u32,
236237
}
237238
}
238239
}
239240

240-
impl<'a> From<&'a ObjInsBranchTo> for InstructionBranchTo {
241-
fn from(value: &'a ObjInsBranchTo) -> Self {
241+
impl InstructionBranchTo {
242+
pub fn new(value: &ObjInsBranchTo) -> Self {
242243
Self { instruction_index: value.ins_idx as u32, branch_index: value.branch_idx as u32 }
243244
}
244245
}

0 commit comments

Comments
 (0)