Skip to main content

macho_assembler/formats/executable/
writer.rs

1use crate::{helpers::MachoWriter, types::MachoProgram};
2use gaia_binary::{BinaryWriter, Fixed, LittleEndian};
3use gaia_types::GaiaError;
4use std::io::{Seek, Write};
5
6/// Mach-O 可执行文件写入器
7///
8/// 专门用于写入 Mach-O 可执行文件的写入器。
9#[derive(Debug)]
10pub struct ExecutableWriter<W: Write + Seek> {
11    writer: BinaryWriter<W, Fixed<LittleEndian>>,
12}
13
14impl<W: Write + Seek> ExecutableWriter<W> {
15    /// 创建一个新的可执行文件写入器
16    pub fn new(writer: W) -> Self {
17        Self { writer: BinaryWriter::new(writer) }
18    }
19}
20
21impl<W: Write + Seek> MachoWriter<W> for ExecutableWriter<W> {
22    fn write_program(&mut self, program: &MachoProgram) -> Result<(), GaiaError> {
23        // 写入 Mach-O 文件头
24        self.writer.write_u32(program.header.magic)?;
25        self.writer.write_u32(program.header.cpu_type)?;
26        self.writer.write_u32(program.header.cpu_subtype)?;
27        self.writer.write_u32(program.header.file_type)?;
28        self.writer.write_u32(program.header.ncmds)?;
29        self.writer.write_u32(program.header.sizeofcmds)?;
30        self.writer.write_u32(program.header.flags)?;
31
32        // 如果是64位格式,写入保留字段
33        if let Some(reserved) = program.header.reserved {
34            self.writer.write_u32(reserved)?;
35        }
36
37        // 写入加载命令
38        for load_cmd in &program.load_commands {
39            self.writer.write_u32(load_cmd.cmd)?;
40            self.writer.write_u32(load_cmd.cmdsize)?;
41            self.writer.write_bytes(&load_cmd.data)?;
42        }
43
44        Ok(())
45    }
46
47    fn writer(&mut self) -> &mut BinaryWriter<W, Fixed<LittleEndian>> {
48        &mut self.writer
49    }
50}