atom_macho/load_command/
symtab.rs

1use crate::io::{Endian, ReadExt as _, WriteExt as _};
2use std::io::{Read, Write};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct SymtabCommand {
6    pub cmd: u32,
7    pub cmdsize: u32,
8    /// the byte offset from the start of the file to the location of the
9    /// symbol table entries
10    pub symoff: u32,
11    /// number of symbol table entries
12    pub nsyms: u32,
13    /// the byte offset from the start of the file to the location of the string table.
14    pub stroff: u32,
15    /// the size (in bytes) of the string table.
16    pub strsize: u32,
17}
18
19impl SymtabCommand {
20    pub const TYPE: u32 = 0x2;
21
22    pub const SIZE: u32 = 0x18; // 24
23
24    pub fn read_from_in<R: Read>(read: &mut R, endian: Endian) -> Self {
25        let cmd = read.read_u32_in(endian);
26        assert_eq!(cmd, SymtabCommand::TYPE);
27
28        let cmdsize = read.read_u32_in(endian);
29        assert_eq!(cmdsize, SymtabCommand::SIZE);
30
31        let symoff = read.read_u32_in(endian);
32        let nsyms = read.read_u32_in(endian);
33        let stroff = read.read_u32_in(endian);
34        let strsize = read.read_u32_in(endian);
35
36        SymtabCommand {
37            cmd,
38            cmdsize,
39            symoff,
40            nsyms,
41            stroff,
42            strsize,
43        }
44    }
45
46    pub fn write_into<W: Write>(&self, write: &mut W) {
47        write.write_u32_native(self.cmd);
48        write.write_u32_native(self.cmdsize);
49        write.write_u32_native(self.symoff);
50        write.write_u32_native(self.nsyms);
51        write.write_u32_native(self.stroff);
52        write.write_u32_native(self.strsize);
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn write_and_read_symtab_command() {
62        let cmd = SymtabCommand {
63            cmd: SymtabCommand::TYPE,
64            cmdsize: SymtabCommand::SIZE,
65            symoff: 42,
66            nsyms: 1,
67            stroff: 100,
68            strsize: 7,
69        };
70
71        let mut buf = Vec::new();
72
73        cmd.write_into(&mut buf);
74
75        assert_eq!(buf.len(), SymtabCommand::SIZE as usize);
76
77        let read_cmd = SymtabCommand::read_from_in(&mut buf.as_slice(), Endian::NATIVE);
78
79        assert_eq!(read_cmd, cmd);
80    }
81}