Skip to content

Commit

Permalink
read/elf: reformat parse_relocation (#726)
Browse files Browse the repository at this point in the history
  • Loading branch information
numas13 authored Sep 10, 2024
1 parent 29f9767 commit 7e292fc
Showing 1 changed file with 119 additions and 184 deletions.
303 changes: 119 additions & 184 deletions src/read/elf/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,238 +247,173 @@ fn parse_relocation<Elf: FileHeader>(
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) {
let g = E::Generic;
let unknown = (K::Unknown, E::Generic, 0);
let (kind, encoding, size) = 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 => (K::Absolute, g, 64),
elf::R_AARCH64_ABS32 => (K::Absolute, g, 32),
elf::R_AARCH64_ABS16 => (K::Absolute, g, 16),
elf::R_AARCH64_PREL64 => (K::Relative, g, 64),
elf::R_AARCH64_PREL32 => (K::Relative, g, 32),
elf::R_AARCH64_PREL16 => (K::Relative, g, 16),
elf::R_AARCH64_CALL26 => (K::PltRelative, E::AArch64Call, 26),
_ => unknown,
}
} else {
match r_type {
elf::R_AARCH64_P32_ABS32 => (RelocationKind::Absolute, 32),
_ => (RelocationKind::Unknown, 0),
elf::R_AARCH64_P32_ABS32 => (K::Absolute, g, 32),
_ => unknown,
}
}
}
elf::EM_ARM => match r_type {
elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32),
_ => (RelocationKind::Unknown, 0),
elf::R_ARM_ABS32 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_AVR_16 => (K::Absolute, g, 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 => (K::Absolute, g, 64),
elf::R_BPF_64_32 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_CKCORE_PCREL32 => (K::Relative, g, 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 => (K::Absolute, g, 32),
elf::R_386_PC32 => (K::Relative, g, 32),
elf::R_386_GOT32 => (K::Got, g, 32),
elf::R_386_PLT32 => (K::PltRelative, g, 32),
elf::R_386_GOTOFF => (K::GotBaseOffset, g, 32),
elf::R_386_GOTPC => (K::GotBaseRelative, g, 32),
elf::R_386_16 => (K::Absolute, g, 16),
elf::R_386_PC16 => (K::Relative, g, 16),
elf::R_386_8 => (K::Absolute, g, 8),
elf::R_386_PC8 => (K::Relative, g, 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 => (K::Absolute, g, 64),
elf::R_X86_64_PC32 => (K::Relative, g, 32),
elf::R_X86_64_GOT32 => (K::Got, g, 32),
elf::R_X86_64_PLT32 => (K::PltRelative, g, 32),
elf::R_X86_64_GOTPCREL => (K::GotRelative, g, 32),
elf::R_X86_64_32 => (K::Absolute, g, 32),
elf::R_X86_64_32S => (K::Absolute, E::X86Signed, 32),
elf::R_X86_64_16 => (K::Absolute, g, 16),
elf::R_X86_64_PC16 => (K::Relative, g, 16),
elf::R_X86_64_8 => (K::Absolute, g, 8),
elf::R_X86_64_PC8 => (K::Relative, g, 8),
_ => unknown,
},
elf::EM_HEXAGON => match r_type {
elf::R_HEX_32 => (RelocationKind::Absolute, 32),
_ => (RelocationKind::Unknown, 0),
elf::R_HEX_32 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_LARCH_64 => (K::Absolute, g, 64),
elf::R_LARCH_32_PCREL => (K::Relative, g, 32),
elf::R_LARCH_64_PCREL => (K::Relative, g, 64),
elf::R_LARCH_B16 => (K::Relative, E::LoongArchBranch, 16),
elf::R_LARCH_B21 => (K::Relative, E::LoongArchBranch, 21),
elf::R_LARCH_B26 => (K::Relative, E::LoongArchBranch, 26),
_ => 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 => (K::Absolute, g, 16),
elf::R_MIPS_32 => (K::Absolute, g, 32),
elf::R_MIPS_64 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_MSP430_16_BYTE => (K::Absolute, g, 16),
_ => unknown,
},
elf::EM_PPC => match r_type {
elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
_ => (RelocationKind::Unknown, 0),
elf::R_PPC_ADDR32 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_PPC64_ADDR64 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_RISCV_64 => (K::Absolute, g, 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 => (K::Absolute, g, 8),
elf::R_390_16 => (K::Absolute, g, 16),
elf::R_390_32 => (K::Absolute, g, 32),
elf::R_390_64 => (K::Absolute, g, 64),
elf::R_390_PC16 => (K::Relative, g, 16),
elf::R_390_PC32 => (K::Relative, g, 32),
elf::R_390_PC64 => (K::Relative, g, 64),
elf::R_390_PC16DBL => (K::Relative, E::S390xDbl, 16),
elf::R_390_PC32DBL => (K::Relative, E::S390xDbl, 32),
elf::R_390_PLT16DBL => (K::PltRelative, E::S390xDbl, 16),
elf::R_390_PLT32DBL => (K::PltRelative, E::S390xDbl, 32),
elf::R_390_GOT16 => (K::Got, g, 16),
elf::R_390_GOT32 => (K::Got, g, 32),
elf::R_390_GOT64 => (K::Got, g, 64),
elf::R_390_GOTENT => (K::GotRelative, E::S390xDbl, 32),
elf::R_390_GOTOFF16 => (K::GotBaseOffset, g, 16),
elf::R_390_GOTOFF32 => (K::GotBaseOffset, g, 32),
elf::R_390_GOTOFF64 => (K::GotBaseOffset, g, 64),
elf::R_390_GOTPC => (K::GotBaseRelative, g, 64),
elf::R_390_GOTPCDBL => (K::GotBaseRelative, E::S390xDbl, 32),
_ => 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 => (K::Absolute, g, 64),
elf::R_SBF_64_32 => (K::Absolute, g, 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 => (K::Absolute, E::SharcTypeA, 24),
elf::R_SHARC_ADDR32_V3 => (K::Absolute, E::SharcTypeA, 32),
elf::R_SHARC_ADDR_VAR_V3 => (K::Absolute, E::Generic, 32),
elf::R_SHARC_PCRSHORT_V3 => (K::Relative, E::SharcTypeA, 6),
elf::R_SHARC_PCRLONG_V3 => (K::Relative, E::SharcTypeA, 24),
elf::R_SHARC_DATA6_V3 => (K::Absolute, E::SharcTypeA, 6),
elf::R_SHARC_DATA16_V3 => (K::Absolute, E::SharcTypeA, 16),
elf::R_SHARC_DATA6_VISA_V3 => (K::Absolute, E::SharcTypeB, 6),
elf::R_SHARC_DATA7_VISA_V3 => (K::Absolute, E::SharcTypeB, 7),
elf::R_SHARC_DATA16_VISA_V3 => (K::Absolute, E::SharcTypeB, 16),
elf::R_SHARC_PCR6_VISA_V3 => (K::Relative, E::SharcTypeB, 16),
elf::R_SHARC_ADDR_VAR16_V3 => (K::Absolute, E::Generic, 16),
_ => 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 => (K::Absolute, g, 32),
elf::R_SPARC_64 | elf::R_SPARC_UA64 => (K::Absolute, g, 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 => (K::Absolute, g, 32),
elf::R_XTENSA_32_PCREL => (K::Relative, g, 32),
_ => unknown,
},
_ => (RelocationKind::Unknown, 0),
_ => unknown,
};
let target = match reloc.symbol(endian, is_mips64el) {
None => RelocationTarget::Absolute,
Expand Down

0 comments on commit 7e292fc

Please sign in to comment.