private string ReadHashInternal(string pdbFileHash) { var bits = new BitAccess(0); using (var read = File.Open(pdbFileHash, FileMode.Open)) { var head = new PdbFileHeader(read, bits); var reader = new PdbReader(read, head.pageSize); var 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()); } }
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; this.slotToken = 0; 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 scopeCount; int slotCount; CountScopesAndSlots(bits, proc.end, out scopeCount, out slotCount); scopes = new PdbScope[scopeCount]; int scope = 0; 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); // public byte[] rgl; // user data, force 4-byte alignment if (oem.idOem == msilMetaData) { metadata = new byte[stop - bits.Position]; bits.ReadBytes(metadata); 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(block, bits, out slotToken); bits.Position = (int)block.end; break; } case SYM.S_UNAMESPACE: bits.Position = stop; break; case SYM.S_END: bits.Position = stop; break; default: { throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); // bits.Position = stop; } } } 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"); } }
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 Exception(string.Format("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 == 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 Exception(string.Format("OEM section: guid={0} ti={1}", oem.idOem, oem.typind)); } case SYM.S_END: bits.Position = stop; break; default: 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 Dictionary<string, int> LoadNameIndex(BitAccess bits) { Dictionary<string, int> result = new Dictionary<string, int>(); 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 // 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 Exception("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 Exception(string.Format("Count mismatch. ({0} != {1})", j, cnt)); } return result; }
static int LoadPdbStream(BitAccess bits) { int nameStream = -1; 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 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; if (name == "/names") { nameStream = ni; } else if (name == "/src/headerblock") { // srchStream = ni; } else if (name == "/LinkInfo") { // linkStream = ni; } j++; } } if (j != cnt) { throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); } return(nameStream); }