Skip to main content

macho_assembler/formats/object/
writer.rs

1use crate::{
2    helpers::MachoWriter,
3    types::{LoadCommand, MachoHeader, MachoProgram},
4};
5use gaia_binary::{BinaryWriter, Fixed, LittleEndian};
6use gaia_types::GaiaError;
7use std::io::Write;
8
9/// Mach-O 目标文件写入器
10#[derive(Debug)]
11pub struct ObjectWriter<W: Write> {
12    writer: BinaryWriter<W, Fixed<LittleEndian>>,
13}
14
15impl<W: Write> ObjectWriter<W> {
16    /// 创建一个新的目标文件写入器
17    pub fn new(writer: BinaryWriter<W, Fixed<LittleEndian>>) -> Self {
18        Self { writer }
19    }
20
21    /// 写入目标文件头
22    pub fn write_header(&mut self, header: &MachoHeader) -> Result<(), GaiaError> {
23        self.writer.write_u32(header.magic)?;
24        self.writer.write_u32(header.cpu_type)?;
25        self.writer.write_u32(header.cpu_subtype)?;
26        self.writer.write_u32(header.file_type)?;
27        self.writer.write_u32(header.ncmds)?;
28        self.writer.write_u32(header.sizeofcmds)?;
29        self.writer.write_u32(header.flags)?;
30
31        if let Some(reserved) = header.reserved {
32            self.writer.write_u32(reserved)?;
33        }
34
35        Ok(())
36    }
37
38    /// 写入加载命令
39    pub fn write_load_commands(&mut self, load_commands: &[LoadCommand]) -> Result<(), GaiaError> {
40        for cmd in load_commands {
41            self.writer.write_u32(cmd.cmd)?;
42            self.writer.write_u32(cmd.cmdsize)?;
43            self.writer.write_bytes(&cmd.data)?;
44        }
45        Ok(())
46    }
47}
48
49impl<W: Write> MachoWriter<W> for ObjectWriter<W> {
50    fn write_program(&mut self, program: &MachoProgram) -> Result<(), GaiaError> {
51        self.write_header(&program.header)?;
52        self.write_load_commands(&program.load_commands)?;
53        Ok(())
54    }
55
56    fn writer(&mut self) -> &mut BinaryWriter<W, Fixed<LittleEndian>> {
57        &mut self.writer
58    }
59}