diff --git a/src/tpi/data.rs b/src/tpi/data.rs index ed7d987..dc8f494 100644 --- a/src/tpi/data.rs +++ b/src/tpi/data.rs @@ -25,6 +25,8 @@ pub enum TypeData<'t> { Nested(NestedType<'t>), BaseClass(BaseClassType), VirtualBaseClass(VirtualBaseClassType), + VirtualFunctionTable(VirtualFunctionTableType<'t>), + VirtualTableShape(VirtualTableShapeType), VirtualFunctionTablePointer(VirtualFunctionTablePointerType), Procedure(ProcedureType), Pointer(PointerType), @@ -345,14 +347,40 @@ pub(crate) fn parse_type_data<'t>(buf: &mut ParseBuffer<'t>) -> Result { - // TODO - Err(Error::UnimplementedTypeKind(leaf)) + let mut vtshape = VirtualTableShapeType { + descriptors: vec![], + }; + let count = buf.parse_u16()? as usize; + // These are packed 4-bit values + for _ in 0..((count + 1) / 2) { + let desc: u8 = buf.parse()?; + vtshape.descriptors.push(desc & 0xF); + if vtshape.descriptors.len() < count { + vtshape.descriptors.push(desc >> 4); + } + } + Ok(TypeData::VirtualTableShape(vtshape)) } // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L1825-L1837 LF_VFTABLE => { - // TODO - Err(Error::UnimplementedTypeKind(leaf)) + let mut vftable = VirtualFunctionTableType { + owner: buf.parse()?, + base: buf.parse()?, + object_offset: parse_unsigned(buf)? as u32, + names: vec![], + }; + + let names_length = parse_unsigned(buf)? as usize; + + let mut len = 0; + while len < names_length { + let s = buf.parse_cstring()?; + len += s.len() + 1; + vftable.names.push(s); + } + + Ok(TypeData::VirtualFunctionTable(vftable)) } // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L2521-L2528 @@ -826,6 +854,32 @@ impl PointerAttributes { } } +/* +typedef enum CV_VTS_desc_e { + CV_VTS_near = 0x00, + CV_VTS_far = 0x01, + CV_VTS_thin = 0x02, + CV_VTS_outer = 0x03, + CV_VTS_meta = 0x04, + CV_VTS_near32 = 0x05, + CV_VTS_far32 = 0x06, + CV_VTS_unused = 0x07 +} CV_VTS_desc_e; + */ +#[allow(unused)] +#[repr(u8)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum VirtualTableShapeDescriptor { + Near = 0x00, + Far = 0x01, + Thin = 0x02, + Outer = 0x03, + Meta = 0x04, + Near32 = 0x05, + Far32 = 0x06, + Unused = 0x07, +} + /// The information parsed from a type record with kind /// `LF_CLASS`, `LF_CLASS_ST`, `LF_STRUCTURE`, `LF_STRUCTURE_ST` or `LF_INTERFACE`. // https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L1631 @@ -947,6 +1001,21 @@ pub struct VirtualFunctionTablePointerType { pub table: TypeIndex, } +/// The information parsed from a type record with kind `LF_VTSHAPE`. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VirtualTableShapeType { + pub descriptors: Vec, +} + +/// The information parsed from a type record with kind `LF_VFTABLE`. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct VirtualFunctionTableType<'t> { + pub owner: TypeIndex, + pub base: TypeIndex, + pub object_offset: u32, + pub names: Vec>, +} + /// The information parsed from a type record with kind `LF_PROCEDURE`. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct ProcedureType {