1use std::{fmt, mem, ops, slice};
2use crate::image::*;
3use crate::Pod;
4
5#[derive(Copy, Clone)]
9#[repr(transparent)]
10pub struct SectionHeader(IMAGE_SECTION_HEADER);
11
12impl SectionHeader {
13 #[inline]
15 pub fn name_bytes(&self) -> &[u8] {
16 crate::util::trimn(&self.0.Name)
17 }
18 pub fn name(&self) -> Result<&str, &[u8]> {
20 crate::util::parsen(&self.0.Name)
21 }
22 #[inline]
24 pub fn virtual_range(&self) -> std::ops::Range<u32> {
25 let start = self.0.VirtualAddress;
26 let end = u32::wrapping_add(self.0.VirtualAddress, self.0.VirtualSize);
27 start..end
28 }
29 #[inline]
31 pub fn file_range(&self) -> std::ops::Range<u32> {
32 let start = self.0.PointerToRawData;
33 let end = u32::wrapping_add(self.0.PointerToRawData, self.0.SizeOfRawData);
34 start..end
35 }
36}
37
38unsafe impl Pod for SectionHeader {}
39
40impl ops::Deref for SectionHeader {
41 type Target = IMAGE_SECTION_HEADER;
42 #[inline]
43 fn deref(&self) -> &IMAGE_SECTION_HEADER {
44 &self.0
45 }
46}
47
48impl fmt::Debug for SectionHeader {
49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 let name = self.name();
51 let name = match &name {
52 Ok(name) => name as &dyn fmt::Debug,
53 Err(name) => name as &dyn fmt::Debug,
54 };
55 f.debug_struct("SectionHeader")
56 .field("Name", name)
57 .field("VirtualAddress", &format_args!("{:#x}", self.0.VirtualAddress))
58 .field("VirtualSize", &format_args!("{:#x}", self.0.VirtualSize))
59 .field("PointerToRawData", &format_args!("{:#x}", self.0.PointerToRawData))
60 .field("SizeOfRawData", &format_args!("{:#x}", self.0.SizeOfRawData))
61 .field("Characteristics", &format_args!("{:#x}", self.0.Characteristics))
62 .finish()
63 }
64}
65
66#[repr(transparent)]
70pub struct SectionHeaders([IMAGE_SECTION_HEADER]);
71
72impl SectionHeaders {
73 pub(crate) fn new(image: &[IMAGE_SECTION_HEADER]) -> &SectionHeaders {
74 unsafe { mem::transmute(image) }
75 }
76 #[inline]
78 pub fn image(&self) -> &[IMAGE_SECTION_HEADER] {
79 &self.0
80 }
81 #[inline]
83 pub fn as_slice(&self) -> &[SectionHeader] {
84 unsafe { mem::transmute(self) }
85 }
86 #[inline]
88 pub fn iter(&self) -> slice::Iter<'_, SectionHeader> {
89 self.as_slice().iter()
90 }
91 #[inline]
93 pub fn by_name<S: ?Sized + AsRef<[u8]>>(&self, name: &S) -> Option<&SectionHeader> {
94 let name = name.as_ref();
96 if name.len() > IMAGE_SIZEOF_SHORT_NAME {
97 return None;
98 }
99 let mut name_buf = [0u8; IMAGE_SIZEOF_SHORT_NAME];
101 for i in 0..name.len() {
102 name_buf[i] = name[i];
103 }
104 for sect in self.iter() {
105 if sect.0.Name == name_buf {
106 return Some(sect);
107 }
108 }
109 None
110 }
111 #[inline]
113 pub fn by_rva(&self, rva: u32) -> Option<&SectionHeader> {
114 for sect in self.iter() {
115 if rva >= sect.VirtualAddress && rva < u32::wrapping_add(sect.VirtualAddress, sect.VirtualSize) {
117 return Some(sect);
118 }
119 }
120 None
121 }
122}
123
124unsafe impl Pod for SectionHeaders {}
125
126impl<'a> IntoIterator for &'a SectionHeaders {
127 type Item = &'a SectionHeader;
128 type IntoIter = slice::Iter<'a, SectionHeader>;
129 fn into_iter(self) -> Self::IntoIter {
130 self.as_slice().into_iter()
131 }
132}
133
134impl fmt::Debug for SectionHeaders {
135 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136 self.as_slice().fmt(f)
137 }
138}
139
140#[cfg(feature = "serde")]
143pub(crate) fn serialize_name<S: ::serde::ser::Serializer>(name: &[u8; IMAGE_SIZEOF_SHORT_NAME], serializer: S) -> Result<S::Ok, S::Error> {
144 match crate::util::parsen(name) {
145 Ok(name) => serializer.serialize_str(name),
146 Err(name) => serializer.serialize_bytes(name),
147 }
148}
149
150#[cfg(feature = "serde")]
151mod serde {
152 use crate::util::serde_helper::*;
153 use super::{SectionHeader, SectionHeaders};
154
155 impl serde::Serialize for SectionHeaders {
156 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
157 serializer.collect_seq(self.iter())
158 }
159 }
160
161 impl serde::Serialize for SectionHeader {
162 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
163 self.0.serialize(serializer)
164 }
165 }
166}