diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index 0920a0dd..ccfee04b 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -155,6 +155,9 @@ impl<'a> Object<'a> { } pub(crate) fn elf_translate_relocation(&mut self, reloc: &mut Relocation) -> Result<()> { + use RelocationEncoding as E; + use RelocationKind as K; + let (kind, encoding, size) = if let RelocationFlags::Generic { kind, encoding, @@ -166,280 +169,173 @@ impl<'a> Object<'a> { return Ok(()); }; + let unsupported_reloc = || Err(Error(format!("unimplemented relocation {:?}", reloc))); let r_type = match self.architecture { Architecture::Aarch64 => match (kind, encoding, size) { - (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => elf::R_AARCH64_ABS64, - (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => elf::R_AARCH64_ABS32, - (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => elf::R_AARCH64_ABS16, - (RelocationKind::Relative, RelocationEncoding::Generic, 64) => { - elf::R_AARCH64_PREL64 - } - (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { - elf::R_AARCH64_PREL32 - } - (RelocationKind::Relative, RelocationEncoding::Generic, 16) => { - elf::R_AARCH64_PREL16 - } - (RelocationKind::Relative, RelocationEncoding::AArch64Call, 26) - | (RelocationKind::PltRelative, RelocationEncoding::AArch64Call, 26) => { - elf::R_AARCH64_CALL26 - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, E::Generic, 64) => elf::R_AARCH64_ABS64, + (K::Absolute, E::Generic, 32) => elf::R_AARCH64_ABS32, + (K::Absolute, E::Generic, 16) => elf::R_AARCH64_ABS16, + (K::Relative, E::Generic, 64) => elf::R_AARCH64_PREL64, + (K::Relative, E::Generic, 32) => elf::R_AARCH64_PREL32, + (K::Relative, E::Generic, 16) => elf::R_AARCH64_PREL16, + (K::Relative, E::AArch64Call, 26) => elf::R_AARCH64_CALL26, + (K::PltRelative, E::AArch64Call, 26) => elf::R_AARCH64_CALL26, + _ => return unsupported_reloc(), }, Architecture::Aarch64_Ilp32 => match (kind, encoding, size) { - (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { - elf::R_AARCH64_P32_ABS32 - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, E::Generic, 32) => elf::R_AARCH64_P32_ABS32, + _ => return unsupported_reloc(), }, Architecture::Arm => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_ARM_ABS32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_ARM_ABS32, + _ => return unsupported_reloc(), }, Architecture::Avr => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_AVR_32, - (RelocationKind::Absolute, _, 16) => elf::R_AVR_16, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_AVR_32, + (K::Absolute, _, 16) => elf::R_AVR_16, + _ => return unsupported_reloc(), }, Architecture::Bpf => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 64) => elf::R_BPF_64_64, - (RelocationKind::Absolute, _, 32) => elf::R_BPF_64_32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 64) => elf::R_BPF_64_64, + (K::Absolute, _, 32) => elf::R_BPF_64_32, + _ => return unsupported_reloc(), }, Architecture::Csky => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_CKCORE_ADDR32, - (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { - elf::R_CKCORE_PCREL32 - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_CKCORE_ADDR32, + (K::Relative, E::Generic, 32) => elf::R_CKCORE_PCREL32, + _ => return unsupported_reloc(), }, Architecture::I386 => match (kind, size) { - (RelocationKind::Absolute, 32) => elf::R_386_32, - (RelocationKind::Relative, 32) => elf::R_386_PC32, - (RelocationKind::Got, 32) => elf::R_386_GOT32, - (RelocationKind::PltRelative, 32) => elf::R_386_PLT32, - (RelocationKind::GotBaseOffset, 32) => elf::R_386_GOTOFF, - (RelocationKind::GotBaseRelative, 32) => elf::R_386_GOTPC, - (RelocationKind::Absolute, 16) => elf::R_386_16, - (RelocationKind::Relative, 16) => elf::R_386_PC16, - (RelocationKind::Absolute, 8) => elf::R_386_8, - (RelocationKind::Relative, 8) => elf::R_386_PC8, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, 32) => elf::R_386_32, + (K::Relative, 32) => elf::R_386_PC32, + (K::Got, 32) => elf::R_386_GOT32, + (K::PltRelative, 32) => elf::R_386_PLT32, + (K::GotBaseOffset, 32) => elf::R_386_GOTOFF, + (K::GotBaseRelative, 32) => elf::R_386_GOTPC, + (K::Absolute, 16) => elf::R_386_16, + (K::Relative, 16) => elf::R_386_PC16, + (K::Absolute, 8) => elf::R_386_8, + (K::Relative, 8) => elf::R_386_PC8, + _ => return unsupported_reloc(), }, Architecture::X86_64 | Architecture::X86_64_X32 => match (kind, encoding, size) { - (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => elf::R_X86_64_64, - (RelocationKind::Relative, RelocationEncoding::X86Branch, 32) => { - elf::R_X86_64_PLT32 - } - (RelocationKind::Relative, _, 32) => elf::R_X86_64_PC32, - (RelocationKind::Got, _, 32) => elf::R_X86_64_GOT32, - (RelocationKind::PltRelative, _, 32) => elf::R_X86_64_PLT32, - (RelocationKind::GotRelative, _, 32) => elf::R_X86_64_GOTPCREL, - (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => elf::R_X86_64_32, - (RelocationKind::Absolute, RelocationEncoding::X86Signed, 32) => elf::R_X86_64_32S, - (RelocationKind::Absolute, _, 16) => elf::R_X86_64_16, - (RelocationKind::Relative, _, 16) => elf::R_X86_64_PC16, - (RelocationKind::Absolute, _, 8) => elf::R_X86_64_8, - (RelocationKind::Relative, _, 8) => elf::R_X86_64_PC8, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, E::Generic, 64) => elf::R_X86_64_64, + (K::Relative, E::X86Branch, 32) => elf::R_X86_64_PLT32, + (K::Relative, _, 32) => elf::R_X86_64_PC32, + (K::Got, _, 32) => elf::R_X86_64_GOT32, + (K::PltRelative, _, 32) => elf::R_X86_64_PLT32, + (K::GotRelative, _, 32) => elf::R_X86_64_GOTPCREL, + (K::Absolute, E::Generic, 32) => elf::R_X86_64_32, + (K::Absolute, E::X86Signed, 32) => elf::R_X86_64_32S, + (K::Absolute, _, 16) => elf::R_X86_64_16, + (K::Relative, _, 16) => elf::R_X86_64_PC16, + (K::Absolute, _, 8) => elf::R_X86_64_8, + (K::Relative, _, 8) => elf::R_X86_64_PC8, + _ => return unsupported_reloc(), }, Architecture::Hexagon => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_HEX_32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_HEX_32, + _ => return unsupported_reloc(), }, Architecture::LoongArch64 => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_LARCH_32, - (RelocationKind::Absolute, _, 64) => elf::R_LARCH_64, - (RelocationKind::Relative, _, 32) => elf::R_LARCH_32_PCREL, - (RelocationKind::Relative, _, 64) => elf::R_LARCH_64_PCREL, - (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 16) - | (RelocationKind::PltRelative, RelocationEncoding::LoongArchBranch, 16) => { - elf::R_LARCH_B16 - } - (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 21) - | (RelocationKind::PltRelative, RelocationEncoding::LoongArchBranch, 21) => { - elf::R_LARCH_B21 - } - (RelocationKind::Relative, RelocationEncoding::LoongArchBranch, 26) - | (RelocationKind::PltRelative, RelocationEncoding::LoongArchBranch, 26) => { - elf::R_LARCH_B26 - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_LARCH_32, + (K::Absolute, _, 64) => elf::R_LARCH_64, + (K::Relative, _, 32) => elf::R_LARCH_32_PCREL, + (K::Relative, _, 64) => elf::R_LARCH_64_PCREL, + (K::Relative, E::LoongArchBranch, 16) => elf::R_LARCH_B16, + (K::PltRelative, E::LoongArchBranch, 16) => elf::R_LARCH_B16, + (K::Relative, E::LoongArchBranch, 21) => elf::R_LARCH_B21, + (K::PltRelative, E::LoongArchBranch, 21) => elf::R_LARCH_B21, + (K::Relative, E::LoongArchBranch, 26) => elf::R_LARCH_B26, + (K::PltRelative, E::LoongArchBranch, 26) => elf::R_LARCH_B26, + _ => return unsupported_reloc(), }, Architecture::Mips | Architecture::Mips64 => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 16) => elf::R_MIPS_16, - (RelocationKind::Absolute, _, 32) => elf::R_MIPS_32, - (RelocationKind::Absolute, _, 64) => elf::R_MIPS_64, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (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) { - (RelocationKind::Absolute, _, 32) => elf::R_MSP430_32, - (RelocationKind::Absolute, _, 16) => elf::R_MSP430_16_BYTE, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_MSP430_32, + (K::Absolute, _, 16) => elf::R_MSP430_16_BYTE, + _ => return unsupported_reloc(), }, Architecture::PowerPc => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_PPC_ADDR32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_PPC_ADDR32, + _ => return unsupported_reloc(), }, Architecture::PowerPc64 => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_PPC64_ADDR32, - (RelocationKind::Absolute, _, 64) => elf::R_PPC64_ADDR64, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_PPC64_ADDR32, + (K::Absolute, _, 64) => elf::R_PPC64_ADDR64, + _ => return unsupported_reloc(), }, Architecture::Riscv32 | Architecture::Riscv64 => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_RISCV_32, - (RelocationKind::Absolute, _, 64) => elf::R_RISCV_64, - (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { - elf::R_RISCV_32_PCREL - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_RISCV_32, + (K::Absolute, _, 64) => elf::R_RISCV_64, + (K::Relative, E::Generic, 32) => elf::R_RISCV_32_PCREL, + _ => return unsupported_reloc(), }, Architecture::S390x => match (kind, encoding, size) { - (RelocationKind::Absolute, RelocationEncoding::Generic, 8) => elf::R_390_8, - (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => elf::R_390_16, - (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => elf::R_390_32, - (RelocationKind::Absolute, RelocationEncoding::Generic, 64) => elf::R_390_64, - (RelocationKind::Relative, RelocationEncoding::Generic, 16) => elf::R_390_PC16, - (RelocationKind::Relative, RelocationEncoding::Generic, 32) => elf::R_390_PC32, - (RelocationKind::Relative, RelocationEncoding::Generic, 64) => elf::R_390_PC64, - (RelocationKind::Relative, RelocationEncoding::S390xDbl, 16) => elf::R_390_PC16DBL, - (RelocationKind::Relative, RelocationEncoding::S390xDbl, 32) => elf::R_390_PC32DBL, - (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 16) => { - elf::R_390_PLT16DBL - } - (RelocationKind::PltRelative, RelocationEncoding::S390xDbl, 32) => { - elf::R_390_PLT32DBL - } - (RelocationKind::Got, RelocationEncoding::Generic, 16) => elf::R_390_GOT16, - (RelocationKind::Got, RelocationEncoding::Generic, 32) => elf::R_390_GOT32, - (RelocationKind::Got, RelocationEncoding::Generic, 64) => elf::R_390_GOT64, - (RelocationKind::GotRelative, RelocationEncoding::S390xDbl, 32) => { - elf::R_390_GOTENT - } - (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 16) => { - elf::R_390_GOTOFF16 - } - (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 32) => { - elf::R_390_GOTOFF32 - } - (RelocationKind::GotBaseOffset, RelocationEncoding::Generic, 64) => { - elf::R_390_GOTOFF64 - } - (RelocationKind::GotBaseRelative, RelocationEncoding::Generic, 64) => { - elf::R_390_GOTPC - } - (RelocationKind::GotBaseRelative, RelocationEncoding::S390xDbl, 32) => { - elf::R_390_GOTPCDBL - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, E::Generic, 8) => elf::R_390_8, + (K::Absolute, E::Generic, 16) => elf::R_390_16, + (K::Absolute, E::Generic, 32) => elf::R_390_32, + (K::Absolute, E::Generic, 64) => elf::R_390_64, + (K::Relative, E::Generic, 16) => elf::R_390_PC16, + (K::Relative, E::Generic, 32) => elf::R_390_PC32, + (K::Relative, E::Generic, 64) => elf::R_390_PC64, + (K::Relative, E::S390xDbl, 16) => elf::R_390_PC16DBL, + (K::Relative, E::S390xDbl, 32) => elf::R_390_PC32DBL, + (K::PltRelative, E::S390xDbl, 16) => elf::R_390_PLT16DBL, + (K::PltRelative, E::S390xDbl, 32) => elf::R_390_PLT32DBL, + (K::Got, E::Generic, 16) => elf::R_390_GOT16, + (K::Got, E::Generic, 32) => elf::R_390_GOT32, + (K::Got, E::Generic, 64) => elf::R_390_GOT64, + (K::GotRelative, E::S390xDbl, 32) => elf::R_390_GOTENT, + (K::GotBaseOffset, E::Generic, 16) => elf::R_390_GOTOFF16, + (K::GotBaseOffset, E::Generic, 32) => elf::R_390_GOTOFF32, + (K::GotBaseOffset, E::Generic, 64) => elf::R_390_GOTOFF64, + (K::GotBaseRelative, E::Generic, 64) => elf::R_390_GOTPC, + (K::GotBaseRelative, E::S390xDbl, 32) => elf::R_390_GOTPCDBL, + _ => return unsupported_reloc(), }, Architecture::Sbf => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 64) => elf::R_SBF_64_64, - (RelocationKind::Absolute, _, 32) => elf::R_SBF_64_32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 64) => elf::R_SBF_64_64, + (K::Absolute, _, 32) => elf::R_SBF_64_32, + _ => return unsupported_reloc(), }, Architecture::Sharc => match (kind, encoding, size) { - (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 32) => { - elf::R_SHARC_ADDR32_V3 - } - (RelocationKind::Absolute, RelocationEncoding::Generic, 32) => { - elf::R_SHARC_ADDR_VAR_V3 - } - (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 24) => { - elf::R_SHARC_PCRLONG_V3 - } - (RelocationKind::Relative, RelocationEncoding::SharcTypeA, 6) => { - elf::R_SHARC_PCRSHORT_V3 - } - (RelocationKind::Relative, RelocationEncoding::SharcTypeB, 6) => { - elf::R_SHARC_PCRSHORT_V3 - } - (RelocationKind::Absolute, RelocationEncoding::Generic, 16) => { - elf::R_SHARC_ADDR_VAR16_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 16) => { - elf::R_SHARC_DATA16_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 16) => { - elf::R_SHARC_DATA16_VISA_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 24) => { - elf::R_SHARC_ADDR24_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeA, 6) => { - elf::R_SHARC_DATA6_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 6) => { - elf::R_SHARC_DATA6_VISA_V3 - } - (RelocationKind::Absolute, RelocationEncoding::SharcTypeB, 7) => { - elf::R_SHARC_DATA7_VISA_V3 - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, E::SharcTypeA, 32) => elf::R_SHARC_ADDR32_V3, + (K::Absolute, E::Generic, 32) => elf::R_SHARC_ADDR_VAR_V3, + (K::Relative, E::SharcTypeA, 24) => elf::R_SHARC_PCRLONG_V3, + (K::Relative, E::SharcTypeA, 6) => elf::R_SHARC_PCRSHORT_V3, + (K::Relative, E::SharcTypeB, 6) => elf::R_SHARC_PCRSHORT_V3, + (K::Absolute, E::Generic, 16) => elf::R_SHARC_ADDR_VAR16_V3, + (K::Absolute, E::SharcTypeA, 16) => elf::R_SHARC_DATA16_V3, + (K::Absolute, E::SharcTypeB, 16) => elf::R_SHARC_DATA16_VISA_V3, + (K::Absolute, E::SharcTypeA, 24) => elf::R_SHARC_ADDR24_V3, + (K::Absolute, E::SharcTypeA, 6) => elf::R_SHARC_DATA6_V3, + (K::Absolute, E::SharcTypeB, 6) => elf::R_SHARC_DATA6_VISA_V3, + (K::Absolute, E::SharcTypeB, 7) => elf::R_SHARC_DATA7_VISA_V3, + _ => return unsupported_reloc(), }, Architecture::Sparc | Architecture::Sparc32Plus => match (kind, encoding, size) { // TODO: use R_SPARC_32 if aligned. - (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_SPARC_UA32, + _ => return unsupported_reloc(), }, Architecture::Sparc64 => match (kind, encoding, size) { // TODO: use R_SPARC_32/R_SPARC_64 if aligned. - (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32, - (RelocationKind::Absolute, _, 64) => elf::R_SPARC_UA64, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_SPARC_UA32, + (K::Absolute, _, 64) => elf::R_SPARC_UA64, + _ => return unsupported_reloc(), }, Architecture::Xtensa => match (kind, encoding, size) { - (RelocationKind::Absolute, _, 32) => elf::R_XTENSA_32, - (RelocationKind::Relative, RelocationEncoding::Generic, 32) => { - elf::R_XTENSA_32_PCREL - } - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + (K::Absolute, _, 32) => elf::R_XTENSA_32, + (K::Relative, E::Generic, 32) => elf::R_XTENSA_32_PCREL, + _ => return unsupported_reloc(), }, - _ => { - return Err(Error(format!("unimplemented relocation {:?}", reloc))); - } + _ => return unsupported_reloc(), }; reloc.flags = RelocationFlags::Elf { r_type }; Ok(())