mirror of https://github.com/encounter/objdiff.git
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
This commit is contained in:
parent
fc598af329
commit
09cc9952df
|
@ -227,6 +227,7 @@ impl ObjArch for ObjArchArm {
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
|
_file: &File<'_>,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
address: u64,
|
address: u64,
|
||||||
reloc: &Relocation,
|
reloc: &Relocation,
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use std::{borrow::Cow, collections::BTreeMap, sync::Mutex};
|
use std::{borrow::Cow, collections::BTreeMap, sync::Mutex};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
|
use object::{
|
||||||
|
elf, Endian, Endianness, File, FileFlags, Object, ObjectSection, ObjectSymbol, Relocation,
|
||||||
|
RelocationFlags, RelocationTarget,
|
||||||
|
};
|
||||||
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
|
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -22,6 +25,7 @@ pub struct ObjArchMips {
|
||||||
pub endianness: Endianness,
|
pub endianness: Endianness,
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
pub instr_category: InstrCategory,
|
pub instr_category: InstrCategory,
|
||||||
|
pub ri_gp_value: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const EF_MIPS_ABI: u32 = 0x0000F000;
|
const EF_MIPS_ABI: u32 = 0x0000F000;
|
||||||
|
@ -56,7 +60,19 @@ impl ObjArchMips {
|
||||||
}
|
}
|
||||||
_ => bail!("Unsupported MIPS file flags"),
|
_ => bail!("Unsupported MIPS file flags"),
|
||||||
}
|
}
|
||||||
Ok(Self { endianness: object.endianness(), abi, instr_category })
|
|
||||||
|
// Parse the ri_gp_value stored in .reginfo to be able to correctly
|
||||||
|
// calculate R_MIPS_GPREL16 relocations later. The value is stored
|
||||||
|
// 0x14 bytes into .reginfo (on 32 bit platforms)
|
||||||
|
let ri_gp_value = object
|
||||||
|
.section_by_name(".reginfo")
|
||||||
|
.and_then(|section| section.data().ok())
|
||||||
|
.and_then(|data| data.get(0x14..0x18))
|
||||||
|
.and_then(|s| s.try_into().ok())
|
||||||
|
.map(|bytes| object.endianness().read_i32_bytes(bytes))
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
Ok(Self { endianness: object.endianness(), abi, instr_category, ri_gp_value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +195,7 @@ impl ObjArch for ObjArchMips {
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
|
file: &File<'_>,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
address: u64,
|
address: u64,
|
||||||
reloc: &Relocation,
|
reloc: &Relocation,
|
||||||
|
@ -191,9 +208,22 @@ impl ObjArch for ObjArchMips {
|
||||||
((addend & 0x0000FFFF) << 16) as i32 as i64
|
((addend & 0x0000FFFF) << 16) as i32 as i64
|
||||||
}
|
}
|
||||||
RelocationFlags::Elf {
|
RelocationFlags::Elf {
|
||||||
r_type:
|
r_type: elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16,
|
||||||
elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16 | elf::R_MIPS_GPREL16,
|
|
||||||
} => (addend & 0x0000FFFF) as i16 as i64,
|
} => (addend & 0x0000FFFF) as i16 as i64,
|
||||||
|
RelocationFlags::Elf { r_type: elf::R_MIPS_GPREL16 } => {
|
||||||
|
let RelocationTarget::Symbol(idx) = reloc.target() else {
|
||||||
|
bail!("Unsupported R_MIPS_GPREL16 relocation against a non-symbol");
|
||||||
|
};
|
||||||
|
let sym = file.symbol_by_index(idx)?;
|
||||||
|
|
||||||
|
// if the symbol we are relocating against is in a local section we need to add
|
||||||
|
// the ri_gp_value from .reginfo to the addend.
|
||||||
|
if sym.section().index().is_some() {
|
||||||
|
((addend & 0x0000FFFF) as i16 as i64) + self.ri_gp_value as i64
|
||||||
|
} else {
|
||||||
|
(addend & 0x0000FFFF) as i16 as i64
|
||||||
|
}
|
||||||
|
}
|
||||||
RelocationFlags::Elf { r_type: elf::R_MIPS_26 } => ((addend & 0x03FFFFFF) << 2) as i64,
|
RelocationFlags::Elf { r_type: elf::R_MIPS_26 } => ((addend & 0x03FFFFFF) << 2) as i64,
|
||||||
flags => bail!("Unsupported MIPS implicit relocation {flags:?}"),
|
flags => bail!("Unsupported MIPS implicit relocation {flags:?}"),
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{borrow::Cow, collections::BTreeMap};
|
use std::{borrow::Cow, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use object::{Architecture, Object, ObjectSymbol, Relocation, RelocationFlags, Symbol};
|
use object::{Architecture, File, Object, ObjectSymbol, Relocation, RelocationFlags, Symbol};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::DiffObjConfig,
|
diff::DiffObjConfig,
|
||||||
|
@ -28,8 +28,13 @@ pub trait ObjArch: Send + Sync {
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult>;
|
) -> Result<ProcessCodeResult>;
|
||||||
|
|
||||||
fn implcit_addend(&self, section: &ObjSection, address: u64, reloc: &Relocation)
|
fn implcit_addend(
|
||||||
-> Result<i64>;
|
&self,
|
||||||
|
file: &File<'_>,
|
||||||
|
section: &ObjSection,
|
||||||
|
address: u64,
|
||||||
|
reloc: &Relocation,
|
||||||
|
) -> Result<i64>;
|
||||||
|
|
||||||
fn demangle(&self, _name: &str) -> Option<String> { None }
|
fn demangle(&self, _name: &str) -> Option<String> { None }
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ impl ObjArch for ObjArchPpc {
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
|
_file: &File<'_>,
|
||||||
_section: &ObjSection,
|
_section: &ObjSection,
|
||||||
address: u64,
|
address: u64,
|
||||||
reloc: &Relocation,
|
reloc: &Relocation,
|
||||||
|
|
|
@ -128,6 +128,7 @@ impl ObjArch for ObjArchX86 {
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
|
_file: &File<'_>,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
address: u64,
|
address: u64,
|
||||||
reloc: &Relocation,
|
reloc: &Relocation,
|
||||||
|
|
|
@ -364,7 +364,7 @@ fn relocations_by_section(
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let addend = if reloc.has_implicit_addend() {
|
let addend = if reloc.has_implicit_addend() {
|
||||||
arch.implcit_addend(section, address, &reloc)?
|
arch.implcit_addend(obj_file, section, address, &reloc)?
|
||||||
} else {
|
} else {
|
||||||
reloc.addend()
|
reloc.addend()
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue