macho_assembler/builder/
executable_builder.rs

1use crate::types::{MachoHeader, MachoProgram, LoadCommand, CpuType, MachoType};
2use gaia_types::GaiaError;
3
4/// Mach-O 可执行文件构建器
5///
6/// 提供了构建 Mach-O 可执行文件的高级接口。
7#[derive(Debug)]
8pub struct ExecutableBuilder {
9    header: MachoHeader,
10    load_commands: Vec<LoadCommand>,
11    entry_point: Option<u64>,
12}
13
14impl ExecutableBuilder {
15    /// 创建一个新的可执行文件构建器
16    pub fn new(cpu_type: CpuType) -> Self {
17        let header = MachoHeader {
18            magic: match cpu_type {
19                CpuType::X86_64 | CpuType::Arm64 => 0xfeedfacf, // MH_MAGIC_64
20                _ => 0xfeedface, // MH_MAGIC
21            },
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    /// 设置程序入口点
42    pub fn set_entry_point(&mut self, entry_point: u64) -> &mut Self {
43        self.entry_point = Some(entry_point);
44        self
45    }
46
47    /// 添加一个加载命令
48    pub fn add_load_command(&mut self, cmd: u32, data: Vec<u8>) -> &mut Self {
49        let cmdsize = 8 + data.len() as u32; // cmd + cmdsize + data
50        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    /// 设置文件标志
64    pub fn set_flags(&mut self, flags: u32) -> &mut Self {
65        self.header.flags = flags;
66        self
67    }
68
69    /// 构建 MachoProgram
70    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}