sbpf_disassembler/
elf_header.rs

1use std::io::Cursor;
2use std::str;
3
4use serde::{Deserialize, Serialize, Serializer};
5
6use crate::{cursor::ELFCursor, errors::EZBpfError};
7
8pub const EI_MAGIC: [u8; 4] = *b"\x7fELF"; // ELF magic
9pub const EI_CLASS: u8 = 0x02; // 64-bit
10pub const EI_DATA: u8 = 0x01; // Little endian
11pub const EI_VERSION: u8 = 0x01; // Version 1
12pub const EI_OSABI: u8 = 0x00; // System V
13pub const EI_ABIVERSION: u8 = 0x00; // No ABI version
14pub const EI_PAD: [u8; 7] = [0u8; 7]; // Padding
15pub const E_TYPE: u16 = 0x03; // ET_DYN - shared object
16pub const E_MACHINE: u16 = 0xf7; // Berkeley Packet Filter
17pub const E_MACHINE_SBPF: u16 = 0x0107; // Solana Berkeley Packet Filter
18pub const E_VERSION: u32 = 0x01; // Original version of BPF
19
20fn elf_magic<S>(magic: &[u8; 4], serializer: S) -> Result<S::Ok, S::Error>
21where
22    S: Serializer,
23{
24    let s = String::from_utf8_lossy(magic);
25    serializer.serialize_str(&s)
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ELFHeader {
30    #[serde(serialize_with = "elf_magic")]
31    pub ei_magic: [u8; 4],
32    pub ei_class: u8,
33    pub ei_data: u8,
34    pub ei_version: u8,
35    pub ei_osabi: u8,
36    pub ei_abiversion: u8,
37    pub ei_pad: [u8; 7],
38    pub e_type: u16,
39    pub e_machine: u16,
40    pub e_version: u32,
41    pub e_entry: u64,
42    pub e_phoff: u64,
43    pub e_shoff: u64,
44    pub e_flags: u32,
45    pub e_ehsize: u16,
46    pub e_phentsize: u16,
47    pub e_phnum: u16,
48    pub e_shentsize: u16,
49    pub e_shnum: u16,
50    pub e_shstrndx: u16,
51}
52
53impl ELFHeader {
54    pub fn from_bytes(b: &[u8]) -> Result<Self, EZBpfError> {
55        let mut c = Cursor::new(b);
56        c.read_elf_header()
57    }
58
59    pub fn to_bytes(&self) -> Vec<u8> {
60        let mut b = self.ei_magic.to_vec();
61        b.extend_from_slice(&[
62            self.ei_class,
63            self.ei_data,
64            self.ei_version,
65            self.ei_osabi,
66            self.ei_abiversion,
67        ]);
68        b.extend_from_slice(&self.ei_pad);
69        b.extend_from_slice(&self.e_type.to_le_bytes());
70        b.extend_from_slice(&self.e_machine.to_le_bytes());
71        b.extend_from_slice(&self.e_version.to_le_bytes());
72        b.extend_from_slice(&self.e_entry.to_le_bytes());
73        b.extend_from_slice(&self.e_phoff.to_le_bytes());
74        b.extend_from_slice(&self.e_shoff.to_le_bytes());
75        b.extend_from_slice(&self.e_flags.to_le_bytes());
76        b.extend_from_slice(&self.e_ehsize.to_le_bytes());
77        b.extend_from_slice(&self.e_phentsize.to_le_bytes());
78        b.extend_from_slice(&self.e_phnum.to_le_bytes());
79        b.extend_from_slice(&self.e_shentsize.to_le_bytes());
80        b.extend_from_slice(&self.e_shnum.to_le_bytes());
81        b.extend_from_slice(&self.e_shstrndx.to_le_bytes());
82        b
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use hex_literal::hex;
89
90    use super::ELFHeader;
91
92    #[test]
93    fn serialize_e2e() {
94        let b = hex!(
95            "7F454C460201010000000000000000000300F7000100000078000000000000004000000000000000900000000000000000000000400038000100400003000200"
96        );
97        let h = ELFHeader::from_bytes(&b).unwrap();
98        assert_eq!(h.to_bytes(), &b)
99    }
100
101    #[test]
102    fn serialize_sbpf_machine_e2e() {
103        let b = hex!(
104            "7F454C46020101000000000000000000030007010100000020010000000000004000000000000000680200000000000000000000400038000300400006000500"
105        );
106        let h = ELFHeader::from_bytes(&b).unwrap();
107        assert_eq!(h.to_bytes(), &b)
108    }
109}