sbpf_disassembler/
section_header_entry.rs1use std::{fmt::Debug, io::Cursor};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{cursor::ELFCursor, errors::EZBpfError, instructions::Ix};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SectionHeaderEntry {
9 pub label: String,
10 pub offset: usize,
11 pub data: Vec<u8>,
12 #[serde(skip_serializing_if = "Vec::is_empty")]
13 pub ixs: Vec<Ix>,
14 #[serde(skip_serializing_if = "String::is_empty")]
15 pub utf8: String,
16}
17
18impl SectionHeaderEntry {
19 pub fn new(label: String, offset: usize, data: Vec<u8>) -> Result<Self, EZBpfError> {
20 let mut h = SectionHeaderEntry {
21 label,
22 offset,
23 data,
24 ixs: vec![],
25 utf8: String::new(),
26 };
27
28 if &h.label == ".text\0" {
29 h.ixs = h.to_ixs()?;
30 }
31
32 if let Ok(utf8) = String::from_utf8(h.data.clone()) {
33 h.utf8 = utf8;
34 }
35 Ok(h)
36 }
37
38 pub fn offset(&self) -> usize {
39 self.offset
40 }
41
42 pub fn to_ixs(&self) -> Result<Vec<Ix>, EZBpfError> {
43 if self.data.len() % 8 != 0 {
44 return Err(EZBpfError::InvalidDataLength);
45 }
46 let mut ixs: Vec<Ix> = vec![];
47 if self.data.len() >= 8 {
48 let mut c = Cursor::new(self.data.as_slice());
49 while let Ok(ix) = c.read_ix() {
50 ixs.push(ix);
51 }
52 }
53 Ok(ixs)
54 }
55
56 pub fn to_bytes(&self) -> Vec<u8> {
57 self.data.clone()
58 }
59}
60
61#[cfg(test)]
62mod test {
63 use crate::{instructions::Ix, opcodes::OpCode, section_header_entry::SectionHeaderEntry};
64
65 #[test]
66 fn serialize_e2e() {
67 let data = vec![
68 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 ];
71
72 let h = SectionHeaderEntry::new(".text\0".to_string(), 128, data.clone()).unwrap();
73
74 let ixs = vec![
75 Ix {
76 op: OpCode::Lddw,
77 dst: 1,
78 src: 0,
79 off: 0,
80 imm: 0,
81 },
82 Ix {
83 op: OpCode::Exit,
84 dst: 0,
85 src: 0,
86 off: 0,
87 imm: 0,
88 },
89 ];
90 assert_eq!(ixs, h.to_ixs().unwrap());
91
92 assert_eq!(
93 data,
94 h.to_ixs()
95 .expect("Invalid IX")
96 .into_iter()
97 .flat_map(|i| i.to_bytes())
98 .collect::<Vec<u8>>()
99 )
100 }
101}