Skip to content

Commit

Permalink
Merge pull request gimli-rs#309 from philipc/arch
Browse files Browse the repository at this point in the history
elf: consistent architecture support
  • Loading branch information
philipc authored May 30, 2021
2 parents 1e5ac4c + be6ae01 commit bfd09f9
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 77 deletions.
16 changes: 14 additions & 2 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ pub enum Architecture {
Unknown,
Aarch64,
Arm,
Avr,
Bpf,
I386,
X86_64,
Hexagon,
Mips,
Mips64,
Msp430,
PowerPc,
PowerPc64,
Riscv32,
Riscv64,
S390x,
Sparc64,
Wasm32,
X86_64,
}

impl Architecture {
Expand All @@ -27,16 +32,21 @@ impl Architecture {
Architecture::Unknown => None,
Architecture::Aarch64 => Some(AddressSize::U64),
Architecture::Arm => Some(AddressSize::U32),
Architecture::Avr => Some(AddressSize::U8),
Architecture::Bpf => Some(AddressSize::U64),
Architecture::I386 => Some(AddressSize::U32),
Architecture::X86_64 => Some(AddressSize::U64),
Architecture::Hexagon => Some(AddressSize::U32),
Architecture::Mips => Some(AddressSize::U32),
Architecture::Mips64 => Some(AddressSize::U64),
Architecture::Msp430 => Some(AddressSize::U16),
Architecture::PowerPc => Some(AddressSize::U32),
Architecture::PowerPc64 => Some(AddressSize::U64),
Architecture::Riscv32 => Some(AddressSize::U32),
Architecture::Riscv64 => Some(AddressSize::U64),
Architecture::S390x => Some(AddressSize::U64),
Architecture::Sparc64 => Some(AddressSize::U64),
Architecture::Wasm32 => Some(AddressSize::U32),
Architecture::X86_64 => Some(AddressSize::U64),
}
}
}
Expand All @@ -49,6 +59,8 @@ impl Architecture {
#[non_exhaustive]
#[repr(u8)]
pub enum AddressSize {
U8 = 1,
U16 = 2,
U32 = 4,
U64 = 8,
}
Expand Down
2 changes: 2 additions & 0 deletions src/read/coff/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ where

fn architecture(&self) -> Architecture {
match self.header.machine.get(LE) {
pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
pe::IMAGE_FILE_MACHINE_ARM64 => Architecture::Aarch64,
pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
_ => Architecture::Unknown,
Expand Down
37 changes: 22 additions & 15 deletions src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,28 @@ where
type DynamicRelocationIterator = ElfDynamicRelocationIterator<'data, 'file, Elf, R>;

fn architecture(&self) -> Architecture {
match self.header.e_machine(self.endian) {
elf::EM_ARM => Architecture::Arm,
elf::EM_AARCH64 => Architecture::Aarch64,
elf::EM_386 => Architecture::I386,
elf::EM_X86_64 => Architecture::X86_64,
elf::EM_MIPS => Architecture::Mips,
elf::EM_S390 => {
// This is either s390 or s390x, depending on the ELF class.
// We only support the 64-bit variant s390x here.
if self.is_64() {
Architecture::S390x
} else {
Architecture::Unknown
}
}
match (
self.header.e_machine(self.endian),
self.header.is_class_64(),
) {
(elf::EM_AARCH64, _) => Architecture::Aarch64,
(elf::EM_ARM, _) => Architecture::Arm,
(elf::EM_AVR, _) => Architecture::Avr,
(elf::EM_BPF, _) => Architecture::Bpf,
(elf::EM_386, _) => Architecture::I386,
(elf::EM_X86_64, _) => Architecture::X86_64,
(elf::EM_HEXAGON, _) => Architecture::Hexagon,
(elf::EM_MIPS, false) => Architecture::Mips,
(elf::EM_MIPS, true) => Architecture::Mips64,
(elf::EM_MSP430, _) => Architecture::Msp430,
(elf::EM_PPC, _) => Architecture::PowerPc,
(elf::EM_PPC64, _) => Architecture::PowerPc64,
(elf::EM_RISCV, false) => Architecture::Riscv32,
(elf::EM_RISCV, true) => Architecture::Riscv64,
// This is either s390 or s390x, depending on the ELF class.
// We only support the 64-bit variant s390x here.
(elf::EM_S390, true) => Architecture::S390x,
(elf::EM_SPARCV9, true) => Architecture::Sparc64,
_ => Architecture::Unknown,
}
}
Expand Down
86 changes: 43 additions & 43 deletions src/read/elf/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,6 @@ fn parse_relocation<Elf: FileHeader>(
let mut encoding = RelocationEncoding::Generic;
let is_mips64el = header.is_mips64el(endian);
let (kind, size) = match header.e_machine(endian) {
elf::EM_ARM => match reloc.r_type(endian, false) {
elf::R_ARM_ABS32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_AARCH64 => match reloc.r_type(endian, false) {
elf::R_AARCH64_ABS64 => (RelocationKind::Absolute, 64),
elf::R_AARCH64_ABS32 => (RelocationKind::Absolute, 32),
Expand All @@ -253,6 +249,20 @@ fn parse_relocation<Elf: FileHeader>(
elf::R_AARCH64_PREL16 => (RelocationKind::Relative, 16),
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),
},
elf::EM_AVR => match reloc.r_type(endian, false) {
elf::R_AVR_32 => (RelocationKind::Absolute, 32),
elf::R_AVR_16 => (RelocationKind::Absolute, 16),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_BPF => match reloc.r_type(endian, false) {
elf::R_BPF_64_64 => (RelocationKind::Absolute, 64),
elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_386 => match reloc.r_type(endian, false) {
elf::R_386_32 => (RelocationKind::Absolute, 32),
elf::R_386_PC32 => (RelocationKind::Relative, 32),
Expand Down Expand Up @@ -283,6 +293,35 @@ fn parse_relocation<Elf: FileHeader>(
elf::R_X86_64_PC8 => (RelocationKind::Relative, 8),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_HEXAGON => match reloc.r_type(endian, false) {
elf::R_HEX_32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) {
elf::R_MIPS_16 => (RelocationKind::Absolute, 16),
elf::R_MIPS_32 => (RelocationKind::Absolute, 32),
elf::R_MIPS_64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_MSP430 => match reloc.r_type(endian, false) {
elf::R_MSP430_32 => (RelocationKind::Absolute, 32),
elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_PPC => match reloc.r_type(endian, false) {
elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_PPC64 => match reloc.r_type(endian, false) {
elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32),
elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_RISCV => match reloc.r_type(endian, false) {
elf::R_RISCV_32 => (RelocationKind::Absolute, 32),
elf::R_RISCV_64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_S390 => match reloc.r_type(endian, false) {
elf::R_390_8 => (RelocationKind::Absolute, 8),
elf::R_390_16 => (RelocationKind::Absolute, 16),
Expand Down Expand Up @@ -324,52 +363,13 @@ fn parse_relocation<Elf: FileHeader>(
}
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_AVR => match reloc.r_type(endian, false) {
elf::R_AVR_32 => (RelocationKind::Absolute, 32),
elf::R_AVR_16 => (RelocationKind::Absolute, 16),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_MSP430 => match reloc.r_type(endian, false) {
elf::R_MSP430_32 => (RelocationKind::Absolute, 32),
elf::R_MSP430_16_BYTE => (RelocationKind::Absolute, 16),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_PPC => match reloc.r_type(endian, false) {
elf::R_PPC_ADDR32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_PPC64 => match reloc.r_type(endian, false) {
elf::R_PPC64_ADDR32 => (RelocationKind::Absolute, 32),
elf::R_PPC64_ADDR64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_RISCV => match reloc.r_type(endian, false) {
elf::R_RISCV_32 => (RelocationKind::Absolute, 32),
elf::R_RISCV_64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_SPARC | elf::EM_SPARC32PLUS | elf::EM_SPARCV9 => {
match reloc.r_type(endian, false) {
elf::R_SPARC_32 | elf::R_SPARC_UA32 => (RelocationKind::Absolute, 32),
elf::R_SPARC_64 | elf::R_SPARC_UA64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
}
}
elf::EM_MIPS => match reloc.r_type(endian, is_mips64el) {
elf::R_MIPS_16 => (RelocationKind::Absolute, 16),
elf::R_MIPS_32 => (RelocationKind::Absolute, 32),
elf::R_MIPS_64 => (RelocationKind::Absolute, 64),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_HEXAGON => match reloc.r_type(endian, false) {
elf::R_HEX_32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
elf::EM_BPF => match reloc.r_type(endian, false) {
elf::R_BPF_64_64 => (RelocationKind::Absolute, 64),
elf::R_BPF_64_32 => (RelocationKind::Absolute, 32),
r_type => (RelocationKind::Elf(r_type), 0),
},
_ => (RelocationKind::Elf(reloc.r_type(endian, false)), 0),
};
let sym = reloc.r_sym(endian, is_mips64el) as usize;
Expand Down
3 changes: 2 additions & 1 deletion src/read/pe/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ where

fn architecture(&self) -> Architecture {
match self.nt_headers.file_header().machine.get(LE) {
// TODO: Arm/Arm64
pe::IMAGE_FILE_MACHINE_ARMNT => Architecture::Arm,
pe::IMAGE_FILE_MACHINE_ARM64 => Architecture::Aarch64,
pe::IMAGE_FILE_MACHINE_I386 => Architecture::I386,
pe::IMAGE_FILE_MACHINE_AMD64 => Architecture::X86_64,
_ => Architecture::Unknown,
Expand Down
2 changes: 2 additions & 0 deletions src/write/coff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ impl Object {
machine: U16::new(
LE,
match self.architecture {
Architecture::Arm => coff::IMAGE_FILE_MACHINE_ARMNT,
Architecture::Aarch64 => coff::IMAGE_FILE_MACHINE_ARM64,
Architecture::I386 => coff::IMAGE_FILE_MACHINE_I386,
Architecture::X86_64 => coff::IMAGE_FILE_MACHINE_AMD64,
_ => {
Expand Down
Loading

0 comments on commit bfd09f9

Please sign in to comment.