From 0941701f1222d0946791868b7b13385f54cf1d4a Mon Sep 17 00:00:00 2001 From: Dmitri Makarov Date: Sat, 10 Dec 2022 21:07:40 -0500 Subject: [PATCH] elf: add Solana Binary Format (#491) --- crates/examples/src/readobj/elf.rs | 3 +++ src/common.rs | 2 ++ src/elf.rs | 10 ++++++++++ src/read/elf/file.rs | 1 + src/read/elf/relocation.rs | 5 +++++ src/write/elf/object.rs | 10 ++++++++++ tests/round_trip/mod.rs | 1 + 7 files changed, 32 insertions(+) diff --git a/crates/examples/src/readobj/elf.rs b/crates/examples/src/readobj/elf.rs index f1bf134d..05c4ac68 100644 --- a/crates/examples/src/readobj/elf.rs +++ b/crates/examples/src/readobj/elf.rs @@ -473,6 +473,7 @@ fn rel_flag_type(endian: Elf::Endian, elf: &Elf) -> &'static [F EM_TILEGX => FLAGS_R_TILEGX, EM_RISCV => FLAGS_R_RISCV, EM_BPF => FLAGS_R_BPF, + EM_SBF => FLAGS_R_SBF, EM_LOONGARCH => FLAGS_R_LOONGARCH, EM_METAG => FLAGS_R_METAG, EM_NDS32 => FLAGS_R_NDS32, @@ -999,6 +1000,7 @@ static FLAGS_EM: &[Flag] = &flags!( EM_AMDGPU, EM_RISCV, EM_BPF, + EM_SBF, EM_CSKY, EM_ALPHA, EM_LOONGARCH, @@ -2911,6 +2913,7 @@ static FLAGS_R_RISCV: &[Flag] = &flags!( R_RISCV_32_PCREL, ); static FLAGS_R_BPF: &[Flag] = &flags!(R_BPF_NONE, R_BPF_64_64, R_BPF_64_32); +static FLAGS_R_SBF: &[Flag] = &flags!(R_SBF_NONE, R_SBF_64_64, R_SBF_64_32); static FLAGS_R_METAG: &[Flag] = &flags!( R_METAG_HIADDR16, R_METAG_LOADDR16, diff --git a/src/common.rs b/src/common.rs index 658fe507..958f2d66 100644 --- a/src/common.rs +++ b/src/common.rs @@ -22,6 +22,7 @@ pub enum Architecture { Riscv32, Riscv64, S390x, + Sbf, Sparc64, Wasm32, Xtensa, @@ -51,6 +52,7 @@ impl Architecture { Architecture::Riscv32 => Some(AddressSize::U32), Architecture::Riscv64 => Some(AddressSize::U64), Architecture::S390x => Some(AddressSize::U64), + Architecture::Sbf => Some(AddressSize::U64), Architecture::Sparc64 => Some(AddressSize::U64), Architecture::Wasm32 => Some(AddressSize::U32), Architecture::Xtensa => Some(AddressSize::U32), diff --git a/src/elf.rs b/src/elf.rs index 958a77e5..ac974208 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -576,6 +576,8 @@ pub const EM_BPF: u16 = 247; pub const EM_CSKY: u16 = 252; /// Loongson LoongArch pub const EM_LOONGARCH: u16 = 258; +/// Solana Binary Format +pub const EM_SBF: u16 = 263; /// Digital Alpha pub const EM_ALPHA: u16 = 0x9026; @@ -6122,6 +6124,14 @@ pub const R_BPF_64_64: u32 = 1; #[allow(missing_docs)] pub const R_BPF_64_32: u32 = 10; +// SBF values `Rel*::r_type`. +/// No reloc +pub const R_SBF_NONE: u32 = 0; +#[allow(missing_docs)] +pub const R_SBF_64_64: u32 = 1; +#[allow(missing_docs)] +pub const R_SBF_64_32: u32 = 10; + // Imagination Meta values `Rel*::r_type`. #[allow(missing_docs)] diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index a00dd0ae..299bb979 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -175,6 +175,7 @@ where // 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_SBF, _) => Architecture::Sbf, (elf::EM_SPARCV9, true) => Architecture::Sparc64, (elf::EM_XTENSA, false) => Architecture::Xtensa, _ => Architecture::Unknown, diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index 0c20be34..17052033 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -385,6 +385,11 @@ fn parse_relocation( } r_type => (RelocationKind::Elf(r_type), 0), }, + elf::EM_SBF => match reloc.r_type(endian, false) { + elf::R_SBF_64_64 => (RelocationKind::Absolute, 64), + elf::R_SBF_64_32 => (RelocationKind::Absolute, 32), + 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), diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index 6ea6592a..7080da9a 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -83,6 +83,7 @@ impl<'a> Object<'a> { Architecture::Riscv64 => true, Architecture::Riscv32 => true, Architecture::S390x => true, + Architecture::Sbf => false, Architecture::Sparc64 => true, Architecture::Xtensa => true, _ => { @@ -281,6 +282,7 @@ impl<'a> Object<'a> { Architecture::Riscv32 => elf::EM_RISCV, Architecture::Riscv64 => elf::EM_RISCV, Architecture::S390x => elf::EM_S390, + Architecture::Sbf => elf::EM_SBF, Architecture::Sparc64 => elf::EM_SPARCV9, Architecture::Xtensa => elf::EM_XTENSA, _ => { @@ -673,6 +675,14 @@ impl<'a> Object<'a> { return Err(Error(format!("unimplemented relocation {:?}", reloc))); } }, + Architecture::Sbf => match (reloc.kind, reloc.encoding, reloc.size) { + (RelocationKind::Absolute, _, 64) => elf::R_SBF_64_64, + (RelocationKind::Absolute, _, 32) => elf::R_SBF_64_32, + (RelocationKind::Elf(x), _, _) => x, + _ => { + return Err(Error(format!("unimplemented relocation {:?}", reloc))); + } + }, Architecture::Sparc64 => match (reloc.kind, reloc.encoding, reloc.size) { // TODO: use R_SPARC_32/R_SPARC_64 if aligned. (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32, diff --git a/tests/round_trip/mod.rs b/tests/round_trip/mod.rs index 31f7fd78..f22d15ec 100644 --- a/tests/round_trip/mod.rs +++ b/tests/round_trip/mod.rs @@ -247,6 +247,7 @@ fn elf_any() { (Architecture::Riscv32, Endianness::Little), (Architecture::Riscv64, Endianness::Little), (Architecture::S390x, Endianness::Big), + (Architecture::Sbf, Endianness::Little), (Architecture::Sparc64, Endianness::Big), (Architecture::Xtensa, Endianness::Little), ]