1use super::{ItemId, ItemIdLe};
5use crate::parser::{Parser, ParserError, ParserMut};
6use crate::types::{introduces_virtual, PointerFlags};
7use crate::types::{Leaf, TypeIndex, TypeIndexLe};
8use anyhow::Context;
9use std::mem::replace;
10use tracing::error;
11use zerocopy::{LE, U32};
12
13pub trait RecordVisitor {
19 fn is_empty(&self) -> bool;
21
22 fn peek_rest(&self) -> &[u8];
24
25 fn u16(&mut self) -> Result<u16, ParserError>;
27
28 fn u32(&mut self) -> Result<u32, ParserError>;
30
31 fn skip(&mut self, n: usize) -> Result<(), ParserError>;
33
34 fn item(&mut self) -> Result<(), ParserError>;
36
37 fn ty(&mut self) -> Result<(), ParserError>;
39
40 fn name_index(&mut self) -> Result<(), ParserError>;
42
43 fn number(&mut self) -> Result<(), ParserError>;
45
46 fn strz(&mut self) -> Result<(), ParserError>;
48}
49
50#[allow(missing_docs)]
52pub trait IndexVisitorMut {
53 #[allow(unused_variables)]
54 fn type_index(&mut self, offset: usize, value: &mut TypeIndexLe) -> Result<(), ParserError> {
55 Ok(())
56 }
57
58 #[allow(unused_variables)]
59 fn item_id(&mut self, offset: usize, value: &mut ItemIdLe) -> Result<(), ParserError> {
60 Ok(())
61 }
62
63 #[allow(unused_variables)]
64 fn name_index(&mut self, offset: usize, value: &mut U32<LE>) -> Result<(), ParserError> {
65 Ok(())
66 }
67}
68
69#[allow(missing_docs)]
71pub trait IndexVisitor {
72 #[allow(unused_variables)]
73 fn type_index(&mut self, offset: usize, value: TypeIndex) -> Result<(), ParserError> {
74 Ok(())
75 }
76
77 #[allow(unused_variables)]
78 fn item_id(&mut self, offset: usize, value: ItemId) -> Result<(), ParserError> {
79 Ok(())
80 }
81
82 #[allow(unused_variables)]
83 fn name_index(&mut self, offset: usize, value: u32) -> Result<(), ParserError> {
84 Ok(())
85 }
86}
87
88struct RefVisitor<'a, IV: IndexVisitor> {
89 parser: Parser<'a>,
90 original_len: usize,
91 index_visitor: IV,
92}
93
94impl<'a, IV: IndexVisitor> RecordVisitor for RefVisitor<'a, IV> {
95 fn is_empty(&self) -> bool {
96 self.parser.is_empty()
97 }
98
99 fn peek_rest(&self) -> &[u8] {
100 self.parser.peek_rest()
101 }
102
103 fn u16(&mut self) -> Result<u16, ParserError> {
104 self.parser.u16()
105 }
106
107 fn u32(&mut self) -> Result<u32, ParserError> {
108 self.parser.u32()
109 }
110
111 fn skip(&mut self, n: usize) -> Result<(), ParserError> {
112 self.parser.skip(n)
113 }
114
115 fn ty(&mut self) -> Result<(), ParserError> {
116 let offset = self.original_len - self.parser.len();
117 let ti = self.parser.type_index()?;
118 self.index_visitor.type_index(offset, ti)?;
119 Ok(())
120 }
121
122 fn item(&mut self) -> Result<(), ParserError> {
123 let offset = self.original_len - self.parser.len();
124 let ii = self.parser.u32()?;
125 self.index_visitor.item_id(offset, ii)?;
126 Ok(())
127 }
128
129 fn number(&mut self) -> Result<(), ParserError> {
130 self.parser.number()?;
131 Ok(())
132 }
133
134 fn strz(&mut self) -> Result<(), ParserError> {
135 self.parser.skip_strz()
136 }
137
138 fn name_index(&mut self) -> Result<(), ParserError> {
139 let offset = self.original_len - self.parser.len();
140 let ni = self.parser.u32()?;
141 self.index_visitor.name_index(offset, ni)?;
142 Ok(())
143 }
144}
145
146struct MutVisitor<'a, IV: IndexVisitorMut> {
147 parser: ParserMut<'a>,
148 original_len: usize,
149 index_visitor: IV,
150}
151
152impl<'a, IV: IndexVisitorMut> RecordVisitor for MutVisitor<'a, IV> {
153 fn is_empty(&self) -> bool {
154 self.parser.is_empty()
155 }
156
157 fn peek_rest(&self) -> &[u8] {
158 self.parser.peek_rest()
159 }
160
161 fn u16(&mut self) -> Result<u16, ParserError> {
162 self.parser.u16()
163 }
164
165 fn u32(&mut self) -> Result<u32, ParserError> {
166 self.parser.u32()
167 }
168
169 fn skip(&mut self, n: usize) -> Result<(), ParserError> {
170 self.parser.skip(n)
171 }
172
173 fn ty(&mut self) -> Result<(), ParserError> {
174 let offset = self.original_len - self.parser.len();
175 let ti: &mut TypeIndexLe = self.parser.get_mut()?;
176 self.index_visitor.type_index(offset, ti)?;
177 Ok(())
178 }
179
180 fn item(&mut self) -> Result<(), ParserError> {
181 let offset = self.original_len - self.parser.len();
182 let ii: &mut ItemIdLe = self.parser.get_mut()?;
183 self.index_visitor.item_id(offset, ii)?;
184 Ok(())
185 }
186
187 fn number(&mut self) -> Result<(), ParserError> {
188 self.parser.skip_number()
189 }
190
191 fn strz(&mut self) -> Result<(), ParserError> {
192 self.parser.skip_strz()
193 }
194
195 fn name_index(&mut self) -> Result<(), ParserError> {
196 let offset = self.original_len - self.parser.len();
197 let ni: &mut U32<LE> = self.parser.get_mut()?;
198 self.index_visitor.name_index(offset, ni)?;
199 Ok(())
200 }
201}
202
203#[inline(never)]
206pub fn visit_type_indexes_in_record_slice<IV: IndexVisitor>(
207 type_kind: Leaf,
208 record_data: &[u8],
209 index_visitor: IV,
210) -> Result<(), anyhow::Error> {
211 let record_data_len = record_data.len();
212
213 let mut v = RefVisitor {
214 original_len: record_data.len(),
215 parser: Parser::new(record_data),
216 index_visitor,
217 };
218
219 visit_type_indexes_in_record(type_kind, &mut v).with_context(|| {
220 let offset = record_data_len - v.parser.len();
221 format!(
222 "at byte offset 0x{:x} {} within type record",
223 offset, offset
224 )
225 })
226}
227
228#[inline(never)]
231pub fn visit_type_indexes_in_record_slice_mut<IV>(
232 type_kind: Leaf,
233 record_data: &mut [u8],
234 index_visitor: IV,
235) -> Result<(), anyhow::Error>
236where
237 IV: IndexVisitorMut,
238{
239 let record_data_len = record_data.len();
240
241 let mut v = MutVisitor {
242 original_len: record_data.len(),
243 parser: ParserMut::new(record_data),
244 index_visitor,
245 };
246
247 visit_type_indexes_in_record(type_kind, &mut v).with_context(|| {
248 let offset = record_data_len - v.parser.len();
249 format!(
250 "at byte offset 0x{:x} {} within type record",
251 offset, offset
252 )
253 })
254}
255
256pub fn visit_type_indexes_in_record<V: RecordVisitor>(
262 type_kind: Leaf,
263 p: &mut V,
264) -> Result<(), ParserError> {
265 match type_kind {
266 Leaf::LF_LABEL => {}
267
268 Leaf::LF_MODIFIER => {
269 p.ty()?;
270 }
271
272 Leaf::LF_POINTER => {
273 p.ty()?; let attr = PointerFlags(p.u32()?);
275 match attr.mode() {
276 2 => {
277 p.ty()?;
279 }
280 3 => {
281 p.ty()?;
283 }
284 _ => {}
285 }
286 }
287
288 Leaf::LF_ALIAS => {
289 p.ty()?;
290 }
291
292 Leaf::LF_ARRAY => {
293 p.ty()?; p.ty()?; }
296
297 Leaf::LF_CLASS | Leaf::LF_STRUCTURE => {
298 p.u16()?; p.skip(2)?; p.ty()?; p.ty()?; p.ty()?; }
304
305 Leaf::LF_ENUM => {
306 p.u16()?; p.skip(2)?; p.ty()?; p.ty()?; }
311
312 Leaf::LF_UNION => {
313 p.u16()?; p.skip(2)?; p.ty()?; }
317
318 Leaf::LF_PROCEDURE => {
319 p.ty()?; p.skip(4)?; p.ty()?; }
323
324 Leaf::LF_MFUNCTION => {
325 p.ty()?; p.ty()?; p.ty()?; p.skip(4)?; p.ty()?; }
331
332 Leaf::LF_ARGLIST => {
333 let num_args = p.u32()?;
334 for _ in 0..num_args {
335 p.ty()?;
336 }
337 }
338
339 Leaf::LF_FIELDLIST => {
340 let mut prev_item_kind = None;
341 loop {
342 let rest = p.peek_rest();
343 if rest.is_empty() {
344 break;
345 }
346
347 let mut padding_len = 0;
349 while padding_len < rest.len() && rest[padding_len] >= 0xf0 {
350 padding_len += 1;
351 }
352 if padding_len > 0 {
353 p.skip(padding_len)?;
354 }
355
356 if p.is_empty() {
357 break;
358 }
359
360 let item_kind = Leaf(p.u16()?);
361 let after = replace(&mut prev_item_kind, Some(item_kind));
362
363 match item_kind {
364 Leaf::LF_BCLASS => {
365 let _attr = p.u16()?;
366 p.ty()?; p.number()?; }
369
370 Leaf::LF_VBCLASS => {
371 let _attr = p.u16()?;
372 p.ty()?; p.ty()?; p.number()?; p.number()?; }
377
378 Leaf::LF_IVBCLASS => {
379 let _attr = p.u16()?;
380 p.ty()?; p.ty()?; p.number()?; p.number()?; }
385
386 Leaf::LF_ENUMERATE => {
387 let _attr = p.u16()?;
389 p.number()?; p.strz()?; }
392
393 Leaf::LF_FRIENDFCN => {
394 p.skip(2)?; p.ty()?; p.strz()?; }
398
399 Leaf::LF_INDEX => {
400 p.skip(2)?; p.ty()?; }
403
404 Leaf::LF_MEMBER => {
405 let _attr = p.u16()?;
406 p.ty()?; p.number()?; p.strz()?; }
410
411 Leaf::LF_STMEMBER => {
412 let _attr = p.u16()?;
413 p.ty()?; p.strz()?; }
416
417 Leaf::LF_METHOD => {
418 let _count = p.u16()?;
419 p.ty()?; p.strz()?; }
422
423 Leaf::LF_NESTEDTYPE => {
424 p.skip(2)?; p.ty()?; p.strz()?; }
428
429 Leaf::LF_VFUNCTAB => {
430 p.skip(2)?; p.ty()?; }
433
434 Leaf::LF_FRIENDCLS => {
435 p.skip(2)?; p.ty()?; }
438
439 Leaf::LF_ONEMETHOD => {
440 let attr = p.u16()?; p.ty()?; if introduces_virtual(attr) {
443 p.u32()?; }
445 p.strz()?; }
447
448 Leaf::LF_VFUNCOFF => {
449 p.u16()?; p.ty()?; p.u32()?; }
453
454 Leaf::LF_NESTEDTYPEEX => {
455 p.u16()?; p.ty()?; p.strz()?; }
459
460 unknown_item_kind => {
461 error!(
462 ?unknown_item_kind,
463 ?after,
464 "unrecognized item within LF_FIELDLIST"
465 );
466 break;
467 }
468 }
469 }
470 }
471
472 Leaf::LF_DERIVED => {
473 let count = p.u32()?;
474 for _ in 0..count {
475 p.ty()?;
476 }
477 }
478
479 Leaf::LF_BITFIELD => {
480 p.ty()?;
481 }
482
483 Leaf::LF_METHODLIST => {
484 while !p.is_empty() {
485 let attr = p.u16()?;
486 p.skip(2)?; p.ty()?;
488 if introduces_virtual(attr) {
489 p.skip(4)?; }
491 }
492 }
493
494 Leaf::LF_DIMCONU => {
495 p.ty()?; }
497
498 Leaf::LF_DIMCONLU => {
499 p.ty()?; }
501
502 Leaf::LF_DIMVARU => {
503 let rank = p.u32()?;
504 p.ty()?; for _ in 0..rank {
506 p.ty()?; }
508 }
509
510 Leaf::LF_VTSHAPE | Leaf::LF_PRECOMP | Leaf::LF_ENDPRECOMP | Leaf::LF_SKIP => {}
512
513 Leaf::LF_VFTPATH => {
514 let count = p.u32()?;
515 for _ in 0..count {
516 p.ty()?;
517 }
518 }
519
520 Leaf::LF_VFTABLE => {
521 p.ty()?; p.ty()?; }
524
525 Leaf::LF_CLASS2 | Leaf::LF_STRUCTURE2 | Leaf::LF_UNION2 | Leaf::LF_INTERFACE2 => {
526 p.skip(4)?; p.ty()?; p.ty()?; p.ty()?; }
531
532 Leaf::LF_FUNC_ID => {
533 p.item()?; p.ty()?; }
536
537 Leaf::LF_MFUNC_ID => {
538 p.ty()?; p.ty()?; }
541
542 Leaf::LF_BUILDINFO => {
543 let n = p.u16()?;
544 for _ in 0..n {
545 p.item()?;
546 }
547 }
548
549 Leaf::LF_SUBSTR_LIST => {
550 let count = p.u32()?;
551 for _ in 0..count {
552 p.item()?;
553 }
554 }
555
556 Leaf::LF_STRING_ID => {
557 p.item()?; }
559
560 Leaf::LF_UDT_SRC_LINE => {
561 p.ty()?;
562 p.name_index()?; }
564
565 Leaf::LF_UDT_MOD_SRC_LINE => {
566 p.ty()?;
567 p.name_index()?; }
569
570 _ => {
571 error!("unrecognized type kind: {:?}", type_kind);
572 return Err(ParserError::new());
573 }
574 }
575
576 Ok(())
577}