public int Compare(object x, object y) { PdbFunction fx = (PdbFunction)x; PdbFunction fy = (PdbFunction)y; if (fx.Segment < fy.Segment) { return(-1); } if (fx.Segment > fy.Segment) { return(1); } if (fx.Address < fy.Address) { return(-1); } if (fx.Address > fy.Address) { return(1); } return(0); }
private static SourceLocation FindNearestLine(PdbFunction function, int ilOffset) { int distance = int.MaxValue; SourceLocation nearest = null; foreach (PdbSequencePointCollection sequenceCollection in function.SequencePoints) { foreach (PdbSequencePoint point in sequenceCollection.Lines) { int dist = (int)Math.Abs(point.Offset - ilOffset); if (dist < distance) { if (nearest == null) nearest = new SourceLocation(); nearest.FilePath = sequenceCollection.File.Name; nearest.LineNumber = (int)point.LineBegin; nearest.LineNumberEnd = (int)point.LineEnd; nearest.ColStart = (int)point.ColBegin; nearest.ColEnd = (int)point.ColEnd; } } } return nearest; }
/// <summary> /// Retreives a PdbFunction by its metadata token. /// </summary> /// <param name="methodToken"></param> /// <returns></returns> public PdbFunction GetFunctionFromToken(uint methodToken) { PdbFunction result = null; _pdbFunctionMap.TryGetValue(methodToken, out result); return(result); }
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 FileAndLineNumber FindNearestLine(PdbFunction function, int ilOffset) { int distance = int.MaxValue; FileAndLineNumber nearest = new FileAndLineNumber(); foreach (PdbSequencePointCollection sequenceCollection in function.SequencePoints) { foreach (PdbSequencePoint point in sequenceCollection.Lines) { int dist = (int)Math.Abs(point.Offset - ilOffset); if (dist < distance) { nearest.File = sequenceCollection.File.Name; nearest.Line = (int)point.LineBegin; } } } return nearest; }
public int Compare(Object x, Object y) { PdbFunction fx = (PdbFunction)x; PdbFunction fy = (PdbFunction)y; if (fx.Segment < fy.Segment) { return(-1); } else if (fx.Segment > fy.Segment) { return(1); } else if (fx.Address < fy.Address) { return(-1); } else if (fx.Address > fy.Address) { return(1); } else { if (fx.Token < fy.Token) { return(-1); } else if (fx.Token > fy.Token) { return(1); } else { return(0); } } }
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)) { BitAccess 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; } PdbFunction func = funcs[funcIndex]; if (func.SequencePoints == null) { while (funcIndex > 0) { PdbFunction 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) { PdbFunction 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 = 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 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 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); }
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 static int FindFunction(PdbFunction[] funcs, ushort sec, uint off) { s_match.Segment = sec; s_match.Address = off; return Array.BinarySearch(funcs, s_match, PdbFunction.byAddress); }
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; }