Skip to content

Commit

Permalink
Merge pull request #581 from philipc/issue-580
Browse files Browse the repository at this point in the history
Mach-O AArch64 relocation addend improvements
  • Loading branch information
philipc authored Oct 24, 2023
2 parents 312015d + df35618 commit a829634
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 77 deletions.
4 changes: 2 additions & 2 deletions crates/examples/testfiles/macho/base-aarch64-debug.o.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ Symbols
5: Symbol { name: "_printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: MachO { n_desc: 0 } }

__text relocations
(20, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: fffffffffffffffc, implicit_addend: true })
(20, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true })
(1c, Relocation { kind: MachO { value: 4, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true })
(18, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: fffffffffffffffc, implicit_addend: true })
(18, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true })

__debug_info relocations
(33, Relocation { kind: Absolute, encoding: Generic, size: 40, target: Section(SectionIndex(1)), addend: 0, implicit_addend: true })
Expand Down
4 changes: 2 additions & 2 deletions crates/examples/testfiles/macho/base-aarch64.o.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ Symbols
5: Symbol { name: "_printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: MachO { n_desc: 0 } }

__text relocations
(20, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: fffffffffffffffc, implicit_addend: true })
(20, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true })
(1c, Relocation { kind: MachO { value: 4, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true })
(18, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: fffffffffffffffc, implicit_addend: true })
(18, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true })

__compact_unwind relocations
(0, Relocation { kind: Absolute, encoding: Generic, size: 40, target: Section(SectionIndex(1)), addend: 0, implicit_addend: true })
Expand Down
19 changes: 8 additions & 11 deletions crates/examples/testfiles/macho/reloc-aarch64.o.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,18 @@ Symbols

__text relocations
(24, Relocation { kind: MachO { value: 9, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(20, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(20, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(1c, Relocation { kind: MachO { value: 6, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(18, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(14, Relocation { kind: MachO { value: a, relative: false }, encoding: Generic, size: 20, target: Section(SectionIndex(14)), addend: 0, implicit_addend: true })
(14, Relocation { kind: MachO { value: 4, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(10, Relocation { kind: MachO { value: a, relative: false }, encoding: Generic, size: 20, target: Section(SectionIndex(14)), addend: 0, implicit_addend: true })
(10, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(18, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(14, Relocation { kind: MachO { value: 4, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false })
(10, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false })
(c, Relocation { kind: MachO { value: 4, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(8, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(4, Relocation { kind: MachO { value: a, relative: false }, encoding: Generic, size: 20, target: Section(SectionIndex(14)), addend: 0, implicit_addend: true })
(4, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(0, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(8, Relocation { kind: MachO { value: 3, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(4, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false })
(0, Relocation { kind: MachO { value: 2, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })

__data relocations
(1c, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(1c, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(14, Relocation { kind: MachO { value: 7, relative: false }, encoding: Generic, size: 40, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(10, Relocation { kind: MachO { value: 1, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(4)), addend: 0, implicit_addend: true })
(10, Relocation { kind: Absolute, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
Expand Down
8 changes: 4 additions & 4 deletions crates/examples/testfiles/macho/reloc-arm.o.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ __text relocations
(14, Relocation { kind: MachO { value: 1, relative: false }, encoding: Generic, size: 40, target: Section(SectionIndex(ffffff)), addend: 0, implicit_addend: true })
(20, Relocation { kind: MachO { value: 8, relative: false }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(0, Relocation { kind: MachO { value: 1, relative: false }, encoding: Generic, size: 20, target: Section(SectionIndex(ffffff)), addend: 0, implicit_addend: true })
(18, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(1)), addend: fffffffffffffffc, implicit_addend: true })
(14, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(18, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(1)), addend: 0, implicit_addend: true })
(14, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(10, Relocation { kind: MachO { value: 8, relative: false }, encoding: Generic, size: 10, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(14, Relocation { kind: MachO { value: 1, relative: false }, encoding: Generic, size: 10, target: Section(SectionIndex(ffffff)), addend: 0, implicit_addend: true })
(c, Relocation { kind: MachO { value: 8, relative: false }, encoding: Generic, size: 8, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })
(0, Relocation { kind: MachO { value: 1, relative: false }, encoding: Generic, size: 8, target: Section(SectionIndex(ffffff)), addend: 0, implicit_addend: true })
(4, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(2)), addend: fffffffffffffffc, implicit_addend: true })
(0, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: fffffffffffffffc, implicit_addend: true })
(4, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(2)), addend: 0, implicit_addend: true })
(0, Relocation { kind: MachO { value: 5, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true })

__data relocations
(4, Relocation { kind: Absolute, encoding: Generic, size: 20, target: Section(SectionIndex(1)), addend: 0, implicit_addend: true })
Expand Down
12 changes: 6 additions & 6 deletions crates/examples/testfiles/macho/reloc-x86_64.o.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ __text relocations
(4f, Relocation { kind: MachO { value: 9, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(48, Relocation { kind: GotRelative, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(42, Relocation { kind: GotRelative, encoding: X86RipRelativeMovq, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(37, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffffc, implicit_addend: true })
(2f, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffffc, implicit_addend: true })
(27, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffffc, implicit_addend: true })
(1d, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(15, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(d, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(37, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffff8, implicit_addend: true })
(2f, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffffa, implicit_addend: true })
(27, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Section(SectionIndex(2)), addend: fffffffffffffffb, implicit_addend: true })
(1d, Relocation { kind: MachO { value: 8, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffff8, implicit_addend: true })
(15, Relocation { kind: MachO { value: 7, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffa, implicit_addend: true })
(d, Relocation { kind: MachO { value: 6, relative: true }, encoding: Generic, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffb, implicit_addend: true })
(7, Relocation { kind: Relative, encoding: X86RipRelative, size: 20, target: Symbol(SymbolIndex(0)), addend: fffffffffffffffc, implicit_addend: true })
(1, Relocation { kind: Relative, encoding: X86Branch, size: 20, target: Symbol(SymbolIndex(1)), addend: fffffffffffffffc, implicit_addend: true })

Expand Down
35 changes: 33 additions & 2 deletions src/read/macho/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ where
type Item = (u64, Relocation);

fn next(&mut self) -> Option<Self::Item> {
let mut paired_addend = 0;
loop {
let reloc = self.relocations.next()?;
let endian = self.file.endian;
Expand All @@ -56,6 +57,12 @@ where
macho::CPU_TYPE_ARM64 | macho::CPU_TYPE_ARM64_32 => {
match (reloc.r_type, reloc.r_pcrel) {
(macho::ARM64_RELOC_UNSIGNED, false) => RelocationKind::Absolute,
(macho::ARM64_RELOC_ADDEND, _) => {
paired_addend = i64::from(reloc.r_symbolnum)
.wrapping_shl(64 - 24)
.wrapping_shr(64 - 24);
continue;
}
_ => RelocationKind::MachO {
value: reloc.r_type,
relative: reloc.r_pcrel,
Expand Down Expand Up @@ -100,7 +107,31 @@ where
} else {
RelocationTarget::Section(SectionIndex(reloc.r_symbolnum as usize))
};
let addend = if reloc.r_pcrel { -4 } else { 0 };
let implicit_addend = paired_addend == 0;
let mut addend = paired_addend;
if reloc.r_pcrel {
// For PC relative relocations on some architectures, the
// addend does not include the offset required due to the
// PC being different from the place of the relocation.
// This differs from other file formats, so adjust the
// addend here to account for this.
match cputype {
macho::CPU_TYPE_X86 => {
addend -= 1 << reloc.r_length;
}
macho::CPU_TYPE_X86_64 => {
addend -= 1 << reloc.r_length;
match reloc.r_type {
macho::X86_64_RELOC_SIGNED_1 => addend -= 1,
macho::X86_64_RELOC_SIGNED_2 => addend -= 2,
macho::X86_64_RELOC_SIGNED_4 => addend -= 4,
_ => {}
}
}
// TODO: maybe missing support for some architectures and relocations
_ => {}
}
}
return Some((
reloc.r_address as u64,
Relocation {
Expand All @@ -109,7 +140,7 @@ where
size,
target,
addend,
implicit_addend: true,
implicit_addend,
},
));
}
Expand Down
Loading

0 comments on commit a829634

Please sign in to comment.