use crate::format::constants::*;
use crate::model::addr::ThinFileOffset;
use crate::model::addr::Va;
use crate::model::names::{SectionName, SegmentName};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SectionType {
Regular,
ZeroFill,
CStringLiterals,
FourByteLiterals,
EightByteLiterals,
LiteralPointers,
NonLazySymbolPointers,
LazySymbolPointers,
SymbolStubs,
ModInitFuncPointers,
ModTermFuncPointers,
Coalesced,
GbZeroFill,
Interposing,
SixteenByteLiterals,
DTraceDof,
LazyDylibSymbolPointers,
ThreadLocalRegular,
ThreadLocalZeroFill,
ThreadLocalVariables,
ThreadLocalVariablePointers,
ThreadLocalInitFunctionPointers,
InitFuncOffsets,
Unknown(u8),
}
impl SectionType {
pub fn from_flags(flags: u32) -> Self {
let ty = (flags & SECTION_TYPE_MASK) as u8;
match ty {
S_REGULAR => Self::Regular,
S_ZEROFILL => Self::ZeroFill,
S_CSTRING_LITERALS => Self::CStringLiterals,
S_4BYTE_LITERALS => Self::FourByteLiterals,
S_8BYTE_LITERALS => Self::EightByteLiterals,
S_LITERAL_POINTERS => Self::LiteralPointers,
S_NON_LAZY_SYMBOL_POINTERS => Self::NonLazySymbolPointers,
S_LAZY_SYMBOL_POINTERS => Self::LazySymbolPointers,
S_SYMBOL_STUBS => Self::SymbolStubs,
S_MOD_INIT_FUNC_POINTERS => Self::ModInitFuncPointers,
S_MOD_TERM_FUNC_POINTERS => Self::ModTermFuncPointers,
S_COALESCED => Self::Coalesced,
S_GB_ZEROFILL => Self::GbZeroFill,
S_INTERPOSING => Self::Interposing,
S_16BYTE_LITERALS => Self::SixteenByteLiterals,
S_DTRACE_DOF => Self::DTraceDof,
S_LAZY_DYLIB_SYMBOL_POINTERS => Self::LazyDylibSymbolPointers,
S_THREAD_LOCAL_REGULAR => Self::ThreadLocalRegular,
S_THREAD_LOCAL_ZEROFILL => Self::ThreadLocalZeroFill,
S_THREAD_LOCAL_VARIABLES => Self::ThreadLocalVariables,
S_THREAD_LOCAL_VARIABLE_POINTERS => Self::ThreadLocalVariablePointers,
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => Self::ThreadLocalInitFunctionPointers,
S_INIT_FUNC_OFFSETS => Self::InitFuncOffsets,
other => Self::Unknown(other),
}
}
pub fn name(&self) -> &'static str {
match self {
Self::Regular => "S_REGULAR",
Self::ZeroFill => "S_ZEROFILL",
Self::CStringLiterals => "S_CSTRING_LITERALS",
Self::FourByteLiterals => "S_4BYTE_LITERALS",
Self::EightByteLiterals => "S_8BYTE_LITERALS",
Self::LiteralPointers => "S_LITERAL_POINTERS",
Self::NonLazySymbolPointers => "S_NON_LAZY_SYMBOL_POINTERS",
Self::LazySymbolPointers => "S_LAZY_SYMBOL_POINTERS",
Self::SymbolStubs => "S_SYMBOL_STUBS",
Self::ModInitFuncPointers => "S_MOD_INIT_FUNC_POINTERS",
Self::ModTermFuncPointers => "S_MOD_TERM_FUNC_POINTERS",
Self::Coalesced => "S_COALESCED",
Self::GbZeroFill => "S_GB_ZEROFILL",
Self::Interposing => "S_INTERPOSING",
Self::SixteenByteLiterals => "S_16BYTE_LITERALS",
Self::DTraceDof => "S_DTRACE_DOF",
Self::LazyDylibSymbolPointers => "S_LAZY_DYLIB_SYMBOL_POINTERS",
Self::ThreadLocalRegular => "S_THREAD_LOCAL_REGULAR",
Self::ThreadLocalZeroFill => "S_THREAD_LOCAL_ZEROFILL",
Self::ThreadLocalVariables => "S_THREAD_LOCAL_VARIABLES",
Self::ThreadLocalVariablePointers => "S_THREAD_LOCAL_VARIABLE_POINTERS",
Self::ThreadLocalInitFunctionPointers => "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS",
Self::InitFuncOffsets => "S_INIT_FUNC_OFFSETS",
Self::Unknown(_) => "S_UNKNOWN",
}
}
pub fn is_zerofill(&self) -> bool {
matches!(
self,
Self::ZeroFill | Self::GbZeroFill | Self::ThreadLocalZeroFill
)
}
}
#[derive(Debug, Clone)]
pub struct Section {
pub(crate) segment_name: SegmentName,
pub(crate) section_name: SectionName,
pub(crate) addr: Va,
pub(crate) size: u64,
pub(crate) offset: ThinFileOffset,
pub(crate) align: u32,
pub(crate) reloff: ThinFileOffset,
pub(crate) nreloc: u32,
pub(crate) section_type: SectionType,
pub(crate) attributes: SectionAttributes,
pub(crate) reserved1: u32,
pub(crate) reserved2: u32,
pub(crate) reserved3: u32,
}
impl Section {
pub const fn segment_name(&self) -> &SegmentName {
&self.segment_name
}
pub const fn section_name(&self) -> &SectionName {
&self.section_name
}
pub const fn addr(&self) -> Va {
self.addr
}
pub const fn size(&self) -> u64 {
self.size
}
pub const fn offset(&self) -> ThinFileOffset {
self.offset
}
pub const fn align(&self) -> u32 {
self.align
}
pub const fn relocation_offset(&self) -> ThinFileOffset {
self.reloff
}
pub const fn relocation_count(&self) -> u32 {
self.nreloc
}
pub const fn section_type(&self) -> SectionType {
self.section_type
}
pub const fn attributes(&self) -> SectionAttributes {
self.attributes
}
pub const fn reserved1(&self) -> u32 {
self.reserved1
}
pub const fn reserved2(&self) -> u32 {
self.reserved2
}
pub const fn reserved3(&self) -> u32 {
self.reserved3
}
}