internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); new DbiSecCon(bits); bits.ReadUInt16(out flags); bits.ReadInt16(out stream); bits.ReadInt32(out cbSyms); bits.ReadInt32(out cbOldLines); bits.ReadInt32(out cbLines); bits.ReadInt16(out files); bits.ReadInt16(out pad1); bits.ReadUInt32(out offsets); bits.ReadInt32(out niSource); bits.ReadInt32(out niCompiler); if (readStrings) { bits.ReadCString(out moduleName); bits.ReadCString(out objectName); } else { bits.SkipCString(out moduleName); bits.SkipCString(out objectName); } bits.Align(4); //if (opened != 0 || pad1 != 0) { // throw new PdbException("Invalid DBI module. "+ // "(opened={0}, pad={1})", opened, pad1); //} }
internal DataStream(int contentSize, BitAccess bits, int count) { this._contentSize = contentSize; if (count > 0) { this._pages = new int[count]; bits.ReadInt32(this._pages); } }
internal DbiDbgHdr(BitAccess bits) { bits.ReadUInt16(out snFPO); bits.ReadUInt16(out snException); bits.ReadUInt16(out snFixup); bits.ReadUInt16(out snOmapToSrc); bits.ReadUInt16(out snOmapFromSrc); bits.ReadUInt16(out snSectionHdr); bits.ReadUInt16(out snTokenRidMap); bits.ReadUInt16(out snXdata); bits.ReadUInt16(out snPdata); bits.ReadUInt16(out snNewFPO); bits.ReadUInt16(out snSectionHdrOrig); }
private static void LoadGuidStream(BitAccess bits, out Guid doctype, out Guid language, out Guid vendor, out Guid algorithmId, out byte[] checksum, out byte[] embeddedSource) { bits.ReadGuid(out language); bits.ReadGuid(out vendor); bits.ReadGuid(out doctype); bits.ReadGuid(out algorithmId); int checksumSize; bits.ReadInt32(out checksumSize); int sourceSize; bits.ReadInt32(out sourceSize); checksum = new byte[checksumSize]; bits.ReadBytes(checksum); embeddedSource = new byte[sourceSize]; bits.ReadBytes(embeddedSource); }
internal DbiSecCon(BitAccess bits) { bits.ReadInt16(out section); bits.ReadInt16(out pad1); bits.ReadInt32(out offset); bits.ReadInt32(out size); bits.ReadUInt32(out flags); bits.ReadInt16(out module); bits.ReadInt16(out pad2); bits.ReadUInt32(out dataCrc); bits.ReadUInt32(out relocCrc); //if (pad1 != 0 || pad2 != 0) { // throw new PdbException("Invalid DBI section. "+ // "(pad1={0}, pad2={1})", // pad1, pad2); //} }
internal MsfDirectory(PdbStreamHelper 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])); } } }
/// <summary> /// Gets the properties of a given pdb. Throws IOException on error. /// </summary> /// <param name="pdbFile">The pdb file to load.</param> /// <param name="signature">The signature of pdbFile.</param> /// <param name="age">The age of pdbFile.</param> public static void GetPdbProperties(string pdbFile, out Guid signature, out int age) { BitAccess bits = new BitAccess(512 * 1024); using (FileStream pdbStream = File.OpenRead(pdbFile)) { PdbFileHeader header = new PdbFileHeader(pdbStream, bits); PdbStreamHelper reader = new PdbStreamHelper(pdbStream, header.PageSize); MsfDirectory dir = new MsfDirectory(reader, header, bits); dir._streams[1].Read(reader, bits); int ver, sig; bits.ReadInt32(out ver); // 0..3 Version bits.ReadInt32(out sig); // 4..7 Signature bits.ReadInt32(out age); // 8..11 Age bits.ReadGuid(out signature); // 12..27 GUID } }
//internal PdbFileHeader(int pageSize) { // this.magic = new byte[32] { // 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, // "Microsof" // 0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20, // "t C/C++ " // 0x4D, 0x53, 0x46, 0x20, 0x37, 0x2E, 0x30, 0x30, // "MSF 7.00" // 0x0D, 0x0A, 0x1A, 0x44, 0x53, 0x00, 0x00, 0x00 // "^^^DS^^^" // }; // this.pageSize = pageSize; //} internal PdbFileHeader(Stream reader, BitAccess bits) { bits.MinCapacity(56); reader.Seek(0, SeekOrigin.Begin); bits.FillBuffer(reader, 52); this.Magic = new byte[32]; bits.ReadBytes(this.Magic); // 0..31 bits.ReadInt32(out this.PageSize); // 32..35 bits.ReadInt32(out this.FreePageMap); // 36..39 bits.ReadInt32(out this.PagesUsed); // 40..43 bits.ReadInt32(out this.DirectorySize); // 44..47 bits.ReadInt32(out this.Zero); // 48..51 int directoryPages = ((((DirectorySize + PageSize - 1) / PageSize) * 4) + PageSize - 1) / PageSize; this.DirectoryRoot = new int[directoryPages]; bits.FillBuffer(reader, directoryPages * 4); bits.ReadInt32(this.DirectoryRoot); }
//internal uint segment; //internal uint address; internal PdbSlot(BitAccess bits, out uint typind) { AttrSlotSym slot; bits.ReadUInt32(out slot.index); bits.ReadUInt32(out slot.typind); bits.ReadUInt32(out slot.offCod); bits.ReadUInt16(out slot.segCod); bits.ReadUInt16(out slot.flags); bits.ReadCString(out slot.name); Slot = slot.index; Name = slot.name; Flags = slot.flags; //Console.WriteLinesegment = slot.segCod; //Console.WriteLineaddress = slot.offCod; typind = slot.typind; }
internal DbiHeader(BitAccess bits) { bits.ReadInt32(out sig); bits.ReadInt32(out ver); bits.ReadInt32(out age); bits.ReadInt16(out gssymStream); bits.ReadUInt16(out vers); bits.ReadInt16(out pssymStream); bits.ReadUInt16(out pdbver); bits.ReadInt16(out symrecStream); bits.ReadUInt16(out pdbver2); bits.ReadInt32(out gpmodiSize); bits.ReadInt32(out secconSize); bits.ReadInt32(out secmapSize); bits.ReadInt32(out filinfSize); bits.ReadInt32(out tsmapSize); bits.ReadInt32(out mfcIndex); bits.ReadInt32(out dbghdrSize); bits.ReadInt32(out ecinfoSize); bits.ReadUInt16(out flags); bits.ReadUInt16(out machine); bits.ReadInt32(out reserved); }
private void ReadIteratorLocals(BitAccess bits) { uint numberOfLocals; bits.ReadUInt32(out numberOfLocals); }
internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ BitAccess bits, uint limit, bool readStrings) { //string mod = StripNamespace(module); int begin = bits.Position; int count = 0; while (bits.Position < limit) { 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_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.Position = (int)proc.end; count++; break; 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; } } if (count == 0) { return(null); } bits.Position = begin; PdbFunction[] funcs = new PdbFunction[count]; int func = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; //int offset = bits.Position; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.ReadUInt32(out proc.next); bits.ReadUInt32(out proc.len); bits.ReadUInt32(out proc.dbgStart); bits.ReadUInt32(out proc.dbgEnd); bits.ReadUInt32(out proc.token); bits.ReadUInt32(out proc.off); bits.ReadUInt16(out proc.seg); bits.ReadUInt8(out proc.flags); bits.ReadUInt16(out proc.retReg); if (readStrings) { bits.ReadCString(out proc.name); } else { bits.SkipCString(out proc.name); } //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); bits.Position = stop; funcs[func++] = new PdbFunction(/*module,*/ proc, bits); break; default: { //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); bits.Position = stop; break; } } } return(funcs); }
internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int ver, out int sig, out int age, out Guid guid, out IEnumerable<PdbSource> sources) { sources = null; PdbFileHeader head = new PdbFileHeader(read, bits); PdbStreamHelper reader = new PdbStreamHelper(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 ver, out sig, out age, out guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } dir._streams[nameStream].Read(reader, bits); Dictionary<int, string> names = LoadNameStream(bits); dir._streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, readAllStrings); List<PdbFunction> funcList = new List<PdbFunction>(); Dictionary<string, PdbSource> sourceDictionary = new Dictionary<string, PdbSource>(); 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, sourceDictionary); } } } PdbFunction[] funcs = funcList.ToArray(); sources = sourceDictionary.Values; // 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; }
private void ReadUsingInfo(BitAccess bits) { ushort numberOfNamespaces; bits.ReadUInt16(out numberOfNamespaces); this.UsingCounts = new ushort[numberOfNamespaces]; for (ushort i = 0; i < numberOfNamespaces; i++) { bits.ReadUInt16(out this.UsingCounts[i]); } }
private static void LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, Dictionary<int, string> names, List<PdbFunction> funcList, bool readStrings, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbStreamHelper reader, Dictionary<string, PdbSource> sources) { 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), sources); for (int i = 0; i < funcs.Length; i++) { funcList.Add(funcs[i]); } } }
private static void LoadDbiStream(BitAccess bits, out DbiModuleInfo[] modules, out DbiDbgHdr header, bool readStrings) { DbiHeader dh = new DbiHeader(bits); header = new DbiDbgHdr(); //if (dh.sig != -1 || dh.ver != 19990903) { // throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}", // dh.sig, dh.ver); //} // Read gpmod section. List<DbiModuleInfo> modList = new List<DbiModuleInfo>(); int end = bits.Position + dh.gpmodiSize; while (bits.Position < end) { DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings); modList.Add(mod); } if (bits.Position != end) { throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}", bits.Position, end); } if (modList.Count > 0) { modules = modList.ToArray(); } else { modules = null; } // Skip the Section Contribution substream. bits.Position += dh.secconSize; // Skip the Section Map substream. bits.Position += dh.secmapSize; // Skip the File Info substream. bits.Position += dh.filinfSize; // Skip the TSM substream. bits.Position += dh.tsmapSize; // Skip the EC substream. bits.Position += dh.ecinfoSize; // Read the optional header. end = bits.Position + dh.dbghdrSize; if (dh.dbghdrSize > 0) { header = new DbiDbgHdr(bits); } bits.Position = end; }
internal PdbConstant(BitAccess bits) { uint token; bits.ReadUInt32(out token); this.Token = token; byte tag1; bits.ReadUInt8(out tag1); byte tag2; bits.ReadUInt8(out tag2); if (tag2 == 0) { this.Value = tag1; } else if (tag2 == 0x80) { switch (tag1) { case 0x00: //sbyte sbyte sb; bits.ReadInt8(out sb); this.Value = sb; break; case 0x01: //short short s; bits.ReadInt16(out s); this.Value = s; break; case 0x02: //ushort ushort us; bits.ReadUInt16(out us); this.Value = us; break; case 0x03: //int int i; bits.ReadInt32(out i); this.Value = i; break; case 0x04: //uint uint ui; bits.ReadUInt32(out ui); this.Value = ui; break; case 0x05: //float this.Value = bits.ReadFloat(); break; case 0x06: //double this.Value = bits.ReadDouble(); break; case 0x09: //long long sl; bits.ReadInt64(out sl); this.Value = sl; break; case 0x0a: //ulong ulong ul; bits.ReadUInt64(out ul); this.Value = ul; break; case 0x10: //string string str; bits.ReadBString(out str); this.Value = str; break; case 0x19: //decimal this.Value = bits.ReadDecimal(); break; default: //TODO: error break; } } else { //TODO: error } string name; bits.ReadCString(out name); Name = name; }
private static void LoadManagedLines(PdbFunction[] funcs, Dictionary<int, string> names, BitAccess bits, MsfDirectory dir, Dictionary<string, int> nameIndex, PdbStreamHelper reader, uint limit, Dictionary<string, PdbSource> sources) { Array.Sort(funcs, PdbFunction.byAddressAndToken); Dictionary<int, PdbSource> checks = new Dictionary<int, PdbSource>(); // 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 = names[(int)chk.name]; PdbSource src; if (!sources.TryGetValue(name.ToUpperInvariant(), out src)) { int guidStream; Guid doctypeGuid = Guid.Empty; Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; Guid algorithmId = Guid.Empty; byte[] checksum = null; byte[] source = null; 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, out algorithmId, out checksum, out source); } src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid, algorithmId, checksum, source); sources.Add(name.ToUpperInvariant(), src); } 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.SequencePoints == null) { while (funcIndex > 0) { var f = funcs[funcIndex - 1]; if (f.SequencePoints != null || f.Segment != sec.sec || f.Address != sec.off) break; func = f; funcIndex--; } } else { while (funcIndex < funcs.Length - 1 && func.SequencePoints != null) { var f = funcs[funcIndex + 1]; if (f.Segment != sec.sec || f.Address != sec.off) break; func = f; funcIndex++; } } if (func.SequencePoints != 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.SequencePoints = new PdbSequencePointCollection[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]; PdbSequencePointCollection tmp = new PdbSequencePointCollection(src, file.count); func.SequencePoints[block++] = tmp; PdbSequencePoint[] 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 PdbSequencePoint(line.offset, lineBegin, column.offColumnStart, lineBegin + delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int ver, out int sig, out int age, out Guid guid, out IEnumerable <PdbSource> sources) { sources = null; PdbFileHeader head = new PdbFileHeader(read, bits); PdbStreamHelper reader = new PdbStreamHelper(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 ver, out sig, out age, out guid); int nameStream; if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } dir._streams[nameStream].Read(reader, bits); Dictionary <int, string> names = LoadNameStream(bits); dir._streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, readAllStrings); List <PdbFunction> funcList = new List <PdbFunction>(); Dictionary <string, PdbSource> sourceDictionary = new Dictionary <string, PdbSource>(); 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, sourceDictionary); } } } PdbFunction[] funcs = funcList.ToArray(); sources = sourceDictionary.Values; // 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 static void CountScopesAndSlots(BitAccess bits, uint limit, out int constants, out int scopes, out int slots, out int usedNamespaces) { int pos = bits.Position; BlockSym32 block; constants = 0; slots = 0; scopes = 0; usedNamespaces = 0; while (bits.Position < limit) { 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_BLOCK32: { bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); scopes++; bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: slots++; bits.Position = stop; break; case SYM.S_UNAMESPACE: usedNamespaces++; bits.Position = stop; break; case SYM.S_MANCONSTANT: constants++; bits.Position = stop; break; default: bits.Position = stop; break; } } bits.Position = pos; }
private static void LoadDbiStream(BitAccess bits, out DbiModuleInfo[] modules, out DbiDbgHdr header, bool readStrings) { DbiHeader dh = new DbiHeader(bits); header = new DbiDbgHdr(); //if (dh.sig != -1 || dh.ver != 19990903) { // throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}", // dh.sig, dh.ver); //} // Read gpmod section. List <DbiModuleInfo> modList = new List <DbiModuleInfo>(); int end = bits.Position + dh.gpmodiSize; while (bits.Position < end) { DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings); modList.Add(mod); } if (bits.Position != end) { throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}", bits.Position, end); } if (modList.Count > 0) { modules = modList.ToArray(); } else { modules = null; } // Skip the Section Contribution substream. bits.Position += dh.secconSize; // Skip the Section Map substream. bits.Position += dh.secmapSize; // Skip the File Info substream. bits.Position += dh.filinfSize; // Skip the TSM substream. bits.Position += dh.tsmapSize; // Skip the EC substream. bits.Position += dh.ecinfoSize; // Read the optional header. end = bits.Position + dh.dbghdrSize; if (dh.dbghdrSize > 0) { header = new DbiDbgHdr(bits); } bits.Position = end; }
private static Dictionary <string, int> LoadNameIndex(BitAccess bits, out int ver, out int sig, out int age, out Guid guid) { Dictionary <string, int> result = new Dictionary <string, int>(); 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 //if (ver != 20000404) { // throw new PdbDebugException("Unsupported PDB Stream version {0}", ver); //} // Read string buffer. int buf; bits.ReadInt32(out buf); // 28..31 Bytes of Strings int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read map index. int cnt; // n+0..3 hash size. int max; // n+4..7 maximum ni. bits.ReadInt32(out cnt); bits.ReadInt32(out max); BitSet present = new BitSet(bits); BitSet deleted = new BitSet(bits); if (!deleted.IsEmpty) { //throw new PdbDebugException("Unsupported PDB deleted bitset is not empty."); } int j = 0; for (int i = 0; i < max; i++) { if (present.IsSet(i)) { int ns; int ni; bits.ReadInt32(out ns); bits.ReadInt32(out ni); string name; int saved = bits.Position; bits.Position = beg + ns; bits.ReadCString(out name); bits.Position = saved; result.Add(name.ToUpperInvariant(), ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return(result); }
private static void LoadManagedLines(PdbFunction[] funcs, Dictionary <int, string> names, BitAccess bits, MsfDirectory dir, Dictionary <string, int> nameIndex, PdbStreamHelper reader, uint limit, Dictionary <string, PdbSource> sources) { Array.Sort(funcs, PdbFunction.byAddressAndToken); Dictionary <int, PdbSource> checks = new Dictionary <int, PdbSource>(); // 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 = names[(int)chk.name]; PdbSource src; if (!sources.TryGetValue(name.ToUpperInvariant(), out src)) { int guidStream; Guid doctypeGuid = Guid.Empty; Guid languageGuid = Guid.Empty; Guid vendorGuid = Guid.Empty; Guid algorithmId = Guid.Empty; byte[] checksum = null; byte[] source = null; 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, out algorithmId, out checksum, out source); } src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid, algorithmId, checksum, source); sources.Add(name.ToUpperInvariant(), src); } 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.SequencePoints == null) { while (funcIndex > 0) { var f = funcs[funcIndex - 1]; if (f.SequencePoints != null || f.Segment != sec.sec || f.Address != sec.off) { break; } func = f; funcIndex--; } } else { while (funcIndex < funcs.Length - 1 && func.SequencePoints != null) { var f = funcs[funcIndex + 1]; if (f.Segment != sec.sec || f.Address != sec.off) { break; } func = f; funcIndex++; } } if (func.SequencePoints != 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.SequencePoints = new PdbSequencePointCollection[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]; PdbSequencePointCollection tmp = new PdbSequencePointCollection(src, file.count); func.SequencePoints[block++] = tmp; PdbSequencePoint[] 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 PdbSequencePoint(line.offset, lineBegin, column.offColumnStart, lineBegin + delta, column.offColumnEnd); } } break; } } bits.Position = endSym; } }
private void ReadCustomMetadata(BitAccess bits) { int savedPosition = bits.Position; byte version; bits.ReadUInt8(out version); if (version != 4) { throw new PdbDebugException("Unknown custom metadata item version: {0}", version); } byte kind; bits.ReadUInt8(out kind); bits.Align(4); uint numberOfBytesInItem; bits.ReadUInt32(out numberOfBytesInItem); switch (kind) { case 0: this.ReadUsingInfo(bits); break; case 1: break; // this.ReadForwardInfo(bits); break; case 2: break; // this.ReadForwardedToModuleInfo(bits); break; case 3: this.ReadIteratorLocals(bits); break; case 4: this.ReadForwardIterator(bits); break; default: throw new PdbDebugException("Unknown custom metadata item kind: {0}", kind); } bits.Position = savedPosition + (int)numberOfBytesInItem; }
internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ BitAccess bits, uint limit, bool readStrings) { //string mod = StripNamespace(module); int begin = bits.Position; int count = 0; while (bits.Position < limit) { 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_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.Position = (int)proc.end; count++; break; 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; } } if (count == 0) { return null; } bits.Position = begin; PdbFunction[] funcs = new PdbFunction[count]; int func = 0; while (bits.Position < limit) { ushort siz; ushort rec; bits.ReadUInt16(out siz); int star = bits.Position; int stop = bits.Position + siz; bits.ReadUInt16(out rec); switch ((SYM)rec) { case SYM.S_GMANPROC: case SYM.S_LMANPROC: ManProcSym proc; //int offset = bits.Position; bits.ReadUInt32(out proc.parent); bits.ReadUInt32(out proc.end); bits.ReadUInt32(out proc.next); bits.ReadUInt32(out proc.len); bits.ReadUInt32(out proc.dbgStart); bits.ReadUInt32(out proc.dbgEnd); bits.ReadUInt32(out proc.token); bits.ReadUInt32(out proc.off); bits.ReadUInt16(out proc.seg); bits.ReadUInt8(out proc.flags); bits.ReadUInt16(out proc.retReg); if (readStrings) { bits.ReadCString(out proc.name); } else { bits.SkipCString(out proc.name); } //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); bits.Position = stop; funcs[func++] = new PdbFunction(/*module,*/ proc, bits); break; default: { //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); bits.Position = stop; break; } } } return funcs; }
internal BitSet(BitAccess bits) { bits.ReadInt32(out _size); // 0..3 : Number of words _words = new uint[_size]; bits.ReadUInt32(_words); }
internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) { this.Token = proc.token; //this.module = module; //this.name = proc.name; //this.flags = proc.flags; this.Segment = proc.seg; this.Address = proc.off; //this.length = proc.len; if (proc.seg != 1) { throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); } if (proc.parent != 0 || proc.next != 0) { throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next); } //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { // throw new PdbDebugException("Warning DBG start={0}, end={1}", // proc.dbgStart, proc.dbgEnd); //} int constantCount; int scopeCount; int slotCount; int usedNamespacesCount; CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; int slot = 0; int constant = 0; int usedNs = 0; Scopes = new PdbScope[scopeCount + scope]; Slots = new PdbSlot[slotCount]; Constants = new PdbConstant[constantCount]; Namespaces = new string[usedNamespacesCount]; if (scope > 0) Scopes[0] = new PdbScope(this.Address, proc.len, Slots, Constants, Namespaces); while (bits.Position < proc.end) { 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: { // 0x0404 OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { string name = bits.ReadString(); if (name == "MD2") { byte version; bits.ReadUInt8(out version); if (version == 4) { byte count; bits.ReadUInt8(out count); bits.Align(4); while (count-- > 0) this.ReadCustomMetadata(bits); } } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } } case SYM.S_BLOCK32: { BlockSym32 block = new BlockSym32(); bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); bits.ReadUInt32(out block.len); bits.ReadUInt32(out block.off); bits.ReadUInt16(out block.seg); bits.SkipCString(out block.name); bits.Position = stop; Scopes[scope++] = new PdbScope(this.Address, block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: uint typind; Slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_MANCONSTANT: Constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out Namespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); bits.Position = stop; break; } } } if (bits.Position != proc.end) { throw new PdbDebugException("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new PdbDebugException("Missing S_END"); } }
internal BitSet(BitAccess bits) { bits.ReadInt32(out _size); // 0..3 : Number of words _words = new uint[_size]; bits.ReadUInt32(_words); }
internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) { //this.segment = block.seg; this.Address = block.off; this.Offset = block.off - funcOffset; this.Length = block.len; typind = 0; int constantCount; int scopeCount; int slotCount; int namespaceCount; PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount); Constants = new PdbConstant[constantCount]; Scopes = new PdbScope[scopeCount]; Slots = new PdbSlot[slotCount]; UsedNamespaces = new string[namespaceCount]; int constant = 0; int scope = 0; int slot = 0; int usedNs = 0; while (bits.Position < block.end) { 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_BLOCK32: { BlockSym32 sub = new BlockSym32(); bits.ReadUInt32(out sub.parent); bits.ReadUInt32(out sub.end); bits.ReadUInt32(out sub.len); bits.ReadUInt32(out sub.off); bits.ReadUInt16(out sub.seg); bits.SkipCString(out sub.name); bits.Position = stop; Scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind); break; } case SYM.S_MANSLOT: Slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out UsedNamespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; case SYM.S_MANCONSTANT: Constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; default: //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); bits.Position = stop; break; } } if (bits.Position != block.end) { throw new Exception("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new Exception("Missing S_END"); } }
internal void Read(PdbStreamHelper reader, BitAccess bits) { bits.MinCapacity(_contentSize); Read(reader, 0, bits.Buffer, 0, _contentSize); }
internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) { //this.segment = block.seg; Address = block.off; Offset = block.off - funcOffset; Length = block.len; typind = 0; int constantCount; int scopeCount; int slotCount; int namespaceCount; PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount); Constants = new PdbConstant[constantCount]; Scopes = new PdbScope[scopeCount]; Slots = new PdbSlot[slotCount]; UsedNamespaces = new string[namespaceCount]; int constant = 0; int scope = 0; int slot = 0; int usedNs = 0; while (bits.Position < block.end) { 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_BLOCK32: { BlockSym32 sub = new BlockSym32(); bits.ReadUInt32(out sub.parent); bits.ReadUInt32(out sub.end); bits.ReadUInt32(out sub.len); bits.ReadUInt32(out sub.off); bits.ReadUInt16(out sub.seg); bits.SkipCString(out sub.name); bits.Position = stop; Scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind); break; } case SYM.S_MANSLOT: Slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out UsedNamespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; case SYM.S_MANCONSTANT: Constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; default: //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); bits.Position = stop; break; } } if (bits.Position != block.end) { throw new Exception("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new Exception("Missing S_END"); } }
private static Dictionary<string, int> LoadNameIndex(BitAccess bits, out int ver, out int sig, out int age, out Guid guid) { Dictionary<string, int> result = new Dictionary<string, int>(); 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 //if (ver != 20000404) { // throw new PdbDebugException("Unsupported PDB Stream version {0}", ver); //} // Read string buffer. int buf; bits.ReadInt32(out buf); // 28..31 Bytes of Strings int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read map index. int cnt; // n+0..3 hash size. int max; // n+4..7 maximum ni. bits.ReadInt32(out cnt); bits.ReadInt32(out max); BitSet present = new BitSet(bits); BitSet deleted = new BitSet(bits); if (!deleted.IsEmpty) { throw new PdbDebugException("Unsupported PDB deleted bitset is not empty."); } int j = 0; for (int i = 0; i < max; i++) { if (present.IsSet(i)) { int ns; int ni; bits.ReadInt32(out ns); bits.ReadInt32(out ni); string name; int saved = bits.Position; bits.Position = beg + ns; bits.ReadCString(out name); bits.Position = saved; result.Add(name.ToUpperInvariant(), ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return result; }
internal PdbFunction(/*string module, */ ManProcSym proc, BitAccess bits) { this.Token = proc.token; //this.module = module; //this.name = proc.name; //this.flags = proc.flags; this.Segment = proc.seg; this.Address = proc.off; //this.length = proc.len; if (proc.seg != 1) { throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); } if (proc.parent != 0 || proc.next != 0) { throw new PdbDebugException("Warning parent={0}, next={1}", proc.parent, proc.next); } //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { // throw new PdbDebugException("Warning DBG start={0}, end={1}", // proc.dbgStart, proc.dbgEnd); //} int constantCount; int scopeCount; int slotCount; int usedNamespacesCount; CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; int slot = 0; int constant = 0; int usedNs = 0; Scopes = new PdbScope[scopeCount + scope]; Slots = new PdbSlot[slotCount]; Constants = new PdbConstant[constantCount]; Namespaces = new string[usedNamespacesCount]; if (scope > 0) { Scopes[0] = new PdbScope(this.Address, proc.len, Slots, Constants, Namespaces); } while (bits.Position < proc.end) { 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: { // 0x0404 OemSymbol oem; bits.ReadGuid(out oem.idOem); bits.ReadUInt32(out oem.typind); // internal byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { string name = bits.ReadString(); if (name == "MD2") { byte version; bits.ReadUInt8(out version); if (version == 4) { byte count; bits.ReadUInt8(out count); bits.Align(4); while (count-- > 0) { this.ReadCustomMetadata(bits); } } } bits.Position = stop; break; } else { throw new PdbDebugException("OEM section: guid={0} ti={1}", oem.idOem, oem.typind); // bits.Position = stop; } } case SYM.S_BLOCK32: { BlockSym32 block = new BlockSym32(); bits.ReadUInt32(out block.parent); bits.ReadUInt32(out block.end); bits.ReadUInt32(out block.len); bits.ReadUInt32(out block.off); bits.ReadUInt16(out block.seg); bits.SkipCString(out block.name); bits.Position = stop; Scopes[scope++] = new PdbScope(this.Address, block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_MANSLOT: uint typind; Slots[slot++] = new PdbSlot(bits, out typind); bits.Position = stop; break; case SYM.S_MANCONSTANT: Constants[constant++] = new PdbConstant(bits); bits.Position = stop; break; case SYM.S_UNAMESPACE: bits.ReadCString(out Namespaces[usedNs++]); bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); bits.Position = stop; break; } } } if (bits.Position != proc.end) { throw new PdbDebugException("Not at S_END"); } ushort esiz; ushort erec; bits.ReadUInt16(out esiz); bits.ReadUInt16(out erec); if (erec != (ushort)SYM.S_END) { throw new PdbDebugException("Missing S_END"); } }
internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings, out int ver, out int sig, out int age, out Guid guid, out IEnumerable<PdbSource> sources) { BitAccess bits = new BitAccess(512 * 1024); return LoadFunctions(read, bits, readAllStrings, out ver, out sig, out age, out guid, out sources); }
private void ReadForwardIterator(BitAccess bits) { this.iteratorClass = bits.ReadString(); }
private static Dictionary<int, string> LoadNameStream(BitAccess bits) { Dictionary<int, string> ht = new Dictionary<int, string>(); uint sig; int ver; bits.ReadUInt32(out sig); // 0..3 Signature bits.ReadInt32(out ver); // 4..7 Version // Read (or skip) string buffer. int buf; bits.ReadInt32(out buf); // 8..11 Bytes of Strings if (sig != 0xeffeeffe || ver != 1) { throw new PdbDebugException("Unsupported Name Stream version. " + "(sig={0:x8}, ver={1})", sig, ver); } int beg = bits.Position; int nxt = bits.Position + buf; bits.Position = nxt; // Read hash table. int siz; bits.ReadInt32(out siz); // n+0..3 Number of hash buckets. nxt = bits.Position; for (int i = 0; i < siz; i++) { int ni; string name; bits.ReadInt32(out ni); if (ni != 0) { int saved = bits.Position; bits.Position = beg + ni; bits.ReadCString(out name); bits.Position = saved; ht.Add(ni, name); } } bits.Position = nxt; return ht; }
private void ReadIteratorLocals(BitAccess bits) { uint numberOfLocals; bits.ReadUInt32(out numberOfLocals); }
internal void Read(PdbStreamHelper reader, BitAccess bits) { bits.MinCapacity(_contentSize); Read(reader, 0, bits.Buffer, 0, _contentSize); }
private void ReadForwardIterator(BitAccess bits) { this.iteratorClass = bits.ReadString(); }