ms_pdb/dbi/
section_map.rs#![allow(missing_docs)]
use super::*;
use bitflags::bitflags;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
#[derive(IntoBytes, KnownLayout, Immutable, FromBytes, Unaligned)]
#[repr(C)]
pub struct SectionMapHeader {
pub num_segments: U16<LE>,
pub num_logical_segments: U16<LE>,
}
#[derive(IntoBytes, KnownLayout, Immutable, FromBytes, Unaligned)]
#[repr(C)]
pub struct SectionMapEntry {
pub flags: U16<LE>,
pub overlay: U16<LE>,
pub group: U16<LE>,
pub frame: U16<LE>,
pub section_name: U16<LE>,
pub class_name: U16<LE>,
pub offset: U32<LE>,
pub section_length: U32<LE>,
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct SectionMapEntryFlags: u16 {
const READ = 1 << 0;
const WRITE = 1 << 1;
const EXECUTE = 1 << 2;
const ADDRESS_IS32_BIT = 1 << 3;
const IS_SELECTOR = 1 << 8;
const IS_ABSOLUTE_ADDRESS = 1 << 9;
const IS_GROUP = 1 << 10;
}
}
pub struct SectionMap<'a> {
pub header: SectionMapHeader,
pub entries: &'a [SectionMapEntry],
}
impl<'a> SectionMap<'a> {
pub fn parse(bytes: &'a [u8]) -> anyhow::Result<Self> {
let mut p = Parser::new(bytes);
if p.is_empty() {
return Ok(Self {
entries: &[],
header: SectionMapHeader {
num_logical_segments: U16::ZERO,
num_segments: U16::ZERO,
},
});
}
let header: SectionMapHeader = p.copy()?;
let Ok(entries) = <[SectionMapEntry]>::ref_from_bytes(p.take_rest()) else {
bail!("Section map has invalid length (is not a multiple of SectionMapEntry size). Length (including 4-byte header): 0x{:x}", bytes.len());
};
Ok(Self { header, entries })
}
}