mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 23:23:34 +00:00
Support MIPS PIC relocations
This commit is contained in:
parent
09bbc534bd
commit
8278d5d207
@ -1,15 +1,11 @@
|
|||||||
use std::{collections::BTreeMap, fs, io::Cursor, path::Path};
|
use std::{collections::BTreeMap, fs, io::Cursor, path::Path};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{anyhow, bail, Context, Result};
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
use cwdemangle::demangle;
|
use cwdemangle::demangle;
|
||||||
use flagset::Flags;
|
use flagset::Flags;
|
||||||
use object::{
|
use object::{
|
||||||
elf::{
|
elf, Architecture, File, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget,
|
||||||
R_MIPS_26, R_MIPS_HI16, R_MIPS_LO16, R_PPC_ADDR16_HA, R_PPC_ADDR16_HI, R_PPC_ADDR16_LO,
|
|
||||||
R_PPC_EMB_SDA21, R_PPC_REL14, R_PPC_REL24,
|
|
||||||
},
|
|
||||||
Architecture, File, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget,
|
|
||||||
SectionIndex, SectionKind, Symbol, SymbolKind, SymbolSection,
|
SectionIndex, SectionKind, Symbol, SymbolKind, SymbolSection,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -207,12 +203,12 @@ fn relocations_by_section(
|
|||||||
RelocationKind::Absolute => ObjRelocKind::Absolute,
|
RelocationKind::Absolute => ObjRelocKind::Absolute,
|
||||||
RelocationKind::Elf(kind) => match arch {
|
RelocationKind::Elf(kind) => match arch {
|
||||||
ObjArchitecture::PowerPc => match kind {
|
ObjArchitecture::PowerPc => match kind {
|
||||||
R_PPC_ADDR16_LO => ObjRelocKind::PpcAddr16Lo,
|
elf::R_PPC_ADDR16_LO => ObjRelocKind::PpcAddr16Lo,
|
||||||
R_PPC_ADDR16_HI => ObjRelocKind::PpcAddr16Hi,
|
elf::R_PPC_ADDR16_HI => ObjRelocKind::PpcAddr16Hi,
|
||||||
R_PPC_ADDR16_HA => ObjRelocKind::PpcAddr16Ha,
|
elf::R_PPC_ADDR16_HA => ObjRelocKind::PpcAddr16Ha,
|
||||||
R_PPC_REL24 => ObjRelocKind::PpcRel24,
|
elf::R_PPC_REL24 => ObjRelocKind::PpcRel24,
|
||||||
R_PPC_REL14 => ObjRelocKind::PpcRel14,
|
elf::R_PPC_REL14 => ObjRelocKind::PpcRel14,
|
||||||
R_PPC_EMB_SDA21 => ObjRelocKind::PpcEmbSda21,
|
elf::R_PPC_EMB_SDA21 => ObjRelocKind::PpcEmbSda21,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(anyhow::Error::msg(format!(
|
return Err(anyhow::Error::msg(format!(
|
||||||
"Unhandled PPC relocation type: {kind}"
|
"Unhandled PPC relocation type: {kind}"
|
||||||
@ -220,14 +216,14 @@ fn relocations_by_section(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
ObjArchitecture::Mips => match kind {
|
ObjArchitecture::Mips => match kind {
|
||||||
R_MIPS_26 => ObjRelocKind::Mips26,
|
elf::R_MIPS_26 => ObjRelocKind::Mips26,
|
||||||
R_MIPS_HI16 => ObjRelocKind::MipsHi16,
|
elf::R_MIPS_HI16 => ObjRelocKind::MipsHi16,
|
||||||
R_MIPS_LO16 => ObjRelocKind::MipsLo16,
|
elf::R_MIPS_LO16 => ObjRelocKind::MipsLo16,
|
||||||
_ => {
|
elf::R_MIPS_GOT16 => ObjRelocKind::MipsGot16,
|
||||||
return Err(anyhow::Error::msg(format!(
|
elf::R_MIPS_CALL16 => ObjRelocKind::MipsCall16,
|
||||||
"Unhandled MIPS relocation type: {kind}"
|
elf::R_MIPS_GPREL16 => ObjRelocKind::MipsGpRel16,
|
||||||
)))
|
elf::R_MIPS_GPREL32 => ObjRelocKind::MipsGpRel32,
|
||||||
}
|
_ => bail!("Unhandled MIPS relocation type: {kind}"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@ -244,37 +240,36 @@ fn relocations_by_section(
|
|||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
// println!("Reloc: {:?}, symbol: {:?}", reloc, symbol);
|
|
||||||
let target = match symbol.kind() {
|
|
||||||
SymbolKind::Text | SymbolKind::Data | SymbolKind::Label | SymbolKind::Unknown => {
|
|
||||||
to_obj_symbol(obj_file, &symbol, reloc.addend())
|
|
||||||
}
|
|
||||||
SymbolKind::Section => {
|
|
||||||
let addend = if reloc.has_implicit_addend() {
|
let addend = if reloc.has_implicit_addend() {
|
||||||
let addend = u32::from_be_bytes(
|
let addend = u32::from_be_bytes(
|
||||||
section.data[address as usize..address as usize + 4].try_into()?,
|
section.data[address as usize..address as usize + 4].try_into()?,
|
||||||
);
|
);
|
||||||
match kind {
|
match kind {
|
||||||
ObjRelocKind::Absolute => addend,
|
ObjRelocKind::Absolute => addend as i64,
|
||||||
ObjRelocKind::MipsHi16 | ObjRelocKind::MipsLo16 => addend & 0x0000FFFF,
|
ObjRelocKind::MipsHi16 => ((addend & 0x0000FFFF) << 16) as i16 as i64,
|
||||||
ObjRelocKind::Mips26 => (addend & 0x03FFFFFF) * 4,
|
ObjRelocKind::MipsLo16
|
||||||
_ => todo!(),
|
| ObjRelocKind::MipsGot16
|
||||||
|
| ObjRelocKind::MipsCall16
|
||||||
|
| ObjRelocKind::MipsGpRel16 => (addend & 0x0000FFFF) as i16 as i64,
|
||||||
|
ObjRelocKind::MipsGpRel32 => addend as i32 as i64,
|
||||||
|
ObjRelocKind::Mips26 => ((addend & 0x03FFFFFF) << 2) as i64,
|
||||||
|
_ => bail!("Unsupported implicit relocation {kind:?}"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let addend = reloc.addend();
|
reloc.addend()
|
||||||
if addend < 0 {
|
|
||||||
return Err(anyhow::Error::msg(format!(
|
|
||||||
"Negative addend in section reloc: {addend}"
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
addend as u32
|
|
||||||
};
|
};
|
||||||
|
// println!("Reloc: {reloc:?}, symbol: {symbol:?}, addend: {addend:#X}");
|
||||||
|
let target = match symbol.kind() {
|
||||||
|
SymbolKind::Text | SymbolKind::Data | SymbolKind::Label | SymbolKind::Unknown => {
|
||||||
|
to_obj_symbol(obj_file, &symbol, addend)
|
||||||
|
}
|
||||||
|
SymbolKind::Section => {
|
||||||
|
if addend < 0 {
|
||||||
|
return Err(anyhow::Error::msg(format!("Negative addend in reloc: {addend}")));
|
||||||
|
}
|
||||||
find_section_symbol(obj_file, &symbol, addend as u64)
|
find_section_symbol(obj_file, &symbol, addend as u64)
|
||||||
}
|
}
|
||||||
_ => Err(anyhow::Error::msg(format!(
|
kind => Err(anyhow!("Unhandled relocation symbol type {kind:?}")),
|
||||||
"Unhandled relocation symbol type {:?}",
|
|
||||||
symbol.kind()
|
|
||||||
))),
|
|
||||||
}?;
|
}?;
|
||||||
relocations.push(ObjReloc { kind, address, target, target_section });
|
relocations.push(ObjReloc { kind, address, target, target_section });
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,10 @@ pub enum ObjRelocKind {
|
|||||||
Mips26,
|
Mips26,
|
||||||
MipsHi16,
|
MipsHi16,
|
||||||
MipsLo16,
|
MipsLo16,
|
||||||
|
MipsGot16,
|
||||||
|
MipsCall16,
|
||||||
|
MipsGpRel16,
|
||||||
|
MipsGpRel32,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ObjReloc {
|
pub struct ObjReloc {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::default::Default;
|
use std::{cmp::Ordering, default::Default};
|
||||||
|
|
||||||
use cwdemangle::demangle;
|
use cwdemangle::demangle;
|
||||||
use eframe::emath::Align;
|
use eframe::emath::Align;
|
||||||
@ -20,8 +20,14 @@ use crate::{
|
|||||||
fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) {
|
fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) {
|
||||||
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
|
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
|
||||||
write_text(name, Color32::LIGHT_GRAY, job, font_id.clone());
|
write_text(name, Color32::LIGHT_GRAY, job, font_id.clone());
|
||||||
if reloc.target.addend != 0 {
|
match reloc.target.addend.cmp(&0i64) {
|
||||||
write_text(&format!("+{:X}", reloc.target.addend), color, job, font_id);
|
Ordering::Greater => {
|
||||||
|
write_text(&format!("+{:#X}", reloc.target.addend), color, job, font_id)
|
||||||
|
}
|
||||||
|
Ordering::Less => {
|
||||||
|
write_text(&format!("-{:#X}", -reloc.target.addend), color, job, font_id);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,12 +59,27 @@ fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: F
|
|||||||
write_reloc_name(reloc, color, job, font_id.clone());
|
write_reloc_name(reloc, color, job, font_id.clone());
|
||||||
write_text(")", color, job, font_id);
|
write_text(")", color, job, font_id);
|
||||||
}
|
}
|
||||||
ObjRelocKind::Absolute
|
ObjRelocKind::MipsGot16 => {
|
||||||
| ObjRelocKind::PpcRel24
|
write_text("%got(", color, job, font_id.clone());
|
||||||
| ObjRelocKind::PpcRel14
|
write_reloc_name(reloc, color, job, font_id.clone());
|
||||||
| ObjRelocKind::Mips26 => {
|
write_text(")", color, job, font_id);
|
||||||
|
}
|
||||||
|
ObjRelocKind::MipsCall16 => {
|
||||||
|
write_text("%call16(", color, job, font_id.clone());
|
||||||
|
write_reloc_name(reloc, color, job, font_id.clone());
|
||||||
|
write_text(")", color, job, font_id);
|
||||||
|
}
|
||||||
|
ObjRelocKind::MipsGpRel16 => {
|
||||||
|
write_text("%gp_rel(", color, job, font_id.clone());
|
||||||
|
write_reloc_name(reloc, color, job, font_id.clone());
|
||||||
|
write_text(")", color, job, font_id);
|
||||||
|
}
|
||||||
|
ObjRelocKind::PpcRel24 | ObjRelocKind::PpcRel14 | ObjRelocKind::Mips26 => {
|
||||||
write_reloc_name(reloc, color, job, font_id);
|
write_reloc_name(reloc, color, job, font_id);
|
||||||
}
|
}
|
||||||
|
ObjRelocKind::Absolute | ObjRelocKind::MipsGpRel32 => {
|
||||||
|
write_text("[INVALID]", color, job, font_id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user