Skip to main content

macho2/command/
routines.rs

1use nom::number::complete::le_u64;
2
3use crate::macho::MachOResult;
4
5use super::{pad_to_size, LCLoadCommand, LoadCommandBase, LoadCommandParser};
6
7#[derive(Debug, PartialEq, Eq)]
8pub struct RoutinesCommand64 {
9    pub cmd: LCLoadCommand,
10    pub cmdsize: u32,
11    pub init_address: u64,
12    pub init_module: u64,
13    pub reserved1: u64,
14    pub reserved2: u64,
15    pub reserved3: u64,
16    pub reserved4: u64,
17    pub reserved5: u64,
18    pub reserved6: u64,
19}
20
21impl LoadCommandParser for RoutinesCommand64 {
22    fn parse(ldcmd: &[u8]) -> MachOResult<Self> {
23        let (cursor, base) = LoadCommandBase::parse(ldcmd)?;
24        let (cursor, init_address) = le_u64(cursor)?;
25        let (cursor, init_module) = le_u64(cursor)?;
26        let (cursor, reserved1) = le_u64(cursor)?;
27        let (cursor, reserved2) = le_u64(cursor)?;
28        let (cursor, reserved3) = le_u64(cursor)?;
29        let (cursor, reserved4) = le_u64(cursor)?;
30        let (cursor, reserved5) = le_u64(cursor)?;
31        let (_, reserved6) = le_u64(cursor)?;
32
33        Ok(
34            RoutinesCommand64 {
35                cmd: base.cmd,
36                cmdsize: base.cmdsize,
37                init_address,
38                init_module,
39                reserved1,
40                reserved2,
41                reserved3,
42                reserved4,
43                reserved5,
44                reserved6,
45            },
46        )
47    }
48
49    fn serialize(&self) -> Vec<u8> {
50        let mut buf = Vec::new();
51        buf.extend(self.cmd.serialize());
52        buf.extend(self.cmdsize.to_le_bytes());
53        buf.extend(self.init_address.to_le_bytes());
54        buf.extend(self.init_module.to_le_bytes());
55        buf.extend(self.reserved1.to_le_bytes());
56        buf.extend(self.reserved2.to_le_bytes());
57        buf.extend(self.reserved3.to_le_bytes());
58        buf.extend(self.reserved4.to_le_bytes());
59        buf.extend(self.reserved5.to_le_bytes());
60        buf.extend(self.reserved6.to_le_bytes());
61        pad_to_size(&mut buf, self.cmdsize as usize);
62        buf
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::command::LCLoadCommand;
70
71    #[test]
72    fn test_routines_command64() {
73        let cmd = RoutinesCommand64 {
74            cmd: LCLoadCommand::LcThread,
75            cmdsize: 72,
76            init_address: 0,
77            init_module: 0,
78            reserved1: 0,
79            reserved2: 0,
80            reserved3: 0,
81            reserved4: 0,
82            reserved5: 0,
83            reserved6: 0,
84        };
85
86        let serialized = cmd.serialize();
87        let deserialized = RoutinesCommand64::parse(&serialized).unwrap();
88        assert_eq!(cmd, deserialized);
89    }
90}