/// <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 DebugSubsectionStream(IBinaryReader reader, long end = -1) { Reader = reader; references = new List <DebugSubsectionReference>(); long position = reader.Position; if (end < 0 || end > reader.Length) { end = reader.Length; } while (position < end) { DebugSubsectionKind kind = (DebugSubsectionKind)reader.ReadUint(); uint dataLen = reader.ReadUint(); references.Add(new DebugSubsectionReference { DataOffset = position + 8, Kind = kind, DataLen = dataLen, }); position += dataLen + 8; reader.Move(dataLen); } debugSubsectionsByKind = new DictionaryCache <DebugSubsectionKind, DebugSubsection[]>(GetDebugSubsectionsByKind); }
/// <summary> /// Reads <see cref="FileChecksumSubsection"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Debug subsection kind.</param> public static FileChecksumSubsection Read(IBinaryReader reader, DebugSubsectionKind kind) { uint nameIndex = reader.ReadUint(); byte hashLength = reader.ReadByte(); FileChecksumHashType hashType = (FileChecksumHashType)reader.ReadByte(); reader.Align(4); return(new FileChecksumSubsection { Kind = kind, NameIndex = nameIndex, HashType = hashType, HashReader = reader.ReadSubstream(hashLength), }); }
/// <summary> /// Parses all debug subsections of the specified debug subsection kind. /// </summary> /// <param name="kind">Debug subsection kind.</param> /// <returns>Array of debug subsections for the specified debug subsection kind.</returns> private DebugSubsection[] GetDebugSubsectionsByKind(DebugSubsectionKind kind) { List <DebugSubsection> debugSubsections = new List <DebugSubsection>(); for (int i = 0; i < references.Count; i++) { if (references[i].Kind == kind) { DebugSubsection debugSubsection = GetDebugSubsection(i); if (debugSubsection != null) { debugSubsections.Add(debugSubsection); } } } return(debugSubsections.ToArray()); }
/// <summary> /// Reads <see cref="LinesSubsection"/> from the stream. /// </summary> /// <param name="reader">Stream binary reader.</param> /// <param name="kind">Debug subsection kind.</param> /// <param name="dataLength">Debug subsection length.</param> public static LinesSubsection Read(IBinaryReader reader, DebugSubsectionKind kind, uint dataLength) { long positionEnd = reader.Position + dataLength; LinesSubsection linesSubsection = new LinesSubsection { Kind = kind, CodeOffset = reader.ReadUint(), Segment = reader.ReadUshort(), Flags = (LinesSubsectionFlags)reader.ReadUshort(), Cod = reader.ReadUint(), }; bool columnsAvailable = (linesSubsection.Flags & LinesSubsectionFlags.LinesHaveColumns) == LinesSubsectionFlags.LinesHaveColumns; List <SourceFile> files = new List <SourceFile>(); while (reader.Position < positionEnd) { SourceFile file = new SourceFile { Index = reader.ReadUint(), Lines = new Line[reader.ReadUint()], }; uint size = reader.ReadUint(); for (int i = 0; i < file.Lines.Length; i++) { file.Lines[i].Offset = reader.ReadUint(); LineFlags flags = (LineFlags)reader.ReadUint(); file.Lines[i].LineStart = (uint)(flags & LineFlags.LineNumberStart); file.Lines[i].LineEnd = file.Lines[i].LineStart + ((uint)(flags & LineFlags.LineEndDelta) >> 24); file.Lines[i].Statement = (flags & LineFlags.Statement) == LineFlags.Statement; } if (columnsAvailable) { for (int i = 0; i < file.Lines.Length; i++) { file.Lines[i].ColumnStart = reader.ReadUshort(); file.Lines[i].ColumnEnd = reader.ReadUshort(); } } files.Add(file); } linesSubsection.Files = files.ToArray(); return(linesSubsection); }
/// <summary> /// Indexing operator for getting all debug subsections of the given kind. /// </summary> /// <param name="kind">Debug subsection kind that should be parsed from this stream.</param> /// <returns>Array of debug subsections for the specified debug subsection kind.</returns> public DebugSubsection[] this[DebugSubsectionKind kind] => debugSubsectionsByKind[kind];