diff --git a/src/common.rs b/src/common.rs index 9f2bcc14..4edd9302 100644 --- a/src/common.rs +++ b/src/common.rs @@ -22,6 +22,8 @@ pub enum Architecture { M68k, Mips, Mips64, + #[allow(non_camel_case_types)] + Mips64_N32, Msp430, PowerPc, PowerPc64, @@ -70,6 +72,7 @@ impl Architecture { Architecture::M68k => Some(AddressSize::U32), Architecture::Mips => Some(AddressSize::U32), Architecture::Mips64 => Some(AddressSize::U64), + Architecture::Mips64_N32 => Some(AddressSize::U32), Architecture::Msp430 => Some(AddressSize::U16), Architecture::PowerPc => Some(AddressSize::U32), Architecture::PowerPc64 => Some(AddressSize::U64), diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index ad5d9add..2c7e45bd 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -217,7 +217,13 @@ where (elf::EM_HEXAGON, _) => Architecture::Hexagon, (elf::EM_LOONGARCH, true) => Architecture::LoongArch64, (elf::EM_68K, false) => Architecture::M68k, - (elf::EM_MIPS, false) => Architecture::Mips, + (elf::EM_MIPS, false) => { + if (self.header.e_flags(self.endian) & elf::EF_MIPS_ABI2) != 0 { + Architecture::Mips64_N32 + } else { + Architecture::Mips + } + } (elf::EM_MIPS, true) => Architecture::Mips64, (elf::EM_MSP430, _) => Architecture::Msp430, (elf::EM_PPC, _) => Architecture::PowerPc, diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index 1c2828e7..81a004f3 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -136,6 +136,7 @@ impl<'a> Object<'a> { Architecture::M68k => false, Architecture::Mips => false, Architecture::Mips64 => true, + Architecture::Mips64_N32 => true, Architecture::Msp430 => true, Architecture::PowerPc => true, Architecture::PowerPc64 => true, @@ -276,12 +277,14 @@ impl<'a> Object<'a> { (RelocationKind::PltRelative, _, 32) => elf::R_68K_PLT32, _ => return unsupported_reloc(), }, - Architecture::Mips | Architecture::Mips64 => match (kind, encoding, size) { - (K::Absolute, _, 16) => elf::R_MIPS_16, - (K::Absolute, _, 32) => elf::R_MIPS_32, - (K::Absolute, _, 64) => elf::R_MIPS_64, - _ => return unsupported_reloc(), - }, + Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => { + match (kind, encoding, size) { + (K::Absolute, _, 16) => elf::R_MIPS_16, + (K::Absolute, _, 32) => elf::R_MIPS_32, + (K::Absolute, _, 64) => elf::R_MIPS_64, + _ => return unsupported_reloc(), + } + } Architecture::Msp430 => match (kind, encoding, size) { (K::Absolute, _, 32) => elf::R_MSP430_32, (K::Absolute, _, 16) => elf::R_MSP430_16_BYTE, @@ -562,6 +565,7 @@ impl<'a> Object<'a> { (Architecture::M68k, None) => elf::EM_68K, (Architecture::Mips, None) => elf::EM_MIPS, (Architecture::Mips64, None) => elf::EM_MIPS, + (Architecture::Mips64_N32, None) => elf::EM_MIPS, (Architecture::Msp430, None) => elf::EM_MSP430, (Architecture::PowerPc, None) => elf::EM_PPC, (Architecture::PowerPc64, None) => elf::EM_PPC64, @@ -581,7 +585,7 @@ impl<'a> Object<'a> { ))); } }; - let (os_abi, abi_version, e_flags) = if let FileFlags::Elf { + let (os_abi, abi_version, mut e_flags) = if let FileFlags::Elf { os_abi, abi_version, e_flags, @@ -591,6 +595,11 @@ impl<'a> Object<'a> { } else { (elf::ELFOSABI_NONE, 0, 0) }; + + if self.architecture == Architecture::Mips64_N32 { + e_flags |= elf::EF_MIPS_ABI2; + } + writer.write_file_header(&FileHeader { os_abi, abi_version, diff --git a/tests/round_trip/mod.rs b/tests/round_trip/mod.rs index bc61370e..91f3ce6d 100644 --- a/tests/round_trip/mod.rs +++ b/tests/round_trip/mod.rs @@ -275,6 +275,7 @@ fn elf_any() { (Architecture::M68k, Endianness::Big), (Architecture::Mips, Endianness::Little), (Architecture::Mips64, Endianness::Little), + (Architecture::Mips64_N32, Endianness::Little), (Architecture::Msp430, Endianness::Little), (Architecture::PowerPc, Endianness::Big), (Architecture::PowerPc64, Endianness::Big),