elf_utilities/segment/
elf32.rs

1//! Type definitions for 32-bit ELF binaries.
2
3use crate::*;
4
5use crate::segment::*;
6use serde::{Deserialize, Serialize};
7
8#[derive(
9    Default, Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize,
10)]
11pub struct Segment32 {
12    pub header: Phdr32,
13}
14impl Segment32 {
15    pub fn new(header: Phdr32) -> Self {
16        Self { header }
17    }
18}
19
20#[repr(C)]
21#[derive(Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
22pub struct Phdr32 {
23    /// Segment type
24    pub p_type: Elf32Word,
25
26    /// Segment file offset
27    pub p_offset: Elf32Off,
28
29    /// Segment virtual address
30    pub p_vaddr: Elf32Addr,
31
32    /// Segment physical address
33    pub p_paddr: Elf32Addr,
34
35    /// Segment size in file
36    pub p_filesz: Elf32Word,
37
38    /// Segment size in memory
39    pub p_memsz: Elf32Word,
40
41    /// Segment flags
42    pub p_flags: Elf32Word,
43
44    /// Segment alignment
45    pub p_align: Elf32Word,
46}
47
48impl Default for Phdr32 {
49    fn default() -> Self {
50        Self {
51            p_type: 0,
52            p_flags: 0,
53            p_offset: 0,
54            p_vaddr: 0,
55            p_paddr: 0,
56            p_filesz: 0,
57            p_memsz: 0,
58            p_align: 0,
59        }
60    }
61}
62
63impl Phdr32 {
64    pub const SIZE: usize = 0x20;
65    // getter
66    pub fn get_type(&self) -> segment_type::Type {
67        segment_type::Type::from(self.p_type)
68    }
69
70    // setter
71    pub fn set_flags<'a, I>(&mut self, flags: I)
72    where
73        I: Iterator<Item = &'a segment::Flag>,
74    {
75        for flag in flags {
76            self.p_flags = self.p_flags | Into::<Elf32Word>::into(*flag);
77        }
78    }
79
80    /// # Examples
81    ///
82    /// ```
83    /// use elf_utilities::segment;
84    ///
85    /// let mut phdr : segment::Phdr32 = Default::default();
86    /// phdr.set_type(segment::Type::Load);
87    ///
88    /// assert_eq!(phdr.get_type(), segment::Type::Load);
89    /// ```
90    pub fn set_type(&mut self, ptype: segment_type::Type) {
91        self.p_type = ptype.to_bytes();
92    }
93
94    /// Create Vec<u8> from this.
95    ///
96    /// # Examples
97    ///
98    /// ```
99    /// use elf_utilities::segment::Phdr32;
100    /// let null_phdr : Phdr32 = Default::default();
101    ///
102    /// assert_eq!([0].repeat(Phdr32::SIZE), null_phdr.to_le_bytes());
103    /// ```
104    pub fn to_le_bytes(&self) -> Vec<u8> {
105        bincode::serialize(self).unwrap()
106    }
107
108    pub fn deserialize(buf: &[u8], start: usize) -> Result<Self, Box<dyn std::error::Error>> {
109        // bincode::ErrorKindをトレイトオブジェクトとするため,この冗長な書き方が必要
110        match bincode::deserialize(&buf[start..]) {
111            Ok(header) => Ok(header),
112            Err(e) => Err(e),
113        }
114    }
115}