1use bstr::BStr;
7use core::fmt::Debug;
8use core::mem::size_of;
9use static_assertions::const_assert_eq;
10use zerocopy_derive::*;
11
12#[derive(
13 Copy,
14 Clone,
15 Eq,
16 PartialEq,
17 Default,
18 Hash,
19 Ord,
20 PartialOrd,
21 IntoBytes,
22 FromBytes,
23 Immutable,
24 KnownLayout,
25)]
26#[repr(transparent)]
27pub struct SectionCharacteristics(pub u32);
28
29bitflags::bitflags! {
30 impl SectionCharacteristics: u32 {
31 const IMAGE_SCN_TYPE_NO_PAD = 8; const IMAGE_SCN_CNT_CODE = 0x00000020; const IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; const IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080; const IMAGE_SCN_LNK_OTHER = 0x00000100; const IMAGE_SCN_LNK_INFO = 0x00000200; const IMAGE_SCN_LNK_REMOVE = 0x00000800; const IMAGE_SCN_LNK_COMDAT = 0x00001000; const IMAGE_SCN_NO_DEFER_SPEC_EXC = 0x00004000; const IMAGE_SCN_GPREL = 0x00008000; const IMAGE_SCN_MEM_FARDATA = 0x00008000;
55 const IMAGE_SCN_MEM_PURGEABLE = 0x00020000;
57 const IMAGE_SCN_MEM_16BIT = 0x00020000;
58 const IMAGE_SCN_MEM_LOCKED = 0x00040000;
59 const IMAGE_SCN_MEM_PRELOAD = 0x00080000;
60
61 const IMAGE_SCN_ALIGN_1BYTES = 0x00100000; const IMAGE_SCN_ALIGN_2BYTES = 0x00200000; const IMAGE_SCN_ALIGN_4BYTES = 0x00300000; const IMAGE_SCN_ALIGN_8BYTES = 0x00400000; const IMAGE_SCN_ALIGN_16BYTES = 0x00500000; const IMAGE_SCN_ALIGN_32BYTES = 0x00600000; const IMAGE_SCN_ALIGN_64BYTES = 0x00700000; const IMAGE_SCN_ALIGN_128BYTES = 0x00800000; const IMAGE_SCN_ALIGN_256BYTES = 0x00900000; const IMAGE_SCN_ALIGN_512BYTES = 0x00A00000; const IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000; const IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000; const IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000; const IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000; const IMAGE_SCN_ALIGN_MASK = 0x00F00000;
77
78 const IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000; const IMAGE_SCN_MEM_DISCARDABLE = 0x02000000; const IMAGE_SCN_MEM_NOT_CACHED = 0x04000000; const IMAGE_SCN_MEM_NOT_PAGED = 0x08000000; const IMAGE_SCN_MEM_SHARED = 0x10000000; const IMAGE_SCN_MEM_EXECUTE = 0x20000000; const IMAGE_SCN_MEM_READ = 0x40000000; const IMAGE_SCN_MEM_WRITE = 0x80000000; }
87}
88
89impl SectionCharacteristics {
90 pub fn is_read(self) -> bool {
92 self.intersects(Self::IMAGE_SCN_MEM_READ)
93 }
94
95 pub fn is_write(self) -> bool {
97 self.intersects(Self::IMAGE_SCN_MEM_WRITE)
98 }
99
100 pub fn is_exec(self) -> bool {
102 self.intersects(Self::IMAGE_SCN_MEM_EXECUTE)
103 }
104}
105
106impl Debug for SectionCharacteristics {
107 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
108 write!(f, "[{:08x}", self.0)?;
109
110 write!(f, "]")
111 }
112}
113
114pub const IMAGE_SIZEOF_SHORT_NAME: usize = 8;
115
116#[allow(non_camel_case_types)]
117#[repr(C)]
118#[derive(
119 Clone,
120 Default,
121 Eq,
122 PartialEq,
123 Ord,
124 PartialOrd,
125 Hash,
126 FromBytes,
127 IntoBytes,
128 Immutable,
129 KnownLayout,
130)]
131pub struct IMAGE_SECTION_HEADER {
132 pub name: [u8; IMAGE_SIZEOF_SHORT_NAME],
133 pub physical_address_or_virtual_size: u32,
134 pub virtual_address: u32,
135 pub size_of_raw_data: u32,
136 pub pointer_to_raw_data: u32,
137 pub pointer_to_relocations: u32,
138 pub pointer_to_linenumbers: u32,
139 pub number_of_relocations: u16,
140 pub number_of_linenumbers: u16,
141 pub characteristics: SectionCharacteristics,
142}
143
144impl IMAGE_SECTION_HEADER {
145 pub fn name(&self) -> &BStr {
146 BStr::new(if let Some(i) = self.name.iter().position(|&b| b == 0) {
147 &self.name[..i]
148 } else {
149 &self.name
150 })
151 }
152}
153
154pub const IMAGE_SIZEOF_SECTION_HEADER: usize = 40;
155
156const_assert_eq!(
157 size_of::<IMAGE_SECTION_HEADER>(),
158 IMAGE_SIZEOF_SECTION_HEADER
159);