1use super::{ItemId, ItemIdLe};
5use crate::parser::{Parser, ParserError, ParserMut};
6use crate::types::{Leaf, TypeIndex, TypeIndexLe};
7use crate::types::{PointerFlags, introduces_virtual};
8use anyhow::Context;
9use tracing::error;
10use zerocopy::{LE, U32};
11
12pub trait RecordVisitor {
18 fn is_empty(&self) -> bool;
20
21 fn peek_rest(&self) -> &[u8];
23
24 fn u16(&mut self) -> Result<u16, ParserError>;
26
27 fn u32(&mut self) -> Result<u32, ParserError>;
29
30 fn skip(&mut self, n: usize) -> Result<(), ParserError>;
32
33 fn item(&mut self) -> Result<(), ParserError>;
35
36 fn ty(&mut self) -> Result<(), ParserError>;
38
39 fn name_index(&mut self) -> Result<(), ParserError>;
41
42 fn number(&mut self) -> Result<(), ParserError>;
44
45 fn strz(&mut self) -> Result<(), ParserError>;
47}
48
49#[allow(missing_docs)]
51pub trait IndexVisitorMut {
52 #[allow(unused_variables)]
53 fn type_index(&mut self, offset: usize, value: &mut TypeIndexLe) -> Result<(), ParserError> {
54 Ok(())
55 }
56
57 #[allow(unused_variables)]
58 fn item_id(&mut self, offset: usize, value: &mut ItemIdLe) -> Result<(), ParserError> {
59 Ok(())
60 }
61
62 #[allow(unused_variables)]
63 fn name_index(&mut self, offset: usize, value: &mut U32<LE>) -> Result<(), ParserError> {
64 Ok(())
65 }
66}
67
68#[allow(missing_docs)]
70pub trait IndexVisitor {
71 #[allow(unused_variables)]
72 fn type_index(&mut self, offset: usize, value: TypeIndex) -> Result<(), ParserError> {
73 Ok(())
74 }
75
76 #[allow(unused_variables)]
77 fn item_id(&mut self, offset: usize, value: ItemId) -> Result<(), ParserError> {
78 Ok(())
79 }
80
81 #[allow(unused_variables)]
82 fn name_index(&mut self, offset: usize, value: u32) -> Result<(), ParserError> {
83 Ok(())
84 }
85}
86
87struct RefVisitor<'a, IV: IndexVisitor> {
88 parser: Parser<'a>,
89 original_len: usize,
90 index_visitor: IV,
91}
92
93impl<'a, IV: IndexVisitor> RecordVisitor for RefVisitor<'a, IV> {
94 fn is_empty(&self) -> bool {
95 self.parser.is_empty()
96 }
97
98 fn peek_rest(&self) -> &[u8] {
99 self.parser.peek_rest()
100 }
101
102 fn u16(&mut self) -> Result<u16, ParserError> {
103 self.parser.u16()
104 }
105
106 fn u32(&mut self) -> Result<u32, ParserError> {
107 self.parser.u32()
108 }
109
110 fn skip(&mut self, n: usize) -> Result<(), ParserError> {
111 self.parser.skip(n)
112 }
113
114 fn ty(&mut self) -> Result<(), ParserError> {
115 let offset = self.original_len - self.parser.len();
116 let ti = self.parser.type_index()?;
117 self.index_visitor.type_index(offset, ti)?;
118 Ok(())
119 }
120
121 fn item(&mut self) -> Result<(), ParserError> {
122 let offset = self.original_len - self.parser.len();
123 let ii = self.parser.u32()?;
124 self.index_visitor.item_id(offset, ii)?;
125 Ok(())
126 }
127
128 fn number(&mut self) -> Result<(), ParserError> {
129 self.parser.number()?;
130 Ok(())
131 }
132
133 fn strz(&mut self) -> Result<(), ParserError> {
134 self.parser.skip_strz()
135 }
136
137 fn name_index(&mut self) -> Result<(), ParserError> {
138 let offset = self.original_len - self.parser.len();
139 let ni = self.parser.u32()?;
140 self.index_visitor.name_index(offset, ni)?;
141 Ok(())
142 }
143}
144
145struct MutVisitor<'a, IV: IndexVisitorMut> {
146 parser: ParserMut<'a>,
147 original_len: usize,
148 index_visitor: IV,
149}
150
151impl<'a, IV: IndexVisitorMut> RecordVisitor for MutVisitor<'a, IV> {
152 fn is_empty(&self) -> bool {
153 self.parser.is_empty()
154 }
155
156 fn peek_rest(&self) -> &[u8] {
157 self.parser.peek_rest()
158 }
159
160 fn u16(&mut self) -> Result<u16, ParserError> {
161 self.parser.u16()
162 }
163
164 fn u32(&mut self) -> Result<u32, ParserError> {
165 self.parser.u32()
166 }
167
168 fn skip(&mut self, n: usize) -> Result<(), ParserError> {
169 self.parser.skip(n)
170 }
171
172 fn ty(&mut self) -> Result<(), ParserError> {
173 let offset = self.original_len - self.parser.len();
174 let ti: &mut TypeIndexLe = self.parser.get_mut()?;
175 self.index_visitor.type_index(offset, ti)?;
176 Ok(())
177 }
178
179 fn item(&mut self) -> Result<(), ParserError> {
180 let offset = self.original_len - self.parser.len();
181 let ii: &mut ItemIdLe = self.parser.get_mut()?;
182 self.index_visitor.item_id(offset, ii)?;
183 Ok(())
184 }
185
186 fn number(&mut self) -> Result<(), ParserError> {
187 self.parser.skip_number()
188 }
189
190 fn strz(&mut self) -> Result<(), ParserError> {
191 self.parser.skip_strz()
192 }
193
194 fn name_index(&mut self) -> Result<(), ParserError> {
195 let offset = self.original_len - self.parser.len();
196 let ni: &mut U32<LE> = self.parser.get_mut()?;
197 self.index_visitor.name_index(offset, ni)?;
198 Ok(())
199 }
200}
201
202#[inline(never)]
205pub fn visit_type_indexes_in_record_slice<IV: IndexVisitor>(
206 type_kind: Leaf,
207 record_data: &[u8],
208 index_visitor: IV,
209) -> Result<(), anyhow::Error> {
210 let record_data_len = record_data.len();
211
212 let mut v = RefVisitor {
213 original_len: record_data.len(),
214 parser: Parser::new(record_data),
215 index_visitor,
216 };
217
218 visit_type_indexes_in_record(type_kind, &mut v).with_context(|| {
219 let offset = record_data_len - v.parser.len();
220 format!("at byte offset 0x{offset:x} {offset} within type record")
221 })
222}
223
224#[inline(never)]
227pub fn visit_type_indexes_in_record_slice_mut<IV>(
228 type_kind: Leaf,
229 record_data: &mut [u8],
230 index_visitor: IV,
231) -> Result<(), anyhow::Error>
232where
233 IV: IndexVisitorMut,
234{
235 let record_data_len = record_data.len();
236
237 let mut v = MutVisitor {
238 original_len: record_data.len(),
239 parser: ParserMut::new(record_data),
240 index_visitor,
241 };
242
243 visit_type_indexes_in_record(type_kind, &mut v).with_context(|| {
244 let offset = record_data_len - v.parser.len();
245 format!("at byte offset 0x{offset:x} {offset} within type record")
246 })
247}
248
249pub fn visit_type_indexes_in_record<V: RecordVisitor>(
255 type_kind: Leaf,
256 p: &mut V,
257) -> Result<(), ParserError> {
258 match type_kind {
259 Leaf::LF_LABEL => {}
260
261 Leaf::LF_MODIFIER => {
262 p.ty()?;
263 }
264
265 Leaf::LF_POINTER => {
266 p.ty()?; let attr = PointerFlags(p.u32()?);
268 match attr.mode() {
269 2 => {
270 p.ty()?;
272 }
273 3 => {
274 p.ty()?;
276 }
277 _ => {}
278 }
279 }
280
281 Leaf::LF_ALIAS => {
282 p.ty()?;
283 }
284
285 Leaf::LF_ARRAY => {
286 p.ty()?; p.ty()?; }
289
290 Leaf::LF_CLASS | Leaf::LF_STRUCTURE => {
291 p.u16()?; p.skip(2)?; p.ty()?; p.ty()?; p.ty()?; }
297
298 Leaf::LF_ENUM => {
299 p.u16()?; p.skip(2)?; p.ty()?; p.ty()?; }
304
305 Leaf::LF_UNION => {
306 p.u16()?; p.skip(2)?; p.ty()?; }
310
311 Leaf::LF_PROCEDURE => {
312 p.ty()?; p.skip(4)?; p.ty()?; }
316
317 Leaf::LF_MFUNCTION => {
318 p.ty()?; p.ty()?; p.ty()?; p.skip(4)?; p.ty()?; }
324
325 Leaf::LF_ARGLIST => {
326 let num_args = p.u32()?;
327 for _ in 0..num_args {
328 p.ty()?;
329 }
330 }
331
332 Leaf::LF_FIELDLIST => {
333 let mut prev_item_kind = None;
334 loop {
335 let rest = p.peek_rest();
336 if rest.is_empty() {
337 break;
338 }
339
340 let mut padding_len = 0;
342 while padding_len < rest.len() && rest[padding_len] >= 0xf0 {
343 padding_len += 1;
344 }
345 if padding_len > 0 {
346 p.skip(padding_len)?;
347 }
348
349 if p.is_empty() {
350 break;
351 }
352
353 let item_kind = Leaf(p.u16()?);
354 let after = prev_item_kind.replace(item_kind);
355
356 match item_kind {
357 Leaf::LF_BCLASS => {
358 let _attr = p.u16()?;
359 p.ty()?; p.number()?; }
362
363 Leaf::LF_VBCLASS => {
364 let _attr = p.u16()?;
365 p.ty()?; p.ty()?; p.number()?; p.number()?; }
370
371 Leaf::LF_IVBCLASS => {
372 let _attr = p.u16()?;
373 p.ty()?; p.ty()?; p.number()?; p.number()?; }
378
379 Leaf::LF_ENUMERATE => {
380 let _attr = p.u16()?;
382 p.number()?; p.strz()?; }
385
386 Leaf::LF_FRIENDFCN => {
387 p.skip(2)?; p.ty()?; p.strz()?; }
391
392 Leaf::LF_INDEX => {
393 p.skip(2)?; p.ty()?; }
396
397 Leaf::LF_MEMBER => {
398 let _attr = p.u16()?;
399 p.ty()?; p.number()?; p.strz()?; }
403
404 Leaf::LF_STMEMBER => {
405 let _attr = p.u16()?;
406 p.ty()?; p.strz()?; }
409
410 Leaf::LF_METHOD => {
411 let _count = p.u16()?;
412 p.ty()?; p.strz()?; }
415
416 Leaf::LF_NESTEDTYPE => {
417 p.skip(2)?; p.ty()?; p.strz()?; }
421
422 Leaf::LF_VFUNCTAB => {
423 p.skip(2)?; p.ty()?; }
426
427 Leaf::LF_FRIENDCLS => {
428 p.skip(2)?; p.ty()?; }
431
432 Leaf::LF_ONEMETHOD => {
433 let attr = p.u16()?; p.ty()?; if introduces_virtual(attr) {
436 p.u32()?; }
438 p.strz()?; }
440
441 Leaf::LF_VFUNCOFF => {
442 p.u16()?; p.ty()?; p.u32()?; }
446
447 Leaf::LF_NESTEDTYPEEX => {
448 p.u16()?; p.ty()?; p.strz()?; }
452
453 unknown_item_kind => {
454 error!(
455 ?unknown_item_kind,
456 ?after,
457 "unrecognized item within LF_FIELDLIST"
458 );
459 break;
460 }
461 }
462 }
463 }
464
465 Leaf::LF_DERIVED => {
466 let count = p.u32()?;
467 for _ in 0..count {
468 p.ty()?;
469 }
470 }
471
472 Leaf::LF_BITFIELD => {
473 p.ty()?;
474 }
475
476 Leaf::LF_METHODLIST => {
477 while !p.is_empty() {
478 let attr = p.u16()?;
479 p.skip(2)?; p.ty()?;
481 if introduces_virtual(attr) {
482 p.skip(4)?; }
484 }
485 }
486
487 Leaf::LF_DIMCONU => {
488 p.ty()?; }
490
491 Leaf::LF_DIMCONLU => {
492 p.ty()?; }
494
495 Leaf::LF_DIMVARU => {
496 let rank = p.u32()?;
497 p.ty()?; for _ in 0..rank {
499 p.ty()?; }
501 }
502
503 Leaf::LF_VTSHAPE | Leaf::LF_PRECOMP | Leaf::LF_ENDPRECOMP | Leaf::LF_SKIP => {}
505
506 Leaf::LF_VFTPATH => {
507 let count = p.u32()?;
508 for _ in 0..count {
509 p.ty()?;
510 }
511 }
512
513 Leaf::LF_VFTABLE => {
514 p.ty()?; p.ty()?; }
517
518 Leaf::LF_CLASS2 | Leaf::LF_STRUCTURE2 | Leaf::LF_UNION2 | Leaf::LF_INTERFACE2 => {
519 p.skip(4)?; p.ty()?; p.ty()?; p.ty()?; }
524
525 Leaf::LF_FUNC_ID => {
526 p.item()?; p.ty()?; }
529
530 Leaf::LF_MFUNC_ID => {
531 p.ty()?; p.ty()?; }
534
535 Leaf::LF_BUILDINFO => {
536 let n = p.u16()?;
537 for _ in 0..n {
538 p.item()?;
539 }
540 }
541
542 Leaf::LF_SUBSTR_LIST => {
543 let count = p.u32()?;
544 for _ in 0..count {
545 p.item()?;
546 }
547 }
548
549 Leaf::LF_STRING_ID => {
550 p.item()?; }
552
553 Leaf::LF_UDT_SRC_LINE => {
554 p.ty()?;
555 p.name_index()?; }
557
558 Leaf::LF_UDT_MOD_SRC_LINE => {
559 p.ty()?;
560 p.name_index()?; }
562
563 _ => {
564 error!("unrecognized type kind: {:?}", type_kind);
565 return Err(ParserError::new());
566 }
567 }
568
569 Ok(())
570}