Skip to content

Commit 35ed7c9

Browse files
committed
Implement VirtualFunctionTable / VirtualTableShape
1 parent b052964 commit 35ed7c9

File tree

1 file changed

+73
-4
lines changed

1 file changed

+73
-4
lines changed

src/tpi/data.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum TypeData<'t> {
2525
Nested(NestedType<'t>),
2626
BaseClass(BaseClassType),
2727
VirtualBaseClass(VirtualBaseClassType),
28+
VirtualFunctionTable(VirtualFunctionTableType<'t>),
29+
VirtualTableShape(VirtualTableShapeType),
2830
VirtualFunctionTablePointer(VirtualFunctionTablePointerType),
2931
Procedure(ProcedureType),
3032
Pointer(PointerType),
@@ -345,14 +347,40 @@ pub(crate) fn parse_type_data<'t>(buf: &mut ParseBuffer<'t>) -> Result<TypeData<
345347

346348
// https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L1819-L1823
347349
LF_VTSHAPE => {
348-
// TODO
349-
Err(Error::UnimplementedTypeKind(leaf))
350+
let mut vtshape = VirtualTableShapeType {
351+
descriptors: vec![],
352+
};
353+
let count = buf.parse_u16()? as usize;
354+
// These are packed 4-bit values
355+
for i in 0..((count + 1) / 2) {
356+
let desc: u8 = buf.parse()?;
357+
vtshape.descriptors.push(desc & 0xF);
358+
if vtshape.descriptors.len() < count {
359+
vtshape.descriptors.push(desc >> 4);
360+
}
361+
}
362+
Ok(TypeData::VirtualTableShape(vtshape))
350363
}
351364

352365
// https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L1825-L1837
353366
LF_VFTABLE => {
354-
// TODO
355-
Err(Error::UnimplementedTypeKind(leaf))
367+
let mut vftable = VirtualFunctionTableType {
368+
owner: buf.parse()?,
369+
base: buf.parse()?,
370+
object_offset: parse_unsigned(buf)? as u32,
371+
names: vec![],
372+
};
373+
374+
let names_length = parse_unsigned(buf)? as usize;
375+
376+
let mut len = 0;
377+
while len < names_length {
378+
let s = buf.parse_cstring()?;
379+
len += s.len() + 1;
380+
vftable.names.push(s);
381+
}
382+
383+
Ok(TypeData::VirtualFunctionTable(vftable))
356384
}
357385

358386
// https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L2521-L2528
@@ -826,6 +854,32 @@ impl PointerAttributes {
826854
}
827855
}
828856

857+
/*
858+
typedef enum CV_VTS_desc_e {
859+
CV_VTS_near = 0x00,
860+
CV_VTS_far = 0x01,
861+
CV_VTS_thin = 0x02,
862+
CV_VTS_outer = 0x03,
863+
CV_VTS_meta = 0x04,
864+
CV_VTS_near32 = 0x05,
865+
CV_VTS_far32 = 0x06,
866+
CV_VTS_unused = 0x07
867+
} CV_VTS_desc_e;
868+
*/
869+
#[allow(unused)]
870+
#[repr(u8)]
871+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
872+
pub enum VirtualTableShapeDescriptor {
873+
Near = 0x00,
874+
Far = 0x01,
875+
Thin = 0x02,
876+
Outer = 0x03,
877+
Meta = 0x04,
878+
Near32 = 0x05,
879+
Far32 = 0x06,
880+
Unused = 0x07,
881+
}
882+
829883
/// The information parsed from a type record with kind
830884
/// `LF_CLASS`, `LF_CLASS_ST`, `LF_STRUCTURE`, `LF_STRUCTURE_ST` or `LF_INTERFACE`.
831885
// https://github.com/Microsoft/microsoft-pdb/blob/082c5290e5aff028ae84e43affa8be717aa7af73/include/cvinfo.h#L1631
@@ -947,6 +1001,21 @@ pub struct VirtualFunctionTablePointerType {
9471001
pub table: TypeIndex,
9481002
}
9491003

1004+
/// The information parsed from a type record with kind `LF_VTSHAPE`.
1005+
#[derive(Debug, Clone, PartialEq, Eq)]
1006+
pub struct VirtualTableShapeType {
1007+
pub descriptors: Vec<u8>,
1008+
}
1009+
1010+
/// The information parsed from a type record with kind `LF_VFTABLE`.
1011+
#[derive(Debug, Clone, PartialEq, Eq)]
1012+
pub struct VirtualFunctionTableType<'t> {
1013+
pub owner: TypeIndex,
1014+
pub base: TypeIndex,
1015+
pub object_offset: u32,
1016+
pub names: Vec<RawString<'t>>,
1017+
}
1018+
9501019
/// The information parsed from a type record with kind `LF_PROCEDURE`.
9511020
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9521021
pub struct ProcedureType {

0 commit comments

Comments
 (0)