sbpf_disassembler/
elf_header.rs1use std::str;
2
3use object::Endianness;
4use object::read::elf::ElfFile64;
5use serde::{Deserialize, Serialize, Serializer};
6
7use crate::errors::DisassemblerError;
8
9pub const EI_MAGIC: [u8; 4] = *b"\x7fELF"; pub const EI_CLASS: u8 = 0x02; pub const EI_DATA: u8 = 0x01; pub const EI_VERSION: u8 = 0x01; pub const EI_OSABI: u8 = 0x00; pub const EI_ABIVERSION: u8 = 0x00; pub const EI_PAD: [u8; 7] = [0u8; 7]; pub const E_TYPE: u16 = 0x03; pub const E_MACHINE: u16 = 0xf7; pub const E_MACHINE_SBPF: u16 = 0x0107; pub const E_VERSION: u32 = 0x01; fn elf_magic<S>(magic: &[u8; 4], serializer: S) -> Result<S::Ok, S::Error>
22where
23 S: Serializer,
24{
25 let s = String::from_utf8_lossy(magic);
26 serializer.serialize_str(&s)
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ELFHeader {
31 #[serde(serialize_with = "elf_magic")]
32 pub ei_magic: [u8; 4],
33 pub ei_class: u8,
34 pub ei_data: u8,
35 pub ei_version: u8,
36 pub ei_osabi: u8,
37 pub ei_abiversion: u8,
38 pub ei_pad: [u8; 7],
39 pub e_type: u16,
40 pub e_machine: u16,
41 pub e_version: u32,
42 pub e_entry: u64,
43 pub e_phoff: u64,
44 pub e_shoff: u64,
45 pub e_flags: u32,
46 pub e_ehsize: u16,
47 pub e_phentsize: u16,
48 pub e_phnum: u16,
49 pub e_shentsize: u16,
50 pub e_shnum: u16,
51 pub e_shstrndx: u16,
52}
53
54impl ELFHeader {
55 pub fn from_elf_file(elf_file: &ElfFile64<Endianness>) -> Result<Self, DisassemblerError> {
56 let endian = elf_file.endian();
57 let elf_header = elf_file.elf_header();
58
59 let e_ident = elf_header.e_ident;
61 let e_type = elf_header.e_type.get(endian);
62 let e_machine = elf_header.e_machine.get(endian);
63 let e_version = elf_header.e_version.get(endian);
64 let e_entry = elf_header.e_entry.get(endian);
65 let e_phoff = elf_header.e_phoff.get(endian);
66 let e_shoff = elf_header.e_shoff.get(endian);
67 let e_flags = elf_header.e_flags.get(endian);
68 let e_ehsize = elf_header.e_ehsize.get(endian);
69 let e_phentsize = elf_header.e_phentsize.get(endian);
70 let e_phnum = elf_header.e_phnum.get(endian);
71 let e_shentsize = elf_header.e_shentsize.get(endian);
72 let e_shnum = elf_header.e_shnum.get(endian);
73 let e_shstrndx = elf_header.e_shstrndx.get(endian);
74
75 if e_ident.magic.ne(&EI_MAGIC)
77 || e_ident.class.ne(&EI_CLASS)
78 || e_ident.data.ne(&EI_DATA)
79 || e_ident.version.ne(&EI_VERSION)
80 || e_ident.os_abi.ne(&EI_OSABI)
81 || e_ident.abi_version.ne(&EI_ABIVERSION)
82 || e_ident.padding.ne(&EI_PAD)
83 || (e_machine.ne(&E_MACHINE) && e_machine.ne(&E_MACHINE_SBPF))
84 || e_version.ne(&E_VERSION)
85 {
86 return Err(DisassemblerError::NonStandardElfHeader);
87 }
88
89 Ok(ELFHeader {
90 ei_magic: e_ident.magic,
91 ei_class: e_ident.class,
92 ei_data: e_ident.data,
93 ei_version: e_ident.version,
94 ei_osabi: e_ident.os_abi,
95 ei_abiversion: e_ident.abi_version,
96 ei_pad: e_ident.padding,
97 e_type,
98 e_machine,
99 e_version,
100 e_entry,
101 e_phoff,
102 e_shoff,
103 e_flags,
104 e_ehsize,
105 e_phentsize,
106 e_phnum,
107 e_shentsize,
108 e_shnum,
109 e_shstrndx,
110 })
111 }
112
113 pub fn to_bytes(&self) -> Vec<u8> {
114 let mut b = self.ei_magic.to_vec();
115 b.extend_from_slice(&[
116 self.ei_class,
117 self.ei_data,
118 self.ei_version,
119 self.ei_osabi,
120 self.ei_abiversion,
121 ]);
122 b.extend_from_slice(&self.ei_pad);
123 b.extend_from_slice(&self.e_type.to_le_bytes());
124 b.extend_from_slice(&self.e_machine.to_le_bytes());
125 b.extend_from_slice(&self.e_version.to_le_bytes());
126 b.extend_from_slice(&self.e_entry.to_le_bytes());
127 b.extend_from_slice(&self.e_phoff.to_le_bytes());
128 b.extend_from_slice(&self.e_shoff.to_le_bytes());
129 b.extend_from_slice(&self.e_flags.to_le_bytes());
130 b.extend_from_slice(&self.e_ehsize.to_le_bytes());
131 b.extend_from_slice(&self.e_phentsize.to_le_bytes());
132 b.extend_from_slice(&self.e_phnum.to_le_bytes());
133 b.extend_from_slice(&self.e_shentsize.to_le_bytes());
134 b.extend_from_slice(&self.e_shnum.to_le_bytes());
135 b.extend_from_slice(&self.e_shstrndx.to_le_bytes());
136 b
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use hex_literal::hex;
143
144 use crate::elf_header::{
145 E_MACHINE, E_MACHINE_SBPF, E_TYPE, E_VERSION, EI_ABIVERSION, EI_CLASS, EI_DATA, EI_MAGIC,
146 EI_OSABI, EI_PAD, EI_VERSION,
147 };
148 use crate::program::Program;
149
150 #[test]
151 fn test_elf_header() {
152 let program = Program::from_bytes(&hex!("7F454C460201010000000000000000000300F700010000002001000000000000400000000000000028020000000000000000000040003800030040000600050001000000050000002001000000000000200100000000000020010000000000003000000000000000300000000000000000100000000000000100000004000000C001000000000000C001000000000000C0010000000000003C000000000000003C000000000000000010000000000000020000000600000050010000000000005001000000000000500100000000000070000000000000007000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007912A000000000007911182900000000B7000000010000002D21010000000000B70000000000000095000000000000001E0000000000000004000000000000000600000000000000C0010000000000000B0000000000000018000000000000000500000000000000F0010000000000000A000000000000000C00000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000120001002001000000000000300000000000000000656E747279706F696E7400002E74657874002E64796E737472002E64796E73796D002E64796E616D6963002E73687374727461620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000600000000000000200100000000000020010000000000003000000000000000000000000000000008000000000000000000000000000000170000000600000003000000000000005001000000000000500100000000000070000000000000000400000000000000080000000000000010000000000000000F0000000B0000000200000000000000C001000000000000C001000000000000300000000000000004000000010000000800000000000000180000000000000007000000030000000200000000000000F001000000000000F0010000000000000C00000000000000000000000000000001000000000000000000000000000000200000000300000000000000000000000000000000000000FC010000000000002A00000000000000000000000000000001000000000000000000000000000000")).unwrap();
153
154 assert_eq!(program.elf_header.ei_magic, EI_MAGIC);
156 assert_eq!(program.elf_header.ei_class, EI_CLASS);
157 assert_eq!(program.elf_header.ei_data, EI_DATA);
158 assert_eq!(program.elf_header.ei_version, EI_VERSION);
159 assert_eq!(program.elf_header.ei_osabi, EI_OSABI);
160 assert_eq!(program.elf_header.ei_abiversion, EI_ABIVERSION);
161 assert_eq!(program.elf_header.ei_pad, EI_PAD);
162 assert_eq!(program.elf_header.e_type, E_TYPE);
163 assert!(
164 program.elf_header.e_machine == E_MACHINE
165 || program.elf_header.e_machine == E_MACHINE_SBPF
166 );
167 assert_eq!(program.elf_header.e_version, E_VERSION);
168 }
169}