monistode_binutils/
symbols.rs1use crate::executable::segments::flags::SegmentFlags;
2use crate::executable::segments::SegmentHeader;
3use crate::object_file::{SectionHeader, SymbolTableHeader};
4
5use super::address::Address;
6use super::serializable::*;
7
8#[derive(Debug, Clone)]
9pub struct Symbol {
10 pub name: String,
11 pub address: Address,
12}
13
14#[derive(Debug, Clone)]
15struct SymbolEntry {
16 section_id: u32,
17 offset: Address,
18 name_offset: u32,
19}
20
21#[derive(Debug, Clone)]
22pub struct SymbolTable {
23 entries: Vec<SymbolEntry>,
24 names: Vec<u8>,
25}
26
27impl SymbolTable {
28 pub fn new() -> Self {
29 SymbolTable {
30 entries: Vec::new(),
31 names: Vec::new(),
32 }
33 }
34
35 pub fn add_symbol(&mut self, section_id: u32, symbol: Symbol) {
36 let name_offset = self.names.len() as u32;
37 self.names.extend(symbol.name.as_bytes());
38 self.names.push(0); self.entries.push(SymbolEntry {
41 section_id,
42 offset: symbol.address,
43 name_offset,
44 });
45 }
46
47 pub fn serialize_as_section(&self) -> (SectionHeader, Vec<u8>) {
48 let mut data = Vec::new();
49
50 for entry in &self.entries {
52 data.extend(entry.section_id.to_le_bytes());
53 data.extend((entry.offset.0 as u32).to_le_bytes());
54 data.extend(entry.name_offset.to_le_bytes());
55 }
56
57 data.extend(&self.names);
59
60 let header = SectionHeader::SymbolTable(SymbolTableHeader {
61 entry_count: self.entries.len() as u32,
62 names_length: self.names.len() as u32,
63 });
64
65 (header, data)
66 }
67
68 pub fn serialize_as_segment(&self) -> (SegmentHeader, Vec<u8>) {
69 let mut data = Vec::new();
70
71 for entry in &self.entries {
73 data.extend(entry.section_id.to_le_bytes());
74 data.extend((entry.offset.0 as u32).to_le_bytes());
75 data.extend(entry.name_offset.to_le_bytes());
76 }
77
78 data.extend(&self.names);
80
81 let header = SegmentHeader {
82 address_space_start: 0, address_space_size: self.entries.len() as u64, disk_bit_count: data.len(),
88 flags: SegmentFlags {
89 executable: false,
90 writable: false,
91 readable: false,
92 special: true,
93 },
94 };
95
96 (header, data)
97 }
98
99 pub fn deserialize_section(
100 header: &SymbolTableHeader,
101 data: &[u8],
102 ) -> Result<(usize, Self), SerializationError> {
103 let required_size = (header.entry_count as usize * 12) + header.names_length as usize;
104 if data.len() < required_size {
105 return Err(SerializationError::DataTooShort);
106 }
107
108 let mut offset = 0;
109 let mut entries = Vec::new();
110
111 for _ in 0..header.entry_count {
113 if offset + 12 > data.len() {
114 return Err(SerializationError::DataTooShort);
115 }
116
117 let section_id = u32::from_le_bytes([
118 data[offset],
119 data[offset + 1],
120 data[offset + 2],
121 data[offset + 3],
122 ]);
123 offset += 4;
124
125 let addr = u32::from_le_bytes([
126 data[offset],
127 data[offset + 1],
128 data[offset + 2],
129 data[offset + 3],
130 ]) as usize;
131 offset += 4;
132
133 let name_offset = u32::from_le_bytes([
134 data[offset],
135 data[offset + 1],
136 data[offset + 2],
137 data[offset + 3],
138 ]);
139 offset += 4;
140
141 if name_offset >= header.names_length {
142 return Err(SerializationError::InvalidData);
143 }
144
145 entries.push(SymbolEntry {
146 section_id,
147 offset: Address(addr),
148 name_offset,
149 });
150 }
151
152 if offset + header.names_length as usize > data.len() {
154 return Err(SerializationError::DataTooShort);
155 }
156 let names = data[offset..offset + header.names_length as usize].to_vec();
157
158 if names.len() > 0 {
160 if !names.iter().any(|&b| b == 0) {
161 return Err(SerializationError::InvalidData);
162 }
163 }
164
165 Ok((
166 offset + header.names_length as usize,
167 SymbolTable { entries, names },
168 ))
169 }
170
171 pub fn deserialize_segment(
172 header: &SegmentHeader,
173 data: &[u8],
174 ) -> Result<(usize, Self), SerializationError> {
175 let required_size = header.disk_bit_count as usize;
176 if data.len() < required_size {
177 return Err(SerializationError::DataTooShort);
178 }
179
180 let mut offset = 0;
181 let mut entries = Vec::new();
182
183 for _ in 0..header.address_space_size {
185 if offset + 12 > data.len() {
186 return Err(SerializationError::DataTooShort);
187 }
188
189 let section_id = u32::from_le_bytes([
190 data[offset],
191 data[offset + 1],
192 data[offset + 2],
193 data[offset + 3],
194 ]);
195 offset += 4;
196
197 let addr = u32::from_le_bytes([
198 data[offset],
199 data[offset + 1],
200 data[offset + 2],
201 data[offset + 3],
202 ]) as usize;
203 offset += 4;
204
205 let name_offset = u32::from_le_bytes([
206 data[offset],
207 data[offset + 1],
208 data[offset + 2],
209 data[offset + 3],
210 ]);
211 offset += 4;
212
213 if name_offset >= header.disk_bit_count as u32 - header.address_space_size as u32 * 12 {
214 return Err(SerializationError::InvalidData);
215 }
216
217 entries.push(SymbolEntry {
218 section_id,
219 offset: Address(addr),
220 name_offset,
221 });
222 }
223
224 let names = data[offset..header.disk_bit_count as usize].to_vec();
226
227 if !names.iter().any(|&b| b == 0) {
229 return Err(SerializationError::InvalidData);
230 }
231
232 Ok((
233 header.disk_bit_count as usize,
234 SymbolTable { entries, names },
235 ))
236 }
237
238 pub fn get_symbols(&self, section_id: u32) -> Vec<Symbol> {
239 self.entries
240 .iter()
241 .filter(|entry| entry.section_id == section_id)
242 .map(|entry| {
243 let mut name = String::new();
244 let mut i = entry.name_offset as usize;
245 while i < self.names.len() && self.names[i] != 0 {
246 name.push(self.names[i] as char);
247 i += 1;
248 }
249 Symbol {
250 name,
251 address: Address(entry.offset.0),
252 }
253 })
254 .collect()
255 }
256}