Skip to content

Commit 78d1e1f

Browse files
committed
Support R_MIPS_GPREL16 relocations correctly
symbols defined in the same file require adding a special ri_gp_value from the .reginfo section to their relocation calculations.
1 parent fc598af commit 78d1e1f

File tree

6 files changed

+75
-22
lines changed

6 files changed

+75
-22
lines changed

objdiff-core/src/arch/arm.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,13 @@ impl ObjArchArm {
4848
s.kind() == SectionKind::Elf(SHT_ARM_ATTRIBUTES) && s.name() == Ok(".ARM.attributes")
4949
}) {
5050
let attr_data = arm_attrs.uncompressed_data()?;
51-
let build_attrs = BuildAttrs::new(&attr_data, match file.endianness() {
52-
object::Endianness::Little => arm_attr::Endian::Little,
53-
object::Endianness::Big => arm_attr::Endian::Big,
54-
})?;
51+
let build_attrs = BuildAttrs::new(
52+
&attr_data,
53+
match file.endianness() {
54+
object::Endianness::Little => arm_attr::Endian::Little,
55+
object::Endianness::Big => arm_attr::Endian::Big,
56+
},
57+
)?;
5558
for subsection in build_attrs.subsections() {
5659
let subsection = subsection?;
5760
if !subsection.is_aeabi() {
@@ -227,6 +230,7 @@ impl ObjArch for ObjArchArm {
227230

228231
fn implcit_addend(
229232
&self,
233+
_file: &File<'_>,
230234
section: &ObjSection,
231235
address: u64,
232236
reloc: &Relocation,

objdiff-core/src/arch/mips.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::{borrow::Cow, collections::BTreeMap, sync::Mutex};
22

33
use anyhow::{anyhow, bail, Result};
4-
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
4+
use object::{
5+
elf, Endian, Endianness, File, FileFlags, Object, ObjectSection, ObjectSymbol, Relocation,
6+
RelocationFlags, RelocationTarget,
7+
};
58
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
69

710
use crate::{
@@ -22,6 +25,7 @@ pub struct ObjArchMips {
2225
pub endianness: Endianness,
2326
pub abi: Abi,
2427
pub instr_category: InstrCategory,
28+
pub ri_gp_value: i32,
2529
}
2630

2731
const EF_MIPS_ABI: u32 = 0x0000F000;
@@ -56,7 +60,19 @@ impl ObjArchMips {
5660
}
5761
_ => bail!("Unsupported MIPS file flags"),
5862
}
59-
Ok(Self { endianness: object.endianness(), abi, instr_category })
63+
64+
// Parse the ri_gp_value stored in .reginfo to be able to correctly
65+
// calculate R_MIPS_GPREL16 relocations later. The value is stored
66+
// 0x14 bytes into .reginfo (on 32 bit platforms)
67+
let ri_gp_value = match object.section_by_name(".reginfo").and_then(|s| s.data().ok()) {
68+
Some(reginfo) => {
69+
let gp_ri_value_bytes = reginfo[0x14..0x18].try_into().unwrap_or([0u8; 4]);
70+
object.endianness().read_i32_bytes(gp_ri_value_bytes)
71+
}
72+
None => 0,
73+
};
74+
75+
Ok(Self { endianness: object.endianness(), abi, instr_category, ri_gp_value })
6076
}
6177
}
6278

@@ -179,6 +195,7 @@ impl ObjArch for ObjArchMips {
179195

180196
fn implcit_addend(
181197
&self,
198+
file: &File<'_>,
182199
section: &ObjSection,
183200
address: u64,
184201
reloc: &Relocation,
@@ -191,9 +208,22 @@ impl ObjArch for ObjArchMips {
191208
((addend & 0x0000FFFF) << 16) as i32 as i64
192209
}
193210
RelocationFlags::Elf {
194-
r_type:
195-
elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16 | elf::R_MIPS_GPREL16,
211+
r_type: elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16,
196212
} => (addend & 0x0000FFFF) as i16 as i64,
213+
RelocationFlags::Elf { r_type: elf::R_MIPS_GPREL16 } => {
214+
let RelocationTarget::Symbol(idx) = reloc.target() else {
215+
bail!("Unsupported R_MIPS_GPREL16 relocation against a non-symbol");
216+
};
217+
let sym = file.symbol_by_index(idx)?;
218+
219+
// if the symbol we are relocating against is in a local section we need to add
220+
// the ri_gp_value from .reginfo to the addend.
221+
if sym.section().index().is_some() {
222+
((addend & 0x0000FFFF) as i16 as i64) + self.ri_gp_value as i64
223+
} else {
224+
(addend & 0x0000FFFF) as i16 as i64
225+
}
226+
}
197227
RelocationFlags::Elf { r_type: elf::R_MIPS_26 } => ((addend & 0x03FFFFFF) << 2) as i64,
198228
flags => bail!("Unsupported MIPS implicit relocation {flags:?}"),
199229
})

objdiff-core/src/arch/mod.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{borrow::Cow, collections::BTreeMap};
22

33
use anyhow::{bail, Result};
4-
use object::{Architecture, Object, ObjectSymbol, Relocation, RelocationFlags, Symbol};
4+
use object::{Architecture, File, Object, ObjectSymbol, Relocation, RelocationFlags, Symbol};
55

66
use crate::{
77
diff::DiffObjConfig,
@@ -28,14 +28,23 @@ pub trait ObjArch: Send + Sync {
2828
config: &DiffObjConfig,
2929
) -> Result<ProcessCodeResult>;
3030

31-
fn implcit_addend(&self, section: &ObjSection, address: u64, reloc: &Relocation)
32-
-> Result<i64>;
31+
fn implcit_addend(
32+
&self,
33+
file: &File<'_>,
34+
section: &ObjSection,
35+
address: u64,
36+
reloc: &Relocation,
37+
) -> Result<i64>;
3338

34-
fn demangle(&self, _name: &str) -> Option<String> { None }
39+
fn demangle(&self, _name: &str) -> Option<String> {
40+
None
41+
}
3542

3643
fn display_reloc(&self, flags: RelocationFlags) -> Cow<'static, str>;
3744

38-
fn symbol_address(&self, symbol: &Symbol) -> u64 { symbol.address() }
45+
fn symbol_address(&self, symbol: &Symbol) -> u64 {
46+
symbol.address()
47+
}
3948
}
4049

4150
pub struct ProcessCodeResult {

objdiff-core/src/arch/ppc.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@ fn is_rel_abs_arg(arg: &Argument) -> bool {
2020
matches!(arg, Argument::Uimm(_) | Argument::Simm(_) | Argument::Offset(_))
2121
}
2222

23-
fn is_offset_arg(arg: &Argument) -> bool { matches!(arg, Argument::Offset(_)) }
23+
fn is_offset_arg(arg: &Argument) -> bool {
24+
matches!(arg, Argument::Offset(_))
25+
}
2426

2527
pub struct ObjArchPpc {}
2628

2729
impl ObjArchPpc {
28-
pub fn new(_file: &File) -> Result<Self> { Ok(Self {}) }
30+
pub fn new(_file: &File) -> Result<Self> {
31+
Ok(Self {})
32+
}
2933
}
3034

3135
impl ObjArch for ObjArchPpc {
@@ -150,6 +154,7 @@ impl ObjArch for ObjArchPpc {
150154

151155
fn implcit_addend(
152156
&self,
157+
_file: &File<'_>,
153158
_section: &ObjSection,
154159
address: u64,
155160
reloc: &Relocation,

objdiff-core/src/arch/x86.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ impl ObjArch for ObjArchX86 {
128128

129129
fn implcit_addend(
130130
&self,
131+
_file: &File<'_>,
131132
section: &ObjSection,
132133
address: u64,
133134
reloc: &Relocation,
@@ -261,9 +262,12 @@ impl FormatterOutput for InstructionFormatterOutput {
261262
match kind {
262263
FormatterTextKind::LabelAddress => {
263264
if let Some(reloc) = self.ins.reloc.as_ref() {
264-
if matches!(reloc.flags, RelocationFlags::Coff {
265-
typ: pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32
266-
}) {
265+
if matches!(
266+
reloc.flags,
267+
RelocationFlags::Coff {
268+
typ: pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32
269+
}
270+
) {
267271
self.ins.args.push(ObjInsArg::Reloc);
268272
return;
269273
} else if self.error.is_none() {
@@ -279,9 +283,10 @@ impl FormatterOutput for InstructionFormatterOutput {
279283
}
280284
FormatterTextKind::FunctionAddress => {
281285
if let Some(reloc) = self.ins.reloc.as_ref() {
282-
if matches!(reloc.flags, RelocationFlags::Coff {
283-
typ: pe::IMAGE_REL_I386_REL32
284-
}) {
286+
if matches!(
287+
reloc.flags,
288+
RelocationFlags::Coff { typ: pe::IMAGE_REL_I386_REL32 }
289+
) {
285290
self.ins.args.push(ObjInsArg::Reloc);
286291
return;
287292
} else if self.error.is_none() {

objdiff-core/src/obj/read.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ fn relocations_by_section(
364364
_ => None,
365365
};
366366
let addend = if reloc.has_implicit_addend() {
367-
arch.implcit_addend(section, address, &reloc)?
367+
arch.implcit_addend(obj_file, section, address, &reloc)?
368368
} else {
369369
reloc.addend()
370370
};

0 commit comments

Comments
 (0)