From 757ded9892ca2195f0ceb2202108eeaaf4a3e4e9 Mon Sep 17 00:00:00 2001 From: Denis Drakhnia Date: Mon, 9 Sep 2024 12:51:36 +0300 Subject: [PATCH] elf: reformat parse_relocation --- src/read/elf/relocation.rs | 307 +++++++++++++++---------------------- 1 file changed, 123 insertions(+), 184 deletions(-) diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index 3790e027..37de94a1 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -247,238 +247,177 @@ fn parse_relocation( reloc: Elf::Rela, implicit_addend: bool, ) -> Relocation { - let mut encoding = RelocationEncoding::Generic; + use RelocationEncoding as E; + use RelocationKind as K; + let is_mips64el = header.is_mips64el(endian); let r_type = reloc.r_type(endian, is_mips64el); let flags = RelocationFlags::Elf { r_type }; - let (kind, size) = match header.e_machine(endian) { + + // helper wrappers + let r = |kind, size| (kind, size, E::Generic); + let e = |kind, size, encoding| (kind, size, encoding); + + let unknown = r(K::Unknown, 0); + let (kind, size, encoding) = match header.e_machine(endian) { elf::EM_AARCH64 => { if header.is_type_64() { match r_type { - 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) - } - _ => (RelocationKind::Unknown, 0), + elf::R_AARCH64_ABS64 => r(K::Absolute, 64), + elf::R_AARCH64_ABS32 => r(K::Absolute, 32), + elf::R_AARCH64_ABS16 => r(K::Absolute, 16), + elf::R_AARCH64_PREL64 => r(K::Relative, 64), + elf::R_AARCH64_PREL32 => r(K::Relative, 32), + elf::R_AARCH64_PREL16 => r(K::Relative, 16), + elf::R_AARCH64_CALL26 => e(K::PltRelative, 26, E::AArch64Call), + _ => unknown, } } else { match r_type { - elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_AARCH64_P32_ABS32 => r(K::Absolute, 32), + _ => unknown, } } } elf::EM_ARM => match r_type { - elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_ARM_ABS32 => r(K::Absolute, 32), + _ => unknown, }, elf::EM_AVR => match r_type { - elf::R_AVR_32 => (RelocationKind::Absolute, 32), - elf::R_AVR_16 => (RelocationKind::Absolute, 16), - _ => (RelocationKind::Unknown, 0), + elf::R_AVR_32 => r(K::Absolute, 32), + elf::R_AVR_16 => r(K::Absolute, 16), + _ => unknown, }, elf::EM_BPF => match r_type { - elf::R_BPF_64_64 => (RelocationKind::Absolute, 64), - elf::R_BPF_64_32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_BPF_64_64 => r(K::Absolute, 64), + elf::R_BPF_64_32 => r(K::Absolute, 32), + _ => unknown, }, elf::EM_CSKY => match r_type { - elf::R_CKCORE_ADDR32 => (RelocationKind::Absolute, 32), - elf::R_CKCORE_PCREL32 => (RelocationKind::Relative, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_CKCORE_ADDR32 => r(K::Absolute, 32), + elf::R_CKCORE_PCREL32 => r(K::Relative, 32), + _ => unknown, }, elf::EM_386 => match r_type { - elf::R_386_32 => (RelocationKind::Absolute, 32), - elf::R_386_PC32 => (RelocationKind::Relative, 32), - elf::R_386_GOT32 => (RelocationKind::Got, 32), - elf::R_386_PLT32 => (RelocationKind::PltRelative, 32), - elf::R_386_GOTOFF => (RelocationKind::GotBaseOffset, 32), - elf::R_386_GOTPC => (RelocationKind::GotBaseRelative, 32), - elf::R_386_16 => (RelocationKind::Absolute, 16), - elf::R_386_PC16 => (RelocationKind::Relative, 16), - elf::R_386_8 => (RelocationKind::Absolute, 8), - elf::R_386_PC8 => (RelocationKind::Relative, 8), - _ => (RelocationKind::Unknown, 0), + elf::R_386_32 => r(K::Absolute, 32), + elf::R_386_PC32 => r(K::Relative, 32), + elf::R_386_GOT32 => r(K::Got, 32), + elf::R_386_PLT32 => r(K::PltRelative, 32), + elf::R_386_GOTOFF => r(K::GotBaseOffset, 32), + elf::R_386_GOTPC => r(K::GotBaseRelative, 32), + elf::R_386_16 => r(K::Absolute, 16), + elf::R_386_PC16 => r(K::Relative, 16), + elf::R_386_8 => r(K::Absolute, 8), + elf::R_386_PC8 => r(K::Relative, 8), + _ => unknown, }, elf::EM_X86_64 => match r_type { - elf::R_X86_64_64 => (RelocationKind::Absolute, 64), - elf::R_X86_64_PC32 => (RelocationKind::Relative, 32), - elf::R_X86_64_GOT32 => (RelocationKind::Got, 32), - elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 32), - elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 32), - elf::R_X86_64_32 => (RelocationKind::Absolute, 32), - elf::R_X86_64_32S => { - encoding = RelocationEncoding::X86Signed; - (RelocationKind::Absolute, 32) - } - elf::R_X86_64_16 => (RelocationKind::Absolute, 16), - elf::R_X86_64_PC16 => (RelocationKind::Relative, 16), - elf::R_X86_64_8 => (RelocationKind::Absolute, 8), - elf::R_X86_64_PC8 => (RelocationKind::Relative, 8), - _ => (RelocationKind::Unknown, 0), + elf::R_X86_64_64 => r(K::Absolute, 64), + elf::R_X86_64_PC32 => r(K::Relative, 32), + elf::R_X86_64_GOT32 => r(K::Got, 32), + elf::R_X86_64_PLT32 => r(K::PltRelative, 32), + elf::R_X86_64_GOTPCREL => r(K::GotRelative, 32), + elf::R_X86_64_32 => r(K::Absolute, 32), + elf::R_X86_64_32S => e(K::Absolute, 32, E::X86Signed), + elf::R_X86_64_16 => r(K::Absolute, 16), + elf::R_X86_64_PC16 => r(K::Relative, 16), + elf::R_X86_64_8 => r(K::Absolute, 8), + elf::R_X86_64_PC8 => r(K::Relative, 8), + _ => unknown, }, elf::EM_HEXAGON => match r_type { - elf::R_HEX_32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_HEX_32 => r(K::Absolute, 32), + _ => unknown, }, elf::EM_LOONGARCH => match r_type { - elf::R_LARCH_32 => (RelocationKind::Absolute, 32), - elf::R_LARCH_64 => (RelocationKind::Absolute, 64), - elf::R_LARCH_32_PCREL => (RelocationKind::Relative, 32), - elf::R_LARCH_64_PCREL => (RelocationKind::Relative, 64), - elf::R_LARCH_B16 => { - encoding = RelocationEncoding::LoongArchBranch; - (RelocationKind::Relative, 16) - } - elf::R_LARCH_B21 => { - encoding = RelocationEncoding::LoongArchBranch; - (RelocationKind::Relative, 21) - } - elf::R_LARCH_B26 => { - encoding = RelocationEncoding::LoongArchBranch; - (RelocationKind::Relative, 26) - } - _ => (RelocationKind::Unknown, 0), + elf::R_LARCH_32 => r(K::Absolute, 32), + elf::R_LARCH_64 => r(K::Absolute, 64), + elf::R_LARCH_32_PCREL => r(K::Relative, 32), + elf::R_LARCH_64_PCREL => r(K::Relative, 64), + elf::R_LARCH_B16 => e(K::Relative, 16, E::LoongArchBranch), + elf::R_LARCH_B21 => e(K::Relative, 21, E::LoongArchBranch), + elf::R_LARCH_B26 => e(K::Relative, 26, E::LoongArchBranch), + _ => unknown, }, elf::EM_MIPS => match r_type { - elf::R_MIPS_16 => (RelocationKind::Absolute, 16), - elf::R_MIPS_32 => (RelocationKind::Absolute, 32), - elf::R_MIPS_64 => (RelocationKind::Absolute, 64), - _ => (RelocationKind::Unknown, 0), + elf::R_MIPS_16 => r(K::Absolute, 16), + elf::R_MIPS_32 => r(K::Absolute, 32), + elf::R_MIPS_64 => r(K::Absolute, 64), + _ => unknown, }, elf::EM_MSP430 => match r_type { - elf::R_MSP430_32 => (RelocationKind::Absolute, 32), - elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16), - _ => (RelocationKind::Unknown, 0), + elf::R_MSP430_32 => r(K::Absolute, 32), + elf::R_MSP430_16_BYTE => r(K::Absolute, 16), + _ => unknown, }, elf::EM_PPC => match r_type { - elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_PPC_ADDR32 => r(K::Absolute, 32), + _ => unknown, }, elf::EM_PPC64 => match r_type { - elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32), - elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64), - _ => (RelocationKind::Unknown, 0), + elf::R_PPC64_ADDR32 => r(K::Absolute, 32), + elf::R_PPC64_ADDR64 => r(K::Absolute, 64), + _ => unknown, }, elf::EM_RISCV => match r_type { - elf::R_RISCV_32 => (RelocationKind::Absolute, 32), - elf::R_RISCV_64 => (RelocationKind::Absolute, 64), - _ => (RelocationKind::Unknown, 0), + elf::R_RISCV_32 => r(K::Absolute, 32), + elf::R_RISCV_64 => r(K::Absolute, 64), + _ => unknown, }, elf::EM_S390 => match r_type { - elf::R_390_8 => (RelocationKind::Absolute, 8), - elf::R_390_16 => (RelocationKind::Absolute, 16), - elf::R_390_32 => (RelocationKind::Absolute, 32), - elf::R_390_64 => (RelocationKind::Absolute, 64), - elf::R_390_PC16 => (RelocationKind::Relative, 16), - elf::R_390_PC32 => (RelocationKind::Relative, 32), - elf::R_390_PC64 => (RelocationKind::Relative, 64), - elf::R_390_PC16DBL => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::Relative, 16) - } - elf::R_390_PC32DBL => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::Relative, 32) - } - elf::R_390_PLT16DBL => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::PltRelative, 16) - } - elf::R_390_PLT32DBL => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::PltRelative, 32) - } - elf::R_390_GOT16 => (RelocationKind::Got, 16), - elf::R_390_GOT32 => (RelocationKind::Got, 32), - elf::R_390_GOT64 => (RelocationKind::Got, 64), - elf::R_390_GOTENT => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::GotRelative, 32) - } - elf::R_390_GOTOFF16 => (RelocationKind::GotBaseOffset, 16), - elf::R_390_GOTOFF32 => (RelocationKind::GotBaseOffset, 32), - elf::R_390_GOTOFF64 => (RelocationKind::GotBaseOffset, 64), - elf::R_390_GOTPC => (RelocationKind::GotBaseRelative, 64), - elf::R_390_GOTPCDBL => { - encoding = RelocationEncoding::S390xDbl; - (RelocationKind::GotBaseRelative, 32) - } - _ => (RelocationKind::Unknown, 0), + elf::R_390_8 => r(K::Absolute, 8), + elf::R_390_16 => r(K::Absolute, 16), + elf::R_390_32 => r(K::Absolute, 32), + elf::R_390_64 => r(K::Absolute, 64), + elf::R_390_PC16 => r(K::Relative, 16), + elf::R_390_PC32 => r(K::Relative, 32), + elf::R_390_PC64 => r(K::Relative, 64), + elf::R_390_PC16DBL => e(K::Relative, 16, E::S390xDbl), + elf::R_390_PC32DBL => e(K::Relative, 32, E::S390xDbl), + elf::R_390_PLT16DBL => e(K::PltRelative, 16, E::S390xDbl), + elf::R_390_PLT32DBL => e(K::PltRelative, 32, E::S390xDbl), + elf::R_390_GOT16 => r(K::Got, 16), + elf::R_390_GOT32 => r(K::Got, 32), + elf::R_390_GOT64 => r(K::Got, 64), + elf::R_390_GOTENT => e(K::GotRelative, 32, E::S390xDbl), + elf::R_390_GOTOFF16 => r(K::GotBaseOffset, 16), + elf::R_390_GOTOFF32 => r(K::GotBaseOffset, 32), + elf::R_390_GOTOFF64 => r(K::GotBaseOffset, 64), + elf::R_390_GOTPC => r(K::GotBaseRelative, 64), + elf::R_390_GOTPCDBL => e(K::GotBaseRelative, 32, E::S390xDbl), + _ => unknown, }, elf::EM_SBF => match r_type { - elf::R_SBF_64_64 => (RelocationKind::Absolute, 64), - elf::R_SBF_64_32 => (RelocationKind::Absolute, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_SBF_64_64 => r(K::Absolute, 64), + elf::R_SBF_64_32 => r(K::Absolute, 32), + _ => unknown, }, elf::EM_SHARC => match r_type { - elf::R_SHARC_ADDR24_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Absolute, 24) - } - elf::R_SHARC_ADDR32_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Absolute, 32) - } - elf::R_SHARC_ADDR_VAR_V3 => { - encoding = RelocationEncoding::Generic; - (RelocationKind::Absolute, 32) - } - elf::R_SHARC_PCRSHORT_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Relative, 6) - } - elf::R_SHARC_PCRLONG_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Relative, 24) - } - elf::R_SHARC_DATA6_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Absolute, 6) - } - elf::R_SHARC_DATA16_V3 => { - encoding = RelocationEncoding::SharcTypeA; - (RelocationKind::Absolute, 16) - } - elf::R_SHARC_DATA6_VISA_V3 => { - encoding = RelocationEncoding::SharcTypeB; - (RelocationKind::Absolute, 6) - } - elf::R_SHARC_DATA7_VISA_V3 => { - encoding = RelocationEncoding::SharcTypeB; - (RelocationKind::Absolute, 7) - } - elf::R_SHARC_DATA16_VISA_V3 => { - encoding = RelocationEncoding::SharcTypeB; - (RelocationKind::Absolute, 16) - } - elf::R_SHARC_PCR6_VISA_V3 => { - encoding = RelocationEncoding::SharcTypeB; - (RelocationKind::Relative, 16) - } - elf::R_SHARC_ADDR_VAR16_V3 => { - encoding = RelocationEncoding::Generic; - (RelocationKind::Absolute, 16) - } - _ => (RelocationKind::Unknown, 0), + elf::R_SHARC_ADDR24_V3 => e(K::Absolute, 24, E::SharcTypeA), + elf::R_SHARC_ADDR32_V3 => e(K::Absolute, 32, E::SharcTypeA), + elf::R_SHARC_ADDR_VAR_V3 => e(K::Absolute, 32, E::Generic), + elf::R_SHARC_PCRSHORT_V3 => e(K::Relative, 6, E::SharcTypeA), + elf::R_SHARC_PCRLONG_V3 => e(K::Relative, 24, E::SharcTypeA), + elf::R_SHARC_DATA6_V3 => e(K::Absolute, 6, E::SharcTypeA), + elf::R_SHARC_DATA16_V3 => e(K::Absolute, 16, E::SharcTypeA), + elf::R_SHARC_DATA6_VISA_V3 => e(K::Absolute, 6, E::SharcTypeB), + elf::R_SHARC_DATA7_VISA_V3 => e(K::Absolute, 7, E::SharcTypeB), + elf::R_SHARC_DATA16_VISA_V3 => e(K::Absolute, 16, E::SharcTypeB), + elf::R_SHARC_PCR6_VISA_V3 => e(K::Relative, 16, E::SharcTypeB), + elf::R_SHARC_ADDR_VAR16_V3 => e(K::Absolute, 16, E::Generic), + _ => unknown, }, elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => match r_type { - elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32), - elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64), - _ => (RelocationKind::Unknown, 0), + elf::R_SPARC_32 | elf::R_SPARC_UA32 => r(K::Absolute, 32), + elf::R_SPARC_64 | elf::R_SPARC_UA64 => r(K::Absolute, 64), + _ => unknown, }, elf::EM_XTENSA => match r_type { - elf::R_XTENSA_32 => (RelocationKind::Absolute, 32), - elf::R_XTENSA_32_PCREL => (RelocationKind::Relative, 32), - _ => (RelocationKind::Unknown, 0), + elf::R_XTENSA_32 => r(K::Absolute, 32), + elf::R_XTENSA_32_PCREL => r(K::Relative, 32), + _ => unknown, }, - _ => (RelocationKind::Unknown, 0), + _ => unknown, }; let target = match reloc.symbol(endian, is_mips64el) { None => RelocationTarget::Absolute,