macho_assembler/builder/
dylib_builder.rs1use crate::types::{CpuType, LoadCommand, MachoHeader, MachoProgram, MachoType};
2use gaia_types::GaiaError;
3
4#[derive(Debug)]
8pub struct DylibBuilder {
9 header: MachoHeader,
10 load_commands: Vec<LoadCommand>,
11}
12
13impl DylibBuilder {
14 pub fn new(cpu_type: CpuType) -> Self {
16 let header = MachoHeader {
17 magic: match cpu_type {
18 CpuType::X86_64 | CpuType::Arm64 => 0xfeedfacf, _ => 0xfeedface, },
21 cpu_type: cpu_type as u32,
22 cpu_subtype: 0,
23 file_type: MachoType::Dylib as u32,
24 ncmds: 0,
25 sizeofcmds: 0,
26 flags: 0,
27 reserved: match cpu_type {
28 CpuType::X86_64 | CpuType::Arm64 => Some(0),
29 _ => None,
30 },
31 };
32
33 Self { header, load_commands: Vec::new() }
34 }
35
36 pub fn add_load_command(mut self, cmd: u32, data: Vec<u8>) -> Self {
38 let cmdsize = 8 + data.len() as u32; let load_cmd = LoadCommand { cmd, cmdsize, data };
40
41 self.load_commands.push(load_cmd);
42 self.header.ncmds += 1;
43 self.header.sizeofcmds += cmdsize;
44
45 self
46 }
47
48 pub fn set_flags(mut self, flags: u32) -> Self {
50 self.header.flags = flags;
51 self
52 }
53
54 pub fn build(self) -> Result<MachoProgram, GaiaError> {
56 Ok(MachoProgram { header: self.header, load_commands: self.load_commands, segments: Vec::new(), sections: Vec::new() })
57 }
58}
59
60impl Default for DylibBuilder {
61 fn default() -> Self {
62 Self::new(CpuType::X86_64)
63 }
64}