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)]
7pub enum SectionType {
9 Regular,
11 ZeroFill,
13 CStringLiterals,
15 FourByteLiterals,
17 EightByteLiterals,
19 LiteralPointers,
21 NonLazySymbolPointers,
23 LazySymbolPointers,
25 SymbolStubs,
27 ModInitFuncPointers,
29 ModTermFuncPointers,
31 Coalesced,
33 GbZeroFill,
35 Interposing,
37 SixteenByteLiterals,
39 DTraceDof,
41 LazyDylibSymbolPointers,
43 ThreadLocalRegular,
45 ThreadLocalZeroFill,
47 ThreadLocalVariables,
49 ThreadLocalVariablePointers,
51 ThreadLocalInitFunctionPointers,
53 InitFuncOffsets,
55 Unknown(u8),
57}
58
59impl SectionType {
60 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 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 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)]
131pub 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 pub const fn segment_name(&self) -> &SegmentName {
151 &self.segment_name
152 }
153 pub const fn section_name(&self) -> &SectionName {
155 &self.section_name
156 }
157 pub const fn addr(&self) -> Va {
159 self.addr
160 }
161 pub const fn size(&self) -> u64 {
163 self.size
164 }
165 pub const fn offset(&self) -> ThinFileOffset {
167 self.offset
168 }
169 pub const fn align(&self) -> u32 {
171 self.align
172 }
173 pub const fn relocation_offset(&self) -> ThinFileOffset {
175 self.reloff
176 }
177 pub const fn relocation_count(&self) -> u32 {
179 self.nreloc
180 }
181 pub const fn section_type(&self) -> SectionType {
183 self.section_type
184 }
185 pub const fn attributes(&self) -> SectionAttributes {
187 self.attributes
188 }
189 pub const fn reserved1(&self) -> u32 {
191 self.reserved1
192 }
193 pub const fn reserved2(&self) -> u32 {
195 self.reserved2
196 }
197 pub const fn reserved3(&self) -> u32 {
199 self.reserved3
200 }
201}