} // end constructor public DbgVirtualBaseClassTypeInfo(DbgEngDebugger debugger, DbgModuleInfo module, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId, uint virtualBaseDispIndex, uint virtualBasePointerOffset) : this(debugger, GetModBase(module), typeId, kind, name, size, numChildren, classParentId, vtableShapeId, isVirtBaseClass, isIndirectVirtBaseClass, baseClassTypeId, virtualBaseDispIndex, virtualBasePointerOffset, module.Target) { __mod = module; } // end constructor
} // end AggregateMembers() public DbgVirtualBaseClassTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId, uint virtualBaseDispIndex, uint virtualBasePointerOffset, DbgTarget target) : base(debugger, moduleBase, typeId, kind, name, size, numChildren, classParentId, vtableShapeId, isVirtBaseClass, isIndirectVirtBaseClass, baseClassTypeId, target) { VirtualBaseDispIndex = virtualBaseDispIndex; VirtualBasePointerOffset = virtualBasePointerOffset; } // end constructor
protected DbgBaseClassTypeInfoBase(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId, DbgTarget target) : base(debugger, moduleBase, typeId, kind, name, size, numChildren, classParentId, vtableShapeId, target) { IsVirtualBaseClass = isVirtBaseClass; IsIndirectVirtualBaseClass = isIndirectVirtBaseClass; BaseClassTypeId = baseClassTypeId; } // end constructor
} // end constructor protected DbgBaseClassTypeInfoBase(DbgEngDebugger debugger, DbgModuleInfo module, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0? uint vtableShapeId, // could be 0? bool isVirtBaseClass, bool isIndirectVirtBaseClass, uint baseClassTypeId) : this(debugger, GetModBase(module), typeId, kind, name, size, numChildren, classParentId, vtableShapeId, isVirtBaseClass, isIndirectVirtBaseClass, baseClassTypeId, module.Target) { __mod = module; } // end constructor
} // end GetUdtTypeInfo() public DbgUdtTypeInfo(DbgEngDebugger debugger, ulong moduleBase, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0 uint vtableShapeId, // could be 0 DbgTarget target) : base(debugger, moduleBase, typeId, SymTag.UDT, name, size, target) { UdtKind = kind; m_classParentId = classParentId; m_vtableShapeId = vtableShapeId; m_numChildren = numChildren; } // end constructor
private UserDefinedTypeInformation CreateUserDefinedType(TypeInformationCache type_cache, long module_base, int type_index, SymbolLoadedModule module, string name) { int[] child_ids = GetChildIds(module_base, type_index); List <UserDefinedTypeMember> members = new List <UserDefinedTypeMember>(); long length = GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, type_index) ?? 0; foreach (var id in child_ids) { if (!CheckTypeTag(module_base, id, SymTagEnum.SymTagData)) { continue; } string member_name = GetSymbolName(module_base, id); int offset = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_OFFSET, module_base, id) ?? 0; int? member_type = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_TYPE, module_base, id); var bit_position = GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_BITPOSITION, module_base, id); var bit_length = GetSymbolLength(module_base, id); TypeInformation member_type_value = new TypeInformation(SymTagEnum.SymTagNull, 0, 0, module, member_name); if (member_type.HasValue) { var tag = GetSymbolTag(module_base, member_type.Value); member_type_value = CreateType(type_cache, tag ?? SymTagEnum.SymTagNull, module_base, member_type.Value, GetSymbolLong(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_LENGTH, module_base, member_type.Value) ?? 0 , module, GetSymbolName(module_base, member_type.Value)); } if (bit_position.HasValue) { members.Add(new UserDefinedTypeBitFieldMember(member_type_value, member_name, offset, bit_position.Value, bit_length)); } else { members.Add(new UserDefinedTypeMember(member_type_value, member_name, offset)); } } UdtKind kind = (UdtKind)(GetSymbolDword(IMAGEHLP_SYMBOL_TYPE_INFO.TI_GET_UDTKIND, module_base, type_index) ?? 0); return(new UserDefinedTypeInformation(length, type_index, module, name, kind == UdtKind.UdtUnion, members.AsReadOnly())); }
} // end constructor public DbgUdtTypeInfo(DbgEngDebugger debugger, DbgModuleInfo module, uint typeId, UdtKind kind, string name, ulong size, uint numChildren, uint classParentId, // could be 0 uint vtableShapeId) // could be 0 : this(debugger, GetModBase(module), typeId, kind, name, size, numChildren, classParentId, vtableShapeId, module.Target) { __mod = module; } // end constructor
public static extern bool SymGetTypeInfo(IntPtr hProcess, ulong baseOfDll, int typeId, SymbolTypeInfo typeinfo, out UdtKind tag);
private static void TestUdts(IDiaSession diaSession, PdbFile pdb) { // Extract all udts from PDB var typeRecordReferences = pdb.TpiStream.References; List <ClassRecord> classRecords = new List <ClassRecord>(); List <UnionRecord> unionRecords = new List <UnionRecord>(); for (int i = 0; i < typeRecordReferences.Count; i++) { if (ClassRecord.Kinds.Contains(typeRecordReferences[i].Kind)) { classRecords.Add((ClassRecord)pdb.TpiStream[TypeIndex.FromArrayIndex(i)]); } else if (UnionRecord.Kinds.Contains(typeRecordReferences[i].Kind)) { unionRecords.Add((UnionRecord)pdb.TpiStream[TypeIndex.FromArrayIndex(i)]); } } // Extract UDTs from DIA IDiaSymbol[] udts = diaSession.globalScope.GetChildren(SymTagEnum.UDT).ToArray(); HashSet <string> checkedUdts = new HashSet <string>(); List <Tuple <uint, TypeRecord> > checkedTypes = new List <Tuple <uint, TypeRecord> >(); foreach (IDiaSymbol udt in udts) { string name = udt.name; if (udt.length > 0 && !checkedUdts.Contains(name)) { UdtKind udtKind = (UdtKind)udt.udtKind; TagRecord record; if (udtKind == UdtKind.Union) { UnionRecord unionRecord = unionRecords.FirstOrDefault(cr => !cr.IsForwardReference && cr.Name.String == name); if (unionRecord == null) { unionRecord = unionRecords.FirstOrDefault(cr => cr.Name.String == name); } Assert.NotNull(unionRecord); record = unionRecord; } else { ClassRecord classRecord = classRecords.FirstOrDefault(cr => !cr.IsForwardReference && cr.Name.String == name); if (classRecord == null) { classRecord = classRecords.FirstOrDefault(cr => cr.Name.String == name); } Assert.NotNull(classRecord); record = classRecord; } CompareTypes(udt, pdb, record, checkedTypes); checkedUdts.Add(name); } } }