macho_core/format/
sections.rs1use 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
10pub 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
45pub 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}