macho_assembler/builder/
executable_builder.rs1use crate::types::{MachoHeader, MachoProgram, LoadCommand, CpuType, MachoType};
2use gaia_types::GaiaError;
3
4#[derive(Debug)]
8pub struct ExecutableBuilder {
9 header: MachoHeader,
10 load_commands: Vec<LoadCommand>,
11 entry_point: Option<u64>,
12}
13
14impl ExecutableBuilder {
15 pub fn new(cpu_type: CpuType) -> Self {
17 let header = MachoHeader {
18 magic: match cpu_type {
19 CpuType::X86_64 | CpuType::Arm64 => 0xfeedfacf, _ => 0xfeedface, },
22 cpu_type: cpu_type as u32,
23 cpu_subtype: 0,
24 file_type: MachoType::Execute as u32,
25 ncmds: 0,
26 sizeofcmds: 0,
27 flags: 0,
28 reserved: match cpu_type {
29 CpuType::X86_64 | CpuType::Arm64 => Some(0),
30 _ => None,
31 },
32 };
33
34 Self {
35 header,
36 load_commands: Vec::new(),
37 entry_point: None,
38 }
39 }
40
41 pub fn set_entry_point(&mut self, entry_point: u64) -> &mut Self {
43 self.entry_point = Some(entry_point);
44 self
45 }
46
47 pub fn add_load_command(&mut self, cmd: u32, data: Vec<u8>) -> &mut Self {
49 let cmdsize = 8 + data.len() as u32; let load_cmd = LoadCommand {
51 cmd,
52 cmdsize,
53 data,
54 };
55
56 self.load_commands.push(load_cmd);
57 self.header.ncmds += 1;
58 self.header.sizeofcmds += cmdsize;
59
60 self
61 }
62
63 pub fn set_flags(&mut self, flags: u32) -> &mut Self {
65 self.header.flags = flags;
66 self
67 }
68
69 pub fn build(self) -> Result<MachoProgram, GaiaError> {
71 Ok(MachoProgram {
72 header: self.header,
73 load_commands: self.load_commands,
74 segments: Vec::new(),
75 sections: Vec::new(),
76 })
77 }
78}
79
80impl Default for ExecutableBuilder {
81 fn default() -> Self {
82 Self::new(CpuType::X86_64)
83 }
84}