internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) { bits.MinCapacity(head.directorySize); int pages = reader.PagesFromSize(head.directorySize); // 0..n in page of directory pages. reader.Seek(head.directoryRoot, 0); bits.FillBuffer(reader.reader, pages * 4); DataStream stream = new DataStream(head.directorySize, bits, pages); bits.MinCapacity(head.directorySize); stream.Read(reader, bits); // 0..3 in directory pages int count; bits.ReadInt32(out count); // 4..n int[] sizes = new int[count]; bits.ReadInt32(sizes); // n..m streams = new DataStream[count]; for (int i = 0; i < count; i++) { if (sizes[i] <= 0) { streams[i] = new DataStream(); } else { streams[i] = new DataStream(sizes[i], bits, reader.PagesFromSize(sizes[i])); } } }
internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary<uint, PdbTokenLine> tokenToSourceMapping) { tokenToSourceMapping = new Dictionary<uint, PdbTokenLine>(); BitAccess bits = new BitAccess(512 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; dir.streams[1].Read(reader, bits); Dictionary<string, int> nameIndex = LoadNameIndex(bits); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.token = 0x06000000 | ridMap[func.token & 0xffffff]; } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); return funcs; }
internal void Read(PdbReader reader, int position, byte[] bytes, int offset, int data) { if (position + data > contentSize) { throw new PdbException("DataStream can't read off end of stream. " + "(pos={0},siz={1})", position, data); } if (position == contentSize) { return; } int left = data; int page = position / reader.PageSize; int rema = position % reader.PageSize; // First get remained of first page. if (rema != 0) { int todo = reader.PageSize - rema; if (todo > left) { todo = left; } reader.Seek(pages[page], rema); reader.Read(bytes, offset, todo); offset += todo; left -= todo; page++; } // Now get the remaining pages. while (left > 0) { int todo = reader.PageSize; if (todo > left) { todo = left; } reader.Seek(pages[page], 0); reader.Read(bytes, offset, todo); offset += todo; left -= todo; page++; } }
internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.PageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules; DbiDbgHdr header; dir.streams[1].Read(reader, bits); Dictionary<string, int> nameIndex = LoadNameIndex(bits); int nameStream; if (!nameIndex.TryGetValue("/names", out nameStream)) { throw new PdbException("No `name' stream"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, readAllStrings); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { if (modules[m].stream > 0) { dir.streams[modules[m].stream].Read(reader, bits); LoadFuncsFromDbiModule(bits, modules[m], names, funcList, readAllStrings, dir, nameIndex, reader); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.Token = 0x06000000 | ridMap[func.Token & 0xffffff]; } } // Array.Sort(funcs, PdbFunction.ByAddress); //Array.Sort(funcs, PdbFunction.byToken); return funcs; }
internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) { int pages = reader.PagesFromSize(head.directorySize); // 0..n in page of directory pages. bits.MinCapacity(head.directorySize); int directoryRootPages = head.directoryRoot.Length; int pagesPerPage = head.pageSize / 4; int pagesToGo = pages; for (int i = 0; i < directoryRootPages; i++) { int pagesInThisPage = pagesToGo <= pagesPerPage ? pagesToGo : pagesPerPage; reader.Seek(head.directoryRoot[i], 0); bits.Append(reader.reader, pagesInThisPage * 4); pagesToGo -= pagesInThisPage; } bits.Position = 0; DataStream stream = new DataStream(head.directorySize, bits, pages); bits.MinCapacity(head.directorySize); stream.Read(reader, bits); // 0..3 in directory pages int count; bits.ReadInt32(out count); // 4..n int[] sizes = new int[count]; bits.ReadInt32(sizes); // n..m streams = new DataStream[count]; for (int i = 0; i < count; i++) { if (sizes[i] <= 0) { streams[i] = new DataStream(); } else { streams[i] = new DataStream(sizes[i], bits, reader.PagesFromSize(sizes[i])); } } }
public void WriteHash(string pdbFileHash, string hash) { Guid guid = new Guid(hash.Remove(32)); int age = int.Parse(hash.Substring(32), NumberStyles.HexNumber); using (var read = File.Open(pdbFileHash, FileMode.Open)) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); reader.Seek(dir.streams[1].pages[0], 8); //bo przeskakujemy 8 znaków na ver i sig using (BinaryWriter writer = new BinaryWriter(read)) { writer.Write(age); writer.Write(guid.ToByteArray()); } } }
public string ReadHash(string pdbFileHash) { using (var read = File.Open(pdbFileHash, FileMode.Open)) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); bits.MinCapacity(28); reader.Seek(dir.streams[1].pages[0], 0); reader.Read(bits.Buffer, 0, 28); int ver; int sig; int age; Guid guid; bits.ReadInt32(out ver); // 0..3 Version bits.ReadInt32(out sig); // 4..7 Signature bits.ReadInt32(out age); // 8..11 Age bits.ReadGuid(out guid); // 12..27 GUID return (guid.ToString("N") + age.ToString("x")).ToUpper(); } }
private static void LoadTokenToSourceInfo(BitAccess bits, DbiModuleInfo module, IntHashTable names, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbReader reader, Dictionary <uint, PdbTokenLine> tokenToSourceMapping) { bits.Position = 0; int sig; bits.ReadInt32(out sig); if (sig != 4) { throw new PdbDebugException("Invalid signature. (sig={0})", sig); } bits.Position = 4; while (bits.Position < module.cbSyms) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_OEM: OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == PdbFunction.msilMetaData) { string name = bits.ReadString(); if (name == "TSLI") { uint token; uint file_id; uint line; uint column; uint endLine; uint endColumn; bits.ReadUInt32(out token); bits.ReadUInt32(out file_id); bits.ReadUInt32(out line); bits.ReadUInt32(out column); bits.ReadUInt32(out endLine); bits.ReadUInt32(out endColumn); PdbTokenLine tokenLine; if (!tokenToSourceMapping.TryGetValue(token, out tokenLine)) { tokenToSourceMapping.Add(token, new PdbTokenLine(token, file_id, line, column, endLine, endColumn)); } else { while (tokenLine.nextLine != null) { tokenLine = tokenLine.nextLine; } tokenLine.nextLine = new PdbTokenLine(token, file_id, line, column, endLine, endColumn); } } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } case SYM.S_END: bits.Position = stop; break; default: //Console.WriteLine("{0,6}: {1:x2} {2}", // bits.Position, rec, (SYM)rec); bits.Position = stop; break; } } bits.Position = module.cbSyms + module.cbOldLines; int limit = module.cbSyms + module.cbOldLines + module.cbLines; IntHashTable sourceFiles = ReadSourceFileInfo(bits, (uint)limit, names, dir, nameIndex, reader); foreach (var tokenLine in tokenToSourceMapping.Values) { tokenLine.sourceFile = (PdbSource)sourceFiles[(int)tokenLine.file_id]; } }
internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary <uint, PdbTokenLine> tokenToSourceMapping, out string sourceServerData, out int age, out Guid guid) { tokenToSourceMapping = new Dictionary <uint, PdbTokenLine>(); BitAccess bits = new BitAccess(512 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; dir.streams[1].Read(reader, bits); Dictionary <string, int> nameIndex = LoadNameIndex(bits, out age, out guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); int srcsrvStream; if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) { sourceServerData = string.Empty; } else { DataStream dataStream = dir.streams[srcsrvStream]; byte[] bytes = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); sourceServerData = bits.ReadBString(bytes.Length); } dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.token = 0x06000000 | ridMap[func.token & 0xffffff]; } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); return(funcs); }
static void LoadManagedLines(PdbFunction[] funcs, IntHashTable names, BitAccess bits, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddressAndToken); int begin = bits.Position; IntHashTable checks = ReadSourceFileInfo(bits, limit, names, dir, nameIndex, reader); // Read the lines next. bits.Position = begin; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.LINES: { CV_LineSection sec; bits.ReadUInt32(out sec.off); bits.ReadUInt16(out sec.sec); bits.ReadUInt16(out sec.flags); bits.ReadUInt32(out sec.cod); int funcIndex = FindFunction(funcs, sec.sec, sec.off); if (funcIndex < 0) { break; } var func = funcs[funcIndex]; if (func.lines == null) { while (funcIndex > 0) { var f = funcs[funcIndex - 1]; if (f.lines != null || f.segment != sec.sec || f.address != sec.off) { break; } func = f; funcIndex--; } } else { while (funcIndex < funcs.Length - 1 && func.lines != null) { var f = funcs[funcIndex + 1]; if (f.segment != sec.sec || f.address != sec.off) { break; } func = f; funcIndex++; } } if (func.lines != null) { break; } // Count the line blocks. int begSym = bits.Position; int blocks = 0; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); bits.Position += linsiz; blocks++; } func.lines = new PdbLines[blocks]; int block = 0; bits.Position = begSym; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; int plin = bits.Position; int pcol = bits.Position + 8 * (int)file.count; for (int i = 0; i < file.count; i++) { CV_Line line; CV_Column column = new CV_Column(); bits.Position = plin + 8 * i; bits.ReadUInt32(out line.offset); bits.ReadUInt32(out line.flags); uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart; uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24; //bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0); if ((sec.flags & 1) != 0) { bits.Position = pcol + 4 * i; bits.ReadUInt16(out column.offColumnStart); bits.ReadUInt16(out column.offColumnEnd); } lines[i] = new PdbLine(line.offset, lineBegin, column.offColumnStart, lineBegin + delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
internal static PdbInfo LoadFunctions(Stream read) { PdbInfo pdbInfo = new PdbInfo(); pdbInfo.TokenToSourceMapping = new Dictionary <uint, PdbTokenLine>(); BitAccess bits = new BitAccess(64 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; Dictionary <string, PdbSource> sourceCache = new Dictionary <string, PdbSource>(); dir.streams[1].Read(reader, bits); Dictionary <string, int> nameIndex = LoadNameIndex(bits, out pdbInfo.Age, out pdbInfo.Guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("Could not find the '/NAMES' stream: the PDB file may be a public symbol file instead of a private symbol file"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); int srcsrvStream; if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) { pdbInfo.SourceServerData = string.Empty; } else { DataStream dataStream = dir.streams[srcsrvStream]; byte[] bytes = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); pdbInfo.SourceServerData = bits.ReadBString(bytes.Length); } int sourceLinkStream; if (nameIndex.TryGetValue("SOURCELINK", out sourceLinkStream)) { DataStream dataStream = dir.streams[sourceLinkStream]; pdbInfo.SourceLinkData = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); bits.ReadBytes(pdbInfo.SourceLinkData); } dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); List <PdbFunction> funcList = new List <PdbFunction>(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, pdbInfo.TokenToSourceMapping, sourceCache); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader, sourceCache); } } } PdbFunction[] funcs = funcList.ToArray(); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.token = 0x06000000 | ridMap[func.token & 0xffffff]; } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); pdbInfo.Functions = funcs; return(pdbInfo); }
internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary<uint, PdbTokenLine> tokenToSourceMapping, out string sourceServerData, out int age, out Guid guid) { tokenToSourceMapping = new Dictionary<uint, PdbTokenLine>(); BitAccess bits = new BitAccess(64 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; Dictionary<string, PdbSource> sourceCache = new Dictionary<string, PdbSource>(); dir.streams[1].Read(reader, bits); Dictionary<string, int> nameIndex = LoadNameIndex(bits, out age, out guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("Could not find the '/NAMES' stream: the PDB file may be a public symbol file instead of a private symbol file"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); int srcsrvStream; if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) sourceServerData = string.Empty; else { DataStream dataStream = dir.streams[srcsrvStream]; byte[] bytes = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); sourceServerData = bits.ReadBString(bytes.Length); } dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); List<PdbFunction> funcList = new List<PdbFunction>(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping, sourceCache); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader, sourceCache); } } } PdbFunction[] funcs = funcList.ToArray(); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.token = 0x06000000 | ridMap[func.token & 0xffffff]; } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); return funcs; }
static void LoadManagedLines(PdbFunction[] funcs, IntHashTable names, BitAccess bits, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddressAndToken); IntHashTable checks = new IntHashTable(); // Read the files first int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; Guid doctypeGuid = SymDocumentType.Text; Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } // Read the lines next. bits.Position = begin; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.LINES: { CV_LineSection sec; bits.ReadUInt32(out sec.off); bits.ReadUInt16(out sec.sec); bits.ReadUInt16(out sec.flags); bits.ReadUInt32(out sec.cod); int funcIndex = FindFunction(funcs, sec.sec, sec.off); if (funcIndex < 0) break; var func = funcs[funcIndex]; if (func.lines == null) { while (funcIndex > 0) { var f = funcs[funcIndex-1]; if (f.lines != null || f.segment != sec.sec || f.address != sec.off) break; func = f; funcIndex--; } } else { while (funcIndex < funcs.Length-1 && func.lines != null) { var f = funcs[funcIndex+1]; if (f.segment != sec.sec || f.address != sec.off) break; func = f; funcIndex++; } } if (func.lines != null) break; // Count the line blocks. int begSym = bits.Position; int blocks = 0; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); bits.Position += linsiz; blocks++; } func.lines = new PdbLines[blocks]; int block = 0; bits.Position = begSym; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; int plin = bits.Position; int pcol = bits.Position + 8 * (int)file.count; for (int i = 0; i < file.count; i++) { CV_Line line; CV_Column column = new CV_Column(); bits.Position = plin + 8 * i; bits.ReadUInt32(out line.offset); bits.ReadUInt32(out line.flags); uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart; uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24; //bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0); if ((sec.flags & 1) != 0) { bits.Position = pcol + 4 * i; bits.ReadUInt16(out column.offColumnStart); bits.ReadUInt16(out column.offColumnEnd); } lines[i] = new PdbLine(line.offset, lineBegin, column.offColumnStart, lineBegin+delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
internal void Read(PdbReader reader, BitAccess bits) { bits.MinCapacity(contentSize); Read(reader, 0, bits.Buffer, 0, contentSize); }
private static void LoadTokenToSourceInfo(BitAccess bits, DbiModuleInfo module, IntHashTable names, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader, Dictionary<uint, PdbTokenLine> tokenToSourceMapping) { bits.Position = 0; int sig; bits.ReadInt32(out sig); if (sig != 4) { throw new PdbDebugException("Invalid signature. (sig={0})", sig); } bits.Position = 4; while (bits.Position < module.cbSyms) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.Position = star; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_OEM: OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == PdbFunction.msilMetaData) { string name = bits.ReadString(); if (name == "TSLI") { uint token; uint file_id; uint line; uint column; uint endLine; uint endColumn; bits.ReadUInt32(out token); bits.ReadUInt32(out file_id); bits.ReadUInt32(out line); bits.ReadUInt32(out column); bits.ReadUInt32(out endLine); bits.ReadUInt32(out endColumn); PdbTokenLine tokenLine; if (!tokenToSourceMapping.TryGetValue(token, out tokenLine)) tokenToSourceMapping.Add(token, new PdbTokenLine(token, file_id, line, column, endLine, endColumn)); else { while (tokenLine.nextLine != null) tokenLine = tokenLine.nextLine; tokenLine.nextLine = new PdbTokenLine(token, file_id, line, column, endLine, endColumn); } } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } case SYM.S_END: bits.Position = stop; break; default: //Console.WriteLine("{0,6}: {1:x2} {2}", // bits.Position, rec, (SYM)rec); bits.Position = stop; break; } } bits.Position = module.cbSyms + module.cbOldLines; int limit = module.cbSyms + module.cbOldLines + module.cbLines; IntHashTable sourceFiles = ReadSourceFileInfo(bits, (uint)limit, names, dir, nameIndex, reader); foreach (var tokenLine in tokenToSourceMapping.Values) { tokenLine.sourceFile = (PdbSource)sourceFiles[(int)tokenLine.file_id]; } }
private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbReader reader) { IntHashTable checks = new IntHashTable(); int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; Guid doctypeGuid = SymDocumentType.Text; Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; if (nameIndex.TryGetValue("/SRC/FILES/" + name.ToUpperInvariant(), out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } return(checks); }
private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader) { IntHashTable checks = new IntHashTable(); int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; #if !NET_CORE Guid doctypeGuid = SymDocumentType.Text; #else // Note : netstandard1.6 doesn't support SymDocumentType. Looks like it might be in netstandard2.0, but that // is not coming out for a few months still. Looking at our mono, SymDocumentType.Text simply returns and empty Guid // so let's just go with that Guid doctypeGuid = Guid.Empty; #endif Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } return checks; }
internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int age, out Guid guid) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; dir.streams[1].Read(reader, bits); Dictionary <string, int> nameIndex = LoadNameIndex(bits, out age, out guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, readAllStrings); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { if (modules[m].stream > 0) { dir.streams[modules[m].stream].Read(reader, bits); LoadFuncsFromDbiModule(bits, modules[m], names, funcList, readAllStrings, dir, nameIndex, reader); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { dir.streams[header.snTokenRidMap].Read(reader, bits); uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; bits.ReadUInt32(ridMap); { var __array1 = funcs; var __arrayLength1 = __array1.Length; for (int __i1 = 0; __i1 < __arrayLength1; ++__i1) { var func = (PdbFunction)__array1[__i1]; { func.token = 0x06000000 | ridMap[func.token & 0xffffff]; } } } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); return(funcs); }
static void LoadManagedLines(PdbFunction[] funcs, IntHashTable names, BitAccess bits, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddressAndToken); int begin = bits.Position; IntHashTable checks = ReadSourceFileInfo(bits, limit, names, dir, nameIndex, reader); // Read the lines next. bits.Position = begin; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.LINES: { CV_LineSection sec; bits.ReadUInt32(out sec.off); bits.ReadUInt16(out sec.sec); bits.ReadUInt16(out sec.flags); bits.ReadUInt32(out sec.cod); int funcIndex = FindFunction(funcs, sec.sec, sec.off); if (funcIndex < 0) break; var func = funcs[funcIndex]; if (func.lines == null) { while (funcIndex > 0) { var f = funcs[funcIndex-1]; if (f.lines != null || f.segment != sec.sec || f.address != sec.off) break; func = f; funcIndex--; } } else { while (funcIndex < funcs.Length-1 && func.lines != null) { var f = funcs[funcIndex+1]; if (f.segment != sec.sec || f.address != sec.off) break; func = f; funcIndex++; } } if (func.lines != null) break; // Count the line blocks. int begSym = bits.Position; int blocks = 0; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); bits.Position += linsiz; blocks++; } func.lines = new PdbLines[blocks]; int block = 0; bits.Position = begSym; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; int plin = bits.Position; int pcol = bits.Position + 8 * (int)file.count; for (int i = 0; i < file.count; i++) { CV_Line line; CV_Column column = new CV_Column(); bits.Position = plin + 8 * i; bits.ReadUInt32(out line.offset); bits.ReadUInt32(out line.flags); uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart; uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24; //bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0); if ((sec.flags & 1) != 0) { bits.Position = pcol + 4 * i; bits.ReadUInt16(out column.offColumnStart); bits.ReadUInt16(out column.offColumnEnd); } lines[i] = new PdbLine(line.offset, lineBegin, column.offColumnStart, lineBegin+delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary<uint, PdbTokenLine> tokenToSourceMapping, out string sourceServerData, System.Compiler.Metadata.Reader ilreader) { tokenToSourceMapping = new Dictionary<uint, PdbTokenLine>(); BitAccess bits = new BitAccess(512 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; Dictionary<string, PdbSource> sourceCache = new Dictionary<string, PdbSource>(); dir.streams[1].Read(reader, bits); Dictionary<string, int> nameIndex = LoadNameIndex(bits); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbDebugException("No `name' stream"); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); int srcsrvStream; if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) sourceServerData = string.Empty; else { DataStream dataStream = dir.streams[srcsrvStream]; byte[] bytes = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); sourceServerData = bits.ReadBString(bytes.Length); } dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping, sourceCache); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader, ilreader, sourceCache); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; dir.streams[header.snTokenRidMap].Read(reader, bits); bits.ReadUInt32(ridMap); foreach (PdbFunction func in funcs) { func.MapTokens(ridMap, ilreader); } } else { foreach (PdbFunction func in funcs) { func.MapTokens(null, ilreader); } } // Array.Sort(funcs, PdbFunction.byAddressAndToken); //Array.Sort(funcs, PdbFunction.byToken); return funcs; }
private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader) { IntHashTable checks = new IntHashTable(); int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; Guid doctypeGuid = SymDocumentType.Text; Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } return checks; }
internal static uint[] LoadRemapTable(Stream read) { //tokenToSourceMapping = new Dictionary<uint, PdbTokenLine>(); BitAccess bits = new BitAccess(512 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); DbiModuleInfo[] modules = null; DbiDbgHdr header; dir.streams[1].Read(reader, bits); Dictionary<string, int> nameIndex = LoadNameIndex(bits); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new NoNameStreamPdbException(); } dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); int srcsrvStream; string sourceServerData; if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) sourceServerData = string.Empty; else { DataStream dataStream = dir.streams[srcsrvStream]; byte[] bytes = new byte[dataStream.contentSize]; dataStream.Read(reader, bits); sourceServerData = bits.ReadBString(bytes.Length); } dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); #if SKIP_THIS ArrayList funcList = new ArrayList(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { var module = modules[m]; if (module.stream > 0) { dir.streams[module.stream].Read(reader, bits); if (module.moduleName == "TokenSourceLineInfo") { LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping); continue; } LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader, ilreader); } } } PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); #endif // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; dir.streams[header.snTokenRidMap].Read(reader, bits); bits.ReadUInt32(ridMap); return ridMap; } return null; }
static void LoadManagedLines(PdbFunction[] funcs, IntHashTable names, BitAccess bits, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddress); IntHashTable checks = new IntHashTable(); // Read the files first int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; Guid doctypeGuid = SymDocumentType.Text; Guid languageGuid = SymLanguageType.CSharp; Guid vendorGuid = SymLanguageVendor.Microsoft; if (nameIndex.TryGetValue("/src/files/" + name, out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource((uint)ni, name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } // Read the lines next. bits.Position = begin; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.LINES: { CV_LineSection sec; bits.ReadUInt32(out sec.off); bits.ReadUInt16(out sec.sec); bits.ReadUInt16(out sec.flags); bits.ReadUInt32(out sec.cod); PdbFunction func = FindFunction(funcs, sec.sec, sec.off); if (func == null) { break; } // Count the line blocks. int begSym = bits.Position; int blocks = 0; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); bits.Position += linsiz; blocks++; } func.lines = new PdbLines[blocks]; int block = 0; bits.Position = begSym; while (bits.Position < endSym) { CV_SourceFile file; bits.ReadUInt32(out file.index); bits.ReadUInt32(out file.count); bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; int plin = bits.Position; int pcol = bits.Position + 8 * (int)file.count; for (int i = 0; i < file.count; i++) { CV_Line line; CV_Column column = new CV_Column(); bits.Position = plin + 8 * i; bits.ReadUInt32(out line.offset); bits.ReadUInt32(out line.flags); uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart; uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24; bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0); if ((sec.flags & 1) != 0) { bits.Position = pcol + 4 * i; bits.ReadUInt16(out column.offColumnStart); bits.ReadUInt16(out column.offColumnEnd); } lines[i] = new PdbLine(line.offset, lineBegin, column.offColumnStart, lineBegin + delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
static void LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, IntHashTable names, ArrayList funcList, bool readStrings, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbReader reader) { PdbFunction[] funcs = null; bits.Position = 0; int sig; bits.ReadInt32(out sig); if (sig != 4) { throw new PdbDebugException("Invalid signature. (sig={0})", sig); } bits.Position = 4; // Console.WriteLine("{0}:", info.moduleName); funcs = PdbFunction.LoadManagedFunctions(/*info.moduleName,*/ bits, (uint)info.cbSyms, readStrings); if (funcs != null) { bits.Position = info.cbSyms + info.cbOldLines; LoadManagedLines(funcs, names, bits, dir, nameIndex, reader, (uint)(info.cbSyms + info.cbOldLines + info.cbLines)); for (int i = 0; i < funcs.Length; i++) { funcList.Add(funcs[i]); } } }
private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbReader reader) { IntHashTable checks = new IntHashTable(); int begin = bits.Position; while (bits.Position < limit) { int sig; int siz; bits.ReadInt32(out sig); bits.ReadInt32(out siz); int place = bits.Position; int endSym = bits.Position + siz; switch ((DEBUG_S_SUBSECTION)sig) { case DEBUG_S_SUBSECTION.FILECHKSMS: while (bits.Position < endSym) { CV_FileCheckSum chk; int ni = bits.Position - place; bits.ReadUInt32(out chk.name); bits.ReadUInt8(out chk.len); bits.ReadUInt8(out chk.type); string name = (string)names[(int)chk.name]; int guidStream; #if !NET_CORE Guid doctypeGuid = DocumentType.Text.ToGuid(); #else // Note : netstandard1.6 doesn't support SymDocumentType. Looks like it might be in netstandard2.0, but that // is not coming out for a few months still. Looking at our mono, SymDocumentType.Text simply returns and empty Guid // so let's just go with that Guid doctypeGuid = Guid.Empty; #endif Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; if (nameIndex.TryGetValue("/SRC/FILES/" + name.ToUpperInvariant(), out guidStream)) { var guidBits = new BitAccess(0x100); dir.streams[guidStream].Read(reader, guidBits); LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); } PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); checks.Add(ni, src); bits.Position += chk.len; bits.Align(4); } bits.Position = endSym; break; default: bits.Position = endSym; break; } } return(checks); }