ms_codeview/syms/
offset_segment.rs

1use super::*;
2
3/// Stores an `offset` and `segment` pair, in that order. This structure is directly embedded in
4/// on-disk structures.
5#[repr(C)]
6#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, Unaligned, Default, Clone, Copy, Eq)]
7pub struct OffsetSegment {
8    /// The offset in bytes of a symbol within a segment.
9    pub offset: U32<LE>,
10
11    /// The segment (section) index.
12    pub segment: U16<LE>,
13}
14
15impl PartialEq for OffsetSegment {
16    #[inline]
17    fn eq(&self, other: &Self) -> bool {
18        self.as_u64() == other.as_u64()
19    }
20}
21
22impl PartialOrd for OffsetSegment {
23    #[inline]
24    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
25        Some(self.cmp(other))
26    }
27}
28
29impl Ord for OffsetSegment {
30    #[inline]
31    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
32        Ord::cmp(&self.as_u64(), &other.as_u64())
33    }
34}
35
36impl OffsetSegment {
37    /// Constructor
38    pub fn new(offset: u32, segment: u16) -> Self {
39        Self {
40            offset: offset.into(),
41            segment: segment.into(),
42        }
43    }
44
45    /// The offset in bytes of a symbol within a segment.
46    #[inline]
47    pub fn offset(&self) -> u32 {
48        self.offset.get()
49    }
50
51    /// The segment (section) index.
52    #[inline]
53    pub fn segment(&self) -> u16 {
54        self.segment.get()
55    }
56
57    /// Combines the segment and offset into a tuple. The segment is the first element and the
58    /// offset is the second element. This order gives a sorting order that sorts by segment first.
59    #[inline]
60    pub fn as_tuple(&self) -> (u16, u32) {
61        (self.segment.get(), self.offset.get())
62    }
63
64    /// Combines the segment and offset into a single `u64` value, with the segment in the
65    /// higher-order bits. This allows for efficient comparisons.
66    #[inline]
67    pub fn as_u64(&self) -> u64 {
68        ((self.segment.get() as u64) << 32) | (self.offset.get() as u64)
69    }
70}
71
72impl std::fmt::Display for OffsetSegment {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        write!(f, "[{:04x}:{:08x}]", self.segment.get(), self.offset.get())
75    }
76}
77
78impl Debug for OffsetSegment {
79    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80        <Self as std::fmt::Display>::fmt(self, f)
81    }
82}
83
84impl std::hash::Hash for OffsetSegment {
85    #[inline]
86    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
87        state.write_u16(self.segment());
88        state.write_u32(self.offset());
89    }
90}