Skip to content

Commit

Permalink
Move Aarch64Call special handling to macho module
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanwhit committed Sep 30, 2022
1 parent 6517a8b commit 76877fe
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 13 deletions.
14 changes: 9 additions & 5 deletions src/write/macho.rs
Expand Up @@ -175,11 +175,17 @@ impl<'a> Object<'a> {

pub(crate) fn macho_fixup_relocation(&mut self, mut relocation: &mut Relocation) -> i64 {
let constant = match relocation.kind {
// AArch64Call relocations have special handling for the addend, so don't adjust it
RelocationKind::Relative if relocation.encoding == RelocationEncoding::AArch64Call => 0,
RelocationKind::Relative
| RelocationKind::GotRelative
| RelocationKind::PltRelative => relocation.addend + 4,
_ => relocation.addend,
};
// Aarch64 relocs of these sizes act as if they are double-word length
if self.architecture == Architecture::Aarch64 && matches!(relocation.size, 12 | 21 | 26) {
relocation.size = 32;
}
relocation.addend -= constant;
constant
}
Expand Down Expand Up @@ -546,7 +552,7 @@ impl<'a> Object<'a> {
let r_length = match reloc.size {
8 => 0,
16 => 1,
12 | 21 | 26 | 32 => 2,
32 => 2,
64 => 3,
_ => return Err(Error(format!("unimplemented reloc size {:?}", reloc))),
};
Expand Down Expand Up @@ -590,8 +596,7 @@ impl<'a> Object<'a> {
(RelocationKind::Absolute, RelocationEncoding::Generic, 0) => {
(false, macho::ARM64_RELOC_UNSIGNED)
}
// Due to the fixup an addend of -4 here means the original addend was 0
(RelocationKind::Relative, RelocationEncoding::AArch64Call, -4) => {
(RelocationKind::Relative, RelocationEncoding::AArch64Call, 0) => {
(true, macho::ARM64_RELOC_BRANCH26)
}
// Non-zero addend, so we have to encode the addend separately
Expand All @@ -608,8 +613,7 @@ impl<'a> Object<'a> {
buffer.write(&reloc_info.relocation(endian));

// set up a separate relocation for the addend
// we add 4 to undo the fixup of -4
r_symbolnum = (value + 4) as u32;
r_symbolnum = value as u32;
(false, macho::ARM64_RELOC_ADDEND)
}
(
Expand Down
8 changes: 0 additions & 8 deletions src/write/mod.rs
Expand Up @@ -526,14 +526,6 @@ impl<'a> Object<'a> {
match relocation.size {
32 => data.write_at(offset, &U32::new(self.endian, addend as u32)),
64 => data.write_at(offset, &U64::new(self.endian, addend as u64)),

// For aarch64 call relocations in Mach-O, the addend is
// encoded in a separate relocation, so don't write it here
26 if relocation.encoding == RelocationEncoding::AArch64Call
&& self.format == BinaryFormat::MachO =>
{
Ok(())
}
_ => {
return Err(Error(format!(
"unimplemented relocation addend {:?}",
Expand Down

0 comments on commit 76877fe

Please sign in to comment.