static IntHashTable LoadNameStream(BitAccess bits) { IntHashTable ht = new IntHashTable(); 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); }
static Dictionary<string,int> LoadNameIndex(BitAccess bits, out int age, out Guid guid) { Dictionary<string, int> result = new Dictionary<string, int>(); int ver; int 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 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, ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return result; }
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 DataStream(int contentSize, BitAccess bits, int count) { this.contentSize = contentSize; if (count > 0) { this.pages = new int[count]; bits.ReadInt32(this.pages); } }
internal DbiModuleInfo(BitAccess bits, bool readStrings) { bits.ReadInt32(out opened); section = 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 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 PdbFileHeader(Stream reader, BitAccess bits) { bits.MinCapacity(56); reader.Seek(0, SeekOrigin.Begin); bits.FillBuffer(reader, 56); 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 bits.ReadInt32(out this.directoryRoot); // 52..55 }
static void LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, IntHashTable names, ICollection <PdbFunction> 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]); } } }
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 = new Guid("5a869d0b-6611-11d3-bd2a-0000f80849bd"); Guid languageGuid = new Guid("3f5162f8-07c6-11d3-9053-00c04fa302a1"); Guid vendorGuid = new Guid("994b45c4-e6e9-11d2-903f-00c04fa302a1"); 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 IntHashTable LoadNameStream(BitAccess bits) { IntHashTable ht = new IntHashTable(); 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; }
static void LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, IntHashTable names, ICollection<PdbFunction> 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]); } } }
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); }
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 = new Guid("5a869d0b-6611-11d3-bd2a-0000f80849bd"); Guid languageGuid = new Guid("3f5162f8-07c6-11d3-9053-00c04fa302a1"); Guid vendorGuid = new Guid("994b45c4-e6e9-11d2-903f-00c04fa302a1"); 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 Dictionary <string, int> LoadNameIndex(BitAccess bits, out int age, out Guid guid) { Dictionary <string, int> result = new Dictionary <string, int>(); int ver; int 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 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, ni); j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return(result); }
internal BitSet(BitAccess bits) { bits.ReadInt32(out size); // 0..3 : Number of words words = new uint[size]; bits.ReadUInt32(words); }
internal PdbConstant(BitAccess bits) { bits.ReadUInt32(out this.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 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 } bits.ReadCString(out name); }