private IEnumerable <byte> ReadCustomMetadata(ManagedProcedureSymbol function)
        {
            foreach (OemSymbol oem in function.Children.OfType <OemSymbol>())
            {
                if (oem.Id == MsilMetadataGuid)
                {
                    IBinaryReader reader = oem.UserDataReader;
                    string        name   = reader.ReadCStringWide().String;

                    if (name == "MD2")
                    {
                        byte version = reader.ReadByte();

                        if (version == 4)
                        {
                            int count = reader.ReadByte();

                            reader.Align(4);
                            for (int i = 0; i < count; i++)
                            {
                                long start        = reader.Position;
                                byte entryVersion = reader.ReadByte();
                                byte kind         = reader.ReadByte();

                                reader.Align(4);
                                yield return(kind);

                                uint numberOfBytesInItem = reader.ReadUint();
                                reader.Position = start + numberOfBytesInItem;
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdbFunction"/> class.
        /// </summary>
        /// <param name="pdbFile">Portable PDB file reader.</param>
        /// <param name="procedure">Managed procedure symbol from PDB.</param>
        /// <param name="dbiModule">DBI module descriptor from PDB.</param>
        internal PdbFunction(PdbFile pdbFile, ManagedProcedureSymbol procedure, DbiModuleDescriptor dbiModule)
        {
            PdbFile          = pdbFile;
            Procedure        = procedure;
            DbiModule        = dbiModule;
            localScopesCache = SimpleCache.CreateStruct(() =>
            {
                IEnumerable <BlockSymbol> blocks = Procedure.Children.OfType <BlockSymbol>();
                int count = blocks.Count();
                IPdbLocalScope[] scopes = new IPdbLocalScope[count];
                int i = 0;

                foreach (BlockSymbol block in blocks)
                {
                    scopes[i++] = new PdbLocalScope(this, block);
                }
                return(scopes);
            });
            sequencePointsCache = SimpleCache.CreateStruct(() =>
            {
                var checksums        = DbiModule.DebugSubsectionStream[DebugSubsectionKind.FileChecksums];
                var linesSubsections = dbiModule.DebugSubsectionStream[DebugSubsectionKind.Lines];
                List <IPdbSequencePoint> sequencePoints = new List <IPdbSequencePoint>();

                foreach (LinesSubsection linesSubsection in linesSubsections)
                {
                    foreach (var file in linesSubsection.Files)
                    {
                        var checksum = (FileChecksumSubsection)checksums[file.Index];
                        var source   = PdbFile[checksum];

                        foreach (var line in file.Lines)
                        {
                            sequencePoints.Add(new PdbSequencePoint(this, source, line));
                        }
                    }
                }

                return(sequencePoints);
            });
        }
Beispiel #3
0
        public string Load()
        {
            if (string.IsNullOrWhiteSpace(AssemblyPath))
            {
                return("操作失败,未能找到编译后的文件,请重新生成。");
            }
            FileInfo assemFile = new FileInfo(AssemblyPath);

            if (!assemFile.Exists)
            {
                return("操作失败,未能找到编译后的文件,请重新生成。");
            }
            LastModifyTime = assemFile.LastWriteTime;
            FileInfo pdbFile = new FileInfo(PdbPath);

            if (!assemFile.Exists)
            {
                return("操作失败,未能找到.pdb文件,打开debug-full模式。");
            }

            // 加载pdb
            PdbFile Pdb = new PdbFile(PdbPath);

            try
            {
                Assembly asm = Assembly.LoadFrom(AssemblyPath);
                foreach (var typ in asm.DefinedTypes)
                {
                    var cls = new ClassInfo();
                    cls.Name      = typ.Name;
                    cls.FullName  = typ.FullName;
                    cls.NameSpace = typ.Namespace;
                    foreach (var item in typ.CustomAttributes)
                    {
                        var attr = new AttributeInfo();
                        attr.TypeFullName = item.AttributeType.FullName;
                        foreach (var arg in item.ConstructorArguments)
                        {
                            attr.ArgumentList.Add(arg.Value.ToString());
                        }
                        cls.AttributeList.Add(attr);
                    }
                    foreach (var item in typ.ImplementedInterfaces)
                    {
                        cls.Interfaces.Add(item.FullName);
                    }
                    foreach (var item in typ.DeclaredMethods)
                    {
                        var method = new MethodInfo();
                        method.Name       = item.Name;
                        method.ReturnType = item.ReturnType.FullName;
                        var parameters = item.GetParameters();
                        foreach (var attre in item.CustomAttributes)
                        {
                            var attr = new AttributeInfo();
                            attr.TypeFullName = attre.AttributeType.FullName;
                            foreach (var arg in attre.ConstructorArguments)
                            {
                                attr.ArgumentList.Add(arg.Value.ToString());
                            }
                            method.AttributeList.Add(attr);
                        }
                        cls.MethodList.Add(method);
                    }
                    foreach (var prop in typ.DeclaredProperties)
                    {
                        var property = new PropertyInfo();
                        property.Name = prop.Name;
                        property.Type = prop.PropertyType.FullName;
                        foreach (var item in prop.CustomAttributes)
                        {
                            var attr = new AttributeInfo();
                            attr.TypeFullName = item.AttributeType.FullName;
                            foreach (var arg in item.ConstructorArguments)
                            {
                                attr.ArgumentList.Add(arg.Value.ToString());
                            }

                            property.AttributeList.Add(attr);
                        }
                        cls.PropertyList.Add(property);
                    }
                    // 从pdb文件中取出代码路径和位置
                    foreach (var module in Pdb.DbiStream.Modules)
                    {
                        if (module.ModuleName.String == cls.FullName)
                        {
                            cls.FilePath = module.Files.ToList();
                            if (cls.FilePath.Count > 1)
                            {
                                continue;
                            }
                            var pdbFunctions = GetManagedProcedures(module.LocalSymbolStream);
                            // 确定函数的行号
                            var classMembers = module.DebugSubsectionStream[DebugSubsectionKind.Lines].OfType <LinesSubsection>().ToArray();
                            foreach (var mem in classMembers)
                            {
                                // 找对应的pdbFunction
                                ManagedProcedureSymbol pdbFunction = null;
                                foreach (var pdbf in pdbFunctions)
                                {
                                    if (pdbf.CodeOffset == mem.CodeOffset)
                                    {
                                        pdbFunction = pdbf;
                                        break;
                                    }
                                }
                                if (pdbFunction == null)
                                {
                                    continue;
                                }

                                // 找对应的FunctionInfo
                                var method = cls.MethodList.FirstOrDefault(f => f.Name == pdbFunction.Name.String);
                                if (method == null)
                                {
                                    continue;
                                }

                                // 统计行号
                                uint min   = 999999;
                                uint max   = 0;
                                var  mlins = mem.Files[0].Lines;
                                foreach (var elin in mlins)
                                {
                                    if (elin.LineStart < 10000 && elin.LineEnd < 10000)
                                    {
                                        min = Math.Min(min, elin.LineStart);
                                        max = Math.Max(max, elin.LineEnd);
                                    }
                                }
                                if (min < max)
                                {
                                    method.MinLine = (int)min;
                                    method.MaxLine = (int)max;
                                }
                            }
                        }
                    }
                    ClassList.Add(cls);
                }
                return("");
            }
            catch (Exception e)
            {
                return(e.Message + Environment.NewLine + e.StackTrace);
            }
            finally
            {
                Pdb.Dispose();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Reads symbol record from symbol references for the specified index.
        /// </summary>
        /// <param name="index">Index of the symbol record.</param>
        private SymbolRecord GetSymbol(int index)
        {
            // Since DictionaryCache is allowing only single thread to call this function, we don't need to lock reader here.
            SymbolRecordReference reference = references[index];

            Reader.Position = reference.DataOffset;
            switch (reference.Kind)
            {
            case SymbolRecordKind.S_GPROC32:
            case SymbolRecordKind.S_LPROC32:
            case SymbolRecordKind.S_GPROC32_ID:
            case SymbolRecordKind.S_LPROC32_ID:
            case SymbolRecordKind.S_LPROC32_DPC:
            case SymbolRecordKind.S_LPROC32_DPC_ID:
                return(ProcedureSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_PUB32:
                return(Public32Symbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_CONSTANT:
            case SymbolRecordKind.S_MANCONSTANT:
                return(ConstantSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_LDATA32:
            case SymbolRecordKind.S_GDATA32:
            case SymbolRecordKind.S_LMANDATA:
            case SymbolRecordKind.S_GMANDATA:
                return(DataSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_PROCREF:
            case SymbolRecordKind.S_LPROCREF:
                return(ProcedureReferenceSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_TOKENREF:
                return(TokenReferenceSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_UDT:
            case SymbolRecordKind.S_COBOLUDT:
                return(UdtSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_LTHREAD32:
            case SymbolRecordKind.S_GTHREAD32:
                return(ThreadLocalDataSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_GMANPROC:
            case SymbolRecordKind.S_LMANPROC:
                return(ManagedProcedureSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_BLOCK32:
                return(BlockSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_OEM:
                return(OemSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_UNAMESPACE:
                return(NamespaceSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_MANSLOT:
                return(AttributeSlotSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_END:
            case SymbolRecordKind.S_INLINESITE_END:
                return(EndSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_ANNOTATION:
                return(AnnotationSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_ANNOTATIONREF:
                return(AnnotationReferenceSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_REGREL32:
                return(RegisterRelativeSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_OBJNAME:
                return(ObjectNameSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_COMPILE2:
                return(Compile2Symbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_COMPILE3:
                return(Compile3Symbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_ENVBLOCK:
                return(EnvironmentBlockSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_BUILDINFO:
                return(BuildInfoSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_FRAMEPROC:
                return(FrameProcedureSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_LABEL32:
                return(LabelSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_HEAPALLOCSITE:
                return(HeapAllocationSiteSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_CALLSITEINFO:
                return(CallSiteInfoSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_FRAMECOOKIE:
                return(FrameCookieSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_THUNK32:
                return(Thunk32Symbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_LOCAL:
                return(LocalSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_DEFRANGE_REGISTER:
                return(DefRangeRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_DEFRANGE_REGISTER_REL:
                return(DefRangeRegisterRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_DEFRANGE_SUBFIELD_REGISTER:
                return(DefRangeSubfieldRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL:
                return(DefRangeFramePointerRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
                return(DefRangeFramePointerRelativeFullScopeSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_CALLEES:
            case SymbolRecordKind.S_CALLERS:
                return(FunctionListSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            case SymbolRecordKind.S_FILESTATIC:
                return(FileStaticSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_TRAMPOLINE:
                return(TrampolineSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_SECTION:
                return(SectionSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_COFFGROUP:
                return(CoffGroupSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_EXPORT:
                return(ExportSymbol.Read(Reader, this, index, reference.Kind));

            case SymbolRecordKind.S_INLINESITE:
                return(InlineSiteSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen));

            default:
#if DEBUG
                throw new NotImplementedException($"Unknown reference kind: {reference.Kind}");
#else
                return(null);
#endif
            }
        }