/// <summary> /// Initializes a new instance of the <see cref="SymbolStream"/> class. /// </summary> /// <param name="stream">PDB symbol stream.</param> public SymbolStream(PdbStream stream) { IBinaryReader reader = stream.Reader; Reader = reader; references = new List <SymbolReference>(); long position = reader.Position, end = reader.Length; while (position < end) { RecordPrefix prefix = RecordPrefix.Read(reader); if (prefix.RecordLength < 2) { throw new Exception("CV corrupt record"); } SymbolRecordKind kind = (SymbolRecordKind)prefix.RecordKind; ushort dataLen = prefix.DataLen; references.Add(new SymbolReference { DataOffset = (uint)position + RecordPrefix.Size, Kind = kind, DataLen = dataLen, }); position += dataLen + RecordPrefix.Size; reader.ReadFake(dataLen); } symbolsByKind = new DictionaryCache <SymbolRecordKind, SymbolRecord[]>(GetSymbolsByKind); }
/// <summary> /// Reads <see cref="UdtSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static UdtSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new UdtSymbol { Kind = kind, Type = TypeIndex.Read(reader), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="ConstantSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static ConstantSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new ConstantSymbol { Kind = kind, TypeIndex = TypeIndex.Read(reader), Value = reader.ReadEncodedInteger(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="ProcedureReferenceSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static ProcedureReferenceSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new ProcedureReferenceSymbol { Kind = kind, Checksum = reader.ReadUint(), Offset = reader.ReadUint(), Module = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="Public32Symbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static Public32Symbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new Public32Symbol { Kind = kind, Flags = (PublicSymbolFlags)reader.ReadUint(), Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="DataSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static DataSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new DataSymbol { Kind = kind, Type = TypeIndex.Read(reader), Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="CoffGroupSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static CoffGroupSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new CoffGroupSymbol { Kind = kind, Size = reader.ReadUint(), Characteristics = (ImageSectionCharacteristics)reader.ReadUint(), Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Parses all symbols of the specified symbol record kind. /// </summary> /// <param name="kind">Symbol record kind.</param> /// <returns>Array of symbol record for the specified symbol record kind.</returns> private SymbolRecord[] GetSymbolsByKind(SymbolRecordKind kind) { List <SymbolRecord> symbols = new List <SymbolRecord>(); for (int i = 0; i < references.Count; i++) { if (references[i].Kind == kind) { symbols.Add(GetSymbol(i)); } } return(symbols.ToArray()); }
/// <summary> /// Reads <see cref="TrampolineSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static TrampolineSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new TrampolineSymbol { Kind = kind, Type = (TrampolineType)reader.ReadUshort(), Size = reader.ReadUshort(), ThunkOffset = reader.ReadUint(), TargetOffset = reader.ReadUint(), ThunkSection = reader.ReadUshort(), TargetSection = reader.ReadUshort(), }); }
/// <summary> /// Reads <see cref="SectionSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static SectionSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new SectionSymbol { Kind = kind, SectionNumber = reader.ReadUshort(), Alignment = reader.ReadByte(), Padding = reader.ReadByte(), RelativeVirtualAddress = reader.ReadUint(), Length = reader.ReadUint(), Characteristics = (ImageSectionCharacteristics)reader.ReadUint(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="Thunk32Symbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> /// <param name="dataLength">Record data length.</param> public static Thunk32Symbol Read(IBinaryReader reader, SymbolRecordKind kind, uint dataLength) { long start = reader.Position; return(new Thunk32Symbol { Kind = kind, Parent = reader.ReadUint(), End = reader.ReadUint(), Next = reader.ReadUint(), Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Length = reader.ReadUshort(), Ordinal = (ThunkOrdinal)reader.ReadByte(), Name = reader.ReadCString(), VariantData = reader.ReadByteArray((int)(dataLength - (reader.Position - start))), }); }
/// <summary> /// Reads <see cref="ProcedureSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Symbol record kind.</param> public static ProcedureSymbol Read(IBinaryReader reader, SymbolRecordKind kind) { return(new ProcedureSymbol { Kind = kind, Parent = reader.ReadUint(), End = reader.ReadUint(), Next = reader.ReadUint(), CodeSize = reader.ReadUint(), DebugStart = reader.ReadUint(), DebugEnd = reader.ReadUint(), FunctionType = TypeIndex.Read(reader), CodeOffset = reader.ReadUint(), Segment = reader.ReadUshort(), Flags = (ProcedureFlags)reader.ReadByte(), Name = reader.ReadCString(), }); }
/// <summary> /// Initializes a new instance of the <see cref="SymbolStream"/> class. /// </summary> /// <param name="reader">Binary reader.</param> /// <param name="end">End of the symbol stream in binary reader. If it is less than 0 or bigger than binary reader length, it will be read fully.</param> public SymbolStream(IBinaryReader reader, long end = -1) { Reader = reader; long position = reader.Position; if (end < 0 || end > reader.Length) { end = reader.Length; } long bytes = end - position; int estimatedCapacity = (int)(bytes / 35); references = new List <SymbolRecordReference>(estimatedCapacity); while (position < end) { RecordPrefix prefix = RecordPrefix.Read(reader); if (prefix.RecordLength < 2) { throw new Exception("CV corrupt record"); } SymbolRecordKind kind = (SymbolRecordKind)prefix.RecordKind; ushort dataLen = prefix.DataLen; references.Add(new SymbolRecordReference { DataOffset = (uint)position + RecordPrefix.Size, Kind = kind, DataLen = dataLen, }); position += dataLen + RecordPrefix.Size; reader.Move(dataLen); } symbolsByKind = new DictionaryCache <SymbolRecordKind, SymbolRecord[]>(GetSymbolsByKind); symbols = new ArrayCache <SymbolRecord>(references.Count, GetSymbol); }
/// <summary> /// Reads <see cref="InlineSiteSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> /// <param name="dataLength">Record data length.</param> public static InlineSiteSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind, uint dataLength) { long start = reader.Position; return(new InlineSiteSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, ParentOffset = reader.ReadUint(), End = reader.ReadUint(), Inlinee = TypeIndex.Read(reader), AnnotationData = reader.ReadByteArray((int)(dataLength - (reader.Position - start))), }); }
/// <summary> /// Reads <see cref="Compile2Symbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static Compile2Symbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { var result = new Compile2Symbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Flags = (CompileSymbolFlags)reader.ReadUint(), Machine = (CpuType)reader.ReadUshort(), VersionFrontendMajor = reader.ReadUshort(), VersionFrontendMinor = reader.ReadUshort(), VersionFrontendBuild = reader.ReadUshort(), VersionBackendMajor = reader.ReadUshort(), VersionBackendMinor = reader.ReadUshort(), VersionBackendBuild = reader.ReadUshort(), Version = reader.ReadCString(), }; List <string> strings = new List <string>(); for (string s = reader.ReadCString().String; !string.IsNullOrEmpty(s); s = reader.ReadCString().String) { strings.Add(s); } result.ExtraStrings = strings; return(result); }
/// <summary> /// Reads <see cref="FrameCookieSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static FrameCookieSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new FrameCookieSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, CodeOffset = reader.ReadUint(), Register = (RegisterId)reader.ReadUshort(), CookieKind = (FrameCookieKind)reader.ReadByte(), Flags = reader.ReadByte(), }); }
/// <summary> /// Reads <see cref="ThreadLocalDataSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static ThreadLocalDataSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new ThreadLocalDataSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Type = TypeIndex.Read(reader), Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="BlockSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static BlockSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new BlockSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, ParentOffset = reader.ReadUint(), End = reader.ReadUint(), CodeSize = reader.ReadUint(), CodeOffset = reader.ReadUint(), Segment = reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="UdtSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static UdtSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new UdtSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Type = TypeIndex.Read(reader), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="ExportSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static ExportSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new ExportSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Ordinal = reader.ReadUshort(), Flags = (ExportFlags)reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="DefRangeSubfieldRegisterSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> /// <param name="dataLength">Record data length.</param> public static DefRangeSubfieldRegisterSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind, uint dataLength) { long start = reader.Position; var symbol = new DefRangeSubfieldRegisterSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Register = (RegisterId)reader.ReadUshort(), MayHaveNoName = reader.ReadUshort(), OffsetInParent = reader.ReadUint(), Range = LocalVariableAddressRange.Read(reader), }; int count = (int)(dataLength - (reader.Position - start)) / LocalVariableAddressGap.Size; symbol.Gaps = new LocalVariableAddressGap[count]; for (int i = 0; i < count; i++) { symbol.Gaps[i] = LocalVariableAddressGap.Read(reader); } return(symbol); }
/// <summary> /// Reads <see cref="AttributeSlotSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static AttributeSlotSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new AttributeSlotSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Index = reader.ReadUint(), TypeIndex = TypeIndex.Read(reader), CodeOffset = reader.ReadUint(), Segment = reader.ReadUshort(), Flags = (LocalVariableFlags)reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="BuildInfoSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static BuildInfoSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new BuildInfoSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, BuildId = TypeIndex.Read(reader), }); }
/// <summary> /// Reads <see cref="Compile3Symbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static Compile3Symbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new Compile3Symbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Flags = (CompileSymbolFlags)reader.ReadUint(), Machine = (CpuType)reader.ReadUshort(), VersionFrontendMajor = reader.ReadUshort(), VersionFrontendMinor = reader.ReadUshort(), VersionFrontendBuild = reader.ReadUshort(), VersionFrontendQFE = reader.ReadUshort(), VersionBackendMajor = reader.ReadUshort(), VersionBackendMinor = reader.ReadUshort(), VersionBackendBuild = reader.ReadUshort(), VersionBackendQFE = reader.ReadUshort(), Version = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="ObjectNameSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static ObjectNameSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new ObjectNameSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Signature = reader.ReadUint(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="DefRangeFramePointerRelativeSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> /// <param name="dataLength">Record data length.</param> public static DefRangeFramePointerRelativeSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind, uint dataLength) { long start = reader.Position; var symbol = new DefRangeFramePointerRelativeSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Offset = reader.ReadUint(), Range = LocalVariableAddressRange.Read(reader), }; int count = (int)(dataLength - (reader.Position - start)) / LocalVariableAddressGap.Size; symbol.Gaps = new LocalVariableAddressGap[count]; for (int i = 0; i < count; i++) { symbol.Gaps[i] = LocalVariableAddressGap.Read(reader); } return(symbol); }
/// <summary> /// Reads <see cref="HeapAllocationSiteSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static HeapAllocationSiteSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new HeapAllocationSiteSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Offset = reader.ReadUint(), Segment = reader.ReadUshort(), CallInstructionSize = reader.ReadUshort(), Type = TypeIndex.Read(reader), }); }
/// <summary> /// Reads <see cref="ConstantSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static ConstantSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new ConstantSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, TypeIndex = TypeIndex.Read(reader), Value = reader.ReadEncodedConstant(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="RegisterRelativeSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static RegisterRelativeSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new RegisterRelativeSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Offset = reader.ReadUint(), Type = TypeIndex.Read(reader), Register = (RegisterId)reader.ReadUshort(), Name = reader.ReadCString(), }); }
/// <summary> /// Reads <see cref="CallSiteInfoSymbol"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="symbolStream">Symbol stream that contains this symbol record.</param> /// <param name="symbolStreamIndex">Index in symbol stream <see cref="SymbolStream.References"/> array.</param> /// <param name="kind">Symbol record kind.</param> public static CallSiteInfoSymbol Read(IBinaryReader reader, SymbolStream symbolStream, int symbolStreamIndex, SymbolRecordKind kind) { return(new CallSiteInfoSymbol { SymbolStream = symbolStream, SymbolStreamIndex = symbolStreamIndex, Kind = kind, Offset = reader.ReadUint(), Segment = reader.ReadUshort(), Padding = reader.ReadUshort(), Type = TypeIndex.Read(reader), }); }