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(Copy, Clone, Eq, PartialEq, Debug)]
26pub enum SymbolStreamKind {
27 Global,
29
30 Module,
32}
33
34impl SymbolStreamKind {
35 pub fn stream_offset(self) -> usize {
37 match self {
38 Self::Global => 0,
39 Self::Module => 4,
40 }
41 }
42}
43
44#[derive(IntoBytes, FromBytes, Unaligned, Immutable, KnownLayout, Default, Clone, Debug)]
46#[repr(C)]
47#[allow(missing_docs)]
48pub struct BlockHeader {
49 pub p_parent: U32<LE>,
55
56 pub p_end: U32<LE>,
58}
59
60#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Debug)]
64#[repr(C)]
65#[allow(missing_docs)]
66pub struct ProcFixed {
67 pub p_parent: U32<LE>,
68 pub p_end: U32<LE>,
69 pub p_next: U32<LE>,
70 pub proc_len: U32<LE>,
71 pub debug_start: U32<LE>,
72 pub debug_end: U32<LE>,
73 pub proc_type: TypeIndexLe,
74 pub offset_segment: OffsetSegment,
75 pub flags: u8,
76}
77
78#[allow(missing_docs)]
90#[derive(Clone, Debug)]
91pub struct Proc<'a> {
92 pub fixed: &'a ProcFixed,
93 pub name: &'a BStr,
94}
95
96impl<'a> Parse<'a> for Proc<'a> {
97 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
98 Ok(Self {
99 fixed: p.get()?,
100 name: p.strz()?,
101 })
102 }
103}
104
105#[test]
107fn test_parse_proc() {
108 #[rustfmt::skip]
109 let data = &[
110 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 ];
125
126 let mut i = SymIter::new(data);
127
128 let s0 = i.next().unwrap();
129 assert_eq!(s0.kind, SymKind::S_GPROC32);
130 assert_eq!(s0.data.len(), 0x2c);
131
132 match s0.parse().unwrap() {
133 SymData::Proc(proc) => {
134 assert_eq!(proc.fixed.p_parent.get(), 0);
135 assert_eq!(proc.fixed.p_end.get(), 0x40);
136 assert_eq!(proc.name, "memset");
137 }
138 _ => panic!(),
139 }
140
141 let s1 = i.next().unwrap();
142 assert_eq!(s1.kind, SymKind::S_END);
143 assert!(s1.data.is_empty());
144}
145
146#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Debug)]
150#[repr(C)]
151#[allow(missing_docs)]
152pub struct ManagedProcFixed {
153 pub p_parent: U32<LE>,
154 pub p_end: U32<LE>,
155 pub p_next: U32<LE>,
156 pub proc_len: U32<LE>,
157 pub debug_start: U32<LE>,
158 pub debug_end: U32<LE>,
159 pub token: U32<LE>,
160 pub offset_segment: OffsetSegment,
161 pub flags: u8,
162 pub return_reg: U16<LE>,
163}
164
165#[allow(missing_docs)]
167#[derive(Clone, Debug)]
168pub struct ManagedProc<'a> {
169 pub fixed: &'a ManagedProcFixed,
170 pub name: &'a BStr,
171}
172
173impl<'a> Parse<'a> for ManagedProc<'a> {
174 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
175 Ok(Self {
176 fixed: p.get()?,
177 name: p.strz()?,
178 })
179 }
180}
181
182#[repr(C)]
183#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
184#[allow(missing_docs)]
185pub struct ThunkFixed {
186 pub block: BlockHeader,
187 pub p_next: U32<LE>,
188 pub offset_segment: OffsetSegment,
189 pub length: U16<LE>,
190 pub thunk_ordinal: u8,
191 }
194
195#[allow(missing_docs)]
196pub struct Thunk<'a> {
197 pub fixed: &'a ThunkFixed,
198 pub name: &'a BStr,
199 pub variant: &'a [u8],
200}
201
202impl<'a> Parse<'a> for Thunk<'a> {
203 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
204 Ok(Self {
205 fixed: p.get()?,
206 name: p.strz()?,
207 variant: p.take_rest(),
208 })
209 }
210}
211
212#[repr(C)]
214#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
215pub struct SymHeader {
216 pub len: U16<LE>,
221
222 pub kind: U16<LE>,
224}
225
226#[derive(Clone)]
228pub struct Sym<'a> {
229 pub kind: SymKind,
231 pub data: &'a [u8],
233}
234
235impl<'a> Sym<'a> {
236 pub fn parse(&self) -> Result<SymData<'a>, ParserError> {
238 SymData::parse(self.kind, self.data)
239 }
240}
241
242impl<'a> Debug for Sym<'a> {
243 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
244 write!(fmt, "{:?}", self.kind)
245 }
246}
247
248pub struct SymMut<'a> {
251 pub kind: SymKind,
253 pub data: &'a mut [u8],
255}
256
257#[allow(missing_docs)]
270#[derive(Clone, Debug)]
271pub struct Pub<'a> {
272 pub fixed: &'a PubFixed,
273 pub name: &'a BStr,
274}
275
276impl<'a> Pub<'a> {
277 pub fn offset_segment(&self) -> OffsetSegment {
279 self.fixed.offset_segment.clone()
280 }
281}
282
283#[allow(missing_docs)]
284#[repr(C)]
285#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
286pub struct PubFixed {
287 pub flags: U32<LE>,
288 pub offset_segment: OffsetSegment,
289 }
291
292#[allow(missing_docs)]
293impl<'a> Parse<'a> for Pub<'a> {
294 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
295 Ok(Self {
296 fixed: p.get()?,
297 name: p.strz()?,
298 })
299 }
300}
301
302impl<'a> Pub<'a> {
303 pub fn parse_st(p: &mut Parser<'a>) -> Result<Self, ParserError> {
305 Ok(Self {
306 fixed: p.get()?,
307 name: p.strt_raw()?,
308 })
309 }
310}
311
312#[allow(missing_docs)]
314#[derive(Clone, Debug)]
315pub struct Constant<'a> {
316 pub type_: TypeIndex,
317 pub value: Number<'a>,
318 pub name: &'a BStr,
319}
320
321impl<'a> Parse<'a> for Constant<'a> {
322 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
323 Ok(Self {
324 type_: p.type_index()?,
325 value: p.number()?,
326 name: p.strz()?,
327 })
328 }
329}
330
331#[allow(missing_docs)]
333#[derive(Clone, Debug)]
334pub struct ManagedConstant<'a> {
335 pub token: u32,
336 pub value: Number<'a>,
337 pub name: &'a BStr,
338}
339
340impl<'a> Parse<'a> for ManagedConstant<'a> {
341 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
342 Ok(Self {
343 token: p.u32()?,
344 value: p.number()?,
345 name: p.strz()?,
346 })
347 }
348}
349
350#[allow(missing_docs)]
358#[derive(Clone, Debug)]
359pub struct RefSym2<'a> {
360 pub header: &'a RefSym2Fixed,
361 pub name: &'a BStr,
362}
363
364#[allow(missing_docs)]
365#[repr(C)]
366#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
367pub struct RefSym2Fixed {
368 pub name_checksum: U32<LE>,
372
373 pub symbol_offset: U32<LE>,
378
379 pub module_index: U16<LE>,
383 }
385
386impl<'a> Parse<'a> for RefSym2<'a> {
387 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
388 Ok(Self {
389 header: p.get()?,
390 name: p.strz()?,
391 })
392 }
393}
394
395#[allow(missing_docs)]
396#[repr(C)]
397#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
398pub struct ThreadStorageFixed {
399 pub type_: TypeIndexLe,
400 pub offset_segment: OffsetSegment,
401}
402
403#[derive(Clone, Debug)]
407pub struct ThreadStorageData<'a> {
408 #[allow(missing_docs)]
409 pub header: &'a ThreadStorageFixed,
410 #[allow(missing_docs)]
411 pub name: &'a BStr,
412}
413
414impl<'a> Parse<'a> for ThreadStorageData<'a> {
415 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
416 Ok(Self {
417 header: p.get()?,
418 name: p.strz()?,
419 })
420 }
421}
422
423#[allow(missing_docs)]
424#[repr(C)]
425#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
426pub struct DataFixed {
427 pub type_: TypeIndexLe,
428 pub offset_segment: OffsetSegment,
429}
430
431#[allow(missing_docs)]
433#[derive(Clone)]
434pub struct Data<'a> {
435 pub header: &'a DataFixed,
436 pub name: &'a BStr,
437}
438
439impl<'a> Parse<'a> for Data<'a> {
440 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
441 Ok(Self {
442 header: p.get()?,
443 name: p.strz()?,
444 })
445 }
446}
447
448impl<'a> Debug for Data<'a> {
449 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
450 write!(
451 f,
452 "Data: {} {:?} {}",
453 self.header.offset_segment,
454 self.header.type_.get(),
455 self.name
456 )
457 }
458}
459
460#[derive(Clone, Debug)]
462pub struct Udt<'a> {
463 pub type_: TypeIndex,
465 pub name: &'a BStr,
467}
468
469impl<'a> Parse<'a> for Udt<'a> {
470 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
471 Ok(Self {
472 type_: p.type_index()?,
473 name: p.strz()?,
474 })
475 }
476}
477
478#[derive(Clone, Debug)]
480pub struct ObjectName<'a> {
481 pub signature: u32,
484 pub name: &'a BStr,
486}
487
488impl<'a> Parse<'a> for ObjectName<'a> {
489 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
490 Ok(Self {
491 signature: p.u32()?,
492 name: p.strz()?,
493 })
494 }
495}
496
497#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
499#[repr(C)]
500#[allow(missing_docs)]
501pub struct Compile3Fixed {
502 pub flags: U32<LE>,
503 pub machine: U16<LE>,
504 pub frontend_major: U16<LE>,
505 pub frontend_minor: U16<LE>,
506 pub frontend_build: U16<LE>,
507 pub frontend_qfe: U16<LE>,
508 pub ver_major: U16<LE>,
509 pub ver_minor: U16<LE>,
510 pub ver_build: U16<LE>,
511 pub ver_qfe: U16<LE>,
512 }
514
515#[allow(missing_docs)]
517#[derive(Clone, Debug)]
518pub struct Compile3<'a> {
519 pub fixed: &'a Compile3Fixed,
520 pub name: &'a BStr,
521}
522
523impl<'a> Parse<'a> for Compile3<'a> {
524 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
525 Ok(Self {
526 fixed: p.get()?,
527 name: p.strz()?,
528 })
529 }
530}
531
532#[repr(C)]
536#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
537#[allow(missing_docs)]
538pub struct FrameProc {
539 frame_size: U32<LE>,
541 pad_size: U32<LE>,
543 pad_offset: U32<LE>,
545 save_regs_size: U32<LE>,
547 offset_exception_handler: U32<LE>,
548 exception_handler_section: U16<LE>,
549 padding: U16<LE>,
550 flags: U32<LE>,
551}
552
553#[repr(C)]
554#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
555#[allow(missing_docs)]
556pub struct RegRelFixed {
557 pub offset: U32<LE>,
558 pub ty: TypeIndexLe,
559 pub register: U16<LE>,
560 }
562
563#[derive(Clone, Debug)]
566#[allow(missing_docs)]
567pub struct RegRel<'a> {
568 pub fixed: &'a RegRelFixed,
569 pub name: &'a BStr,
570}
571
572impl<'a> Parse<'a> for RegRel<'a> {
573 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
574 Ok(Self {
575 fixed: p.get()?,
576 name: p.strz()?,
577 })
578 }
579}
580
581#[derive(Clone, Debug)]
589#[allow(missing_docs)]
590pub struct Block<'a> {
591 pub fixed: &'a BlockFixed,
592 pub name: &'a BStr,
593}
594
595#[repr(C)]
596#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
597#[allow(missing_docs)]
598pub struct BlockFixed {
599 pub header: BlockHeader,
601
602 pub length: U32<LE>,
604
605 pub offset_segment: OffsetSegment,
606}
607
608impl<'a> Parse<'a> for Block<'a> {
609 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
610 Ok(Self {
611 fixed: p.get()?,
612 name: p.strz()?,
613 })
614 }
615}
616
617#[derive(Clone, Debug)]
622#[allow(missing_docs)]
623pub struct Local<'a> {
624 pub fixed: &'a LocalFixed,
625 pub name: &'a BStr,
626}
627
628#[repr(C)]
629#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
630#[allow(missing_docs)]
631pub struct LocalFixed {
632 pub ty: TypeIndexLe,
633 pub flags: U16<LE>,
635 }
637
638impl<'a> Parse<'a> for Local<'a> {
639 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
640 Ok(Self {
641 fixed: p.get()?,
642 name: p.strz()?,
643 })
644 }
645}
646
647#[repr(C)]
651#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
652pub struct LVarAddrRange {
653 pub start: OffsetSegment,
655 pub range_size: U16<LE>,
657}
658
659#[repr(C)]
664#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
665pub struct LVarAddrGap {
666 pub gap_start_offset: U16<LE>,
668 pub range_size: U16<LE>,
670}
671
672#[repr(C)]
674#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
675#[allow(missing_docs)]
676pub struct DefRangeSymFramePointerRelFixed {
677 pub offset_to_frame_pointer: U32<LE>,
678
679 pub range: LVarAddrRange,
681}
682
683#[allow(missing_docs)]
685#[derive(Clone, Debug)]
686pub struct DefRangeSymFramePointerRel<'a> {
687 pub fixed: &'a DefRangeSymFramePointerRelFixed,
688 pub gaps: &'a [LVarAddrGap],
690}
691
692impl<'a> Parse<'a> for DefRangeSymFramePointerRel<'a> {
693 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
694 let fixed = p.get()?;
695 let gaps = p.slice(p.len() / size_of::<LVarAddrGap>())?;
696 Ok(Self { fixed, gaps })
697 }
698}
699
700#[repr(C)]
704#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
705#[allow(missing_docs)]
706pub struct RangeAttrLe {
707 pub value: U16<LE>,
710}
711
712#[repr(C)]
716#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
717#[allow(missing_docs)]
718pub struct DefRangeRegisterFixed {
719 pub reg: U16<LE>,
721 pub attr: RangeAttrLe,
723}
724
725#[derive(Clone, Debug)]
729#[allow(missing_docs)]
730pub struct DefRangeRegister<'a> {
731 pub fixed: &'a DefRangeRegisterFixed,
732 pub gaps: &'a [u8],
733}
734
735impl<'a> Parse<'a> for DefRangeRegister<'a> {
736 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
737 Ok(Self {
738 fixed: p.get()?,
739 gaps: p.take_rest(),
740 })
741 }
742}
743
744#[allow(missing_docs)]
746#[derive(Debug, Clone)]
747pub struct DefRangeRegisterRel<'a> {
748 pub fixed: &'a DefRangeRegisterRelFixed,
749
750 pub gaps: &'a [u8],
752}
753
754#[repr(C)]
756#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
757pub struct DefRangeRegisterRelFixed {
758 pub base_reg: U16<LE>,
760
761 pub flags: U16<LE>,
767
768 pub base_pointer_offset: I32<LE>,
770
771 pub range: LVarAddrRange,
773}
774
775impl<'a> Parse<'a> for DefRangeRegisterRel<'a> {
776 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
777 Ok(Self {
778 fixed: p.get()?,
779 gaps: p.take_rest(),
780 })
781 }
782}
783
784#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
788#[repr(C)]
789pub struct DefRangeFramePointerRelFullScope {
790 pub frame_pointer_offset: I32<LE>,
792}
793
794#[derive(Clone, Debug)]
798#[allow(missing_docs)]
799pub struct DefRangeSubFieldRegister<'a> {
800 pub fixed: &'a DefRangeSubFieldRegisterFixed,
801 pub gaps: &'a [u8],
802}
803
804#[repr(C)]
805#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
806#[allow(missing_docs)]
807pub struct DefRangeSubFieldRegisterFixed {
808 pub reg: U16<LE>,
809 pub attr: RangeAttrLe,
810 pub flags: U32<LE>,
811 pub range: LVarAddrRange,
812}
813
814impl<'a> Parse<'a> for DefRangeSubFieldRegister<'a> {
815 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
816 Ok(Self {
817 fixed: p.get()?,
818 gaps: p.take_rest(),
819 })
820 }
821}
822
823pub struct ManProcSym<'a> {
827 #[allow(missing_docs)]
828 pub fixed: &'a ManProcSymFixed,
829 #[allow(missing_docs)]
830 pub name: &'a BStr,
831}
832
833pub type TokenIdLe = U32<LE>;
835
836#[repr(C)]
837#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
838#[allow(missing_docs)]
839pub struct ManProcSymFixed {
840 pub block: BlockHeader,
841 pub pnext: U32<LE>,
843 pub len: U32<LE>,
845 pub dbg_start: U32<LE>,
847 pub dbg_end: U32<LE>,
849 pub token: TokenIdLe,
851 pub off: U32<LE>,
852 pub seg: U16<LE>,
853 pub flags: u8, pub padding: u8,
855 pub ret_reg: U16<LE>,
857 }
859
860impl<'a> Parse<'a> for ManProcSym<'a> {
861 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
862 Ok(Self {
863 fixed: p.get()?,
864 name: p.strz()?,
865 })
866 }
867}
868
869#[derive(Clone, Debug)]
871pub struct Trampoline<'a> {
872 pub fixed: &'a TrampolineFixed,
874
875 pub rest: &'a [u8],
877}
878
879#[repr(C)]
881#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
882pub struct TrampolineFixed {
883 pub tramp_type: U16<LE>,
885 pub cb_thunk: U16<LE>,
887 pub off_thunk: U32<LE>,
889 pub off_target: U32<LE>,
891 pub sect_thunk: U16<LE>,
893 pub sect_target: U16<LE>,
895}
896
897impl<'a> Parse<'a> for Trampoline<'a> {
898 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
899 Ok(Self {
900 fixed: p.get()?,
901 rest: p.take_rest(),
902 })
903 }
904}
905
906#[derive(Clone, Debug)]
910pub struct BuildInfo {
911 pub item: ItemId,
913}
914
915impl<'a> Parse<'a> for BuildInfo {
916 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
917 Ok(Self { item: p.u32()? })
918 }
919}
920
921#[derive(Clone, Debug)]
923pub struct UsingNamespace<'a> {
924 pub namespace: &'a BStr,
926}
927
928impl<'a> Parse<'a> for UsingNamespace<'a> {
929 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
930 Ok(Self {
931 namespace: p.strz()?,
932 })
933 }
934}
935
936#[derive(Clone, Debug)]
938#[allow(missing_docs)]
939pub struct Label<'a> {
940 pub fixed: &'a LabelFixed,
941 pub name: &'a BStr,
942}
943
944#[repr(C)]
946#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
947#[allow(missing_docs)]
948pub struct LabelFixed {
949 pub offset_segment: OffsetSegment,
950 pub flags: u8,
951}
952
953impl<'a> Parse<'a> for Label<'a> {
954 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
955 Ok(Self {
956 fixed: p.get()?,
957 name: p.strz()?,
958 })
959 }
960}
961
962#[derive(Clone, Debug)]
964pub struct FunctionList<'a> {
965 pub funcs: &'a [ItemIdLe],
967
968 pub invocations: &'a [U32<LE>],
972}
973
974impl<'a> Parse<'a> for FunctionList<'a> {
975 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
976 let count = p.u32()?;
977 let funcs: &[ItemIdLe] = p.slice(count as usize)?;
978 let num_invocations = p.len() / size_of::<U32<LE>>();
979 let invocations = p.slice(num_invocations)?;
980 Ok(Self { funcs, invocations })
981 }
982}
983
984#[allow(missing_docs)]
986#[derive(Clone, Debug)]
987pub struct InlineSite<'a> {
988 pub fixed: &'a InlineSiteFixed,
989 pub binary_annotations: &'a [u8],
991}
992
993#[repr(C)]
995#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
996#[allow(missing_docs)]
997pub struct InlineSiteFixed {
998 pub block: BlockHeader,
999 pub inlinee: ItemIdLe,
1000}
1001
1002impl<'a> Parse<'a> for InlineSite<'a> {
1003 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1004 Ok(Self {
1005 fixed: p.get()?,
1006 binary_annotations: p.take_rest(),
1007 })
1008 }
1009}
1010
1011#[allow(missing_docs)]
1013#[derive(Clone, Debug)]
1014pub struct InlineSite2<'a> {
1015 pub fixed: &'a InlineSite2Fixed,
1016 pub binary_annotations: &'a [u8],
1018}
1019
1020#[repr(C)]
1022#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1023#[allow(missing_docs)]
1024pub struct InlineSite2Fixed {
1025 pub block: BlockHeader,
1026 pub inlinee: ItemIdLe,
1027 pub invocations: U32<LE>,
1028}
1029
1030impl<'a> Parse<'a> for InlineSite2<'a> {
1031 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1032 Ok(Self {
1033 fixed: p.get()?,
1034 binary_annotations: p.take_rest(),
1035 })
1036 }
1037}
1038
1039#[repr(C)]
1042#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1043#[allow(missing_docs)]
1044pub struct FrameCookie {
1045 pub offset: I32<LE>,
1047 pub reg: U16<LE>,
1048 pub cookie_type: u8,
1049 pub flags: u8,
1050}
1051
1052#[repr(C)]
1074#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1075#[allow(missing_docs)]
1076pub struct CallSiteInfo {
1077 pub offset: OffsetSegment,
1078 pub padding: U16<LE>,
1079 pub func_type: TypeIndexLe,
1080}
1081
1082#[repr(C)]
1084#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1085#[allow(missing_docs)]
1086pub struct HeapAllocSite {
1087 pub offset: OffsetSegment,
1088 pub instruction_size: U16<LE>,
1090 pub func_type: TypeIndexLe,
1091}
1092
1093#[allow(missing_docs)]
1095#[derive(Clone, Debug)]
1096pub struct Annotation<'a> {
1097 pub fixed: &'a AnnotationFixed,
1098 pub strings: &'a [u8],
1099}
1100
1101#[repr(C)]
1102#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1103#[allow(missing_docs)]
1104pub struct AnnotationFixed {
1105 pub offset: OffsetSegment,
1106 pub num_strings: U16<LE>,
1107}
1108
1109impl<'a> Parse<'a> for Annotation<'a> {
1110 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1111 Ok(Self {
1112 fixed: p.get()?,
1113 strings: p.take_rest(),
1114 })
1115 }
1116}
1117
1118impl<'a> Annotation<'a> {
1119 pub fn iter_strings(&self) -> AnnotationIterStrings<'a> {
1121 AnnotationIterStrings {
1122 num_strings: self.fixed.num_strings.get(),
1123 bytes: self.strings,
1124 }
1125 }
1126}
1127
1128#[allow(missing_docs)]
1130pub struct AnnotationIterStrings<'a> {
1131 pub num_strings: u16,
1132 pub bytes: &'a [u8],
1133}
1134
1135impl<'a> Iterator for AnnotationIterStrings<'a> {
1136 type Item = &'a BStr;
1137
1138 fn next(&mut self) -> Option<Self::Item> {
1139 if self.num_strings == 0 {
1140 return None;
1141 }
1142
1143 self.num_strings -= 1;
1144 let mut p = Parser::new(self.bytes);
1145 let s = p.strz().ok()?;
1146 self.bytes = p.into_rest();
1147 Some(s)
1148 }
1149}
1150
1151pub const TRAMPOLINE_KIND_INCREMENTAL: u16 = 0;
1155pub const TRAMPOLINE_KIND_BRANCH_ISLAND: u16 = 1;
1157
1158#[derive(Clone, Debug)]
1160#[allow(missing_docs)]
1161pub enum SymData<'a> {
1162 Unknown,
1163 ObjName(ObjectName<'a>),
1164 Compile3(Compile3<'a>),
1165 Proc(Proc<'a>),
1166 Udt(Udt<'a>),
1167 Constant(Constant<'a>),
1168 ManagedConstant(ManagedConstant<'a>),
1169 RefSym2(RefSym2<'a>),
1170 Data(Data<'a>),
1171 ThreadData(ThreadStorageData<'a>),
1172 Pub(Pub<'a>),
1173 End,
1174 FrameProc(&'a FrameProc),
1175 RegRel(RegRel<'a>),
1176 Block(Block<'a>),
1177 Local(Local<'a>),
1178 DefRangeFramePointerRel(DefRangeSymFramePointerRel<'a>),
1179 DefRangeRegister(DefRangeRegister<'a>),
1180 DefRangeRegisterRel(DefRangeRegisterRel<'a>),
1181 DefRangeFramePointerRelFullScope(&'a DefRangeFramePointerRelFullScope),
1182 DefRangeSubFieldRegister(DefRangeSubFieldRegister<'a>),
1183 Trampoline(Trampoline<'a>),
1184 BuildInfo(BuildInfo),
1185 UsingNamespace(UsingNamespace<'a>),
1186 InlineSiteEnd,
1187 Label(Label<'a>),
1188 FunctionList(FunctionList<'a>),
1189 InlineSite(InlineSite<'a>),
1190 InlineSite2(InlineSite2<'a>),
1191 FrameCookie(&'a FrameCookie),
1192 CallSiteInfo(&'a CallSiteInfo),
1193 HeapAllocSite(&'a HeapAllocSite),
1194 ManagedProc(ManagedProc<'a>),
1195 Annotation(Annotation<'a>),
1196}
1197
1198impl<'a> SymData<'a> {
1199 pub fn parse(kind: SymKind, data: &'a [u8]) -> Result<Self, ParserError> {
1202 let mut p = Parser::new(data);
1203 Self::from_parser(kind, &mut p)
1204 }
1205
1206 pub fn from_parser(kind: SymKind, p: &mut Parser<'a>) -> Result<Self, ParserError> {
1212 Ok(match kind {
1213 SymKind::S_OBJNAME => Self::ObjName(p.parse()?),
1214 SymKind::S_GPROC32 | SymKind::S_LPROC32 => Self::Proc(p.parse()?),
1215 SymKind::S_COMPILE3 => Self::Compile3(p.parse()?),
1216 SymKind::S_UDT => Self::Udt(p.parse()?),
1217 SymKind::S_CONSTANT => Self::Constant(p.parse()?),
1218 SymKind::S_MANCONSTANT => Self::Constant(p.parse()?),
1219 SymKind::S_PUB32 => Self::Pub(p.parse()?),
1220 SymKind::S_PUB32_ST => Self::Pub(Pub::parse_st(p)?),
1221
1222 SymKind::S_PROCREF
1223 | SymKind::S_LPROCREF
1224 | SymKind::S_DATAREF
1225 | SymKind::S_ANNOTATIONREF => Self::RefSym2(p.parse()?),
1226
1227 SymKind::S_LDATA32 | SymKind::S_GDATA32 | SymKind::S_LMANDATA | SymKind::S_GMANDATA => {
1228 Self::Data(p.parse()?)
1229 }
1230
1231 SymKind::S_LTHREAD32 | SymKind::S_GTHREAD32 => Self::ThreadData(p.parse()?),
1232 SymKind::S_END => Self::End,
1233 SymKind::S_FRAMEPROC => Self::FrameProc(p.get()?),
1234 SymKind::S_REGREL32 => Self::RegRel(p.parse()?),
1235 SymKind::S_BLOCK32 => Self::Block(p.parse()?),
1236 SymKind::S_LOCAL => Self::Local(p.parse()?),
1237 SymKind::S_DEFRANGE_FRAMEPOINTER_REL => Self::DefRangeFramePointerRel(p.parse()?),
1238 SymKind::S_DEFRANGE_REGISTER => Self::DefRangeRegister(p.parse()?),
1239 SymKind::S_DEFRANGE_REGISTER_REL => Self::DefRangeRegisterRel(p.parse()?),
1240 SymKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE => {
1241 Self::DefRangeFramePointerRelFullScope(p.get()?)
1242 }
1243 SymKind::S_DEFRANGE_SUBFIELD_REGISTER => Self::DefRangeSubFieldRegister(p.parse()?),
1244 SymKind::S_TRAMPOLINE => Self::Trampoline(p.parse()?),
1245 SymKind::S_BUILDINFO => Self::BuildInfo(p.parse()?),
1246 SymKind::S_UNAMESPACE => Self::UsingNamespace(p.parse()?),
1247 SymKind::S_INLINESITE_END => Self::InlineSiteEnd,
1248 SymKind::S_LABEL32 => Self::Label(p.parse()?),
1249 SymKind::S_CALLEES | SymKind::S_CALLERS => Self::FunctionList(p.parse()?),
1250 SymKind::S_INLINESITE => Self::InlineSite(p.parse()?),
1251 SymKind::S_INLINESITE2 => Self::InlineSite2(p.parse()?),
1252 SymKind::S_INLINEES => Self::FunctionList(p.parse()?),
1253 SymKind::S_FRAMECOOKIE => Self::FrameCookie(p.get()?),
1254 SymKind::S_CALLSITEINFO => Self::CallSiteInfo(p.get()?),
1255 SymKind::S_HEAPALLOCSITE => Self::HeapAllocSite(p.get()?),
1256 SymKind::S_GMANPROC | SymKind::S_LMANPROC => Self::ManagedProc(p.parse()?),
1257 SymKind::S_ANNOTATION => Self::Annotation(p.parse()?),
1258
1259 _ => Self::Unknown,
1260 })
1261 }
1262
1263 pub fn name(&self) -> Option<&'a BStr> {
1265 match self {
1266 Self::Proc(proc) => Some(proc.name),
1267 Self::Data(data) => Some(data.name),
1268 Self::ThreadData(thread_data) => Some(thread_data.name),
1269 Self::Udt(udt) => Some(udt.name),
1270 Self::Local(local) => Some(local.name),
1271 Self::RefSym2(refsym) => Some(refsym.name),
1272 Self::Constant(c) => Some(c.name),
1273 Self::ManagedConstant(c) => Some(c.name),
1274 _ => None,
1275 }
1276 }
1277}