macho2/command/
linkedit_data.rs1use nom::{number::complete::le_u32, IResult};
2
3use super::{pad_to_size, LCLoadCommand, LoadCommandBase};
4
5#[derive(Debug, PartialEq, Eq)]
6pub struct LinkeditDataCommand {
7 pub cmd: LCLoadCommand,
8 pub cmdsize: u32,
9 pub dataoff: u32,
10 pub datasize: u32,
11}
12
13impl LinkeditDataCommand {
14 pub fn parse<'a>(ldcmd: &'a [u8]) -> IResult<&'a [u8], Self> {
15 let (cursor, base) = LoadCommandBase::parse(ldcmd)?;
16 let (cursor, dataoff) = le_u32(cursor)?;
17 let (cursor, datasize) = le_u32(cursor)?;
18
19 Ok((
20 cursor,
21 LinkeditDataCommand {
22 cmd: base.cmd,
23 cmdsize: base.cmdsize,
24 dataoff,
25 datasize,
26 },
27 ))
28 }
29
30 pub fn serialize(&self) -> Vec<u8> {
31 let mut buf = Vec::new();
32 buf.extend(self.cmd.serialize());
33 buf.extend(self.cmdsize.to_le_bytes());
34 buf.extend(self.dataoff.to_le_bytes());
35 buf.extend(self.datasize.to_le_bytes());
36 pad_to_size(&mut buf, self.cmdsize as usize);
37 buf
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use crate::command::LCLoadCommand;
45
46 #[test]
47 fn test_linkedit_serialise() {
48 let cmd = LinkeditDataCommand {
49 cmd: LCLoadCommand::LcDyldInfo,
50 cmdsize: 16,
51 dataoff: 0,
52 datasize: 0,
53 };
54
55 let serialized = cmd.serialize();
56 let deserialized = LinkeditDataCommand::parse(&serialized).unwrap().1;
57 assert_eq!(cmd, deserialized);
58 }
59}