ms_pdb/dbi/
section_map.rs1#![allow(missing_docs)]
3
4use super::*;
5use bitflags::bitflags;
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
7
8#[derive(IntoBytes, KnownLayout, Immutable, FromBytes, Unaligned)]
9#[repr(C)]
10pub struct SectionMapHeader {
11 pub num_segments: U16<LE>,
13 pub num_logical_segments: U16<LE>,
15}
16
17#[derive(IntoBytes, KnownLayout, Immutable, FromBytes, Unaligned, Debug)]
18#[repr(C)]
19pub struct SectionMapEntry {
20 pub flags: U16<LE>,
22 pub overlay: U16<LE>,
24 pub group: U16<LE>,
26 pub frame: U16<LE>,
28 pub section_name: U16<LE>,
30 pub class_name: U16<LE>,
32 pub offset: U32<LE>,
35 pub section_length: U32<LE>,
37}
38
39bitflags! {
40 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
41 pub struct SectionMapEntryFlags: u16 {
42 const READ = 1 << 0;
44 const WRITE = 1 << 1;
46 const EXECUTE = 1 << 2;
48 const ADDRESS_IS32_BIT = 1 << 3;
50 const IS_SELECTOR = 1 << 8;
52 const IS_ABSOLUTE_ADDRESS = 1 << 9;
54 const IS_GROUP = 1 << 10;
56 }
57}
58
59pub struct SectionMap<'a> {
60 pub header: SectionMapHeader,
61 pub entries: &'a [SectionMapEntry],
62}
63
64impl<'a> SectionMap<'a> {
65 pub fn parse(bytes: &'a [u8]) -> anyhow::Result<Self> {
66 let mut p = Parser::new(bytes);
67 if p.is_empty() {
68 return Ok(Self {
69 entries: &[],
70 header: SectionMapHeader {
71 num_logical_segments: U16::ZERO,
72 num_segments: U16::ZERO,
73 },
74 });
75 }
76
77 let header: SectionMapHeader = p.copy()?;
78
79 let Ok(entries) = <[SectionMapEntry]>::ref_from_bytes(p.take_rest()) else {
80 bail!(
81 "Section map has invalid length (is not a multiple of SectionMapEntry size). Length (including 4-byte header): 0x{:x}",
82 bytes.len()
83 );
84 };
85 Ok(Self { header, entries })
86 }
87}