1use crate::*;
2use super::Wrap;
3
4impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::debug::Debug<'a, Pe32>, pe64::debug::Debug<'a, Pe64>> {
6 #[inline]
8 pub fn pe(&self) -> Wrap<Pe32, Pe64> {
9 match self {
10 Wrap::T32(debug) => Wrap::T32(debug.pe()),
11 Wrap::T64(debug) => Wrap::T64(debug.pe()),
12 }
13 }
14 #[inline]
16 pub fn image(&self) -> &'a [image::IMAGE_DEBUG_DIRECTORY] {
17 match self {
18 Wrap::T32(debug) => debug.image(),
19 Wrap::T64(debug) => debug.image(),
20 }
21 }
22 #[inline]
24 pub fn pdb_file_name(&self) -> Option<&'a util::CStr> {
25 match self {
26 Wrap::T32(debug) => debug.pdb_file_name(),
27 Wrap::T64(debug) => debug.pdb_file_name(),
28 }
29 }
30 #[inline]
32 pub fn iter(&self) -> Wrap<pe32::debug::Iter<'a, Pe32>, pe64::debug::Iter<'a, Pe64>> {
33 match self {
34 Wrap::T32(debug) => Wrap::T32(debug.iter()),
35 Wrap::T64(debug) => Wrap::T64(debug.iter()),
36 }
37 }
38}
39
40impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> IntoIterator for Wrap<pe32::debug::Debug<'a, Pe32>, pe64::debug::Debug<'a, Pe64>> {
41 type Item = Wrap<pe32::debug::Dir<'a, Pe32>, pe64::debug::Dir<'a, Pe64>>;
42 type IntoIter = Wrap<pe32::debug::Iter<'a, Pe32>, pe64::debug::Iter<'a, Pe64>>;
43 #[inline]
44 fn into_iter(self) -> Self::IntoIter {
45 self.iter()
46 }
47}
48
49impl<'a, Pe32: pe32::Pe<'a>, Pe64: pe64::Pe<'a>> Wrap<pe32::debug::Dir<'a, Pe32>, pe64::debug::Dir<'a, Pe64>> {
51 #[inline]
53 pub fn pe(&self) -> Wrap<Pe32, Pe64> {
54 match self {
55 Wrap::T32(dir) => Wrap::T32(dir.pe()),
56 Wrap::T64(dir) => Wrap::T64(dir.pe()),
57 }
58 }
59 #[inline]
61 pub fn image(&self) -> &'a image::IMAGE_DEBUG_DIRECTORY {
62 match self {
63 Wrap::T32(dir) => dir.image(),
64 Wrap::T64(dir) => dir.image(),
65 }
66 }
67 #[inline]
69 pub fn data(&self) -> Option<&'a [u8]> {
70 match self {
71 Wrap::T32(dir) => dir.data(),
72 Wrap::T64(dir) => dir.data(),
73 }
74 }
75 #[inline]
77 pub fn entry(&self) -> Result<Entry<'a>> {
78 match self {
79 Wrap::T32(dir) => dir.entry(),
80 Wrap::T64(dir) => dir.entry(),
81 }
82 }
83}
84
85#[derive(Copy, Clone, Debug)]
88#[cfg_attr(feature = "serde", derive(::serde::Serialize), serde(untagged))]
89pub enum Entry<'a> {
90 CodeView(CodeView<'a>),
91 Dbg(Dbg<'a>),
92 Pgo(Pgo<'a>),
93 Unknown(Option<&'a [u8]>),
94}
95impl<'a> Entry<'a> {
96 pub fn as_code_view(self) -> Option<CodeView<'a>> {
98 match self { Entry::CodeView(cv) => Some(cv), _ => None }
99 }
100 pub fn as_dbg(self) -> Option<Dbg<'a>> {
102 match self { Entry::Dbg(dbg) => Some(dbg), _ => None }
103 }
104 pub fn as_pgo(self) -> Option<Pgo<'a>> {
106 match self { Entry::Pgo(pgo) => Some(pgo), _ => None }
107 }
108 pub fn as_unknown(self) -> Option<&'a [u8]> {
110 match self { Entry::Unknown(data) => data, _ => None }
111 }
112}
113
114use std::{fmt, str};
117use crate::image::*;
118use crate::util::CStr;
119
120#[derive(Copy, Clone)]
122pub enum CodeView<'a> {
123 Cv20 { image: &'a IMAGE_DEBUG_CV_INFO_PDB20, pdb_file_name: &'a CStr },
125 Cv70 { image: &'a IMAGE_DEBUG_CV_INFO_PDB70, pdb_file_name: &'a CStr },
127}
128impl<'a> CodeView<'a> {
129 pub fn format(&self) -> &'a str {
130 let cv_signature = match self {
131 CodeView::Cv20 { image, .. } => &image.CvSignature,
132 CodeView::Cv70 { image, .. } => &image.CvSignature,
133 } as *const _ as *const [u8; 4];
134 unsafe { str::from_utf8_unchecked(&*cv_signature) }
135 }
136 pub fn age(&self) -> u32 {
137 match self {
138 CodeView::Cv20 { image, .. } => image.Age,
139 CodeView::Cv70 { image, .. } => image.Age,
140 }
141 }
142 pub fn pdb_file_name(&self) -> &'a CStr {
143 match self {
144 CodeView::Cv20 { pdb_file_name, .. } => pdb_file_name,
145 CodeView::Cv70 { pdb_file_name, .. } => pdb_file_name,
146 }
147 }
148}
149impl<'a> fmt::Debug for CodeView<'a> {
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151 let mut stru = f.debug_struct("CodeView");
152 stru.field("format", &self.format());
153 stru.field("pdb_file_name", &self.pdb_file_name());
154 match self {
155 CodeView::Cv20 { image, .. } => {
156 stru.field("time_date_stamp", &image.TimeDateStamp);
157 stru.field("age", &image.Age);
158 },
159 CodeView::Cv70 { image, .. } => {
160 stru.field("signature", &image.Signature);
161 stru.field("age", &image.Age);
162 },
163 }
164 stru.finish()
165 }
166}
167
168#[derive(Copy, Clone)]
172pub struct Dbg<'a> {
173 pub image: &'a IMAGE_DEBUG_MISC,
174}
175impl<'a> Dbg<'a> {
176 pub fn image(&self) -> &'a IMAGE_DEBUG_MISC {
178 self.image
179 }
180}
181impl<'a> fmt::Debug for Dbg<'a> {
182 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
183 f.debug_struct("Dbg").finish()
184 }
185}
186
187#[derive(Copy, Clone)]
191pub struct Pgo<'a> {
192 pub image: &'a [u32],
193}
194impl<'a> Pgo<'a> {
195 pub fn image(&self) -> &'a [u32] {
197 self.image
198 }
199 pub fn iter(&self) -> PgoIter<'a> {
201 let image = if self.image.len() >= 1 { &self.image[1..] } else { self.image };
202 PgoIter { image }
203 }
204}
205impl<'a> IntoIterator for Pgo<'a> {
206 type Item = PgoItem<'a>;
207 type IntoIter = PgoIter<'a>;
208 fn into_iter(self) -> PgoIter<'a> {
209 self.iter()
210 }
211}
212impl<'a> fmt::Debug for Pgo<'a> {
213 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
214 f.debug_list().entries(self.iter()).finish()
215 }
216}
217#[derive(Clone)]
219pub struct PgoIter<'a> {
220 image: &'a [u32],
221}
222impl<'a> Iterator for PgoIter<'a> {
223 type Item = PgoItem<'a>;
224 fn next(&mut self) -> Option<PgoItem<'a>> {
225 if self.image.len() >= 3 {
226 let rva = self.image[0];
227 let size = self.image[1];
228 let name = CStr::from_bytes(dataview::bytes(&self.image[2..]))?;
229 let len = name.len() >> 2;
230 self.image = &self.image[2 + len + 1..];
231 Some(PgoItem { rva, size, name })
232 }
233 else {
234 None
235 }
236 }
237}
238#[derive(Copy, Clone, Debug)]
240#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
241pub struct PgoItem<'a> {
242 pub rva: u32,
243 pub size: u32,
244 pub name: &'a CStr,
245}
246
247#[cfg(feature = "serde")]
250mod serde2 {
251 use crate::util::serde_helper::*;
252 use super::{CodeView, Dbg, Pgo};
253
254 impl<'a> Serialize for CodeView<'a> {
255 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
256 let mut state = serializer.serialize_struct("CodeView", 4)?;
257 state.serialize_field("format", &self.format())?;
258 state.serialize_field("pdb_file_name", &self.pdb_file_name())?;
259 match self {
260 CodeView::Cv20 { image, .. } => {
261 state.serialize_field("time_date_stamp", &image.TimeDateStamp)?;
262 state.serialize_field("age", &image.Age)?;
263 },
264 CodeView::Cv70 { image, .. } => {
265 state.serialize_field("signature", &image.Signature)?;
266 state.serialize_field("age", &image.Age)?;
267 },
268 }
269 state.end()
270 }
271 }
272 impl<'a> Serialize for Dbg<'a> {
273 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
274 serializer.serialize_struct("Dbg", 0)?.end()
275 }
276 }
277 impl<'a> Serialize for Pgo<'a> {
278 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
279 serializer.collect_seq(self.iter())
280 }
281 }
282}