sbpf_disassembler/
section_header_entry.rs1use std::fmt::Debug;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{errors::DisassemblerError, 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, DisassemblerError> {
20 let mut h = SectionHeaderEntry {
21 label,
22 offset,
23 data,
24 ixs: vec![],
25 utf8: String::new(),
26 };
27
28 if h.label.contains(".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>, DisassemblerError> {
43 if self.data.len() % 8 != 0 {
44 return Err(DisassemblerError::InvalidDataLength);
45 }
46 let mut ixs: Vec<Ix> = vec![];
47 let mut pos = 0;
48
49 while pos < self.data.len() {
50 let remaining = &self.data[pos..];
51 if remaining.len() < 8 {
52 break;
53 }
54
55 let ix = Ix::from_bytes(remaining)?;
56 if ix.op == crate::opcodes::OpCode::Lddw {
57 pos += 16;
58 } else {
59 pos += 8;
60 }
61
62 ixs.push(ix);
63 }
64
65 Ok(ixs)
66 }
67
68 pub fn to_bytes(&self) -> Vec<u8> {
69 self.data.clone()
70 }
71}
72
73#[cfg(test)]
74mod test {
75 use crate::{instructions::Ix, opcodes::OpCode, section_header_entry::SectionHeaderEntry};
76
77 #[test]
78 fn serialize_e2e() {
79 let data = vec![
80 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 ];
83
84 let h = SectionHeaderEntry::new(".text\0".to_string(), 128, data.clone()).unwrap();
85
86 let ixs = vec![
87 Ix {
88 op: OpCode::Lddw,
89 dst: 1,
90 src: 0,
91 off: 0,
92 imm: 0,
93 },
94 Ix {
95 op: OpCode::Exit,
96 dst: 0,
97 src: 0,
98 off: 0,
99 imm: 0,
100 },
101 ];
102 assert_eq!(ixs, h.to_ixs().unwrap());
103
104 assert_eq!(
105 data,
106 h.to_ixs()
107 .expect("Invalid IX")
108 .into_iter()
109 .flat_map(|i| i.to_bytes())
110 .collect::<Vec<u8>>()
111 )
112 }
113}