elf_utilities/header/
elf64.rs

1use crate::header::{class, data, elf_type, machine, osabi, version};
2use crate::*;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
6#[repr(C)]
7pub struct Ehdr64 {
8    pub e_ident: [u8; 16],
9    pub e_type: Elf64Half,
10    pub e_machine: Elf64Half,
11    pub e_version: Elf64Word,
12    pub e_entry: Elf64Addr,
13    pub e_phoff: Elf64Off,
14    pub e_shoff: Elf64Off,
15    pub e_flags: Elf64Word,
16    pub e_ehsize: Elf64Half,
17    pub e_phentsize: Elf64Half,
18    pub e_phnum: Elf64Half,
19    pub e_shentsize: Elf64Half,
20    pub e_shnum: Elf64Half,
21    pub e_shstrndx: Elf64Half,
22}
23
24impl Default for Ehdr64 {
25    fn default() -> Self {
26        Self {
27            e_ident: [
28                0x7f, 0x45, 0x4c, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29                0x00, 0x00,
30            ],
31            e_type: 0,
32            e_machine: 0,
33            e_version: 0,
34            e_entry: 0,
35            e_phoff: Self::SIZE as Elf64Off,
36            e_shoff: Self::SIZE as Elf64Off,
37            e_flags: 0,
38            e_ehsize: Self::SIZE as Elf64Half,
39            e_phentsize: segment::Phdr64::SIZE as Elf64Half,
40            e_phnum: 0,
41            e_shentsize: section::Shdr64::SIZE as Elf64Half,
42            e_shnum: 0,
43            e_shstrndx: 0,
44        }
45    }
46}
47
48impl Ehdr64 {
49    /// header size
50    pub const SIZE: Elf64Half = 0x40;
51
52    pub fn get_class(&self) -> class::Class {
53        class::Class::from(self.e_ident[class::Class::INDEX])
54    }
55    pub fn get_data(&self) -> data::Data {
56        data::Data::from(self.e_ident[data::Data::INDEX])
57    }
58    pub fn get_file_version(&self) -> version::Version {
59        version::Version::from(self.e_ident[version::Version::INDEX])
60    }
61    pub fn get_object_version(&self) -> version::Version {
62        version::Version::from(self.e_version)
63    }
64    pub fn get_type(&self) -> elf_type::Type {
65        elf_type::Type::from(self.e_type)
66    }
67    pub fn get_machine(&self) -> machine::Machine {
68        machine::Machine::from(self.e_machine)
69    }
70    pub fn get_osabi(&self) -> osabi::OSABI {
71        osabi::OSABI::from(self.e_ident[osabi::OSABI::INDEX])
72    }
73    pub fn set_class(&mut self, c: class::Class) {
74        self.e_ident[class::Class::INDEX] = c.to_identifier();
75    }
76    pub fn set_data(&mut self, d: data::Data) {
77        self.e_ident[data::Data::INDEX] = d.to_identifier();
78    }
79    pub fn set_file_version(&mut self, v: version::Version) {
80        self.e_ident[version::Version::INDEX] = v.to_identifier();
81    }
82    pub fn set_object_version(&mut self, v: version::Version) {
83        self.e_version = v.to_object_version();
84    }
85    pub fn set_osabi(&mut self, o: osabi::OSABI) {
86        self.e_ident[osabi::OSABI::INDEX] = o.to_identifier();
87    }
88    pub fn set_elf_type(&mut self, e_type: elf_type::Type) {
89        self.e_type = e_type.to_bytes();
90    }
91    pub fn set_machine(&mut self, e_machine: machine::Machine) {
92        self.e_machine = e_machine.to_bytes();
93    }
94
95    /// Create Vec<u8> from this.
96    pub fn to_le_bytes(&self) -> Vec<u8> {
97        bincode::serialize(self).unwrap()
98    }
99
100    pub fn deserialize(buf: &[u8], start: usize) -> Result<Self, Box<dyn std::error::Error>> {
101        // bincode::ErrorKindをトレイトオブジェクトとするため,この冗長な書き方が必要
102        match bincode::deserialize(&buf[start..]) {
103            Ok(header) => Ok(header),
104            Err(e) => Err(e),
105        }
106    }
107}