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; } } } } } }
/// <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); }); }
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(); } }
/// <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 } }