Skip to main content

macho_core/format/
sections.rs

1use crate::error::Result;
2use crate::format::constants::{SECTION_ATTRIBUTES_MASK, SectionAttributes};
3use crate::format::io::endian::Endian;
4use crate::format::io::pod::{self, RawSection32, RawSection64};
5use crate::model::addr::ThinFileOffset;
6use crate::model::addr::Va;
7use crate::model::names::{SectionName, SegmentName};
8use crate::model::section::{Section, SectionType};
9
10/// Performs parse_sections_32.
11pub fn parse_sections_32(
12    data: &[u8],
13    endian: Endian,
14    offset: usize,
15    count: u32,
16) -> Result<Vec<Section>> {
17    let sect_size = size_of::<RawSection32>();
18    let max_sects = data.len().saturating_sub(offset) / sect_size;
19    let mut sections = Vec::with_capacity((count as usize).min(max_sects));
20
21    for i in 0..count as usize {
22        let raw: RawSection32 = pod::read_pod(data, offset + i * sect_size)?;
23        let flags = endian.interpret_u32(raw.flags);
24
25        sections.push(Section {
26            section_name: SectionName::from_bytes(raw.sectname),
27            segment_name: SegmentName::from_bytes(raw.segname),
28            addr: Va(endian.interpret_u32(raw.addr) as u64),
29            size: endian.interpret_u32(raw.size) as u64,
30            offset: ThinFileOffset(endian.interpret_u32(raw.offset) as u64),
31            align: endian.interpret_u32(raw.align),
32            reloff: ThinFileOffset(endian.interpret_u32(raw.reloff) as u64),
33            nreloc: endian.interpret_u32(raw.nreloc),
34            section_type: SectionType::from_flags(flags),
35            attributes: SectionAttributes::from_bits_truncate(flags & SECTION_ATTRIBUTES_MASK),
36            reserved1: endian.interpret_u32(raw.reserved1),
37            reserved2: endian.interpret_u32(raw.reserved2),
38            reserved3: 0,
39        });
40    }
41
42    Ok(sections)
43}
44
45/// Performs parse_sections_64.
46pub fn parse_sections_64(
47    data: &[u8],
48    endian: Endian,
49    offset: usize,
50    count: u32,
51) -> Result<Vec<Section>> {
52    let sect_size = size_of::<RawSection64>();
53    let max_sects = data.len().saturating_sub(offset) / sect_size;
54    let mut sections = Vec::with_capacity((count as usize).min(max_sects));
55
56    for i in 0..count as usize {
57        let raw: RawSection64 = pod::read_pod(data, offset + i * sect_size)?;
58        let flags = endian.interpret_u32(raw.flags);
59
60        sections.push(Section {
61            section_name: SectionName::from_bytes(raw.sectname),
62            segment_name: SegmentName::from_bytes(raw.segname),
63            addr: Va(endian.interpret_u64(raw.addr)),
64            size: endian.interpret_u64(raw.size),
65            offset: ThinFileOffset(endian.interpret_u32(raw.offset) as u64),
66            align: endian.interpret_u32(raw.align),
67            reloff: ThinFileOffset(endian.interpret_u32(raw.reloff) as u64),
68            nreloc: endian.interpret_u32(raw.nreloc),
69            section_type: SectionType::from_flags(flags),
70            attributes: SectionAttributes::from_bits_truncate(flags & SECTION_ATTRIBUTES_MASK),
71            reserved1: endian.interpret_u32(raw.reserved1),
72            reserved2: endian.interpret_u32(raw.reserved2),
73            reserved3: endian.interpret_u32(raw.reserved3),
74        });
75    }
76
77    Ok(sections)
78}