public AssemblyDebugParser(MetadataReaderProvider readerProvider, PdbType pdbType)
        {
            _readerProvider = readerProvider;
            _pdbType        = pdbType;

            // Possible BadImageFormatException if a full PDB is passed
            // in. We'll let the throw bubble up to something that can handle it
            _reader = _readerProvider.GetMetadataReader();
        }
Пример #2
0
        /// <summary>
        /// Gets the type name from array record.
        /// </summary>
        /// <param name="pdb">The PDB file reader.</param>
        /// <param name="arrayRecord">The array record.</param>
        private static string GetTypeName(PdbFileReader pdb, ArrayRecord arrayRecord)
        {
            PdbType elementType = pdb[arrayRecord.ElementType];

            if (elementType.Size == 0)
            {
                return($"{elementType.Name}[]");
            }

            ulong elements = arrayRecord.Size / elementType.Size;

            return($"{elementType.Name}[{elements}]");
        }
Пример #3
0
        public AssemblyDebugParser(MetadataReaderProvider readerProvider, PdbType pdbType)
        {
            _readerProvider = readerProvider;
            _pdbType        = pdbType;

            try
            {
                _reader = _readerProvider.GetMetadataReader();
            }
            catch (BadImageFormatException) // A Full PDB
            {
                _pdbType = PdbType.Full;
            }
        }
Пример #4
0
        private PdbType[] EnumerateArguments()
        {
            TypeRecord typeRecord = Pdb.PdbFile.TpiStream[ProcedureRecord.ArgumentList];

            if (typeRecord is ArgumentListRecord argumentList)
            {
                PdbType[] arguments = new PdbType[argumentList.Arguments.Length];

                for (int i = 0; i < arguments.Length; i++)
                {
                    arguments[i] = Pdb[argumentList.Arguments[i]];
                }
                return(arguments);
            }
            return(new PdbType[0]);
        }
Пример #5
0
        private static void CompareBaseType(IDiaSymbol diaType, PdbType pdbType)
        {
            Assert.IsAssignableFrom <PdbSimpleType>(pdbType);
            PdbSimpleType pdbSimpleType = (PdbSimpleType)pdbType;

            Assert.True(pdbSimpleType.TypeIndex.IsSimple);
            switch (pdbSimpleType.TypeIndex.SimpleKind)
            {
            case SimpleTypeKind.None:
                Assert.True(diaType.baseType == BasicType.NoType);
                break;

            case SimpleTypeKind.Void:
                Assert.True(diaType.baseType == BasicType.Void);
                break;

            case SimpleTypeKind.HResult:
                Assert.True(diaType.baseType == BasicType.Hresult);
                break;

            case SimpleTypeKind.UnsignedCharacter:
                Assert.True(diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.NarrowCharacter:
            case SimpleTypeKind.SignedCharacter:
                Assert.True(diaType.baseType == BasicType.Char || diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.WideCharacter:
                Assert.True(diaType.baseType == BasicType.WChar);
                break;

            case SimpleTypeKind.Character16:
                Assert.True(diaType.baseType == BasicType.Char16);
                break;

            case SimpleTypeKind.Character32:
                Assert.True(diaType.baseType == BasicType.Char32);
                break;

            case SimpleTypeKind.SByte:
                Assert.True(diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.Byte:
                Assert.True(diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.Int16Short:
            case SimpleTypeKind.Int16:
                Assert.True(diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.UInt16:
            case SimpleTypeKind.UInt16Short:
                Assert.True(diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.Int32Long:
            case SimpleTypeKind.Int32:
                Assert.True(diaType.baseType == BasicType.Long || diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.UInt32Long:
            case SimpleTypeKind.UInt32:
                Assert.True(diaType.baseType == BasicType.ULong || diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.Int64Quad:
            case SimpleTypeKind.Int64:
                Assert.True(diaType.baseType == BasicType.Long || diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.UInt64Quad:
            case SimpleTypeKind.UInt64:
                Assert.True(diaType.baseType == BasicType.ULong || diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.Int128Oct:
            case SimpleTypeKind.Int128:
                Assert.True(diaType.baseType == BasicType.Long || diaType.baseType == BasicType.Int);
                break;

            case SimpleTypeKind.UInt128Oct:
            case SimpleTypeKind.UInt128:
                Assert.True(diaType.baseType == BasicType.ULong || diaType.baseType == BasicType.UInt);
                break;

            case SimpleTypeKind.Float16:
                Assert.True(diaType.baseType == BasicType.Float);
                break;

            case SimpleTypeKind.Float32:
            case SimpleTypeKind.Float32PartialPrecision:
            case SimpleTypeKind.Float64:
            case SimpleTypeKind.Float80:
            case SimpleTypeKind.Float128:
                Assert.True(diaType.baseType == BasicType.Float);
                break;

            case SimpleTypeKind.Complex16:
            case SimpleTypeKind.Complex32:
            case SimpleTypeKind.Complex32PartialPrecision:
            case SimpleTypeKind.Complex48:
            case SimpleTypeKind.Complex64:
            case SimpleTypeKind.Complex80:
            case SimpleTypeKind.Complex128:
                Assert.True(diaType.baseType == BasicType.Complex);
                break;

            case SimpleTypeKind.Boolean8:
            case SimpleTypeKind.Boolean16:
            case SimpleTypeKind.Boolean32:
            case SimpleTypeKind.Boolean64:
            case SimpleTypeKind.Boolean128:
                Assert.True(diaType.baseType == BasicType.Bool);
                break;

            case SimpleTypeKind.NotTranslated:
                Assert.True(diaType.baseType == BasicType.NoType);
                break;

            default:
                throw new NotImplementedException($"Unexpected simple type: {pdbType.TypeIndex.SimpleKind}, from type index: {pdbType.TypeIndex}");
            }
        }
Пример #6
0
        private static void CompareTypes(IDiaSymbol diaType, PdbType pdbType, HashSet <Tuple <uint, PdbType> > checkedTypes)
        {
            if (diaType == null)
            {
                Assert.True(pdbType.TypeIndex.IsNoneType);
                return;
            }

            uint diaSymbolId       = diaType.symIndexId;
            var  checkedTypesTuple = Tuple.Create(diaSymbolId, pdbType);

            if (checkedTypes.Contains(checkedTypesTuple))
            {
                return;
            }
            checkedTypes.Add(checkedTypesTuple);

            Assert.Equal(diaType.length, pdbType.Size);
            Assert.Equal(diaType.constType, pdbType.ModifierOptions.HasFlag(ModifierOptions.Const));
            Assert.Equal(diaType.unalignedType, pdbType.ModifierOptions.HasFlag(ModifierOptions.Unaligned));
            Assert.Equal(diaType.volatileType, pdbType.ModifierOptions.HasFlag(ModifierOptions.Volatile));
            if (diaType.symTag == SymTagEnum.UDT)
            {
                Assert.IsAssignableFrom <PdbUserDefinedType>(pdbType);
                PdbUserDefinedType pdbUdt = (PdbUserDefinedType)pdbType;

                if (pdbType.Name != "<unnamed-tag>")
                {
                    Assert.Equal(diaType.name, pdbType.Name);
                }
                Assert.Equal(diaType.nested, pdbUdt.IsNested);
                Assert.Equal(diaType.scoped, pdbUdt.IsScoped);
                Assert.Equal(diaType.packed, pdbUdt.IsPacked);
                Assert.Equal(diaType.overloadedOperator, pdbUdt.HasOverloadedOperator);
                Assert.Equal(diaType.hasNestedTypes, pdbUdt.ContainsNestedClass);
                Assert.Equal(diaType.hasAssignmentOperator, pdbUdt.HasOverloadedAssignmentOperator);
                Assert.Equal(diaType.constructor, pdbUdt.HasConstructorOrDestructor);

                // Fields
                var diaData   = diaType.GetChildren(SymTagEnum.Data).ToArray();
                var diaFields = diaData.Where(d => d.locationType == LocationType.ThisRel || d.locationType == LocationType.BitField).ToArray();
                var pdbFields = pdbUdt.Fields;

                Assert.Equal(diaFields.Length, pdbFields.Count);
                for (int i = 0; i < pdbFields.Count; i++)
                {
                    if (pdbFields[i] is PdbTypeBitField bitField)
                    {
                        Assert.Equal(LocationType.BitField, diaFields[i].locationType);
                        Assert.Equal(diaFields[i].bitPosition, bitField.BitOffset);
                        Assert.Equal(diaFields[i].length, bitField.BitSize);
                    }
                    Assert.Equal(diaFields[i].access, (uint)pdbFields[i].Access);
                    Assert.Equal(diaFields[i].name, pdbFields[i].Name);
                    Assert.Equal((ulong)diaFields[i].offset, pdbFields[i].Offset);
                    CompareTypes(diaFields[i].type, pdbFields[i].Type, checkedTypes);
                }

                // Constants
                var diaConstants = diaData.Where(d => d.locationType == LocationType.Constant).ToArray();
                var pdbConstants = pdbUdt.StaticFields.OfType <PdbTypeConstant>().ToArray();

                Assert.Equal(diaConstants.Length, pdbConstants.Length);
                for (int i = 0; i < pdbConstants.Length; i++)
                {
                    Assert.Equal(diaConstants[i].access, (uint)pdbConstants[i].Access);
                    Assert.Equal(diaConstants[i].name, pdbConstants[i].Name);
                    Assert.Equal(diaConstants[i].value.ToString(), pdbConstants[i].Value.ToString());
                    CompareTypes(diaConstants[i].type, pdbConstants[i].Type, checkedTypes);
                }

                // Thread local storage
                var diaTls = diaData.Where(d => d.locationType == LocationType.TLS).ToArray();
                var pdbTls = pdbUdt.StaticFields.OfType <PdbTypeThreadLocalStorage>().ToArray();

                Assert.Equal(diaTls.Length, pdbTls.Length);
                for (int i = 0; i < pdbTls.Length; i++)
                {
                    Assert.Equal(diaTls[i].access, (uint)pdbTls[i].Access);
                    Assert.Equal(diaTls[i].name, pdbTls[i].Name);
                    Assert.Equal(diaTls[i].addressSection, pdbTls[i].Segment);
                    Assert.Equal(diaTls[i].addressOffset, pdbTls[i].Offset);
                    CompareTypes(diaTls[i].type, pdbTls[i].Type, checkedTypes);
                }

                // Static fields
                var diaStaticFields = diaData.Where(d => d.locationType == LocationType.Static).ToArray();
                var pdbStaticFields = pdbUdt.StaticFields.Where(sf => !(sf is PdbTypeConstant) && !(sf is PdbTypeThreadLocalStorage)).ToArray();

                Assert.Equal(diaStaticFields.Length, pdbStaticFields.Length);
                for (int i = 0; i < pdbStaticFields.Length; i++)
                {
                    Assert.Equal(diaStaticFields[i].access, (uint)pdbStaticFields[i].Access);
                    Assert.Equal(diaStaticFields[i].name, pdbStaticFields[i].Name);
                    if (pdbStaticFields[i] is PdbTypeRegularStaticField regularStaticField)
                    {
                        Assert.Equal(diaStaticFields[i].addressSection, regularStaticField.Segment);
                        Assert.Equal(diaStaticFields[i].addressOffset, regularStaticField.Offset);
                        Assert.Equal(diaStaticFields[i].relativeVirtualAddress, regularStaticField.RelativeVirtualAddress);
                    }
                    CompareTypes(diaStaticFields[i].type, pdbStaticFields[i].Type, checkedTypes);
                }

                // Base classes
                var diaAllBaseClasses = diaType.GetChildren(SymTagEnum.BaseClass).Concat(diaType.GetChildren(SymTagEnum.BaseInterface)).ToArray();
                var diaBaseClasses    = diaAllBaseClasses.Where(b => !b.virtualBaseClass).ToArray();

                Assert.Equal(diaBaseClasses.Length, pdbUdt.BaseClasses.Count);
                for (int i = 0; i < diaBaseClasses.Length; i++)
                {
                    Assert.Equal(diaBaseClasses[i].access, (uint)pdbUdt.BaseClasses[i].Access);
                    Assert.Equal(diaBaseClasses[i].offset, (int)pdbUdt.BaseClasses[i].Offset);
                    CompareTypes(diaBaseClasses[i].type, pdbUdt.BaseClasses[i].BaseType, checkedTypes);
                }

                // Virtual base classes
                var diaVirtualBaseClasses = diaAllBaseClasses.Where(b => b.virtualBaseClass).ToArray();

                Assert.Equal(diaVirtualBaseClasses.Length, pdbUdt.VirtualBaseClasses.Count);
                for (int i = 0; i < diaVirtualBaseClasses.Length; i++)
                {
                    Assert.Equal(diaVirtualBaseClasses[i].access, (uint)pdbUdt.VirtualBaseClasses[i].Access);
                    Assert.Equal(diaVirtualBaseClasses[i].virtualBaseDispIndex, (uint)pdbUdt.VirtualBaseClasses[i].VirtualTableIndex);
                    Assert.Equal(diaVirtualBaseClasses[i].virtualBasePointerOffset, (int)pdbUdt.VirtualBaseClasses[i].VirtualBasePointerOffset);
                    CompareTypes(diaVirtualBaseClasses[i].type, pdbUdt.VirtualBaseClasses[i].BaseType, checkedTypes);
                    CompareTypes(diaVirtualBaseClasses[i].virtualBaseTableType, pdbUdt.VirtualBaseClasses[i].VirtualBasePointerType, checkedTypes);
                }
            }
            else if (diaType.symTag == SymTagEnum.Enum)
            {
                Assert.IsAssignableFrom <PdbEnumType>(pdbType);
                PdbEnumType pdbEnumType = (PdbEnumType)pdbType;

                Assert.Equal(diaType.name, pdbType.Name);
                Assert.Equal(diaType.nested, pdbEnumType.IsNested);
                Assert.Equal(diaType.scoped, pdbEnumType.IsScoped);
                Assert.Equal(diaType.packed, pdbEnumType.IsPacked);
                Assert.Equal(diaType.overloadedOperator, pdbEnumType.HasOverloadedOperator);
                Assert.Equal(diaType.hasNestedTypes, pdbEnumType.ContainsNestedClass);
                Assert.Equal(diaType.hasAssignmentOperator, pdbEnumType.HasOverloadedAssignmentOperator);
                Assert.Equal(diaType.constructor, pdbEnumType.HasConstructorOrDestructor);
                CompareBaseType(diaType.type, pdbEnumType.UnderlyingType);
                CompareBaseType(diaType, pdbEnumType.UnderlyingType);

                // Compare enumeration values
                var diaValues = diaType.GetChildren(SymTagEnum.Data).ToArray();

                Assert.Equal(diaValues.Length, pdbEnumType.Values.Count);
                for (int i = 0; i < diaValues.Length; i++)
                {
                    Assert.Equal(DataKind.Constant, diaValues[i].dataKind);
                    Assert.Equal(diaValues[i].name, pdbEnumType.Values[i].Name);
                    Assert.Equal(diaValues[i].value.ToString(), pdbEnumType.Values[i].Value.ToString());
                }
            }
            else if (diaType.symTag == SymTagEnum.BaseType)
            {
                CompareBaseType(diaType, pdbType);
            }
            else if (diaType.symTag == SymTagEnum.ArrayType)
            {
                Assert.IsAssignableFrom <PdbArrayType>(pdbType);
                PdbArrayType pdbArrayType = (PdbArrayType)pdbType;

                Assert.Equal(diaType.count, pdbArrayType.Count);
                CompareTypes(diaType.type, pdbArrayType.ElementType, checkedTypes);
                CompareTypes(diaType.arrayIndexType, pdbArrayType.IndexType, checkedTypes);
            }
            else if (diaType.symTag == SymTagEnum.PointerType)
            {
                Assert.IsAssignableFrom <PdbPointerType>(pdbType);
                PdbPointerType pdbPointerType = (PdbPointerType)pdbType;

                Assert.Equal(diaType.reference, pdbPointerType.IsLValueReference);
                Assert.Equal(diaType.RValueReference, pdbPointerType.IsRValueReference);
                CompareTypes(diaType.type, pdbPointerType.ElementType, checkedTypes);
            }
            else if (diaType.symTag == SymTagEnum.FunctionType)
            {
                PdbType           returnType;
                CallingConvention callingConvention;
                ushort            parameterCount;
                PdbType[]         pdbArguments;

                if (pdbType is PdbFunctionType)
                {
                    Assert.IsAssignableFrom <PdbFunctionType>(pdbType);
                    PdbFunctionType pdbFunctionType = (PdbFunctionType)pdbType;

                    returnType        = pdbFunctionType.ReturnType;
                    callingConvention = pdbFunctionType.CallingConvention;
                    parameterCount    = pdbFunctionType.ParameterCount;
                    pdbArguments      = pdbFunctionType.Arguments;
                }
                else
                {
                    Assert.IsAssignableFrom <PdbMemberFunctionType>(pdbType);
                    PdbMemberFunctionType pdbMemberFunctionType = (PdbMemberFunctionType)pdbType;

                    returnType        = pdbMemberFunctionType.ReturnType;
                    callingConvention = pdbMemberFunctionType.CallingConvention;
                    parameterCount    = pdbMemberFunctionType.ParameterCount;
                    pdbArguments      = pdbMemberFunctionType.Arguments;

                    CompareTypes(diaType.objectPointerType, pdbMemberFunctionType.ThisType, checkedTypes);
                    Assert.Equal(diaType.thisAdjust, pdbMemberFunctionType.ThisPointerAdjustment);
                }

                Assert.Equal(diaType.callingConvention, (uint)callingConvention);
                Assert.Equal(diaType.count, parameterCount);
                CompareTypes(diaType.type, returnType, checkedTypes);

                IDiaSymbol[] diaArguments = diaType.GetChildren(SymTagEnum.FunctionArgType).ToArray();

                Assert.Equal(diaArguments.Length, pdbArguments.Length);
                for (int i = 0; i < diaArguments.Length; i++)
                {
                    CompareTypes(diaArguments[i].type, pdbArguments[i], checkedTypes);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Пример #7
0
        public void TestPdb(int pdbIndex)
        {
            if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
            {
                return;
            }

            string         pdbPath = GetPdbPath(pdbIndex);
            IDiaDataSource dia     = DiaLoader.CreateDiaSource();
            IDiaSession    diaSession;

            dia.loadDataFromPdb(pdbPath);
            dia.openSession(out diaSession);
            using (PdbFileReader pdb = new PdbFileReader(pdbPath))
            {
                // Verify UDTs
                IReadOnlyList <PdbType> pdbUdts = pdb.UserDefinedTypes;
                IDiaSymbol[]            diaUdts = diaSession.globalScope.GetChildren(SymTagEnum.UDT)
                                                  .Concat(diaSession.globalScope.GetChildren(SymTagEnum.Enum))
                                                  .OrderBy(s => s.constType ? 1 : 0) // Order so that we move types with ModifierRecord to the back
                                                  .ThenBy(s => s.unalignedType ? 1 : 0)
                                                  .ThenBy(s => s.volatileType ? 1 : 0)
                                                  .ToArray();
                HashSet <Tuple <uint, PdbType> > checkedTypes = new HashSet <Tuple <uint, PdbType> >();
                HashSet <string>             checkedUdts      = new HashSet <string>();
                Dictionary <string, PdbType> pdbTypesByName   = new Dictionary <string, PdbType>();

                foreach (PdbType pdbType in pdbUdts)
                {
                    if (!pdbTypesByName.ContainsKey(pdbType.Name))
                    {
                        pdbTypesByName.Add(pdbType.Name, pdbType);
                    }
                }

                foreach (IDiaSymbol diaType in diaUdts)
                {
                    string name = diaType.name;

                    if (!checkedUdts.Contains(name))
                    {
                        PdbType pdbType = pdbTypesByName[name];

                        CompareTypes(diaType, pdbType, checkedTypes);
                        checkedUdts.Add(name);
                    }
                }

                // Verify global variables
                IDiaSymbol[] diaGlobalVariables = diaSession.globalScope.GetChildren(SymTagEnum.Data).Where(s => s.locationType == LocationType.Static).ToArray();

                Assert.Equal(diaGlobalVariables.Length, pdb.GlobalVariables.Length);
                for (int i = 0; i < diaGlobalVariables.Length; i++)
                {
                    IDiaSymbol        diaGlobalVariable = diaGlobalVariables[i];
                    PdbGlobalVariable pdbGlobalVariable = pdb.GlobalVariables[i];

                    Assert.Equal(diaGlobalVariable.name, pdbGlobalVariable.Name);
                    Assert.Equal(diaGlobalVariable.addressSection, pdbGlobalVariable.Segment);
                    Assert.Equal(diaGlobalVariable.addressOffset, pdbGlobalVariable.Offset);
                    Assert.Equal(diaGlobalVariable.relativeVirtualAddress, pdbGlobalVariable.RelativeVirtualAddress);
                    CompareTypes(diaGlobalVariable.type, pdbGlobalVariable.Type, checkedTypes);
                }

                // Verify functions
                IDiaSymbol[] diaFunctions = diaSession.globalScope.GetChildren(SymTagEnum.Function)
                                            .OrderBy(d => d.name)
                                            .ThenBy(d => d.relativeVirtualAddress).ToArray();
                PdbFunction[] pdbFunctions = pdb.Functions
                                             .OrderBy(p => p.Name)
                                             .ThenBy(p => p.RelativeVirtualAddress).ToArray();

                Assert.Equal(diaFunctions.Length, pdbFunctions.Length);
                for (int i = 0; i < diaFunctions.Length; i++)
                {
                    IDiaSymbol  diaFunction = diaFunctions[i];
                    PdbFunction pdbFunction = pdbFunctions[i];

                    Assert.Equal(diaFunction.name, pdbFunction.Name);
                    Assert.Equal(diaFunction.addressSection, pdbFunction.Segment);
                    Assert.Equal(diaFunction.addressOffset, pdbFunction.Offset);
                    Assert.Equal(diaFunction.customCallingConvention, pdbFunction.HasCustomCallingConvention);
                    Assert.Equal(diaFunction.farReturn, pdbFunction.HasFarReturn);
                    Assert.Equal(diaFunction.framePointerPresent, pdbFunction.HasFramePointer);
                    Assert.Equal(diaFunction.interruptReturn, pdbFunction.HasInterruptReturn);
                    Assert.Equal(diaFunction.length, pdbFunction.CodeSize);
                    Assert.Equal(diaFunction.noInline, pdbFunction.IsNoInline);
                    Assert.Equal(diaFunction.notReached, pdbFunction.IsUnreachable);
                    Assert.Equal(diaFunction.noReturn, pdbFunction.IsNoReturn);
                    Assert.Equal(diaFunction.optimizedCodeDebugInfo, pdbFunction.HasOptimizedDebugInfo);
                    Assert.Equal(diaFunction.relativeVirtualAddress, pdbFunction.RelativeVirtualAddress);
                    CompareTypes(diaFunction.type, pdbFunction.FunctionType, checkedTypes);
                    //Assert.Equal(diaFunction.get_undecoratedNameEx(UndecoratedNameOptions.Complete), pdbFunction.GetUndecoratedName(NameUndecorator.Flags.Complete));
                    // TODO: hasAlloca
                    // TODO: hasEH
                    // TODO: hasEHa
                    // TODO: hasInlAsm
                    // TODO: hasLongJump
                    // TODO: hasSecurityChecks
                    // TODO: hasSEH
                    // TODO: hasSetJump
                    // TODO: intro
                    // TODO: InlSpec
                    // TODO: isNaked
                    // TODO: isStatic
                    // TODO: locationType
                    // TODO: noStackOrdering
                    // TODO: pure
                    // TODO: token
                    // TODO: virtual
                    // TODO: virtualBaseOffset
                }

                // Verify publics
                IDiaSymbol[] diaPublicSymbols = diaSession.globalScope.GetChildren(SymTagEnum.PublicSymbol).ToArray();

                Assert.Equal(diaPublicSymbols.Length, pdb.PublicSymbols.Length);
                for (int i = 0; i < diaPublicSymbols.Length; i++)
                {
                    IDiaSymbol      diaPublicSymbol = diaPublicSymbols[i];
                    PdbPublicSymbol pdbPublicSymbol = pdb.PublicSymbols[i];

                    Assert.Equal(diaPublicSymbol.name, pdbPublicSymbol.Name);
                    Assert.Equal(diaPublicSymbol.addressSection, pdbPublicSymbol.Segment);
                    Assert.Equal(diaPublicSymbol.addressOffset, pdbPublicSymbol.Offset);
                    Assert.Equal(diaPublicSymbol.relativeVirtualAddress, pdbPublicSymbol.RelativeVirtualAddress);
                    Assert.Equal(diaPublicSymbol.code, pdbPublicSymbol.IsCode);
                    Assert.Equal(diaPublicSymbol.function, pdbPublicSymbol.IsFunction);
                    Assert.Equal(diaPublicSymbol.managed, pdbPublicSymbol.IsManaged);
                    Assert.Equal(diaPublicSymbol.msil, pdbPublicSymbol.IsMsil);
                    Assert.Equal(LocationType.Static, diaPublicSymbol.locationType);
                    Assert.True(CompareUndecoratedNames(pdbPublicSymbol.Name, diaPublicSymbol.get_undecoratedNameEx(UndecoratedNameOptions.Complete), pdbPublicSymbol.GetUndecoratedName(NameUndecorator.Flags.Complete)));
                    //Assert.Equal(diaPublicSymbol.get_undecoratedNameEx(UndecoratedNameOptions.Complete), pdbPublicSymbol.GetUndecoratedName(NameUndecorator.Flags.Complete));
                    // TODO: diaPublicSymbol.length
                }
            }
        }