Skip to content

Commit 09cc995

Browse files
authored
Support R_MIPS_GPREL16 relocations correctly (#88)
* 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. * Run nightly rustfmt * Prevent potential panic when slicing .reginfo
1 parent fc598af commit 09cc995

File tree

6 files changed

+46
-8
lines changed

6 files changed

+46
-8
lines changed

objdiff-core/src/arch/arm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ impl ObjArch for ObjArchArm {
227227

228228
fn implcit_addend(
229229
&self,
230+
_file: &File<'_>,
230231
section: &ObjSection,
231232
address: u64,
232233
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 = object
68+
.section_by_name(".reginfo")
69+
.and_then(|section| section.data().ok())
70+
.and_then(|data| data.get(0x14..0x18))
71+
.and_then(|s| s.try_into().ok())
72+
.map(|bytes| object.endianness().read_i32_bytes(bytes))
73+
.unwrap_or(0);
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: 8 additions & 3 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,8 +28,13 @@ 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

3439
fn demangle(&self, _name: &str) -> Option<String> { None }
3540

objdiff-core/src/arch/ppc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ impl ObjArch for ObjArchPpc {
150150

151151
fn implcit_addend(
152152
&self,
153+
_file: &File<'_>,
153154
_section: &ObjSection,
154155
address: u64,
155156
reloc: &Relocation,

objdiff-core/src/arch/x86.rs

Lines changed: 1 addition & 0 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,

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)