elf_utilities/segment/
elf64.rs1use std::collections::HashSet;
4
5use crate::*;
6
7use crate::segment::*;
8use serde::{Deserialize, Serialize};
9
10#[derive(
11 Default, Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize,
12)]
13pub struct Segment64 {
14 pub header: Phdr64,
15}
16
17#[repr(C)]
18#[derive(Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
19pub struct Phdr64 {
20 pub p_type: Elf64Word,
22
23 pub p_flags: Elf64Word,
25
26 pub p_offset: Elf64Off,
28
29 pub p_vaddr: Elf64Addr,
31
32 pub p_paddr: Elf64Addr,
34
35 pub p_filesz: Elf64Xword,
37
38 pub p_memsz: Elf64Xword,
40
41 pub p_align: Elf64Xword,
43}
44
45impl Default for Phdr64 {
46 fn default() -> Self {
47 Self {
48 p_type: 0,
49 p_flags: 0,
50 p_offset: 0,
51 p_vaddr: 0,
52 p_paddr: 0,
53 p_filesz: 0,
54 p_memsz: 0,
55 p_align: 0,
56 }
57 }
58}
59
60impl Phdr64 {
61 pub const SIZE: usize = 0x38;
62
63 pub fn get_type(&self) -> segment_type::Type {
65 segment_type::Type::from(self.p_type)
66 }
67 pub fn get_flags(&self) -> HashSet<segment::Flag> {
68 let mut mask: Elf64Word = 0b1;
69 let mut flags = HashSet::new();
70 loop {
71 if mask == 0 {
72 break;
73 }
74 if self.p_flags & mask != 0 {
75 flags.insert(segment::Flag::from(mask));
76 }
77 mask <<= 1;
78 }
79
80 flags
81 }
82
83 pub fn set_type(&mut self, ptype: segment_type::Type) {
95 self.p_type = ptype.to_bytes();
96 }
97
98 pub fn set_flags<'a, I>(&mut self, flags: I)
99 where
100 I: Iterator<Item = &'a segment::Flag>,
101 {
102 for flag in flags {
103 self.p_flags = self.p_flags | Into::<Elf64Word>::into(*flag);
104 }
105 }
106
107 pub fn to_le_bytes(&self) -> Vec<u8> {
118 bincode::serialize(self).unwrap()
119 }
120
121 pub fn deserialize(buf: &[u8], start: usize) -> Result<Self, Box<dyn std::error::Error>> {
122 match bincode::deserialize(&buf[start..]) {
124 Ok(header) => Ok(header),
125 Err(e) => Err(e),
126 }
127 }
128}