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}