monistode_binutils/executable/
mod.rs1pub use header::ExecutableHeader;
2pub use segments::{Segment, SegmentHeader};
3
4use crate::{Architecture, Serializable, SerializationError, SymbolTable};
5
6pub mod header;
7pub mod segments;
8
9#[derive(Debug, Clone)]
10pub struct Executable {
11 architecture: Architecture,
12 entry_point: u64,
13 segments: Vec<Segment>,
14}
15
16impl Serializable for Executable {
17 fn serialize(&self) -> Vec<u8> {
18 let mut data = Vec::new();
19
20 let mut symbol_table = SymbolTable::new();
23
24 for (segment_id, segment) in self.segments.iter().enumerate() {
25 for symbol in segment.symbols() {
26 symbol_table.add_symbol(segment_id as u32, symbol);
27 }
28 }
29
30 let header = ExecutableHeader {
32 architecture: self.architecture,
33 segment_count: self.segments.len() as u64 + 1, entry_point: self.entry_point,
35 };
36 data.extend(header.serialize());
37
38 let mut segment_data = Vec::new();
40 let mut headers = Vec::new();
41
42 for segment in &self.segments {
44 let (header, bytes) = segment.serialize();
45 headers.push(header);
46 segment_data.extend(bytes);
47 }
48
49 let (symbol_header, symbol_data) = symbol_table.serialize_as_segment();
51 headers.push(symbol_header);
52 segment_data.extend(symbol_data);
53
54 for header in headers {
56 data.extend(header.serialize());
57 }
58 data.extend(segment_data);
59
60 data
61 }
62
63 fn deserialize(data: &[u8]) -> Result<(usize, Self), SerializationError> {
64 if data.len() < 9 {
65 return Err(SerializationError::DataTooShort);
66 }
67
68 let (header_size, header) = ExecutableHeader::deserialize(data)?;
70 let mut offset = header_size;
71
72 let mut headers = Vec::new();
74 for _ in 0..header.segment_count {
75 if data.len() < offset + 16 {
76 return Err(SerializationError::DataTooShort);
78 }
79 let (size, segment_header) = SegmentHeader::deserialize(&data[offset..])?;
80 headers.push(segment_header);
81 offset += size;
82 }
83
84 let segment_count = headers.len();
86 if segment_count < 1 {
87 return Err(SerializationError::InvalidData);
88 }
89 if !headers[segment_count - 1].flags.special
90 || !headers[segment_count - 1].address_space_start == 0
91 {
92 return Err(SerializationError::InvalidData);
93 }
94
95 if headers[..segment_count - 1]
97 .iter()
98 .any(|h| h.flags.special && h.address_space_start == 0)
99 {
100 return Err(SerializationError::InvalidData);
101 }
102
103 let mut segment_data_offset = offset;
105 for header in &headers[..segment_count - 1] {
106 segment_data_offset += header.segment_size();
107 }
108
109 let symbol_offset = segment_data_offset;
111 let (_, symbol_table) =
112 SymbolTable::deserialize_segment(&headers[segment_count - 1], &data[symbol_offset..])?;
113
114 let mut segments = Vec::new();
116 let mut current_offset = offset;
117
118 for (idx, segment_header) in headers[..segment_count - 1].iter().enumerate() {
119 let symbols = symbol_table.get_symbols(idx as u32);
120 let (size, segment) =
121 Segment::deserialize(segment_header, &data[current_offset..], symbols)?;
122 segments.push(segment);
123 current_offset += size;
124 }
125
126 Ok((
127 symbol_offset + headers[segment_count - 1].segment_size(), Executable {
129 architecture: header.architecture,
130 entry_point: header.entry_point,
131 segments,
132 },
133 ))
134 }
135}
136
137impl Executable {
138 pub fn new(architecture: Architecture, segments: Vec<Segment>) -> Self {
139 Executable {
140 architecture,
141 segments,
142 entry_point: 0,
143 }
144 }
145
146 pub fn segments(&self) -> &[Segment] {
147 &self.segments
148 }
149
150 pub fn segments_mut(&mut self) -> &mut Vec<Segment> {
151 &mut self.segments
152 }
153
154 pub fn architecture(&self) -> Architecture {
155 self.architecture
156 }
157
158 pub fn entry_point(&self) -> u64 {
159 self.entry_point
160 }
161}