Skip to main content

macho_core/model/
section.rs

1use crate::format::constants::*;
2use crate::model::addr::ThinFileOffset;
3use crate::model::addr::Va;
4use crate::model::names::{SectionName, SegmentName};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7/// The SectionType type.
8pub enum SectionType {
9    /// The Regular variant.
10    Regular,
11    /// The ZeroFill variant.
12    ZeroFill,
13    /// The CStringLiterals variant.
14    CStringLiterals,
15    /// The FourByteLiterals variant.
16    FourByteLiterals,
17    /// The EightByteLiterals variant.
18    EightByteLiterals,
19    /// The LiteralPointers variant.
20    LiteralPointers,
21    /// The NonLazySymbolPointers variant.
22    NonLazySymbolPointers,
23    /// The LazySymbolPointers variant.
24    LazySymbolPointers,
25    /// The SymbolStubs variant.
26    SymbolStubs,
27    /// The ModInitFuncPointers variant.
28    ModInitFuncPointers,
29    /// The ModTermFuncPointers variant.
30    ModTermFuncPointers,
31    /// The Coalesced variant.
32    Coalesced,
33    /// The GbZeroFill variant.
34    GbZeroFill,
35    /// The Interposing variant.
36    Interposing,
37    /// The SixteenByteLiterals variant.
38    SixteenByteLiterals,
39    /// The DTraceDof variant.
40    DTraceDof,
41    /// The LazyDylibSymbolPointers variant.
42    LazyDylibSymbolPointers,
43    /// The ThreadLocalRegular variant.
44    ThreadLocalRegular,
45    /// The ThreadLocalZeroFill variant.
46    ThreadLocalZeroFill,
47    /// The ThreadLocalVariables variant.
48    ThreadLocalVariables,
49    /// The ThreadLocalVariablePointers variant.
50    ThreadLocalVariablePointers,
51    /// The ThreadLocalInitFunctionPointers variant.
52    ThreadLocalInitFunctionPointers,
53    /// The InitFuncOffsets variant.
54    InitFuncOffsets,
55    /// The Unknown variant.
56    Unknown(u8),
57}
58
59impl SectionType {
60    /// Performs from_flags.
61    pub fn from_flags(flags: u32) -> Self {
62        let ty = (flags & SECTION_TYPE_MASK) as u8;
63        match ty {
64            S_REGULAR => Self::Regular,
65            S_ZEROFILL => Self::ZeroFill,
66            S_CSTRING_LITERALS => Self::CStringLiterals,
67            S_4BYTE_LITERALS => Self::FourByteLiterals,
68            S_8BYTE_LITERALS => Self::EightByteLiterals,
69            S_LITERAL_POINTERS => Self::LiteralPointers,
70            S_NON_LAZY_SYMBOL_POINTERS => Self::NonLazySymbolPointers,
71            S_LAZY_SYMBOL_POINTERS => Self::LazySymbolPointers,
72            S_SYMBOL_STUBS => Self::SymbolStubs,
73            S_MOD_INIT_FUNC_POINTERS => Self::ModInitFuncPointers,
74            S_MOD_TERM_FUNC_POINTERS => Self::ModTermFuncPointers,
75            S_COALESCED => Self::Coalesced,
76            S_GB_ZEROFILL => Self::GbZeroFill,
77            S_INTERPOSING => Self::Interposing,
78            S_16BYTE_LITERALS => Self::SixteenByteLiterals,
79            S_DTRACE_DOF => Self::DTraceDof,
80            S_LAZY_DYLIB_SYMBOL_POINTERS => Self::LazyDylibSymbolPointers,
81            S_THREAD_LOCAL_REGULAR => Self::ThreadLocalRegular,
82            S_THREAD_LOCAL_ZEROFILL => Self::ThreadLocalZeroFill,
83            S_THREAD_LOCAL_VARIABLES => Self::ThreadLocalVariables,
84            S_THREAD_LOCAL_VARIABLE_POINTERS => Self::ThreadLocalVariablePointers,
85            S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => Self::ThreadLocalInitFunctionPointers,
86            S_INIT_FUNC_OFFSETS => Self::InitFuncOffsets,
87            other => Self::Unknown(other),
88        }
89    }
90
91    /// Performs name.
92    pub fn name(&self) -> &'static str {
93        match self {
94            Self::Regular => "S_REGULAR",
95            Self::ZeroFill => "S_ZEROFILL",
96            Self::CStringLiterals => "S_CSTRING_LITERALS",
97            Self::FourByteLiterals => "S_4BYTE_LITERALS",
98            Self::EightByteLiterals => "S_8BYTE_LITERALS",
99            Self::LiteralPointers => "S_LITERAL_POINTERS",
100            Self::NonLazySymbolPointers => "S_NON_LAZY_SYMBOL_POINTERS",
101            Self::LazySymbolPointers => "S_LAZY_SYMBOL_POINTERS",
102            Self::SymbolStubs => "S_SYMBOL_STUBS",
103            Self::ModInitFuncPointers => "S_MOD_INIT_FUNC_POINTERS",
104            Self::ModTermFuncPointers => "S_MOD_TERM_FUNC_POINTERS",
105            Self::Coalesced => "S_COALESCED",
106            Self::GbZeroFill => "S_GB_ZEROFILL",
107            Self::Interposing => "S_INTERPOSING",
108            Self::SixteenByteLiterals => "S_16BYTE_LITERALS",
109            Self::DTraceDof => "S_DTRACE_DOF",
110            Self::LazyDylibSymbolPointers => "S_LAZY_DYLIB_SYMBOL_POINTERS",
111            Self::ThreadLocalRegular => "S_THREAD_LOCAL_REGULAR",
112            Self::ThreadLocalZeroFill => "S_THREAD_LOCAL_ZEROFILL",
113            Self::ThreadLocalVariables => "S_THREAD_LOCAL_VARIABLES",
114            Self::ThreadLocalVariablePointers => "S_THREAD_LOCAL_VARIABLE_POINTERS",
115            Self::ThreadLocalInitFunctionPointers => "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS",
116            Self::InitFuncOffsets => "S_INIT_FUNC_OFFSETS",
117            Self::Unknown(_) => "S_UNKNOWN",
118        }
119    }
120
121    /// Performs is_zerofill.
122    pub fn is_zerofill(&self) -> bool {
123        matches!(
124            self,
125            Self::ZeroFill | Self::GbZeroFill | Self::ThreadLocalZeroFill
126        )
127    }
128}
129
130#[derive(Debug, Clone)]
131/// The Section type.
132pub struct Section {
133    pub(crate) segment_name: SegmentName,
134    pub(crate) section_name: SectionName,
135    pub(crate) addr: Va,
136    pub(crate) size: u64,
137    pub(crate) offset: ThinFileOffset,
138    pub(crate) align: u32,
139    pub(crate) reloff: ThinFileOffset,
140    pub(crate) nreloc: u32,
141    pub(crate) section_type: SectionType,
142    pub(crate) attributes: SectionAttributes,
143    pub(crate) reserved1: u32,
144    pub(crate) reserved2: u32,
145    pub(crate) reserved3: u32,
146}
147
148impl Section {
149    /// Fixed-width containing segment name.
150    pub const fn segment_name(&self) -> &SegmentName {
151        &self.segment_name
152    }
153    /// Fixed-width section name.
154    pub const fn section_name(&self) -> &SectionName {
155        &self.section_name
156    }
157    /// Section virtual start address.
158    pub const fn addr(&self) -> Va {
159        self.addr
160    }
161    /// Section virtual size in bytes.
162    pub const fn size(&self) -> u64 {
163        self.size
164    }
165    /// Slice-relative file offset.
166    pub const fn offset(&self) -> ThinFileOffset {
167        self.offset
168    }
169    /// Base-two alignment exponent.
170    pub const fn align(&self) -> u32 {
171        self.align
172    }
173    /// Slice-relative relocation-table offset.
174    pub const fn relocation_offset(&self) -> ThinFileOffset {
175        self.reloff
176    }
177    /// Number of relocation records.
178    pub const fn relocation_count(&self) -> u32 {
179        self.nreloc
180    }
181    /// Decoded section type.
182    pub const fn section_type(&self) -> SectionType {
183        self.section_type
184    }
185    /// Parsed section attributes.
186    pub const fn attributes(&self) -> SectionAttributes {
187        self.attributes
188    }
189    /// First type-specific reserved word.
190    pub const fn reserved1(&self) -> u32 {
191        self.reserved1
192    }
193    /// Second type-specific reserved word.
194    pub const fn reserved2(&self) -> u32 {
195        self.reserved2
196    }
197    /// Third type-specific reserved word.
198    pub const fn reserved3(&self) -> u32 {
199        self.reserved3
200    }
201}