1use crate::astnode::ASTNode;
2use crate::astnode::ROData;
3use crate::debuginfo::DebugInfo;
4use crate::dynsym::DynamicSymbol;
5use crate::dynsym::RelDyn;
6use crate::header::SectionHeader;
7use crate::lexer::Token;
8use std::collections::HashMap;
9
10pub trait Section {
12 fn name(&self) -> &str {
13 ".unknown" }
15
16 fn bytecode(&self) -> Vec<u8> {
17 Vec::new() }
19
20 fn size(&self) -> u64 {
22 self.bytecode().len() as u64
23 }
24
25 }
29
30#[derive(Debug)]
32pub struct CodeSection {
33 name: String,
34 nodes: Vec<ASTNode>,
35 size: u64,
36 offset: u64,
37 debug_map: HashMap<u64, DebugInfo>,
38}
39
40impl CodeSection {
41 pub fn new(nodes: Vec<ASTNode>, size: u64) -> Self {
42 let mut debug_map = HashMap::new();
43 for node in &nodes {
44 if let Some((_, node_debug_map)) = node.bytecode_with_debug_map() {
45 debug_map.extend(node_debug_map);
46 }
47 }
48 Self {
49 name: String::from(".text"),
50 nodes,
51 size,
52 offset: 0,
53 debug_map,
54 }
55 }
56
57 pub fn get_nodes(&self) -> &Vec<ASTNode> {
58 &self.nodes
59 }
60
61 pub fn get_size(&self) -> u64 {
62 self.size
63 }
64
65 pub fn get_debug_map(&self) -> &HashMap<u64, DebugInfo> {
66 &self.debug_map
67 }
68
69 pub fn set_offset(&mut self, offset: u64) {
70 self.offset = offset;
71 }
72
73 pub fn section_header_bytecode(&self) -> Vec<u8> {
74 let flags = SectionHeader::SHF_ALLOC | SectionHeader::SHF_EXECINSTR;
75 SectionHeader::new(
76 1,
77 SectionHeader::SHT_PROGBITS,
78 flags,
79 self.offset,
80 self.offset,
81 self.size,
82 0,
83 0,
84 4,
85 0,
86 )
87 .bytecode()
88 }
89}
90
91impl Section for CodeSection {
92 fn name(&self) -> &str {
93 &self.name
94 }
95
96 fn bytecode(&self) -> Vec<u8> {
97 let mut bytecode = Vec::new();
98 for node in &self.nodes {
99 if let Some(node_bytes) = node.bytecode() {
100 bytecode.extend(node_bytes);
101 }
102 }
103 bytecode
104 }
105
106 fn size(&self) -> u64 {
107 self.size
108 }
109}
110
111#[derive(Debug)]
113pub struct DataSection {
114 name: String,
115 nodes: Vec<ASTNode>,
116 size: u64,
117 offset: u64,
118}
119
120impl DataSection {
121 pub fn new(nodes: Vec<ASTNode>, size: u64) -> Self {
122 Self {
123 name: String::from(".rodata"),
124 nodes,
125 size,
126 offset: 0,
127 }
128 }
129
130 pub fn get_nodes(&self) -> &Vec<ASTNode> {
131 &self.nodes
132 }
133
134 pub fn get_size(&self) -> u64 {
135 self.size
136 }
137
138 pub fn set_offset(&mut self, offset: u64) {
139 self.offset = offset;
140 }
141
142 pub fn rodata(&self) -> Vec<(String, usize, String)> {
143 let mut ro_data_labels = Vec::new();
144 for node in &self.nodes {
145 if let ASTNode::ROData {
146 rodata: ROData { name, args, .. },
147 offset,
148 } = node
149 {
150 if let Some(Token::StringLiteral(str_literal, _)) = args.get(1) {
151 ro_data_labels.push((name.clone(), *offset as usize, str_literal.clone()));
152 }
153 }
154 }
155 ro_data_labels
156 }
157
158 pub fn section_header_bytecode(&self) -> Vec<u8> {
159 let flags = SectionHeader::SHF_ALLOC; SectionHeader::new(
161 7,
162 SectionHeader::SHT_PROGBITS,
163 flags,
164 self.offset,
165 self.offset,
166 self.size,
167 0,
168 0,
169 1,
170 0,
171 )
172 .bytecode()
173 }
174}
175
176impl Section for DataSection {
177 fn name(&self) -> &str {
178 &self.name
179 }
180
181 fn size(&self) -> u64 {
182 self.size
183 }
184
185 fn bytecode(&self) -> Vec<u8> {
186 let mut bytecode = Vec::new();
187 for node in &self.nodes {
188 if let Some(node_bytes) = node.bytecode() {
189 bytecode.extend(node_bytes);
190 }
191 }
192 while bytecode.len() % 8 != 0 {
194 bytecode.push(0);
195 }
196
197 bytecode
198 }
199}
200
201#[derive(Debug, Default)]
202pub struct NullSection {
203 name: String,
204 offset: u64,
205}
206
207impl NullSection {
208 pub fn new() -> Self {
209 Self::default()
210 }
211
212 pub fn section_header_bytecode(&self) -> Vec<u8> {
213 SectionHeader::new(0, SectionHeader::SHT_NULL, 0, 0, 0, 0, 0, 0, 0, 0).bytecode()
214 }
215}
216
217impl Section for NullSection {
218 }
220
221#[derive(Debug)]
222pub struct ShStrTabSection {
223 name: String,
224 name_offset: u32,
225 section_names: Vec<String>,
226 offset: u64,
227}
228
229impl ShStrTabSection {
230 pub fn new(name_offset: u32, section_names: Vec<String>) -> Self {
231 Self {
232 name: String::from(".s"),
233 name_offset,
234 section_names: {
235 let mut names = section_names;
236 names.push(".s".to_string());
237 names
238 },
239 offset: 0,
240 }
241 }
242
243 pub fn set_offset(&mut self, offset: u64) {
244 self.offset = offset;
245 }
246
247 pub fn section_header_bytecode(&self) -> Vec<u8> {
248 SectionHeader::new(
249 self.name_offset,
250 SectionHeader::SHT_STRTAB,
251 0,
252 0,
253 self.offset,
254 self.size(),
255 0,
256 0,
257 1,
258 0,
259 )
260 .bytecode()
261 }
262}
263
264impl Section for ShStrTabSection {
265 fn name(&self) -> &str {
266 &self.name
267 }
268
269 fn bytecode(&self) -> Vec<u8> {
270 let mut bytes = Vec::new();
271 bytes.push(0);
273
274 for name in &self.section_names {
276 if !name.is_empty() {
277 bytes.extend(name.as_bytes());
278 bytes.push(0); }
280 }
281
282 while bytes.len() % 8 != 0 {
284 bytes.push(0);
285 }
286
287 bytes
288 }
289
290 fn size(&self) -> u64 {
291 let mut section_name_size = 0;
293
294 for name in &self.section_names {
295 if !name.is_empty() {
296 section_name_size += 1 + name.len();
297 }
298 }
299
300 section_name_size += 1; section_name_size as u64 }
304}
305
306#[derive(Debug)]
307pub struct DynamicSection {
308 name: String,
309 name_offset: u32,
310 offset: u64,
311 rel_offset: u64,
312 rel_size: u64,
313 rel_count: u64,
314 dynsym_offset: u64,
315 dynstr_offset: u64,
316 dynstr_size: u64,
317}
318
319impl DynamicSection {
320 pub fn new(name_offset: u32) -> Self {
321 Self {
322 name: String::from(".dynamic"),
323 name_offset,
324 offset: 0,
325 rel_offset: 0,
326 rel_size: 0,
327 rel_count: 0,
328 dynsym_offset: 0,
329 dynstr_offset: 0,
330 dynstr_size: 0,
331 }
332 }
333
334 pub fn set_offset(&mut self, offset: u64) {
335 self.offset = offset;
336 }
337
338 pub fn set_rel_offset(&mut self, offset: u64) {
339 self.rel_offset = offset;
340 }
341
342 pub fn set_rel_size(&mut self, size: u64) {
343 self.rel_size = size;
344 }
345
346 pub fn set_rel_count(&mut self, count: u64) {
347 self.rel_count = count;
348 }
349
350 pub fn set_dynsym_offset(&mut self, offset: u64) {
351 self.dynsym_offset = offset;
352 }
353
354 pub fn set_dynstr_offset(&mut self, offset: u64) {
355 self.dynstr_offset = offset;
356 }
357
358 pub fn set_dynstr_size(&mut self, size: u64) {
359 self.dynstr_size = size;
360 }
361
362 pub fn section_header_bytecode(&self) -> Vec<u8> {
363 SectionHeader::new(
364 self.name_offset,
365 SectionHeader::SHT_DYNAMIC,
366 SectionHeader::SHF_ALLOC | SectionHeader::SHF_WRITE,
367 self.offset,
368 self.offset,
369 self.size(),
370 5,
371 0,
372 8,
373 16,
374 )
375 .bytecode()
376 }
377}
378
379impl Section for DynamicSection {
380 fn name(&self) -> &str {
381 &self.name
382 }
383
384 fn bytecode(&self) -> Vec<u8> {
385 let mut bytes = Vec::new();
386
387 bytes.extend_from_slice(&0x1e_u64.to_le_bytes());
389 bytes.extend_from_slice(&0x04_u64.to_le_bytes());
390
391 bytes.extend_from_slice(&0x11_u64.to_le_bytes());
393 bytes.extend_from_slice(&self.rel_offset.to_le_bytes());
394
395 bytes.extend_from_slice(&0x12_u64.to_le_bytes());
397 bytes.extend_from_slice(&self.rel_size.to_le_bytes());
398
399 bytes.extend_from_slice(&0x13_u64.to_le_bytes());
401 bytes.extend_from_slice(&0x10_u64.to_le_bytes()); if self.rel_count > 0 {
405 bytes.extend_from_slice(&0x6fff_fffa_u64.to_le_bytes());
406 bytes.extend_from_slice(&self.rel_count.to_le_bytes());
407 }
408
409 bytes.extend_from_slice(&0x06_u64.to_le_bytes());
411 bytes.extend_from_slice(&self.dynsym_offset.to_le_bytes());
412
413 bytes.extend_from_slice(&0x0b_u64.to_le_bytes());
415 bytes.extend_from_slice(&0x18_u64.to_le_bytes()); bytes.extend_from_slice(&0x05_u64.to_le_bytes());
419 bytes.extend_from_slice(&self.dynstr_offset.to_le_bytes());
420
421 bytes.extend_from_slice(&0x0a_u64.to_le_bytes());
423 bytes.extend_from_slice(&self.dynstr_size.to_le_bytes());
424
425 bytes.extend_from_slice(&0x16_u64.to_le_bytes());
427 bytes.extend_from_slice(&0x00_u64.to_le_bytes());
428
429 bytes.extend_from_slice(&0x00_u64.to_le_bytes());
431 bytes.extend_from_slice(&0x00_u64.to_le_bytes());
432
433 bytes
434 }
435
436 fn size(&self) -> u64 {
437 if self.rel_count > 0 { 11 * 16 } else { 10 * 16 }
438 }
439}
440
441#[derive(Debug)]
442pub struct DynStrSection {
443 name: String,
444 name_offset: u32,
445 symbol_names: Vec<String>,
446 offset: u64,
447}
448
449impl DynStrSection {
450 pub fn new(name_offset: u32, symbol_names: Vec<String>) -> Self {
451 Self {
452 name: String::from(".dynstr"),
453 name_offset,
454 symbol_names,
455 offset: 0,
456 }
457 }
458
459 pub fn set_offset(&mut self, offset: u64) {
460 self.offset = offset;
461 }
462
463 pub fn section_header_bytecode(&self) -> Vec<u8> {
464 SectionHeader::new(
465 self.name_offset,
466 SectionHeader::SHT_STRTAB,
467 SectionHeader::SHF_ALLOC, self.offset,
469 self.offset,
470 self.size(),
471 0,
472 0,
473 1,
474 0,
475 )
476 .bytecode()
477 }
478}
479
480impl Section for DynStrSection {
481 fn name(&self) -> &str {
482 &self.name
483 }
484
485 fn bytecode(&self) -> Vec<u8> {
486 let mut bytes = Vec::new();
487 bytes.push(0);
489
490 for name in &self.symbol_names {
492 bytes.extend(name.as_bytes());
493 bytes.push(0); }
495 while bytes.len() % 8 != 0 {
497 bytes.push(0);
498 }
499 bytes
500 }
501
502 fn size(&self) -> u64 {
503 let mut size = 1 + self
505 .symbol_names
506 .iter()
507 .map(|name| name.len() + 1)
508 .sum::<usize>();
509 while size % 8 != 0 {
511 size += 1;
512 }
513 size as u64
514 }
515}
516
517#[derive(Debug)]
518pub struct DynSymSection {
519 name: String,
520 name_offset: u32,
521 offset: u64,
522 symbols: Vec<DynamicSymbol>,
523}
524
525impl DynSymSection {
526 pub fn new(name_offset: u32, symbols: Vec<DynamicSymbol>) -> Self {
527 Self {
528 name: String::from(".dynsym"),
529 name_offset,
530 offset: 0,
531 symbols,
532 }
533 }
534
535 pub fn set_offset(&mut self, offset: u64) {
536 self.offset = offset;
537 }
538
539 pub fn section_header_bytecode(&self) -> Vec<u8> {
540 let flags = SectionHeader::SHF_ALLOC;
541 SectionHeader::new(
542 self.name_offset,
543 SectionHeader::SHT_DYNSYM,
544 flags,
545 self.offset,
546 self.offset,
547 self.size(),
548 5,
549 1,
550 8,
551 24,
552 )
553 .bytecode()
554 }
555}
556
557impl Section for DynSymSection {
558 fn name(&self) -> &str {
559 &self.name
560 }
561
562 fn size(&self) -> u64 {
563 (self.symbols.len() as u64) * 24
565 }
566
567 fn bytecode(&self) -> Vec<u8> {
568 let mut bytes = Vec::new();
569 for symbol in &self.symbols {
570 bytes.extend(symbol.bytecode());
571 }
572 bytes
573 }
574}
575
576#[derive(Debug)]
577pub struct RelDynSection {
578 name: String,
579 name_offset: u32,
580 offset: u64,
581 entries: Vec<RelDyn>,
582}
583
584impl RelDynSection {
585 pub fn new(name_offset: u32, entries: Vec<RelDyn>) -> Self {
586 Self {
587 name: String::from(".rel.dyn"),
588 name_offset,
589 offset: 0,
590 entries,
591 }
592 }
593
594 pub fn set_offset(&mut self, offset: u64) {
595 self.offset = offset;
596 }
597
598 pub fn size(&self) -> u64 {
599 (self.entries.len() * 16) as u64 }
601
602 pub fn section_header_bytecode(&self) -> Vec<u8> {
603 let flags = SectionHeader::SHF_ALLOC;
604 SectionHeader::new(
605 self.name_offset,
606 SectionHeader::SHT_REL,
607 flags,
608 self.offset,
609 self.offset,
610 self.size(),
611 4,
612 0,
613 8,
614 16,
615 )
616 .bytecode()
617 }
618}
619
620impl Section for RelDynSection {
621 fn name(&self) -> &str {
622 &self.name
623 }
624
625 fn size(&self) -> u64 {
626 self.size()
627 }
628
629 fn bytecode(&self) -> Vec<u8> {
630 let mut bytes = Vec::new();
631 for entry in &self.entries {
632 bytes.extend(entry.bytecode());
633 }
634 bytes
635 }
636}
637
638#[derive(Debug)]
639pub enum SectionType {
640 Code(CodeSection),
641 Data(DataSection),
642 ShStrTab(ShStrTabSection),
643 Dynamic(DynamicSection),
644 DynStr(DynStrSection),
645 DynSym(DynSymSection),
646 Default(NullSection),
647 RelDyn(RelDynSection),
648}
649
650impl SectionType {
651 pub fn name(&self) -> &str {
652 match self {
653 SectionType::Code(cs) => &cs.name,
654 SectionType::Data(ds) => &ds.name,
655 SectionType::ShStrTab(ss) => &ss.name,
656 SectionType::Dynamic(ds) => &ds.name,
657 SectionType::DynStr(ds) => &ds.name,
658 SectionType::DynSym(ds) => &ds.name,
659 SectionType::Default(ds) => &ds.name,
660 SectionType::RelDyn(ds) => &ds.name,
661 }
662 }
663
664 pub fn bytecode(&self) -> Vec<u8> {
665 match self {
666 SectionType::Code(cs) => cs.bytecode(),
667 SectionType::Data(ds) => ds.bytecode(),
668 SectionType::ShStrTab(ss) => ss.bytecode(),
669 SectionType::Dynamic(ds) => ds.bytecode(),
670 SectionType::DynStr(ds) => ds.bytecode(),
671 SectionType::DynSym(ds) => ds.bytecode(),
672 SectionType::Default(ds) => ds.bytecode(),
673 SectionType::RelDyn(ds) => ds.bytecode(),
674 }
675 }
676
677 pub fn size(&self) -> u64 {
678 match self {
679 SectionType::Code(cs) => cs.size(),
680 SectionType::Data(ds) => ds.size(),
681 SectionType::ShStrTab(ss) => ss.size(),
682 SectionType::Dynamic(ds) => ds.size(),
683 SectionType::DynStr(ds) => ds.size(),
684 SectionType::DynSym(ds) => ds.size(),
685 SectionType::Default(ds) => ds.size(),
686 SectionType::RelDyn(ds) => ds.size(),
687 }
688 }
689
690 pub fn section_header_bytecode(&self) -> Vec<u8> {
691 match self {
692 SectionType::Code(cs) => cs.section_header_bytecode(),
693 SectionType::Data(ds) => ds.section_header_bytecode(),
694 SectionType::ShStrTab(ss) => ss.section_header_bytecode(),
695 SectionType::Dynamic(ds) => ds.section_header_bytecode(),
696 SectionType::DynStr(ds) => ds.section_header_bytecode(),
697 SectionType::DynSym(ds) => ds.section_header_bytecode(),
698 SectionType::Default(ds) => ds.section_header_bytecode(),
699 SectionType::RelDyn(ds) => ds.section_header_bytecode(),
700 }
701 }
702
703 pub fn set_offset(&mut self, offset: u64) {
704 match self {
705 SectionType::Code(cs) => cs.set_offset(offset),
706 SectionType::Data(ds) => ds.set_offset(offset),
707 SectionType::ShStrTab(ss) => ss.set_offset(offset),
708 SectionType::Dynamic(ds) => ds.set_offset(offset),
709 SectionType::DynStr(ds) => ds.set_offset(offset),
710 SectionType::DynSym(ds) => ds.set_offset(offset),
711 SectionType::RelDyn(ds) => ds.set_offset(offset),
712 SectionType::Default(_) => (), }
714 }
715
716 pub fn offset(&self) -> u64 {
717 match self {
718 SectionType::Code(cs) => cs.offset,
719 SectionType::Data(ds) => ds.offset,
720 SectionType::ShStrTab(ss) => ss.offset,
721 SectionType::Dynamic(ds) => ds.offset,
722 SectionType::DynStr(ds) => ds.offset,
723 SectionType::DynSym(ds) => ds.offset,
724 SectionType::Default(ns) => ns.offset,
725 SectionType::RelDyn(rs) => rs.offset,
726 }
727 }
728}