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)]
65#[repr(C)]
66#[allow(missing_docs)]
67pub struct ProcFixed {
68 pub p_parent: U32<LE>,
70
71 pub p_end: U32<LE>,
74
75 pub p_next: U32<LE>,
76
77 pub proc_len: U32<LE>,
79
80 pub debug_start: U32<LE>,
83
84 pub debug_end: U32<LE>,
88
89 pub proc_type: TypeIndexLe,
98
99 pub offset_segment: OffsetSegment,
100 pub flags: u8,
101}
102
103#[allow(missing_docs)]
115#[derive(Clone, Debug)]
116pub struct Proc<'a> {
117 pub fixed: &'a ProcFixed,
118 pub name: &'a BStr,
119}
120
121impl<'a> Parse<'a> for Proc<'a> {
122 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
123 Ok(Self {
124 fixed: p.get()?,
125 name: p.strz()?,
126 })
127 }
128}
129
130#[test]
132fn test_parse_proc() {
133 #[rustfmt::skip]
134 let data = &[
135 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 ];
150
151 let mut i = SymIter::new(data);
152
153 let s0 = i.next().unwrap();
154 assert_eq!(s0.kind, SymKind::S_GPROC32);
155 assert_eq!(s0.data.len(), 0x2c);
156
157 match s0.parse().unwrap() {
158 SymData::Proc(proc) => {
159 assert_eq!(proc.fixed.p_parent.get(), 0);
160 assert_eq!(proc.fixed.p_end.get(), 0x40);
161 assert_eq!(proc.name, "memset");
162 }
163 _ => panic!(),
164 }
165
166 let s1 = i.next().unwrap();
167 assert_eq!(s1.kind, SymKind::S_END);
168 assert!(s1.data.is_empty());
169}
170
171#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Debug)]
175#[repr(C)]
176#[allow(missing_docs)]
177pub struct ManagedProcFixed {
178 pub p_parent: U32<LE>,
179 pub p_end: U32<LE>,
180 pub p_next: U32<LE>,
181 pub proc_len: U32<LE>,
182 pub debug_start: U32<LE>,
183 pub debug_end: U32<LE>,
184 pub token: U32<LE>,
185 pub offset_segment: OffsetSegment,
186 pub flags: u8,
187 pub return_reg: U16<LE>,
188}
189
190#[allow(missing_docs)]
192#[derive(Clone, Debug)]
193pub struct ManagedProc<'a> {
194 pub fixed: &'a ManagedProcFixed,
195 pub name: &'a BStr,
196}
197
198impl<'a> Parse<'a> for ManagedProc<'a> {
199 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
200 Ok(Self {
201 fixed: p.get()?,
202 name: p.strz()?,
203 })
204 }
205}
206
207#[repr(C)]
208#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
209#[allow(missing_docs)]
210pub struct ThunkFixed {
211 pub block: BlockHeader,
212 pub p_next: U32<LE>,
213 pub offset_segment: OffsetSegment,
214 pub length: U16<LE>,
215 pub thunk_ordinal: u8,
216 }
219
220#[allow(missing_docs)]
221pub struct Thunk<'a> {
222 pub fixed: &'a ThunkFixed,
223 pub name: &'a BStr,
224 pub variant: &'a [u8],
225}
226
227impl<'a> Parse<'a> for Thunk<'a> {
228 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
229 Ok(Self {
230 fixed: p.get()?,
231 name: p.strz()?,
232 variant: p.take_rest(),
233 })
234 }
235}
236
237#[repr(C)]
239#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Default)]
240pub struct SymHeader {
241 pub len: U16<LE>,
246
247 pub kind: U16<LE>,
249}
250
251#[derive(Clone)]
253pub struct Sym<'a> {
254 pub kind: SymKind,
256 pub data: &'a [u8],
258}
259
260impl<'a> Sym<'a> {
261 pub fn parse(&self) -> Result<SymData<'a>, ParserError> {
263 SymData::parse(self.kind, self.data)
264 }
265}
266
267impl<'a> Debug for Sym<'a> {
268 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
269 write!(fmt, "{:?}", self.kind)
270 }
271}
272
273pub struct SymMut<'a> {
276 pub kind: SymKind,
278 pub data: &'a mut [u8],
280}
281
282#[allow(missing_docs)]
295#[derive(Clone, Debug)]
296pub struct Pub<'a> {
297 pub fixed: &'a PubFixed,
298 pub name: &'a BStr,
299}
300
301impl<'a> Pub<'a> {
302 pub fn offset_segment(&self) -> OffsetSegment {
304 self.fixed.offset_segment.clone()
305 }
306}
307
308#[allow(missing_docs)]
309#[repr(C)]
310#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
311pub struct PubFixed {
312 pub flags: U32<LE>,
313 pub offset_segment: OffsetSegment,
314 }
316
317#[allow(missing_docs)]
318impl<'a> Parse<'a> for Pub<'a> {
319 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
320 Ok(Self {
321 fixed: p.get()?,
322 name: p.strz()?,
323 })
324 }
325}
326
327impl<'a> Pub<'a> {
328 pub fn parse_st(p: &mut Parser<'a>) -> Result<Self, ParserError> {
330 Ok(Self {
331 fixed: p.get()?,
332 name: p.strt_raw()?,
333 })
334 }
335}
336
337#[allow(missing_docs)]
339#[derive(Clone, Debug)]
340pub struct Constant<'a> {
341 pub type_: TypeIndex,
342 pub value: Number<'a>,
343 pub name: &'a BStr,
344}
345
346impl<'a> Parse<'a> for Constant<'a> {
347 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
348 Ok(Self {
349 type_: p.type_index()?,
350 value: p.number()?,
351 name: p.strz()?,
352 })
353 }
354}
355
356#[allow(missing_docs)]
358#[derive(Clone, Debug)]
359pub struct ManagedConstant<'a> {
360 pub token: u32,
361 pub value: Number<'a>,
362 pub name: &'a BStr,
363}
364
365impl<'a> Parse<'a> for ManagedConstant<'a> {
366 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
367 Ok(Self {
368 token: p.u32()?,
369 value: p.number()?,
370 name: p.strz()?,
371 })
372 }
373}
374
375#[allow(missing_docs)]
383#[derive(Clone, Debug)]
384pub struct RefSym2<'a> {
385 pub header: &'a RefSym2Fixed,
386 pub name: &'a BStr,
387}
388
389#[allow(missing_docs)]
390#[repr(C)]
391#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
392pub struct RefSym2Fixed {
393 pub name_checksum: U32<LE>,
397
398 pub symbol_offset: U32<LE>,
403
404 pub module_index: U16<LE>,
408 }
410
411impl<'a> Parse<'a> for RefSym2<'a> {
412 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
413 Ok(Self {
414 header: p.get()?,
415 name: p.strz()?,
416 })
417 }
418}
419
420#[allow(missing_docs)]
421#[repr(C)]
422#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
423pub struct ThreadStorageFixed {
424 pub type_: TypeIndexLe,
425 pub offset_segment: OffsetSegment,
426}
427
428#[derive(Clone, Debug)]
432pub struct ThreadStorageData<'a> {
433 #[allow(missing_docs)]
434 pub header: &'a ThreadStorageFixed,
435 #[allow(missing_docs)]
436 pub name: &'a BStr,
437}
438
439impl<'a> Parse<'a> for ThreadStorageData<'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
448#[allow(missing_docs)]
449#[repr(C)]
450#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
451pub struct DataFixed {
452 pub type_: TypeIndexLe,
453 pub offset_segment: OffsetSegment,
454}
455
456#[allow(missing_docs)]
458#[derive(Clone)]
459pub struct Data<'a> {
460 pub header: &'a DataFixed,
461 pub name: &'a BStr,
462}
463
464impl<'a> Parse<'a> for Data<'a> {
465 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
466 Ok(Self {
467 header: p.get()?,
468 name: p.strz()?,
469 })
470 }
471}
472
473impl<'a> Debug for Data<'a> {
474 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
475 write!(
476 f,
477 "Data: {} {:?} {}",
478 self.header.offset_segment,
479 self.header.type_.get(),
480 self.name
481 )
482 }
483}
484
485#[derive(Clone, Debug)]
487pub struct Udt<'a> {
488 pub type_: TypeIndex,
490 pub name: &'a BStr,
492}
493
494impl<'a> Parse<'a> for Udt<'a> {
495 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
496 Ok(Self {
497 type_: p.type_index()?,
498 name: p.strz()?,
499 })
500 }
501}
502
503#[derive(Clone, Debug)]
505pub struct ObjectName<'a> {
506 pub signature: u32,
509 pub name: &'a BStr,
511}
512
513impl<'a> Parse<'a> for ObjectName<'a> {
514 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
515 Ok(Self {
516 signature: p.u32()?,
517 name: p.strz()?,
518 })
519 }
520}
521
522#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
524#[repr(C)]
525#[allow(missing_docs)]
526pub struct Compile3Fixed {
527 pub flags: U32<LE>,
528 pub machine: U16<LE>,
529 pub frontend_major: U16<LE>,
530 pub frontend_minor: U16<LE>,
531 pub frontend_build: U16<LE>,
532 pub frontend_qfe: U16<LE>,
533 pub ver_major: U16<LE>,
534 pub ver_minor: U16<LE>,
535 pub ver_build: U16<LE>,
536 pub ver_qfe: U16<LE>,
537 }
539
540#[allow(missing_docs)]
542#[derive(Clone, Debug)]
543pub struct Compile3<'a> {
544 pub fixed: &'a Compile3Fixed,
545 pub name: &'a BStr,
546}
547
548impl<'a> Parse<'a> for Compile3<'a> {
549 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
550 Ok(Self {
551 fixed: p.get()?,
552 name: p.strz()?,
553 })
554 }
555}
556
557#[repr(C)]
561#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
562#[allow(missing_docs)]
563pub struct FrameProc {
564 frame_size: U32<LE>,
566 pad_size: U32<LE>,
568 pad_offset: U32<LE>,
570 save_regs_size: U32<LE>,
572 offset_exception_handler: U32<LE>,
573 exception_handler_section: U16<LE>,
574 padding: U16<LE>,
575 flags: U32<LE>,
576}
577
578#[repr(C)]
579#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
580#[allow(missing_docs)]
581pub struct RegRelFixed {
582 pub offset: U32<LE>,
583 pub ty: TypeIndexLe,
584 pub register: U16<LE>,
585 }
587
588#[derive(Clone, Debug)]
591#[allow(missing_docs)]
592pub struct RegRel<'a> {
593 pub fixed: &'a RegRelFixed,
594 pub name: &'a BStr,
595}
596
597impl<'a> Parse<'a> for RegRel<'a> {
598 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
599 Ok(Self {
600 fixed: p.get()?,
601 name: p.strz()?,
602 })
603 }
604}
605
606#[derive(Clone, Debug)]
614#[allow(missing_docs)]
615pub struct Block<'a> {
616 pub fixed: &'a BlockFixed,
617 pub name: &'a BStr,
618}
619
620#[repr(C)]
621#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
622#[allow(missing_docs)]
623pub struct BlockFixed {
624 pub header: BlockHeader,
626
627 pub length: U32<LE>,
629
630 pub offset_segment: OffsetSegment,
631}
632
633impl<'a> Parse<'a> for Block<'a> {
634 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
635 Ok(Self {
636 fixed: p.get()?,
637 name: p.strz()?,
638 })
639 }
640}
641
642#[derive(Clone, Debug)]
647#[allow(missing_docs)]
648pub struct Local<'a> {
649 pub fixed: &'a LocalFixed,
650 pub name: &'a BStr,
651}
652
653#[repr(C)]
654#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
655#[allow(missing_docs)]
656pub struct LocalFixed {
657 pub ty: TypeIndexLe,
658 pub flags: U16<LE>,
660 }
662
663impl<'a> Parse<'a> for Local<'a> {
664 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
665 Ok(Self {
666 fixed: p.get()?,
667 name: p.strz()?,
668 })
669 }
670}
671
672#[repr(C)]
676#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
677pub struct LVarAddrRange {
678 pub start: OffsetSegment,
680 pub range_size: U16<LE>,
682}
683
684#[repr(C)]
689#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
690pub struct LVarAddrGap {
691 pub gap_start_offset: U16<LE>,
693 pub range_size: U16<LE>,
695}
696
697#[repr(C)]
699#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
700#[allow(missing_docs)]
701pub struct DefRangeSymFramePointerRelFixed {
702 pub offset_to_frame_pointer: U32<LE>,
703
704 pub range: LVarAddrRange,
706}
707
708#[allow(missing_docs)]
710#[derive(Clone, Debug)]
711pub struct DefRangeSymFramePointerRel<'a> {
712 pub fixed: &'a DefRangeSymFramePointerRelFixed,
713 pub gaps: &'a [LVarAddrGap],
715}
716
717impl<'a> Parse<'a> for DefRangeSymFramePointerRel<'a> {
718 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
719 let fixed = p.get()?;
720 let gaps = p.slice(p.len() / size_of::<LVarAddrGap>())?;
721 Ok(Self { fixed, gaps })
722 }
723}
724
725#[repr(C)]
729#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
730#[allow(missing_docs)]
731pub struct RangeAttrLe {
732 pub value: U16<LE>,
735}
736
737#[repr(C)]
741#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
742#[allow(missing_docs)]
743pub struct DefRangeRegisterFixed {
744 pub reg: U16<LE>,
746 pub attr: RangeAttrLe,
748}
749
750#[derive(Clone, Debug)]
754#[allow(missing_docs)]
755pub struct DefRangeRegister<'a> {
756 pub fixed: &'a DefRangeRegisterFixed,
757 pub gaps: &'a [u8],
758}
759
760impl<'a> Parse<'a> for DefRangeRegister<'a> {
761 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
762 Ok(Self {
763 fixed: p.get()?,
764 gaps: p.take_rest(),
765 })
766 }
767}
768
769#[allow(missing_docs)]
771#[derive(Debug, Clone)]
772pub struct DefRangeRegisterRel<'a> {
773 pub fixed: &'a DefRangeRegisterRelFixed,
774
775 pub gaps: &'a [u8],
777}
778
779#[repr(C)]
781#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
782pub struct DefRangeRegisterRelFixed {
783 pub base_reg: U16<LE>,
785
786 pub flags: U16<LE>,
792
793 pub base_pointer_offset: I32<LE>,
795
796 pub range: LVarAddrRange,
798}
799
800impl<'a> Parse<'a> for DefRangeRegisterRel<'a> {
801 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
802 Ok(Self {
803 fixed: p.get()?,
804 gaps: p.take_rest(),
805 })
806 }
807}
808
809#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
813#[repr(C)]
814pub struct DefRangeFramePointerRelFullScope {
815 pub frame_pointer_offset: I32<LE>,
817}
818
819#[derive(Clone, Debug)]
823#[allow(missing_docs)]
824pub struct DefRangeSubFieldRegister<'a> {
825 pub fixed: &'a DefRangeSubFieldRegisterFixed,
826 pub gaps: &'a [u8],
827}
828
829#[repr(C)]
830#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
831#[allow(missing_docs)]
832pub struct DefRangeSubFieldRegisterFixed {
833 pub reg: U16<LE>,
834 pub attr: RangeAttrLe,
835 pub flags: U32<LE>,
836 pub range: LVarAddrRange,
837}
838
839impl<'a> Parse<'a> for DefRangeSubFieldRegister<'a> {
840 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
841 Ok(Self {
842 fixed: p.get()?,
843 gaps: p.take_rest(),
844 })
845 }
846}
847
848pub struct ManProcSym<'a> {
852 #[allow(missing_docs)]
853 pub fixed: &'a ManProcSymFixed,
854 #[allow(missing_docs)]
855 pub name: &'a BStr,
856}
857
858pub type TokenIdLe = U32<LE>;
860
861#[repr(C)]
862#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
863#[allow(missing_docs)]
864pub struct ManProcSymFixed {
865 pub block: BlockHeader,
866 pub pnext: U32<LE>,
868 pub len: U32<LE>,
870 pub dbg_start: U32<LE>,
872 pub dbg_end: U32<LE>,
874 pub token: TokenIdLe,
876 pub off: U32<LE>,
877 pub seg: U16<LE>,
878 pub flags: u8, pub padding: u8,
880 pub ret_reg: U16<LE>,
882 }
884
885impl<'a> Parse<'a> for ManProcSym<'a> {
886 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
887 Ok(Self {
888 fixed: p.get()?,
889 name: p.strz()?,
890 })
891 }
892}
893
894#[derive(Clone, Debug)]
896pub struct Trampoline<'a> {
897 pub fixed: &'a TrampolineFixed,
899
900 pub rest: &'a [u8],
902}
903
904#[repr(C)]
906#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Clone, Debug)]
907pub struct TrampolineFixed {
908 pub tramp_type: U16<LE>,
910 pub cb_thunk: U16<LE>,
912 pub off_thunk: U32<LE>,
914 pub off_target: U32<LE>,
916 pub sect_thunk: U16<LE>,
918 pub sect_target: U16<LE>,
920}
921
922impl<'a> Parse<'a> for Trampoline<'a> {
923 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
924 Ok(Self {
925 fixed: p.get()?,
926 rest: p.take_rest(),
927 })
928 }
929}
930
931#[derive(Clone, Debug)]
935pub struct BuildInfo {
936 pub item: ItemId,
938}
939
940impl<'a> Parse<'a> for BuildInfo {
941 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
942 Ok(Self { item: p.u32()? })
943 }
944}
945
946#[derive(Clone, Debug)]
948pub struct UsingNamespace<'a> {
949 pub namespace: &'a BStr,
951}
952
953impl<'a> Parse<'a> for UsingNamespace<'a> {
954 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
955 Ok(Self {
956 namespace: p.strz()?,
957 })
958 }
959}
960
961#[derive(Clone, Debug)]
963#[allow(missing_docs)]
964pub struct Label<'a> {
965 pub fixed: &'a LabelFixed,
966 pub name: &'a BStr,
967}
968
969#[repr(C)]
971#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
972#[allow(missing_docs)]
973pub struct LabelFixed {
974 pub offset_segment: OffsetSegment,
975 pub flags: u8,
976}
977
978impl<'a> Parse<'a> for Label<'a> {
979 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
980 Ok(Self {
981 fixed: p.get()?,
982 name: p.strz()?,
983 })
984 }
985}
986
987#[derive(Clone, Debug)]
989pub struct FunctionList<'a> {
990 pub funcs: &'a [ItemIdLe],
992
993 pub counts: &'a [U32<LE>],
1000}
1001
1002impl<'a> Parse<'a> for FunctionList<'a> {
1003 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1004 let num_funcs = p.u32()? as usize;
1005 let funcs: &[ItemIdLe] = p.slice(num_funcs)?;
1006 let num_counts = num_funcs.min(p.len() / size_of::<U32<LE>>());
1007 let counts = p.slice(num_counts)?;
1008 Ok(Self { funcs, counts })
1009 }
1010}
1011
1012#[allow(missing_docs)]
1014#[derive(Clone, Debug)]
1015pub struct InlineSite<'a> {
1016 pub fixed: &'a InlineSiteFixed,
1017 pub binary_annotations: &'a [u8],
1019}
1020
1021#[repr(C)]
1023#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1024#[allow(missing_docs)]
1025pub struct InlineSiteFixed {
1026 pub block: BlockHeader,
1027 pub inlinee: ItemIdLe,
1028}
1029
1030impl<'a> Parse<'a> for InlineSite<'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#[allow(missing_docs)]
1041#[derive(Clone, Debug)]
1042pub struct InlineSite2<'a> {
1043 pub fixed: &'a InlineSite2Fixed,
1044 pub binary_annotations: &'a [u8],
1046}
1047
1048#[repr(C)]
1050#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1051#[allow(missing_docs)]
1052pub struct InlineSite2Fixed {
1053 pub block: BlockHeader,
1054 pub inlinee: ItemIdLe,
1055 pub invocations: U32<LE>,
1056}
1057
1058impl<'a> Parse<'a> for InlineSite2<'a> {
1059 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1060 Ok(Self {
1061 fixed: p.get()?,
1062 binary_annotations: p.take_rest(),
1063 })
1064 }
1065}
1066
1067#[repr(C)]
1070#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1071#[allow(missing_docs)]
1072pub struct FrameCookie {
1073 pub offset: I32<LE>,
1075 pub reg: U16<LE>,
1076 pub cookie_type: u8,
1077 pub flags: u8,
1078}
1079
1080#[repr(C)]
1102#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1103#[allow(missing_docs)]
1104pub struct CallSiteInfo {
1105 pub offset: OffsetSegment,
1106 pub padding: U16<LE>,
1107 pub func_type: TypeIndexLe,
1108}
1109
1110#[repr(C)]
1112#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1113#[allow(missing_docs)]
1114pub struct HeapAllocSite {
1115 pub offset: OffsetSegment,
1116 pub instruction_size: U16<LE>,
1118 pub func_type: TypeIndexLe,
1119}
1120
1121#[allow(missing_docs)]
1123#[derive(Clone, Debug)]
1124pub struct Annotation<'a> {
1125 pub fixed: &'a AnnotationFixed,
1126 pub strings: &'a [u8],
1127}
1128
1129#[repr(C)]
1130#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Unaligned, Debug)]
1131#[allow(missing_docs)]
1132pub struct AnnotationFixed {
1133 pub offset: OffsetSegment,
1134 pub num_strings: U16<LE>,
1135}
1136
1137impl<'a> Parse<'a> for Annotation<'a> {
1138 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1139 Ok(Self {
1140 fixed: p.get()?,
1141 strings: p.take_rest(),
1142 })
1143 }
1144}
1145
1146impl<'a> Annotation<'a> {
1147 pub fn iter_strings(&self) -> AnnotationIterStrings<'a> {
1149 AnnotationIterStrings {
1150 num_strings: self.fixed.num_strings.get(),
1151 bytes: self.strings,
1152 }
1153 }
1154}
1155
1156#[allow(missing_docs)]
1158pub struct AnnotationIterStrings<'a> {
1159 pub num_strings: u16,
1160 pub bytes: &'a [u8],
1161}
1162
1163impl<'a> Iterator for AnnotationIterStrings<'a> {
1164 type Item = &'a BStr;
1165
1166 fn next(&mut self) -> Option<Self::Item> {
1167 if self.num_strings == 0 {
1168 return None;
1169 }
1170
1171 self.num_strings -= 1;
1172 let mut p = Parser::new(self.bytes);
1173 let s = p.strz().ok()?;
1174 self.bytes = p.into_rest();
1175 Some(s)
1176 }
1177}
1178
1179#[derive(Clone, Debug)]
1181pub struct HotPatchFunc<'a> {
1182 pub func: ItemId,
1184
1185 pub name: &'a BStr,
1187}
1188
1189impl<'a> Parse<'a> for HotPatchFunc<'a> {
1190 fn from_parser(p: &mut Parser<'a>) -> Result<Self, ParserError> {
1191 Ok(Self {
1192 func: p.u32()?,
1193 name: p.strz()?,
1194 })
1195 }
1196}
1197
1198pub const TRAMPOLINE_KIND_INCREMENTAL: u16 = 0;
1202pub const TRAMPOLINE_KIND_BRANCH_ISLAND: u16 = 1;
1204
1205#[derive(Clone, Debug)]
1207#[allow(missing_docs)]
1208pub enum SymData<'a> {
1209 Unknown,
1210 ObjName(ObjectName<'a>),
1211 Compile3(Compile3<'a>),
1212 Proc(Proc<'a>),
1213 Udt(Udt<'a>),
1214 Constant(Constant<'a>),
1215 ManagedConstant(ManagedConstant<'a>),
1216 RefSym2(RefSym2<'a>),
1217 Data(Data<'a>),
1218 ThreadData(ThreadStorageData<'a>),
1219 Pub(Pub<'a>),
1220 End,
1221 FrameProc(&'a FrameProc),
1222 RegRel(RegRel<'a>),
1223 Block(Block<'a>),
1224 Local(Local<'a>),
1225 DefRangeFramePointerRel(DefRangeSymFramePointerRel<'a>),
1226 DefRangeRegister(DefRangeRegister<'a>),
1227 DefRangeRegisterRel(DefRangeRegisterRel<'a>),
1228 DefRangeFramePointerRelFullScope(&'a DefRangeFramePointerRelFullScope),
1229 DefRangeSubFieldRegister(DefRangeSubFieldRegister<'a>),
1230 Trampoline(Trampoline<'a>),
1231 BuildInfo(BuildInfo),
1232 UsingNamespace(UsingNamespace<'a>),
1233 InlineSiteEnd,
1234 Label(Label<'a>),
1235 FunctionList(FunctionList<'a>),
1236 InlineSite(InlineSite<'a>),
1237 InlineSite2(InlineSite2<'a>),
1238 FrameCookie(&'a FrameCookie),
1239 CallSiteInfo(&'a CallSiteInfo),
1240 HeapAllocSite(&'a HeapAllocSite),
1241 ManagedProc(ManagedProc<'a>),
1242 Annotation(Annotation<'a>),
1243 HotPatchFunc(HotPatchFunc<'a>),
1244}
1245
1246impl<'a> SymData<'a> {
1247 pub fn parse(kind: SymKind, data: &'a [u8]) -> Result<Self, ParserError> {
1250 let mut p = Parser::new(data);
1251 Self::from_parser(kind, &mut p)
1252 }
1253
1254 pub fn from_parser(kind: SymKind, p: &mut Parser<'a>) -> Result<Self, ParserError> {
1260 Ok(match kind {
1261 SymKind::S_OBJNAME => Self::ObjName(p.parse()?),
1262 SymKind::S_GPROC32 | SymKind::S_LPROC32 => Self::Proc(p.parse()?),
1263 SymKind::S_COMPILE3 => Self::Compile3(p.parse()?),
1264 SymKind::S_UDT => Self::Udt(p.parse()?),
1265 SymKind::S_CONSTANT => Self::Constant(p.parse()?),
1266 SymKind::S_MANCONSTANT => Self::Constant(p.parse()?),
1267 SymKind::S_PUB32 => Self::Pub(p.parse()?),
1268 SymKind::S_PUB32_ST => Self::Pub(Pub::parse_st(p)?),
1269
1270 SymKind::S_PROCREF
1271 | SymKind::S_LPROCREF
1272 | SymKind::S_DATAREF
1273 | SymKind::S_ANNOTATIONREF => Self::RefSym2(p.parse()?),
1274
1275 SymKind::S_LDATA32 | SymKind::S_GDATA32 | SymKind::S_LMANDATA | SymKind::S_GMANDATA => {
1276 Self::Data(p.parse()?)
1277 }
1278
1279 SymKind::S_LTHREAD32 | SymKind::S_GTHREAD32 => Self::ThreadData(p.parse()?),
1280 SymKind::S_END => Self::End,
1281 SymKind::S_FRAMEPROC => Self::FrameProc(p.get()?),
1282 SymKind::S_REGREL32 => Self::RegRel(p.parse()?),
1283 SymKind::S_BLOCK32 => Self::Block(p.parse()?),
1284 SymKind::S_LOCAL => Self::Local(p.parse()?),
1285 SymKind::S_DEFRANGE_FRAMEPOINTER_REL => Self::DefRangeFramePointerRel(p.parse()?),
1286 SymKind::S_DEFRANGE_REGISTER => Self::DefRangeRegister(p.parse()?),
1287 SymKind::S_DEFRANGE_REGISTER_REL => Self::DefRangeRegisterRel(p.parse()?),
1288 SymKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE => {
1289 Self::DefRangeFramePointerRelFullScope(p.get()?)
1290 }
1291 SymKind::S_DEFRANGE_SUBFIELD_REGISTER => Self::DefRangeSubFieldRegister(p.parse()?),
1292 SymKind::S_TRAMPOLINE => Self::Trampoline(p.parse()?),
1293 SymKind::S_BUILDINFO => Self::BuildInfo(p.parse()?),
1294 SymKind::S_UNAMESPACE => Self::UsingNamespace(p.parse()?),
1295 SymKind::S_INLINESITE_END => Self::InlineSiteEnd,
1296 SymKind::S_LABEL32 => Self::Label(p.parse()?),
1297 SymKind::S_CALLEES | SymKind::S_CALLERS => Self::FunctionList(p.parse()?),
1298 SymKind::S_INLINESITE => Self::InlineSite(p.parse()?),
1299 SymKind::S_INLINESITE2 => Self::InlineSite2(p.parse()?),
1300 SymKind::S_INLINEES => Self::FunctionList(p.parse()?),
1301 SymKind::S_FRAMECOOKIE => Self::FrameCookie(p.get()?),
1302 SymKind::S_CALLSITEINFO => Self::CallSiteInfo(p.get()?),
1303 SymKind::S_HEAPALLOCSITE => Self::HeapAllocSite(p.get()?),
1304 SymKind::S_GMANPROC | SymKind::S_LMANPROC => Self::ManagedProc(p.parse()?),
1305 SymKind::S_ANNOTATION => Self::Annotation(p.parse()?),
1306 SymKind::S_HOTPATCHFUNC => Self::HotPatchFunc(p.parse()?),
1307
1308 _ => Self::Unknown,
1309 })
1310 }
1311
1312 pub fn name(&self) -> Option<&'a BStr> {
1314 match self {
1315 Self::Proc(proc) => Some(proc.name),
1316 Self::Data(data) => Some(data.name),
1317 Self::ThreadData(thread_data) => Some(thread_data.name),
1318 Self::Udt(udt) => Some(udt.name),
1319 Self::Local(local) => Some(local.name),
1320 Self::RefSym2(refsym) => Some(refsym.name),
1321 Self::Constant(c) => Some(c.name),
1322 Self::ManagedConstant(c) => Some(c.name),
1323 _ => None,
1324 }
1325 }
1326}