diff --git a/src/write/macho.rs b/src/write/macho.rs index dbd6e8dd..8ef722fa 100644 --- a/src/write/macho.rs +++ b/src/write/macho.rs @@ -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 } @@ -534,7 +540,7 @@ impl<'a> Object<'a> { debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); for reloc in §ion.relocations { let r_extern; - let r_symbolnum; + let mut r_symbolnum; let symbol = &self.symbols[reloc.symbol.0]; if symbol.kind == SymbolKind::Section { r_symbolnum = section_offsets[symbol.section.id().unwrap().0].index as u32; @@ -590,6 +596,26 @@ impl<'a> Object<'a> { (RelocationKind::Absolute, RelocationEncoding::Generic, 0) => { (false, macho::ARM64_RELOC_UNSIGNED) } + (RelocationKind::Relative, RelocationEncoding::AArch64Call, 0) => { + (true, macho::ARM64_RELOC_BRANCH26) + } + // Non-zero addend, so we have to encode the addend separately + (RelocationKind::Relative, RelocationEncoding::AArch64Call, value) => { + // first emit the BR26 relocation + let reloc_info = macho::RelocationInfo { + r_address: reloc.offset as u32, + r_symbolnum, + r_pcrel: true, + r_length, + r_extern: true, + r_type: macho::ARM64_RELOC_BRANCH26, + }; + buffer.write(&reloc_info.relocation(endian)); + + // set up a separate relocation for the addend + r_symbolnum = value as u32; + (false, macho::ARM64_RELOC_ADDEND) + } ( RelocationKind::MachO { value, relative }, RelocationEncoding::Generic,