1use std::{fmt::Debug, fmt::Display, io::Cursor};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{cursor::ELFCursor, errors::EZBpfError, instructions::Ix};
6
7#[allow(non_camel_case_types)]
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[repr(u32)]
10pub enum SectionHeaderType {
11 SHT_NULL = 0x00, SHT_PROGBITS = 0x01, SHT_SYMTAB = 0x02, SHT_STRTAB = 0x03, SHT_RELA = 0x04, SHT_HASH = 0x05, SHT_DYNAMIC = 0x06, SHT_NOTE = 0x07, SHT_NOBITS = 0x08, SHT_REL = 0x09, SHT_SHLIB = 0x0A, SHT_DYNSYM = 0x0B, SHT_INIT_ARRAY = 0x0E, SHT_FINI_ARRAY = 0x0F, SHT_PREINIT_ARRAY = 0x10, SHT_GROUP = 0x11, SHT_SYMTAB_SHNDX = 0x12, SHT_NUM = 0x13, }
30
31impl TryFrom<u32> for SectionHeaderType {
32 type Error = EZBpfError;
33
34 fn try_from(value: u32) -> Result<Self, Self::Error> {
35 Ok(match value {
36 0x00 => Self::SHT_NULL,
37 0x01 => Self::SHT_PROGBITS,
38 0x02 => Self::SHT_SYMTAB,
39 0x03 => Self::SHT_STRTAB,
40 0x04 => Self::SHT_RELA,
41 0x05 => Self::SHT_HASH,
42 0x06 => Self::SHT_DYNAMIC,
43 0x07 => Self::SHT_NOTE,
44 0x08 => Self::SHT_NOBITS,
45 0x09 => Self::SHT_REL,
46 0x0A => Self::SHT_SHLIB,
47 0x0B => Self::SHT_DYNSYM,
48 0x0E => Self::SHT_INIT_ARRAY,
49 0x0F => Self::SHT_FINI_ARRAY,
50 0x10 => Self::SHT_PREINIT_ARRAY,
51 0x11 => Self::SHT_GROUP,
52 0x12 => Self::SHT_SYMTAB_SHNDX,
53 0x13 => Self::SHT_NUM,
54 _ => return Err(EZBpfError::InvalidSectionHeaderType),
55 })
56 }
57}
58
59impl Display for SectionHeaderType {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 f.write_str(Into::<&str>::into(self.clone()))
62 }
63}
64
65impl From<SectionHeaderType> for &str {
66 fn from(val: SectionHeaderType) -> Self {
67 match val {
68 SectionHeaderType::SHT_NULL => "SHT_NULL",
69 SectionHeaderType::SHT_PROGBITS => "SHT_PROGBITS",
70 SectionHeaderType::SHT_SYMTAB => "SHT_SYMTAB",
71 SectionHeaderType::SHT_STRTAB => "SHT_STRTAB",
72 SectionHeaderType::SHT_RELA => "SHT_RELA",
73 SectionHeaderType::SHT_HASH => "SHT_HASH",
74 SectionHeaderType::SHT_DYNAMIC => "SHT_DYNAMIC",
75 SectionHeaderType::SHT_NOTE => "SHT_NOTE",
76 SectionHeaderType::SHT_NOBITS => "SHT_NOBITS",
77 SectionHeaderType::SHT_REL => "SHT_REL",
78 SectionHeaderType::SHT_SHLIB => "SHT_SHLIB",
79 SectionHeaderType::SHT_DYNSYM => "SHT_DYNSYM",
80 SectionHeaderType::SHT_INIT_ARRAY => "SHT_INIT_ARRAY",
81 SectionHeaderType::SHT_FINI_ARRAY => "SHT_FINI_ARRAY",
82 SectionHeaderType::SHT_PREINIT_ARRAY => "SHT_PREINIT_ARRAY",
83 SectionHeaderType::SHT_GROUP => "SHT_GROUP",
84 SectionHeaderType::SHT_SYMTAB_SHNDX => "SHT_SYMTAB_SHNDX",
85 SectionHeaderType::SHT_NUM => "SHT_NUM",
86 }
87 }
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct SectionHeader {
92 pub sh_name: u32, pub sh_type: SectionHeaderType, pub sh_flags: u64, pub sh_addr: u64, pub sh_offset: u64, pub sh_size: u64, pub sh_link: u32, pub sh_info: u32, pub sh_addralign: u64, pub sh_entsize: u64, }
103
104impl SectionHeader {
105 pub fn from_bytes(b: &[u8]) -> Result<Self, EZBpfError> {
106 let mut c = Cursor::new(b);
107 c.read_section_header()
108 }
109
110 pub fn to_bytes(&self) -> Vec<u8> {
111 let mut b = self.sh_name.to_le_bytes().to_vec();
112 b.extend_from_slice(&(self.sh_type.clone() as u32).to_le_bytes());
113 b.extend_from_slice(&self.sh_flags.to_le_bytes());
114 b.extend_from_slice(&self.sh_addr.to_le_bytes());
115 b.extend_from_slice(&self.sh_offset.to_le_bytes());
116 b.extend_from_slice(&self.sh_size.to_le_bytes());
117 b.extend_from_slice(&self.sh_link.to_le_bytes());
118 b.extend_from_slice(&self.sh_info.to_le_bytes());
119 b.extend_from_slice(&self.sh_addralign.to_le_bytes());
120 b.extend_from_slice(&self.sh_entsize.to_le_bytes());
121 b
122 }
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct SectionHeaderEntry {
127 pub label: String,
128 pub offset: usize,
129 pub data: Vec<u8>,
130}
131
132impl SectionHeaderEntry {
133 pub fn to_ixs(&self) -> Result<Vec<Ix>, EZBpfError> {
134 if self.data.len() % 8 != 0 {
135 return Err(EZBpfError::InvalidDataLength);
136 }
137 let mut ixs: Vec<Ix> = vec![];
138 if self.data.len() >= 8 {
139 let mut c = Cursor::new(self.data.as_slice());
140 while let Ok(ix) = c.read_ix() {
141 ixs.push(ix)
142 }
143 }
144 Ok(ixs)
145 }
146}
147
148#[cfg(test)]
149mod test {
150 use hex_literal::hex;
151
152 use crate::section_header::SectionHeader;
153
154 #[test]
155 fn serialize_e2e() {
156 let b = hex!(
157 "07000000030000000000000000000000000000000000000080000000000000000A00000000000000000000000000000001000000000000000000000000000000"
158 );
159 let h = SectionHeader::from_bytes(&b).unwrap();
160 assert_eq!(h.to_bytes(), &b)
161 }
162}