1pub mod builder;
9mod iter;
10mod kind;
11mod offset_segment;
12
13#[doc(inline)]
14pub use self::{iter::*, kind::SymKind, offset_segment::*};
15
16use crate::parser::{Number, Parse, Parser, ParserError, ParserMut};
17use crate::types::{ItemId, ItemIdLe, TypeIndex, TypeIndexLe};
18use bstr::BStr;
19use std::fmt::Debug;
20use std::mem::size_of;
21use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned, I32, LE, U16, U32};
22
23#[derive(IntoBytes, FromBytes, Unaligned, Immutable, KnownLayout, Default, Clone, Debug)]
25#[repr(C)]
26#[allow(missing_docs)]
27pub struct BlockHeader {
28 pub p_parent: U32<LE>,
34
35 pub p_end: U32<LE>,
37}
38
39#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Debug)]
44#[repr(C)]
45#[allow(missing_docs)]
46pub struct ProcFixed {
47 pub p_parent: U32<LE>,
49
50 pub p_end: U32<LE>,
53
54 pub p_next: U32<LE>,
55
56 pub proc_len: U32<LE>,
58
59 pub debug_start: U32<LE>,
62
63 pub debug_end: U32<LE>,
67
68 pub proc_type: TypeIndexLe,
77
78 pub offset_segment: OffsetSegment,
79 pub flags: u8,
80}
81
82#[allow(missing_docs)]
94#[derive(Clone, Debug)]
95pub struct Proc<'a> {
96 pub fixed: &'a ProcFixed,
97 pub name: &'a BStr,
98}
99
100impl<'a> Parse<'a> for Proc<'a> {
101 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
102 Ok(Self {
103 fixed: p.get()?,
104 name: p.strz()?,
105 })
106 }
107}
108
109#[test]
111fn test_parse_proc() {
112 #[rustfmt::skip]
113 let data = &[
114 0x2e, 0, 0x10, 0x11, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0, 0xee, 0x10, 0, 0, 0xcc, 0x1, 0, 0, 1, 0, 0x50, b'm', b'e', b'm', b's', b'e', b't', 0, 0xf1, 0xf2, 2, 0, 6, 0 ];
129
130 let mut i = SymIter::new(data);
131
132 let s0 = i.next().unwrap();
133 assert_eq!(s0.kind, SymKind::S_GPROC32);
134 assert_eq!(s0.data.len(), 0x2c);
135
136 match s0.parse().unwrap() {
137 SymData::Proc(proc) => {
138 assert_eq!(proc.fixed.p_parent.get(), 0);
139 assert_eq!(proc.fixed.p_end.get(), 0x40);
140 assert_eq!(proc.name, "memset");
141 }
142 _ => panic!(),
143 }
144
145 let s1 = i.next().unwrap();
146 assert_eq!(s1.kind, SymKind::S_END);
147 assert!(s1.data.is_empty());
148}
149
150#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Debug)]
154#[repr(C)]
155#[allow(missing_docs)]
156pub struct ManagedProcFixed {
157 pub p_parent: U32<LE>,
158 pub p_end: U32<LE>,
159 pub p_next: U32<LE>,
160 pub proc_len: U32<LE>,
161 pub debug_start: U32<LE>,
162 pub debug_end: U32<LE>,
163 pub token: U32<LE>,
164 pub offset_segment: OffsetSegment,
165 pub flags: u8,
166 pub return_reg: U16<LE>,
167}
168
169#[allow(missing_docs)]
171#[derive(Clone, Debug)]
172pub struct ManagedProc<'a> {
173 pub fixed: &'a ManagedProcFixed,
174 pub name: &'a BStr,
175}
176
177impl<'a> Parse<'a> for ManagedProc<'a> {
178 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
179 Ok(Self {
180 fixed: p.get()?,
181 name: p.strz()?,
182 })
183 }
184}
185
186#[repr(C)]
187#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
188#[allow(missing_docs)]
189pub struct ThunkFixed {
190 pub block: BlockHeader,
191 pub p_next: U32<LE>,
192 pub offset_segment: OffsetSegment,
193 pub length: U16<LE>,
194 pub thunk_ordinal: u8,
195 }
198
199#[allow(missing_docs)]
200pub struct Thunk<'a> {
201 pub fixed: &'a ThunkFixed,
202 pub name: &'a BStr,
203 pub variant: &'a [u8],
204}
205
206impl<'a> Parse<'a> for Thunk<'a> {
207 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
208 Ok(Self {
209 fixed: p.get()?,
210 name: p.strz()?,
211 variant: p.take_rest(),
212 })
213 }
214}
215
216#[repr(C)]
218#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
219pub struct SymHeader {
220 pub len: U16<LE>,
225
226 pub kind: U16<LE>,
228}
229
230#[derive(Clone)]
232pub struct Sym<'a> {
233 pub kind: SymKind,
235 pub data: &'a [u8],
237}
238
239impl<'a> Sym<'a> {
240 pub fn parse(&self) -> Result<SymData<'a>, ParserError> {
242 SymData::parse(self.kind, self.data)
243 }
244}
245
246impl<'a> Debug for Sym<'a> {
247 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
248 write!(fmt, "{:?}", self.kind)
249 }
250}
251
252pub struct SymMut<'a> {
255 pub kind: SymKind,
257 pub data: &'a mut [u8],
259}
260
261#[allow(missing_docs)]
274#[derive(Clone, Debug)]
275pub struct Pub<'a> {
276 pub fixed: &'a PubFixed,
277 pub name: &'a BStr,
278}
279
280impl<'a> Pub<'a> {
281 pub fn offset_segment(&self) -> OffsetSegment {
283 self.fixed.offset_segment
284 }
285}
286
287#[allow(missing_docs)]
288#[repr(C)]
289#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
290pub struct PubFixed {
291 pub flags: U32<LE>,
292 pub offset_segment: OffsetSegment,
293 }
295
296#[allow(missing_docs)]
297impl<'a> Parse<'a> for Pub<'a> {
298 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
299 Ok(Self {
300 fixed: p.get()?,
301 name: p.strz()?,
302 })
303 }
304}
305
306impl<'a> Pub<'a> {
307 pub fn parse_st(p: &mut Parser<'a>) -> Result<Self, ParserError> {
309 Ok(Self {
310 fixed: p.get()?,
311 name: p.strt_raw()?,
312 })
313 }
314}
315
316#[allow(missing_docs)]
318#[derive(Clone, Debug)]
319pub struct Constant<'a> {
320 pub type_: TypeIndex,
321 pub value: Number<'a>,
322 pub name: &'a BStr,
323}
324
325impl<'a> Parse<'a> for Constant<'a> {
326 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
327 Ok(Self {
328 type_: p.type_index()?,
329 value: p.number()?,
330 name: p.strz()?,
331 })
332 }
333}
334
335#[allow(missing_docs)]
337#[derive(Clone, Debug)]
338pub struct ManagedConstant<'a> {
339 pub token: u32,
340 pub value: Number<'a>,
341 pub name: &'a BStr,
342}
343
344impl<'a> Parse<'a> for ManagedConstant<'a> {
345 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
346 Ok(Self {
347 token: p.u32()?,
348 value: p.number()?,
349 name: p.strz()?,
350 })
351 }
352}
353
354#[allow(missing_docs)]
362#[derive(Clone, Debug)]
363pub struct RefSym2<'a> {
364 pub header: &'a RefSym2Fixed,
365 pub name: &'a BStr,
366}
367
368#[allow(missing_docs)]
369#[repr(C)]
370#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
371pub struct RefSym2Fixed {
372 pub name_checksum: U32<LE>,
376
377 pub symbol_offset: U32<LE>,
382
383 pub module_index: U16<LE>,
387 }
389
390impl<'a> Parse<'a> for RefSym2<'a> {
391 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
392 Ok(Self {
393 header: p.get()?,
394 name: p.strz()?,
395 })
396 }
397}
398
399#[allow(missing_docs)]
400#[repr(C)]
401#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
402pub struct ThreadStorageFixed {
403 pub type_: TypeIndexLe,
404 pub offset_segment: OffsetSegment,
405}
406
407#[derive(Clone, Debug)]
411pub struct ThreadStorageData<'a> {
412 #[allow(missing_docs)]
413 pub header: &'a ThreadStorageFixed,
414 #[allow(missing_docs)]
415 pub name: &'a BStr,
416}
417
418impl<'a> Parse<'a> for ThreadStorageData<'a> {
419 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
420 Ok(Self {
421 header: p.get()?,
422 name: p.strz()?,
423 })
424 }
425}
426
427#[allow(missing_docs)]
428#[repr(C)]
429#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
430pub struct DataFixed {
431 pub type_: TypeIndexLe,
432 pub offset_segment: OffsetSegment,
433}
434
435#[allow(missing_docs)]
437#[derive(Clone)]
438pub struct Data<'a> {
439 pub header: &'a DataFixed,
440 pub name: &'a BStr,
441}
442
443impl<'a> Parse<'a> for Data<'a> {
444 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
445 Ok(Self {
446 header: p.get()?,
447 name: p.strz()?,
448 })
449 }
450}
451
452impl<'a> Debug for Data<'a> {
453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454 write!(
455 f,
456 "Data: {} {:?} {}",
457 self.header.offset_segment,
458 self.header.type_.get(),
459 self.name
460 )
461 }
462}
463
464#[derive(Clone, Debug)]
466pub struct Udt<'a> {
467 pub type_: TypeIndex,
469 pub name: &'a BStr,
471}
472
473impl<'a> Parse<'a> for Udt<'a> {
474 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
475 Ok(Self {
476 type_: p.type_index()?,
477 name: p.strz()?,
478 })
479 }
480}
481
482#[derive(Clone, Debug)]
484pub struct ObjectName<'a> {
485 pub signature: u32,
488 pub name: &'a BStr,
490}
491
492impl<'a> Parse<'a> for ObjectName<'a> {
493 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
494 Ok(Self {
495 signature: p.u32()?,
496 name: p.strz()?,
497 })
498 }
499}
500
501#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
503#[repr(C)]
504#[allow(missing_docs)]
505pub struct Compile3Fixed {
506 pub flags: U32<LE>,
507 pub machine: U16<LE>,
508 pub frontend_major: U16<LE>,
509 pub frontend_minor: U16<LE>,
510 pub frontend_build: U16<LE>,
511 pub frontend_qfe: U16<LE>,
512 pub ver_major: U16<LE>,
513 pub ver_minor: U16<LE>,
514 pub ver_build: U16<LE>,
515 pub ver_qfe: U16<LE>,
516 }
518
519#[allow(missing_docs)]
521#[derive(Clone, Debug)]
522pub struct Compile3<'a> {
523 pub fixed: &'a Compile3Fixed,
524 pub name: &'a BStr,
525}
526
527impl<'a> Parse<'a> for Compile3<'a> {
528 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
529 Ok(Self {
530 fixed: p.get()?,
531 name: p.strz()?,
532 })
533 }
534}
535
536#[repr(C)]
540#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
541#[allow(missing_docs)]
542pub struct FrameProc {
543 frame_size: U32<LE>,
545 pad_size: U32<LE>,
547 pad_offset: U32<LE>,
549 save_regs_size: U32<LE>,
551 offset_exception_handler: U32<LE>,
552 exception_handler_section: U16<LE>,
553 padding: U16<LE>,
554 flags: U32<LE>,
555}
556
557#[repr(C)]
558#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
559#[allow(missing_docs)]
560pub struct RegRelFixed {
561 pub offset: U32<LE>,
562 pub ty: TypeIndexLe,
563 pub register: U16<LE>,
564 }
566
567#[derive(Clone, Debug)]
570#[allow(missing_docs)]
571pub struct RegRel<'a> {
572 pub fixed: &'a RegRelFixed,
573 pub name: &'a BStr,
574}
575
576impl<'a> Parse<'a> for RegRel<'a> {
577 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
578 Ok(Self {
579 fixed: p.get()?,
580 name: p.strz()?,
581 })
582 }
583}
584
585#[derive(Clone, Debug)]
593#[allow(missing_docs)]
594pub struct Block<'a> {
595 pub fixed: &'a BlockFixed,
596 pub name: &'a BStr,
597}
598
599#[repr(C)]
600#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
601#[allow(missing_docs)]
602pub struct BlockFixed {
603 pub header: BlockHeader,
605
606 pub length: U32<LE>,
608
609 pub offset_segment: OffsetSegment,
610}
611
612impl<'a> Parse<'a> for Block<'a> {
613 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
614 Ok(Self {
615 fixed: p.get()?,
616 name: p.strz()?,
617 })
618 }
619}
620
621#[derive(Clone, Debug)]
626#[allow(missing_docs)]
627pub struct Local<'a> {
628 pub fixed: &'a LocalFixed,
629 pub name: &'a BStr,
630}
631
632#[repr(C)]
633#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
634#[allow(missing_docs)]
635pub struct LocalFixed {
636 pub ty: TypeIndexLe,
637 pub flags: U16<LE>,
639 }
641
642impl<'a> Parse<'a> for Local<'a> {
643 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
644 Ok(Self {
645 fixed: p.get()?,
646 name: p.strz()?,
647 })
648 }
649}
650
651#[repr(C)]
655#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
656pub struct LVarAddrRange {
657 pub start: OffsetSegment,
659 pub range_size: U16<LE>,
661}
662
663#[repr(C)]
668#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
669pub struct LVarAddrGap {
670 pub gap_start_offset: U16<LE>,
672 pub range_size: U16<LE>,
674}
675
676#[repr(C)]
678#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
679#[allow(missing_docs)]
680pub struct DefRangeSymFramePointerRelFixed {
681 pub offset_to_frame_pointer: U32<LE>,
682
683 pub range: LVarAddrRange,
685}
686
687#[allow(missing_docs)]
689#[derive(Clone, Debug)]
690pub struct DefRangeSymFramePointerRel<'a> {
691 pub fixed: &'a DefRangeSymFramePointerRelFixed,
692 pub gaps: &'a [LVarAddrGap],
694}
695
696impl<'a> Parse<'a> for DefRangeSymFramePointerRel<'a> {
697 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
698 let fixed = p.get()?;
699 let gaps = p.slice(p.len() / size_of::<LVarAddrGap>())?;
700 Ok(Self { fixed, gaps })
701 }
702}
703
704#[repr(C)]
708#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
709#[allow(missing_docs)]
710pub struct RangeAttrLe {
711 pub value: U16<LE>,
714}
715
716#[repr(C)]
720#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
721#[allow(missing_docs)]
722pub struct DefRangeRegisterFixed {
723 pub reg: U16<LE>,
725 pub attr: RangeAttrLe,
727}
728
729#[derive(Clone, Debug)]
733#[allow(missing_docs)]
734pub struct DefRangeRegister<'a> {
735 pub fixed: &'a DefRangeRegisterFixed,
736 pub gaps: &'a [u8],
737}
738
739impl<'a> Parse<'a> for DefRangeRegister<'a> {
740 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
741 Ok(Self {
742 fixed: p.get()?,
743 gaps: p.take_rest(),
744 })
745 }
746}
747
748#[allow(missing_docs)]
750#[derive(Debug, Clone)]
751pub struct DefRangeRegisterRel<'a> {
752 pub fixed: &'a DefRangeRegisterRelFixed,
753
754 pub gaps: &'a [u8],
756}
757
758#[repr(C)]
760#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
761pub struct DefRangeRegisterRelFixed {
762 pub base_reg: U16<LE>,
764
765 pub flags: U16<LE>,
771
772 pub base_pointer_offset: I32<LE>,
774
775 pub range: LVarAddrRange,
777}
778
779impl<'a> Parse<'a> for DefRangeRegisterRel<'a> {
780 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
781 Ok(Self {
782 fixed: p.get()?,
783 gaps: p.take_rest(),
784 })
785 }
786}
787
788#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
792#[repr(C)]
793pub struct DefRangeFramePointerRelFullScope {
794 pub frame_pointer_offset: I32<LE>,
796}
797
798#[derive(Clone, Debug)]
802#[allow(missing_docs)]
803pub struct DefRangeSubFieldRegister<'a> {
804 pub fixed: &'a DefRangeSubFieldRegisterFixed,
805 pub gaps: &'a [u8],
806}
807
808#[repr(C)]
809#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
810#[allow(missing_docs)]
811pub struct DefRangeSubFieldRegisterFixed {
812 pub reg: U16<LE>,
813 pub attr: RangeAttrLe,
814 pub flags: U32<LE>,
815 pub range: LVarAddrRange,
816}
817
818impl<'a> Parse<'a> for DefRangeSubFieldRegister<'a> {
819 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
820 Ok(Self {
821 fixed: p.get()?,
822 gaps: p.take_rest(),
823 })
824 }
825}
826
827pub struct ManProcSym<'a> {
831 #[allow(missing_docs)]
832 pub fixed: &'a ManProcSymFixed,
833 #[allow(missing_docs)]
834 pub name: &'a BStr,
835}
836
837pub type TokenIdLe = U32<LE>;
839
840#[repr(C)]
841#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
842#[allow(missing_docs)]
843pub struct ManProcSymFixed {
844 pub block: BlockHeader,
845 pub pnext: U32<LE>,
847 pub len: U32<LE>,
849 pub dbg_start: U32<LE>,
851 pub dbg_end: U32<LE>,
853 pub token: TokenIdLe,
855 pub off: U32<LE>,
856 pub seg: U16<LE>,
857 pub flags: u8, pub padding: u8,
859 pub ret_reg: U16<LE>,
861 }
863
864impl<'a> Parse<'a> for ManProcSym<'a> {
865 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
866 Ok(Self {
867 fixed: p.get()?,
868 name: p.strz()?,
869 })
870 }
871}
872
873#[derive(Clone, Debug)]
875pub struct Trampoline<'a> {
876 pub fixed: &'a TrampolineFixed,
878
879 pub rest: &'a [u8],
881}
882
883#[repr(C)]
885#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
886pub struct TrampolineFixed {
887 pub tramp_type: U16<LE>,
889 pub cb_thunk: U16<LE>,
891 pub off_thunk: U32<LE>,
893 pub off_target: U32<LE>,
895 pub sect_thunk: U16<LE>,
897 pub sect_target: U16<LE>,
899}
900
901impl<'a> Parse<'a> for Trampoline<'a> {
902 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
903 Ok(Self {
904 fixed: p.get()?,
905 rest: p.take_rest(),
906 })
907 }
908}
909
910#[derive(Clone, Debug)]
914pub struct BuildInfo {
915 pub item: ItemId,
917}
918
919impl<'a> Parse<'a> for BuildInfo {
920 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
921 Ok(Self { item: p.u32()? })
922 }
923}
924
925#[derive(Clone, Debug)]
927pub struct UsingNamespace<'a> {
928 pub namespace: &'a BStr,
930}
931
932impl<'a> Parse<'a> for UsingNamespace<'a> {
933 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
934 Ok(Self {
935 namespace: p.strz()?,
936 })
937 }
938}
939
940#[derive(Clone, Debug)]
942#[allow(missing_docs)]
943pub struct Label<'a> {
944 pub fixed: &'a LabelFixed,
945 pub name: &'a BStr,
946}
947
948#[repr(C)]
950#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
951#[allow(missing_docs)]
952pub struct LabelFixed {
953 pub offset_segment: OffsetSegment,
954 pub flags: u8,
955}
956
957impl<'a> Parse<'a> for Label<'a> {
958 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
959 Ok(Self {
960 fixed: p.get()?,
961 name: p.strz()?,
962 })
963 }
964}
965
966#[derive(Clone, Debug)]
968pub struct FunctionList<'a> {
969 pub funcs: &'a [ItemIdLe],
971
972 pub counts: &'a [U32<LE>],
979}
980
981impl<'a> Parse<'a> for FunctionList<'a> {
982 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
983 let num_funcs = p.u32()? as usize;
984 let funcs: &[ItemIdLe] = p.slice(num_funcs)?;
985 let num_counts = num_funcs.min(p.len() / size_of::<U32<LE>>());
986 let counts = p.slice(num_counts)?;
987 Ok(Self { funcs, counts })
988 }
989}
990
991#[allow(missing_docs)]
993#[derive(Clone, Debug)]
994pub struct InlineSite<'a> {
995 pub fixed: &'a InlineSiteFixed,
996 pub binary_annotations: &'a [u8],
998}
999
1000#[repr(C)]
1002#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1003#[allow(missing_docs)]
1004pub struct InlineSiteFixed {
1005 pub block: BlockHeader,
1006 pub inlinee: ItemIdLe,
1007}
1008
1009impl<'a> Parse<'a> for InlineSite<'a> {
1010 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1011 Ok(Self {
1012 fixed: p.get()?,
1013 binary_annotations: p.take_rest(),
1014 })
1015 }
1016}
1017
1018#[allow(missing_docs)]
1020#[derive(Clone, Debug)]
1021pub struct InlineSite2<'a> {
1022 pub fixed: &'a InlineSite2Fixed,
1023 pub binary_annotations: &'a [u8],
1025}
1026
1027#[repr(C)]
1029#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1030#[allow(missing_docs)]
1031pub struct InlineSite2Fixed {
1032 pub block: BlockHeader,
1033 pub inlinee: ItemIdLe,
1034 pub invocations: U32<LE>,
1035}
1036
1037impl<'a> Parse<'a> for InlineSite2<'a> {
1038 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1039 Ok(Self {
1040 fixed: p.get()?,
1041 binary_annotations: p.take_rest(),
1042 })
1043 }
1044}
1045
1046#[repr(C)]
1049#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1050#[allow(missing_docs)]
1051pub struct FrameCookie {
1052 pub offset: I32<LE>,
1054 pub reg: U16<LE>,
1055 pub cookie_type: u8,
1056 pub flags: u8,
1057}
1058
1059#[repr(C)]
1081#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1082#[allow(missing_docs)]
1083pub struct CallSiteInfo {
1084 pub offset: OffsetSegment,
1085 pub padding: U16<LE>,
1086 pub func_type: TypeIndexLe,
1087}
1088
1089#[repr(C)]
1091#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1092#[allow(missing_docs)]
1093pub struct HeapAllocSite {
1094 pub offset: OffsetSegment,
1095 pub instruction_size: U16<LE>,
1097 pub func_type: TypeIndexLe,
1098}
1099
1100#[allow(missing_docs)]
1102#[derive(Clone, Debug)]
1103pub struct Annotation<'a> {
1104 pub fixed: &'a AnnotationFixed,
1105 pub strings: &'a [u8],
1106}
1107
1108#[repr(C)]
1109#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1110#[allow(missing_docs)]
1111pub struct AnnotationFixed {
1112 pub offset: OffsetSegment,
1113 pub num_strings: U16<LE>,
1114}
1115
1116impl<'a> Parse<'a> for Annotation<'a> {
1117 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1118 Ok(Self {
1119 fixed: p.get()?,
1120 strings: p.take_rest(),
1121 })
1122 }
1123}
1124
1125impl<'a> Annotation<'a> {
1126 pub fn iter_strings(&self) -> AnnotationIterStrings<'a> {
1128 AnnotationIterStrings {
1129 num_strings: self.fixed.num_strings.get(),
1130 bytes: self.strings,
1131 }
1132 }
1133}
1134
1135#[allow(missing_docs)]
1137pub struct AnnotationIterStrings<'a> {
1138 pub num_strings: u16,
1139 pub bytes: &'a [u8],
1140}
1141
1142impl<'a> Iterator for AnnotationIterStrings<'a> {
1143 type Item = &'a BStr;
1144
1145 fn next(&mut self) -> Option<Self::Item> {
1146 if self.num_strings == 0 {
1147 return None;
1148 }
1149
1150 self.num_strings -= 1;
1151 let mut p = Parser::new(self.bytes);
1152 let s = p.strz().ok()?;
1153 self.bytes = p.into_rest();
1154 Some(s)
1155 }
1156}
1157
1158#[derive(Clone, Debug)]
1160pub struct HotPatchFunc<'a> {
1161 pub func: ItemId,
1163
1164 pub name: &'a BStr,
1166}
1167
1168impl<'a> Parse<'a> for HotPatchFunc<'a> {
1169 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1170 Ok(Self {
1171 func: p.u32()?,
1172 name: p.strz()?,
1173 })
1174 }
1175}
1176
1177pub const TRAMPOLINE_KIND_INCREMENTAL: u16 = 0;
1181pub const TRAMPOLINE_KIND_BRANCH_ISLAND: u16 = 1;
1183
1184#[derive(Clone, Debug)]
1186#[allow(missing_docs)]
1187pub enum SymData<'a> {
1188 Unknown,
1189 ObjName(ObjectName<'a>),
1190 Compile3(Compile3<'a>),
1191 Proc(Proc<'a>),
1192 Udt(Udt<'a>),
1193 Constant(Constant<'a>),
1194 ManagedConstant(ManagedConstant<'a>),
1195 RefSym2(RefSym2<'a>),
1196 Data(Data<'a>),
1197 ThreadData(ThreadStorageData<'a>),
1198 Pub(Pub<'a>),
1199 End,
1200 FrameProc(&'a FrameProc),
1201 RegRel(RegRel<'a>),
1202 Block(Block<'a>),
1203 Local(Local<'a>),
1204 DefRangeFramePointerRel(DefRangeSymFramePointerRel<'a>),
1205 DefRangeRegister(DefRangeRegister<'a>),
1206 DefRangeRegisterRel(DefRangeRegisterRel<'a>),
1207 DefRangeFramePointerRelFullScope(&'a DefRangeFramePointerRelFullScope),
1208 DefRangeSubFieldRegister(DefRangeSubFieldRegister<'a>),
1209 Trampoline(Trampoline<'a>),
1210 BuildInfo(BuildInfo),
1211 UsingNamespace(UsingNamespace<'a>),
1212 InlineSiteEnd,
1213 Label(Label<'a>),
1214 FunctionList(FunctionList<'a>),
1215 InlineSite(InlineSite<'a>),
1216 InlineSite2(InlineSite2<'a>),
1217 FrameCookie(&'a FrameCookie),
1218 CallSiteInfo(&'a CallSiteInfo),
1219 HeapAllocSite(&'a HeapAllocSite),
1220 ManagedProc(ManagedProc<'a>),
1221 Annotation(Annotation<'a>),
1222 HotPatchFunc(HotPatchFunc<'a>),
1223}
1224
1225impl<'a> SymData<'a> {
1226 pub fn parse(kind: SymKind, data: &'a [u8]) -> Result<Self, ParserError> {
1229 let mut p = Parser::new(data);
1230 Self::from_parser(kind, &mut p)
1231 }
1232
1233 pub fn from_parser(kind: SymKind, p: &mut Parser<'a>) -> Result<Self, ParserError> {
1239 Ok(match kind {
1240 SymKind::S_OBJNAME => Self::ObjName(p.parse()?),
1241 SymKind::S_GPROC32 | SymKind::S_LPROC32 => Self::Proc(p.parse()?),
1242 SymKind::S_COMPILE3 => Self::Compile3(p.parse()?),
1243 SymKind::S_UDT => Self::Udt(p.parse()?),
1244 SymKind::S_CONSTANT => Self::Constant(p.parse()?),
1245 SymKind::S_MANCONSTANT => Self::Constant(p.parse()?),
1246 SymKind::S_PUB32 => Self::Pub(p.parse()?),
1247 SymKind::S_PUB32_ST => Self::Pub(Pub::parse_st(p)?),
1248
1249 SymKind::S_PROCREF
1250 | SymKind::S_LPROCREF
1251 | SymKind::S_DATAREF
1252 | SymKind::S_ANNOTATIONREF => Self::RefSym2(p.parse()?),
1253
1254 SymKind::S_LDATA32 | SymKind::S_GDATA32 | SymKind::S_LMANDATA | SymKind::S_GMANDATA => {
1255 Self::Data(p.parse()?)
1256 }
1257
1258 SymKind::S_LTHREAD32 | SymKind::S_GTHREAD32 => Self::ThreadData(p.parse()?),
1259 SymKind::S_END => Self::End,
1260 SymKind::S_FRAMEPROC => Self::FrameProc(p.get()?),
1261 SymKind::S_REGREL32 => Self::RegRel(p.parse()?),
1262 SymKind::S_BLOCK32 => Self::Block(p.parse()?),
1263 SymKind::S_LOCAL => Self::Local(p.parse()?),
1264 SymKind::S_DEFRANGE_FRAMEPOINTER_REL => Self::DefRangeFramePointerRel(p.parse()?),
1265 SymKind::S_DEFRANGE_REGISTER => Self::DefRangeRegister(p.parse()?),
1266 SymKind::S_DEFRANGE_REGISTER_REL => Self::DefRangeRegisterRel(p.parse()?),
1267 SymKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE => {
1268 Self::DefRangeFramePointerRelFullScope(p.get()?)
1269 }
1270 SymKind::S_DEFRANGE_SUBFIELD_REGISTER => Self::DefRangeSubFieldRegister(p.parse()?),
1271 SymKind::S_TRAMPOLINE => Self::Trampoline(p.parse()?),
1272 SymKind::S_BUILDINFO => Self::BuildInfo(p.parse()?),
1273 SymKind::S_UNAMESPACE => Self::UsingNamespace(p.parse()?),
1274 SymKind::S_INLINESITE_END => Self::InlineSiteEnd,
1275 SymKind::S_LABEL32 => Self::Label(p.parse()?),
1276 SymKind::S_CALLEES | SymKind::S_CALLERS => Self::FunctionList(p.parse()?),
1277 SymKind::S_INLINESITE => Self::InlineSite(p.parse()?),
1278 SymKind::S_INLINESITE2 => Self::InlineSite2(p.parse()?),
1279 SymKind::S_INLINEES => Self::FunctionList(p.parse()?),
1280 SymKind::S_FRAMECOOKIE => Self::FrameCookie(p.get()?),
1281 SymKind::S_CALLSITEINFO => Self::CallSiteInfo(p.get()?),
1282 SymKind::S_HEAPALLOCSITE => Self::HeapAllocSite(p.get()?),
1283 SymKind::S_GMANPROC | SymKind::S_LMANPROC => Self::ManagedProc(p.parse()?),
1284 SymKind::S_ANNOTATION => Self::Annotation(p.parse()?),
1285 SymKind::S_HOTPATCHFUNC => Self::HotPatchFunc(p.parse()?),
1286
1287 _ => Self::Unknown,
1288 })
1289 }
1290
1291 pub fn name(&self) -> Option<&'a BStr> {
1293 match self {
1294 Self::Proc(proc) => Some(proc.name),
1295 Self::Data(data) => Some(data.name),
1296 Self::ThreadData(thread_data) => Some(thread_data.name),
1297 Self::Udt(udt) => Some(udt.name),
1298 Self::Local(local) => Some(local.name),
1299 Self::RefSym2(refsym) => Some(refsym.name),
1300 Self::Constant(c) => Some(c.name),
1301 Self::ManagedConstant(c) => Some(c.name),
1302 _ => None,
1303 }
1304 }
1305}