/// <summary> /// Initializes data based on the <see cref="UnionRecord"/>. /// </summary> private void Initialize(UnionRecord record) { Tag = Engine.CodeTypeTag.Union; BasicType = DIA.BasicType.NoType; Name = record.Name; ulong size = record.Size; if (size > int.MaxValue) { throw new ArgumentException("Symbol size is unexpected"); } Size = (int)size; IsForwardReference = record.IsForwardReference; UniqueName = record.UniqueName; }
/// <summary> /// Reads type record for the specified type index. /// </summary> /// <param name="typeIndex">Type record index in <see cref="references"/> list.</param> /// <returns></returns> private TypeRecord ReadType(int typeIndex) { IBinaryReader reader = typeRecordsSubStreamPerThread.Value; RecordReference reference = references[typeIndex]; TypeRecord typeRecord; long dataEnd = reference.DataOffset + reference.DataLen; reader.Position = reference.DataOffset; switch (reference.Kind) { case TypeLeafKind.LF_MODIFIER: typeRecord = ModifierRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_PROCEDURE: typeRecord = ProcedureRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_MFUNCTION: typeRecord = MemberFunctionRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_LABEL: typeRecord = LabelRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_MFUNC_ID: typeRecord = MemberFunctionIdRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_ARGLIST: typeRecord = ArgumentListRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_SUBSTR_LIST: typeRecord = StringListRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_POINTER: typeRecord = PointerRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_NESTTYPE: typeRecord = NestedTypeRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_FIELDLIST: typeRecord = FieldListRecord.Read(reader, reference.Kind, reference.DataLen); break; case TypeLeafKind.LF_ENUM: typeRecord = EnumRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_CLASS: case TypeLeafKind.LF_STRUCTURE: case TypeLeafKind.LF_INTERFACE: typeRecord = ClassRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_ARRAY: typeRecord = ArrayRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_BITFIELD: typeRecord = BitFieldRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_METHODLIST: typeRecord = MethodOverloadListRecord.Read(reader, reference.Kind, reference.DataLen); break; case TypeLeafKind.LF_UNION: typeRecord = UnionRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_VTSHAPE: typeRecord = VirtualFunctionTableShapeRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_UDT_MOD_SRC_LINE: typeRecord = UdtModuleSourceLineRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_STRING_ID: typeRecord = StringIdRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_BUILDINFO: typeRecord = BuildInfoRecord.Read(reader, reference.Kind); break; case TypeLeafKind.LF_FUNC_ID: typeRecord = FunctionIdRecord.Read(reader, reference.Kind); break; default: #if DEBUG throw new NotImplementedException($"Unknown reference kind: {reference.Kind}"); #else return(null); #endif } if (reader.Position + 4 < dataEnd || reader.Position > dataEnd) { throw new Exception("Parsing went wrong"); } return(typeRecord); }
/// <summary> /// Initializes a new instance of the <see cref="PdbType"/> class. /// </summary> /// <param name="pdb">The PDB file reader.</param> /// <param name="typeIndex">Type index.</param> /// <param name="unionRecord">The union record.</param> /// <param name="modifierOptions">The modifier options.</param> internal PdbUnionType(PdbFileReader pdb, TypeIndex typeIndex, UnionRecord unionRecord, ModifierOptions modifierOptions) : base(pdb, typeIndex, unionRecord, modifierOptions, unionRecord.Size) { UnionRecord = unionRecord; }
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); } } }