macho_assembler/builder/
executable_builder.rs1use crate::types::{CpuType, LoadCommand, MachoHeader, MachoProgram, 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 { header, load_commands: Vec::new(), entry_point: None }
35 }
36
37 pub fn set_entry_point(&mut self, entry_point: u64) -> &mut Self {
39 self.entry_point = Some(entry_point);
40 self
41 }
42
43 pub fn add_load_command(&mut self, cmd: u32, data: Vec<u8>) -> &mut Self {
45 let cmdsize = 8 + data.len() as u32; let load_cmd = LoadCommand { cmd, cmdsize, data };
47
48 self.load_commands.push(load_cmd);
49 self.header.ncmds += 1;
50 self.header.sizeofcmds += cmdsize;
51
52 self
53 }
54
55 pub fn set_flags(&mut self, flags: u32) -> &mut Self {
57 self.header.flags = flags;
58 self
59 }
60
61 pub fn build(self) -> Result<MachoProgram, GaiaError> {
63 Ok(MachoProgram { header: self.header, load_commands: self.load_commands, segments: Vec::new(), sections: Vec::new() })
64 }
65}
66
67impl Default for ExecutableBuilder {
68 fn default() -> Self {
69 Self::new(CpuType::X86_64)
70 }
71}