Support R_MIPS_LITERAL, R_MIPS15_S3 relocations

Resolves #92
Resolves #95
This commit is contained in:
Luke Street 2024-08-18 22:05:16 -06:00
parent fd555a6e0f
commit 8250d26b77
1 changed files with 27 additions and 6 deletions

View File

@ -34,6 +34,8 @@ const EF_MIPS_MACH: u32 = 0x00FF0000;
const EF_MIPS_MACH_ALLEGREX: u32 = 0x00840000; const EF_MIPS_MACH_ALLEGREX: u32 = 0x00840000;
const EF_MIPS_MACH_5900: u32 = 0x00920000; const EF_MIPS_MACH_5900: u32 = 0x00920000;
const R_MIPS15_S3: u32 = 119;
impl ObjArchMips { impl ObjArchMips {
pub fn new(object: &File) -> Result<Self> { pub fn new(object: &File) -> Result<Self> {
let mut abi = Abi::NUMERIC; let mut abi = Abi::NUMERIC;
@ -169,6 +171,18 @@ impl ObjArch for ObjArchMips {
))); )));
args.push(ObjInsArg::PlainText(")".into())); args.push(ObjInsArg::PlainText(")".into()));
} }
// OperandType::r5900_immediate15 => match reloc {
// Some(reloc)
// if reloc.flags == RelocationFlags::Elf { r_type: R_MIPS15_S3 } =>
// {
// push_reloc(&mut args, reloc)?;
// }
// _ => {
// args.push(ObjInsArg::Arg(ObjInsArgValue::Opaque(
// op.disassemble(&instruction, None).into(),
// )));
// }
// },
_ => { _ => {
args.push(ObjInsArg::Arg(ObjInsArgValue::Opaque( args.push(ObjInsArg::Arg(ObjInsArgValue::Opaque(
op.disassemble(&instruction, None).into(), op.disassemble(&instruction, None).into(),
@ -205,13 +219,14 @@ impl ObjArch for ObjArchMips {
let addend = self.endianness.read_u32_bytes(data); let addend = self.endianness.read_u32_bytes(data);
Ok(match reloc.flags() { Ok(match reloc.flags() {
RelocationFlags::Elf { r_type: elf::R_MIPS_32 } => addend as i64, RelocationFlags::Elf { r_type: elf::R_MIPS_32 } => addend as i64,
RelocationFlags::Elf { r_type: elf::R_MIPS_26 } => ((addend & 0x03FFFFFF) << 2) as i64,
RelocationFlags::Elf { r_type: elf::R_MIPS_HI16 } => { RelocationFlags::Elf { r_type: elf::R_MIPS_HI16 } => {
((addend & 0x0000FFFF) << 16) as i32 as i64 ((addend & 0x0000FFFF) << 16) as i32 as i64
} }
RelocationFlags::Elf { RelocationFlags::Elf {
r_type: elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16, r_type: elf::R_MIPS_LO16 | elf::R_MIPS_GOT16 | elf::R_MIPS_CALL16,
} => (addend & 0x0000FFFF) as i16 as i64, } => (addend & 0x0000FFFF) as i16 as i64,
RelocationFlags::Elf { r_type: elf::R_MIPS_GPREL16 } => { RelocationFlags::Elf { r_type: elf::R_MIPS_GPREL16 | elf::R_MIPS_LITERAL } => {
let RelocationTarget::Symbol(idx) = reloc.target() else { let RelocationTarget::Symbol(idx) = reloc.target() else {
bail!("Unsupported R_MIPS_GPREL16 relocation against a non-symbol"); bail!("Unsupported R_MIPS_GPREL16 relocation against a non-symbol");
}; };
@ -225,8 +240,8 @@ impl ObjArch for ObjArchMips {
(addend & 0x0000FFFF) as i16 as i64 (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_PC16 } => 0, // PC-relative relocation RelocationFlags::Elf { r_type: elf::R_MIPS_PC16 } => 0, // PC-relative relocation
RelocationFlags::Elf { r_type: R_MIPS15_S3 } => ((addend & 0x001FFFC0) >> 3) as i64,
flags => bail!("Unsupported MIPS implicit relocation {flags:?}"), flags => bail!("Unsupported MIPS implicit relocation {flags:?}"),
}) })
} }
@ -234,14 +249,16 @@ impl ObjArch for ObjArchMips {
fn display_reloc(&self, flags: RelocationFlags) -> Cow<'static, str> { fn display_reloc(&self, flags: RelocationFlags) -> Cow<'static, str> {
match flags { match flags {
RelocationFlags::Elf { r_type } => match r_type { RelocationFlags::Elf { r_type } => match r_type {
elf::R_MIPS_32 => Cow::Borrowed("R_MIPS_32"),
elf::R_MIPS_26 => Cow::Borrowed("R_MIPS_26"),
elf::R_MIPS_HI16 => Cow::Borrowed("R_MIPS_HI16"), elf::R_MIPS_HI16 => Cow::Borrowed("R_MIPS_HI16"),
elf::R_MIPS_LO16 => Cow::Borrowed("R_MIPS_LO16"), elf::R_MIPS_LO16 => Cow::Borrowed("R_MIPS_LO16"),
elf::R_MIPS_GPREL16 => Cow::Borrowed("R_MIPS_GPREL16"),
elf::R_MIPS_LITERAL => Cow::Borrowed("R_MIPS_LITERAL"),
elf::R_MIPS_GOT16 => Cow::Borrowed("R_MIPS_GOT16"), elf::R_MIPS_GOT16 => Cow::Borrowed("R_MIPS_GOT16"),
elf::R_MIPS_PC16 => Cow::Borrowed("R_MIPS_PC16"), elf::R_MIPS_PC16 => Cow::Borrowed("R_MIPS_PC16"),
elf::R_MIPS_CALL16 => Cow::Borrowed("R_MIPS_CALL16"), elf::R_MIPS_CALL16 => Cow::Borrowed("R_MIPS_CALL16"),
elf::R_MIPS_GPREL16 => Cow::Borrowed("R_MIPS_GPREL16"), R_MIPS15_S3 => Cow::Borrowed("R_MIPS15_S3"),
elf::R_MIPS_32 => Cow::Borrowed("R_MIPS_32"),
elf::R_MIPS_26 => Cow::Borrowed("R_MIPS_26"),
_ => Cow::Owned(format!("<{flags:?}>")), _ => Cow::Owned(format!("<{flags:?}>")),
}, },
_ => Cow::Owned(format!("<{flags:?}>")), _ => Cow::Owned(format!("<{flags:?}>")),
@ -277,7 +294,11 @@ fn push_reloc(args: &mut Vec<ObjInsArg>, reloc: &ObjReloc) -> Result<()> {
args.push(ObjInsArg::Reloc); args.push(ObjInsArg::Reloc);
args.push(ObjInsArg::PlainText(")".into())); args.push(ObjInsArg::PlainText(")".into()));
} }
elf::R_MIPS_32 | elf::R_MIPS_26 | elf::R_MIPS_PC16 => { elf::R_MIPS_32
| elf::R_MIPS_26
| elf::R_MIPS_LITERAL
| elf::R_MIPS_PC16
| R_MIPS15_S3 => {
args.push(ObjInsArg::Reloc); args.push(ObjInsArg::Reloc);
} }
_ => bail!("Unsupported ELF MIPS relocation type {r_type}"), _ => bail!("Unsupported ELF MIPS relocation type {r_type}"),