From d4482ec1bb9979ac2773244b9246e0ad43c63d0c Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 4 Jan 2023 02:51:50 +0000 Subject: [PATCH] Add support for AArch64 ILP32 for ELF (#497) --- src/common.rs | 3 +++ src/read/elf/file.rs | 3 ++- src/read/elf/relocation.rs | 33 +++++++++++++++++++++------------ src/write/elf/object.rs | 16 ++++++++++++++++ tests/round_trip/mod.rs | 1 + 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/common.rs b/src/common.rs index 958f2d66..cb009c0f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -5,6 +5,8 @@ pub enum Architecture { Unknown, Aarch64, + #[allow(non_camel_case_types)] + Aarch64_Ilp32, Arm, Avr, Bpf, @@ -36,6 +38,7 @@ impl Architecture { match self { Architecture::Unknown => None, Architecture::Aarch64 => Some(AddressSize::U64), + Architecture::Aarch64_Ilp32 => Some(AddressSize::U32), Architecture::Arm => Some(AddressSize::U32), Architecture::Avr => Some(AddressSize::U8), Architecture::Bpf => Some(AddressSize::U64), diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 299bb979..259da790 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -156,7 +156,8 @@ where self.header.e_machine(self.endian), self.header.is_class_64(), ) { - (elf::EM_AARCH64, _) => Architecture::Aarch64, + (elf::EM_AARCH64, true) => Architecture::Aarch64, + (elf::EM_AARCH64, false) => Architecture::Aarch64_Ilp32, (elf::EM_ARM, _) => Architecture::Arm, (elf::EM_AVR, _) => Architecture::Avr, (elf::EM_BPF, _) => Architecture::Bpf, diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index 17052033..8443dbc7 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -240,19 +240,28 @@ fn parse_relocation( let mut encoding = RelocationEncoding::Generic; let is_mips64el = header.is_mips64el(endian); let (kind, size) = match header.e_machine(endian) { - elf::EM_AARCH64 => match reloc.r_type(endian, false) { - elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64), - elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32), - elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16), - elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64), - elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32), - elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16), - elf::R_AARCH64_CALL26 => { - encoding = RelocationEncoding::AArch64Call; - (RelocationKind::PltRelative, 26) + elf::EM_AARCH64 => { + if header.is_type_64() { + match reloc.r_type(endian, false) { + elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64), + elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32), + elf::R_AARCH64_ABS16 => (RelocationKind::Absolute, 16), + elf::R_AARCH64_PREL64 => (RelocationKind::Relative, 64), + elf::R_AARCH64_PREL32 => (RelocationKind::Relative, 32), + elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16), + elf::R_AARCH64_CALL26 => { + encoding = RelocationEncoding::AArch64Call; + (RelocationKind::PltRelative, 26) + } + r_type => (RelocationKind::Elf(r_type), 0), + } + } else { + match reloc.r_type(endian, false) { + elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32), + r_type => (RelocationKind::Elf(r_type), 0), + } } - r_type => (RelocationKind::Elf(r_type), 0), - }, + } elf::EM_ARM => match reloc.r_type(endian, false) { elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32), r_type => (RelocationKind::Elf(r_type), 0), diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index 7080da9a..068ada6b 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -67,6 +67,7 @@ impl<'a> Object<'a> { fn elf_has_relocation_addend(&self) -> Result { Ok(match self.architecture { Architecture::Aarch64 => true, + Architecture::Aarch64_Ilp32 => true, Architecture::Arm => false, Architecture::Avr => true, Architecture::Bpf => false, @@ -266,6 +267,7 @@ impl<'a> Object<'a> { let e_type = elf::ET_REL; let e_machine = match self.architecture { Architecture::Aarch64 => elf::EM_AARCH64, + Architecture::Aarch64_Ilp32 => elf::EM_AARCH64, Architecture::Arm => elf::EM_ARM, Architecture::Avr => elf::EM_AVR, Architecture::Bpf => elf::EM_BPF, @@ -454,6 +456,20 @@ impl<'a> Object<'a> { return Err(Error(format!("unimplemented relocation {:?}", reloc))); } }, + Architecture::Aarch64_Ilp32 => { + match (reloc.kind, reloc.encoding, reloc.size) { + (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { + elf::R_AARCH64_P32_ABS32 + } + (RelocationKind::Elf(x), _, _) => x, + _ => { + return Err(Error(format!( + "unimplemented relocation {:?}", + reloc + ))); + } + } + } Architecture::Arm => match (reloc.kind, reloc.encoding, reloc.size) { (RelocationKind::Absolute, _, 32) => elf::R_ARM_ABS32, (RelocationKind::Elf(x), _, _) => x, diff --git a/tests/round_trip/mod.rs b/tests/round_trip/mod.rs index f22d15ec..89bed8bf 100644 --- a/tests/round_trip/mod.rs +++ b/tests/round_trip/mod.rs @@ -231,6 +231,7 @@ fn elf_x86_64() { fn elf_any() { for (arch, endian) in [ (Architecture::Aarch64, Endianness::Little), + (Architecture::Aarch64_Ilp32, Endianness::Little), (Architecture::Arm, Endianness::Little), (Architecture::Avr, Endianness::Little), (Architecture::Bpf, Endianness::Little),