diff --git a/crates/examples/testfiles/macho/base-aarch64-debug.o.objdump b/crates/examples/testfiles/macho/base-aarch64-debug.o.objdump index 61084cc..28f9fbb 100644 --- a/crates/examples/testfiles/macho/base-aarch64-debug.o.objdump +++ b/crates/examples/testfiles/macho/base-aarch64-debug.o.objdump @@ -26,7 +26,7 @@ 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: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) +(20, Relocation { kind: PltRelative, encoding: AArch64Call, size: 1a, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) (1c, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true, flags: MachO { r_type: 4, r_pcrel: false, r_length: 2 } }) (18, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true, flags: MachO { r_type: 3, r_pcrel: true, r_length: 2 } }) diff --git a/crates/examples/testfiles/macho/base-aarch64.o.objdump b/crates/examples/testfiles/macho/base-aarch64.o.objdump index f8a4727..8150e15 100644 --- a/crates/examples/testfiles/macho/base-aarch64.o.objdump +++ b/crates/examples/testfiles/macho/base-aarch64.o.objdump @@ -18,7 +18,7 @@ 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: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) +(20, Relocation { kind: PltRelative, encoding: AArch64Call, size: 1a, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) (1c, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true, flags: MachO { r_type: 4, r_pcrel: false, r_length: 2 } }) (18, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(1)), addend: 0, implicit_addend: true, flags: MachO { r_type: 3, r_pcrel: true, r_length: 2 } }) diff --git a/crates/examples/testfiles/macho/reloc-aarch64.o.objdump b/crates/examples/testfiles/macho/reloc-aarch64.o.objdump index 21c9e5e..52e58b7 100644 --- a/crates/examples/testfiles/macho/reloc-aarch64.o.objdump +++ b/crates/examples/testfiles/macho/reloc-aarch64.o.objdump @@ -24,8 +24,8 @@ __text relocations (10, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false, flags: MachO { r_type: 3, r_pcrel: true, r_length: 2 } }) (c, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true, flags: MachO { r_type: 4, r_pcrel: false, r_length: 2 } }) (8, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true, flags: MachO { r_type: 3, r_pcrel: true, r_length: 2 } }) -(4, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) -(0, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) +(4, Relocation { kind: PltRelative, encoding: AArch64Call, size: 1a, target: Symbol(SymbolIndex(3)), addend: 14, implicit_addend: false, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) +(0, Relocation { kind: PltRelative, encoding: AArch64Call, size: 1a, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true, flags: MachO { r_type: 2, r_pcrel: true, r_length: 2 } }) __data relocations (1c, Relocation { kind: Unknown, encoding: Unknown, size: 20, target: Symbol(SymbolIndex(3)), addend: 0, implicit_addend: true, flags: MachO { r_type: 7, r_pcrel: true, r_length: 2 } }) diff --git a/src/read/macho/relocation.rs b/src/read/macho/relocation.rs index c145e10..98cdce7 100644 --- a/src/read/macho/relocation.rs +++ b/src/read/macho/relocation.rs @@ -54,6 +54,7 @@ where r_pcrel: reloc.r_pcrel, r_length: reloc.r_length, }; + let mut size = 8 << reloc.r_length; let g = E::Generic; let unknown = (K::Unknown, E::Unknown); let (kind, encoding) = match cputype { @@ -64,6 +65,10 @@ where macho::CPU_TYPE_ARM64 | macho::CPU_TYPE_ARM64_32 => { match (reloc.r_type, reloc.r_pcrel) { (macho::ARM64_RELOC_UNSIGNED, false) => (K::Absolute, g), + (macho::ARM64_RELOC_BRANCH26, true) => { + size = 26; + (K::PltRelative, E::AArch64Call) + } (macho::ARM64_RELOC_ADDEND, _) => { paired_addend = i64::from(reloc.r_symbolnum) .wrapping_shl(64 - 24) @@ -101,7 +106,6 @@ where } _ => unknown, }; - let size = 8 << reloc.r_length; let target = if reloc.r_extern { RelocationTarget::Symbol(SymbolIndex(reloc.r_symbolnum as usize)) } else { diff --git a/src/write/macho.rs b/src/write/macho.rs index 6558e61..ce87fa6 100644 --- a/src/write/macho.rs +++ b/src/write/macho.rs @@ -348,6 +348,9 @@ impl<'a> Object<'a> { (false, macho::ARM64_RELOC_UNSIGNED) } (K::Relative, E::AArch64Call) => (true, macho::ARM64_RELOC_BRANCH26), + (K::PltRelative, E::Generic | E::AArch64Call) => { + (true, macho::ARM64_RELOC_BRANCH26) + } _ => return unsupported_reloc(), }, Architecture::PowerPc | Architecture::PowerPc64 => match kind { diff --git a/tests/round_trip/reloc.rs b/tests/round_trip/reloc.rs index 84183cb..a0340d0 100644 --- a/tests/round_trip/reloc.rs +++ b/tests/round_trip/reloc.rs @@ -229,6 +229,8 @@ fn reloc_round_trip() { elf_r(A::X86_64, elf::R_X86_64_PLT32), // Canonical: E::X86Branch macho_r(A::X86_64, macho::X86_64_RELOC_BRANCH, true, 2), + // Canonical: E::AArch64Call + macho_r(A::Aarch64, macho::ARM64_RELOC_BRANCH26, true, 2), // Canonical: K::Relative coff_r(A::I386, pe::IMAGE_REL_I386_REL32), coff_r(A::X86_64, pe::IMAGE_REL_AMD64_REL32), @@ -290,7 +292,10 @@ fn reloc_round_trip() { // AArch64 PLT branch or call. ( (K::PltRelative, E::AArch64Call, 26), - vec![elf_r(A::Aarch64, elf::R_AARCH64_CALL26)], + vec![ + elf_r(A::Aarch64, elf::R_AARCH64_CALL26), + macho_r(A::Aarch64, macho::ARM64_RELOC_BRANCH26, true, 2), + ], vec![ // Canonical: K::Relative coff_r(A::Aarch64, pe::IMAGE_REL_ARM64_BRANCH26),