Skip to content

Commit 8278d5d

Browse files
committed
Support MIPS PIC relocations
1 parent 09bbc53 commit 8278d5d

File tree

3 files changed

+72
-52
lines changed

3 files changed

+72
-52
lines changed

src/obj/elf.rs

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
use std::{collections::BTreeMap, fs, io::Cursor, path::Path};
22

3-
use anyhow::{Context, Result};
3+
use anyhow::{anyhow, bail, Context, Result};
44
use byteorder::{BigEndian, ReadBytesExt};
55
use cwdemangle::demangle;
66
use flagset::Flags;
77
use object::{
8-
elf::{
9-
R_MIPS_26, R_MIPS_HI16, R_MIPS_LO16, R_PPC_ADDR16_HA, R_PPC_ADDR16_HI, R_PPC_ADDR16_LO,
10-
R_PPC_EMB_SDA21, R_PPC_REL14, R_PPC_REL24,
11-
},
12-
Architecture, File, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget,
8+
elf, Architecture, File, Object, ObjectSection, ObjectSymbol, RelocationKind, RelocationTarget,
139
SectionIndex, SectionKind, Symbol, SymbolKind, SymbolSection,
1410
};
1511

@@ -207,27 +203,27 @@ fn relocations_by_section(
207203
RelocationKind::Absolute => ObjRelocKind::Absolute,
208204
RelocationKind::Elf(kind) => match arch {
209205
ObjArchitecture::PowerPc => match kind {
210-
R_PPC_ADDR16_LO => ObjRelocKind::PpcAddr16Lo,
211-
R_PPC_ADDR16_HI => ObjRelocKind::PpcAddr16Hi,
212-
R_PPC_ADDR16_HA => ObjRelocKind::PpcAddr16Ha,
213-
R_PPC_REL24 => ObjRelocKind::PpcRel24,
214-
R_PPC_REL14 => ObjRelocKind::PpcRel14,
215-
R_PPC_EMB_SDA21 => ObjRelocKind::PpcEmbSda21,
206+
elf::R_PPC_ADDR16_LO => ObjRelocKind::PpcAddr16Lo,
207+
elf::R_PPC_ADDR16_HI => ObjRelocKind::PpcAddr16Hi,
208+
elf::R_PPC_ADDR16_HA => ObjRelocKind::PpcAddr16Ha,
209+
elf::R_PPC_REL24 => ObjRelocKind::PpcRel24,
210+
elf::R_PPC_REL14 => ObjRelocKind::PpcRel14,
211+
elf::R_PPC_EMB_SDA21 => ObjRelocKind::PpcEmbSda21,
216212
_ => {
217213
return Err(anyhow::Error::msg(format!(
218214
"Unhandled PPC relocation type: {kind}"
219215
)))
220216
}
221217
},
222218
ObjArchitecture::Mips => match kind {
223-
R_MIPS_26 => ObjRelocKind::Mips26,
224-
R_MIPS_HI16 => ObjRelocKind::MipsHi16,
225-
R_MIPS_LO16 => ObjRelocKind::MipsLo16,
226-
_ => {
227-
return Err(anyhow::Error::msg(format!(
228-
"Unhandled MIPS relocation type: {kind}"
229-
)))
230-
}
219+
elf::R_MIPS_26 => ObjRelocKind::Mips26,
220+
elf::R_MIPS_HI16 => ObjRelocKind::MipsHi16,
221+
elf::R_MIPS_LO16 => ObjRelocKind::MipsLo16,
222+
elf::R_MIPS_GOT16 => ObjRelocKind::MipsGot16,
223+
elf::R_MIPS_CALL16 => ObjRelocKind::MipsCall16,
224+
elf::R_MIPS_GPREL16 => ObjRelocKind::MipsGpRel16,
225+
elf::R_MIPS_GPREL32 => ObjRelocKind::MipsGpRel32,
226+
_ => bail!("Unhandled MIPS relocation type: {kind}"),
231227
},
232228
},
233229
_ => {
@@ -244,37 +240,36 @@ fn relocations_by_section(
244240
}
245241
_ => None,
246242
};
247-
// println!("Reloc: {:?}, symbol: {:?}", reloc, symbol);
243+
let addend = if reloc.has_implicit_addend() {
244+
let addend = u32::from_be_bytes(
245+
section.data[address as usize..address as usize + 4].try_into()?,
246+
);
247+
match kind {
248+
ObjRelocKind::Absolute => addend as i64,
249+
ObjRelocKind::MipsHi16 => ((addend & 0x0000FFFF) << 16) as i16 as i64,
250+
ObjRelocKind::MipsLo16
251+
| ObjRelocKind::MipsGot16
252+
| ObjRelocKind::MipsCall16
253+
| ObjRelocKind::MipsGpRel16 => (addend & 0x0000FFFF) as i16 as i64,
254+
ObjRelocKind::MipsGpRel32 => addend as i32 as i64,
255+
ObjRelocKind::Mips26 => ((addend & 0x03FFFFFF) << 2) as i64,
256+
_ => bail!("Unsupported implicit relocation {kind:?}"),
257+
}
258+
} else {
259+
reloc.addend()
260+
};
261+
// println!("Reloc: {reloc:?}, symbol: {symbol:?}, addend: {addend:#X}");
248262
let target = match symbol.kind() {
249263
SymbolKind::Text | SymbolKind::Data | SymbolKind::Label | SymbolKind::Unknown => {
250-
to_obj_symbol(obj_file, &symbol, reloc.addend())
264+
to_obj_symbol(obj_file, &symbol, addend)
251265
}
252266
SymbolKind::Section => {
253-
let addend = if reloc.has_implicit_addend() {
254-
let addend = u32::from_be_bytes(
255-
section.data[address as usize..address as usize + 4].try_into()?,
256-
);
257-
match kind {
258-
ObjRelocKind::Absolute => addend,
259-
ObjRelocKind::MipsHi16 | ObjRelocKind::MipsLo16 => addend & 0x0000FFFF,
260-
ObjRelocKind::Mips26 => (addend & 0x03FFFFFF) * 4,
261-
_ => todo!(),
262-
}
263-
} else {
264-
let addend = reloc.addend();
265-
if addend < 0 {
266-
return Err(anyhow::Error::msg(format!(
267-
"Negative addend in section reloc: {addend}"
268-
)));
269-
}
270-
addend as u32
271-
};
267+
if addend < 0 {
268+
return Err(anyhow::Error::msg(format!("Negative addend in reloc: {addend}")));
269+
}
272270
find_section_symbol(obj_file, &symbol, addend as u64)
273271
}
274-
_ => Err(anyhow::Error::msg(format!(
275-
"Unhandled relocation symbol type {:?}",
276-
symbol.kind()
277-
))),
272+
kind => Err(anyhow!("Unhandled relocation symbol type {kind:?}")),
278273
}?;
279274
relocations.push(ObjReloc { kind, address, target, target_section });
280275
}

src/obj/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ pub enum ObjRelocKind {
159159
Mips26,
160160
MipsHi16,
161161
MipsLo16,
162+
MipsGot16,
163+
MipsCall16,
164+
MipsGpRel16,
165+
MipsGpRel32,
162166
}
163167
#[derive(Debug, Clone)]
164168
pub struct ObjReloc {

src/views/function_diff.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::default::Default;
1+
use std::{cmp::Ordering, default::Default};
22

33
use cwdemangle::demangle;
44
use eframe::emath::Align;
@@ -20,8 +20,14 @@ use crate::{
2020
fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) {
2121
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
2222
write_text(name, Color32::LIGHT_GRAY, job, font_id.clone());
23-
if reloc.target.addend != 0 {
24-
write_text(&format!("+{:X}", reloc.target.addend), color, job, font_id);
23+
match reloc.target.addend.cmp(&0i64) {
24+
Ordering::Greater => {
25+
write_text(&format!("+{:#X}", reloc.target.addend), color, job, font_id)
26+
}
27+
Ordering::Less => {
28+
write_text(&format!("-{:#X}", -reloc.target.addend), color, job, font_id);
29+
}
30+
_ => {}
2531
}
2632
}
2733

@@ -53,12 +59,27 @@ fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: F
5359
write_reloc_name(reloc, color, job, font_id.clone());
5460
write_text(")", color, job, font_id);
5561
}
56-
ObjRelocKind::Absolute
57-
| ObjRelocKind::PpcRel24
58-
| ObjRelocKind::PpcRel14
59-
| ObjRelocKind::Mips26 => {
62+
ObjRelocKind::MipsGot16 => {
63+
write_text("%got(", color, job, font_id.clone());
64+
write_reloc_name(reloc, color, job, font_id.clone());
65+
write_text(")", color, job, font_id);
66+
}
67+
ObjRelocKind::MipsCall16 => {
68+
write_text("%call16(", color, job, font_id.clone());
69+
write_reloc_name(reloc, color, job, font_id.clone());
70+
write_text(")", color, job, font_id);
71+
}
72+
ObjRelocKind::MipsGpRel16 => {
73+
write_text("%gp_rel(", color, job, font_id.clone());
74+
write_reloc_name(reloc, color, job, font_id.clone());
75+
write_text(")", color, job, font_id);
76+
}
77+
ObjRelocKind::PpcRel24 | ObjRelocKind::PpcRel14 | ObjRelocKind::Mips26 => {
6078
write_reloc_name(reloc, color, job, font_id);
6179
}
80+
ObjRelocKind::Absolute | ObjRelocKind::MipsGpRel32 => {
81+
write_text("[INVALID]", color, job, font_id);
82+
}
6283
};
6384
}
6485

0 commit comments

Comments
 (0)