sbpf_disassembler/
cursor.rs

1use std::io::{Cursor, Read, Seek, SeekFrom};
2
3use crate::{
4    elf_header::{
5        E_MACHINE, E_MACHINE_SBPF, E_TYPE, E_VERSION, EI_ABIVERSION, EI_CLASS, EI_DATA, EI_MAGIC,
6        EI_OSABI, EI_PAD, EI_VERSION, ELFHeader,
7    },
8    errors::EZBpfError,
9    instructions::Ix,
10    opcodes::OpCode,
11    program_header::{ProgramFlags, ProgramHeader, ProgramType},
12    section_header::{SectionHeader, SectionHeaderType},
13};
14
15pub trait ELFCursor {
16    fn read_elf_header(&mut self) -> Result<ELFHeader, EZBpfError>;
17    fn read_program_header(&mut self) -> Result<ProgramHeader, EZBpfError>;
18    fn read_section_header(&mut self) -> Result<SectionHeader, EZBpfError>;
19    fn read_ix(&mut self) -> Result<Ix, EZBpfError>;
20    fn read_lddw_imm(&mut self) -> Result<i64, EZBpfError>;
21    fn read_u8(&mut self) -> Result<u8, EZBpfError>;
22    fn read_i16(&mut self) -> Result<i16, EZBpfError>;
23    fn read_u16(&mut self) -> Result<u16, EZBpfError>;
24    fn read_i32(&mut self) -> Result<i32, EZBpfError>;
25    fn read_u32(&mut self) -> Result<u32, EZBpfError>;
26    fn read_u64(&mut self) -> Result<u64, EZBpfError>;
27    fn read_bytes(&mut self, l: usize) -> Result<Vec<u8>, EZBpfError>;
28    fn remainder(&mut self) -> u64;
29}
30
31impl ELFCursor for Cursor<&[u8]> {
32    fn read_elf_header(&mut self) -> Result<ELFHeader, EZBpfError> {
33        let ei_magic = self.read_u32()?.to_le_bytes();
34        let ei_class = self.read_u8()?;
35        let ei_data = self.read_u8()?;
36        let ei_version = self.read_u8()?;
37        let ei_osabi = self.read_u8()?;
38        let ei_abiversion = self.read_u8()?;
39        let mut ei_pad = [0u8; 7];
40        ei_pad.clone_from_slice(&self.read_bytes(7)?);
41        let e_type = self.read_u16()?;
42        let e_machine = self.read_u16()?;
43        let e_version = self.read_u32()?;
44        if ei_magic.ne(&EI_MAGIC)
45            || ei_class.ne(&EI_CLASS)
46            || ei_data.ne(&EI_DATA)
47            || ei_version.ne(&EI_VERSION)
48            || ei_osabi.ne(&EI_OSABI)
49            || ei_abiversion.ne(&EI_ABIVERSION)
50            || ei_pad.ne(&EI_PAD)
51            || e_type.ne(&E_TYPE)
52            || (e_machine.ne(&E_MACHINE) && e_machine.ne(&E_MACHINE_SBPF))
53            || e_version.ne(&E_VERSION)
54        {
55            return Err(EZBpfError::NonStandardElfHeader);
56        }
57
58        let e_entry = self.read_u64()?;
59        let e_phoff = self.read_u64()?;
60        let e_shoff = self.read_u64()?;
61        let e_flags = self.read_u32()?;
62        let e_ehsize = self.read_u16()?;
63        let e_phentsize = self.read_u16()?;
64        let e_phnum = self.read_u16()?;
65        let e_shentsize = self.read_u16()?;
66        let e_shnum = self.read_u16()?;
67        let e_shstrndx = self.read_u16()?;
68        Ok(ELFHeader {
69            ei_magic,
70            ei_class,
71            ei_data,
72            ei_version,
73            ei_osabi,
74            ei_abiversion,
75            ei_pad,
76            e_type,
77            e_machine,
78            e_version,
79            e_entry,
80            e_phoff,
81            e_shoff,
82            e_flags,
83            e_ehsize,
84            e_phentsize,
85            e_phnum,
86            e_shentsize,
87            e_shnum,
88            e_shstrndx,
89        })
90    }
91
92    fn read_program_header(&mut self) -> Result<ProgramHeader, EZBpfError> {
93        let p_type = ProgramType::try_from(self.read_u32()?)?;
94        let p_flags = ProgramFlags::from(self.read_u32()?);
95        let p_offset = self.read_u64()?;
96        let p_vaddr = self.read_u64()?;
97        let p_paddr = self.read_u64()?;
98        let p_filesz = self.read_u64()?;
99        let p_memsz = self.read_u64()?;
100        let p_align = self.read_u64()?;
101        Ok(ProgramHeader {
102            p_type,
103            p_flags,
104            p_offset,
105            p_vaddr,
106            p_paddr,
107            p_filesz,
108            p_memsz,
109            p_align,
110        })
111    }
112
113    fn read_section_header(&mut self) -> Result<SectionHeader, EZBpfError> {
114        let sh_name = self.read_u32()?;
115        let sh_type = SectionHeaderType::try_from(self.read_u32()?)?;
116        let sh_flags = self.read_u64()?;
117        let sh_addr = self.read_u64()?;
118        let sh_offset = self.read_u64()?;
119        let sh_size = self.read_u64()?;
120        let sh_link = self.read_u32()?;
121        let sh_info = self.read_u32()?;
122        let sh_addralign = self.read_u64()?;
123        let sh_entsize = self.read_u64()?;
124        Ok(SectionHeader {
125            sh_name,
126            sh_type,
127            sh_flags,
128            sh_addr,
129            sh_offset,
130            sh_size,
131            sh_link,
132            sh_info,
133            sh_addralign,
134            sh_entsize,
135        })
136    }
137
138    fn read_u8(&mut self) -> Result<u8, EZBpfError> {
139        let mut b = [0u8];
140        self.read_exact(&mut b)
141            .map_err(|_| EZBpfError::CursorError)?;
142        Ok(b[0])
143    }
144
145    fn read_u16(&mut self) -> Result<u16, EZBpfError> {
146        let mut b = [0u8; 2];
147        self.read_exact(&mut b)
148            .map_err(|_| EZBpfError::CursorError)?;
149        Ok(u16::from_le_bytes(b))
150    }
151
152    fn read_i16(&mut self) -> Result<i16, EZBpfError> {
153        let mut b = [0u8; 2];
154        self.read_exact(&mut b)
155            .map_err(|_| EZBpfError::CursorError)?;
156        Ok(i16::from_le_bytes(b))
157    }
158
159    fn read_u32(&mut self) -> Result<u32, EZBpfError> {
160        let mut b = [0u8; 4];
161        self.read_exact(&mut b)
162            .map_err(|_| EZBpfError::CursorError)?;
163        Ok(u32::from_le_bytes(b))
164    }
165
166    fn read_i32(&mut self) -> Result<i32, EZBpfError> {
167        let mut b = [0u8; 4];
168        self.read_exact(&mut b)
169            .map_err(|_| EZBpfError::CursorError)?;
170        Ok(i32::from_le_bytes(b))
171    }
172
173    fn read_u64(&mut self) -> Result<u64, EZBpfError> {
174        let mut b = [0u8; 8];
175        self.read_exact(&mut b)
176            .map_err(|_| EZBpfError::CursorError)?;
177        Ok(u64::from_le_bytes(b))
178    }
179
180    fn read_lddw_imm(&mut self) -> Result<i64, EZBpfError> {
181        let mut b = [0u8; 8];
182        b[0..4].clone_from_slice(&self.read_bytes(4)?);
183        if self.read_u32()? != 0 {
184            return Err(EZBpfError::InvalidImmediate);
185        }
186        b[4..8].clone_from_slice(&self.read_bytes(4)?);
187        Ok(i64::from_le_bytes(b))
188    }
189
190    fn read_ix(&mut self) -> Result<Ix, EZBpfError> {
191        let op = OpCode::try_from(self.read_u8()?)?;
192        let reg = self.read_u8()?;
193        let src = reg >> 4;
194        let dst = reg & 0x0f;
195        let off = self.read_i16()?;
196        let imm = match op {
197            OpCode::Lddw => self.read_lddw_imm()?,
198            _ => self.read_i32()? as i64,
199        };
200        Ok(Ix {
201            op,
202            src,
203            dst,
204            off,
205            imm,
206        })
207    }
208
209    fn read_bytes(&mut self, l: usize) -> Result<Vec<u8>, EZBpfError> {
210        let mut v = vec![0_u8; l];
211        self.read_exact(&mut v)
212            .map_err(|_| EZBpfError::CursorError)?;
213        Ok(v)
214    }
215
216    fn remainder(&mut self) -> u64 {
217        let pos = self.position();
218        let end = self.seek(SeekFrom::End(0)).unwrap();
219        self.seek(SeekFrom::Start(pos)).unwrap();
220        end - pos
221    }
222}