/// <summary> /// /// </summary> /// <param name="localDefinition"></param> /// <param name="isCompilerGenerated"></param> /// <returns></returns> public string GetSourceNameFor(ILocalDefinition localDefinition, out bool isCompilerGenerated) { isCompilerGenerated = true; PdbFunction /*?*/ pdbFunction = this.GetPdbFunctionFor(localDefinition); if (pdbFunction != null) { uint index = 0; foreach (ILocation location in localDefinition.Locations) { IILLocation /*?*/ mbLocation = location as IILLocation; if (mbLocation != null) { index = mbLocation.Offset; break; } } PdbSlot /*?*/ slot = this.GetSlotFor(pdbFunction.scopes, index); if (slot != null) { isCompilerGenerated = (slot.flags & 0x4) != 0; return(slot.name); } } return(localDefinition.Name.Value); }
/// <summary> /// If the given method body is the "MoveNext" method of the state class of an asynchronous method, the returned /// object describes where synchronization points occur in the IL operations of the "MoveNext" method. Otherwise /// the result is null. /// </summary> public ISynchronizationInformation /*?*/ GetSynchronizationInformation(IMethodBody methodBody) { PdbFunction /*?*/ pdbFunction = this.GetPdbFunctionFor(methodBody); if (pdbFunction == null) { return(null); } var info = pdbFunction.synchronizationInformation; if (info == null) { return(null); } uint moveNextToken; var decoder = GetTokenDecoderFor(methodBody, out moveNextToken); if (decoder != null) { info.asyncMethod = (decoder.GetObjectForToken(info.kickoffMethodToken) as IMethodDefinition) ?? Dummy.MethodDefinition; info.moveNextMethod = (decoder.GetObjectForToken(moveNextToken) as IMethodDefinition) ?? Dummy.MethodDefinition; if (info.synchronizationPoints != null) { foreach (var synchPoint in info.synchronizationPoints) { synchPoint.continuationMethod = (decoder.GetObjectForToken(synchPoint.continuationMethodToken) as IMethodDefinition) ?? Dummy.MethodDefinition; } } } return(info); }
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; distance = dist; } } } return(nearest); }
public static void Dump(PdbFunction f, int indent) { string pad = new String(' ', indent); Console.WriteLine(" {0}Func: [{1}.{2}] addr={3:x4}:{4:x8} len={5:x4} token={6:x8}", pad, StripNamespace(f.module), f.name, f.segment, f.address, f.length, f.token); if (f.metadata != null) { Console.Write(" {0} Meta: [", pad); for (int i = 0; i < f.metadata.Length; i++) { Console.Write("{0:x2}", f.metadata[i]); } Console.WriteLine("]"); } if (f.scopes != null) { for (int i = 0; i < f.scopes.Length; i++) { Dump(f.scopes[i], indent + 1); } } if (f.lines != null) { for (int i = 0; i < f.lines.Length; i++) { Dump(f.lines[i], indent + 1); } } }
internal void RunTest(string name, out PdbFunction original, out PdbFunction rewritten) { int originalAge; Guid originalGuid; PdbFunction[] originalFunctions; using (var file = File.OpenRead(pdbFileName)) originalFunctions = PdbFile.LoadFunctions(file, true, out originalAge, out originalGuid); var method = GetMethod(name); original = originalFunctions.Single(f => f.token == method.MetadataToken.ToUInt32()); var pdb = ProgramDatabase.Read(pdbFileName); pdb.Write(pdbFileName, new CecilMetadataProvider(module)); int rewrittenAge; Guid rewrittenGuid; PdbFunction[] rewrittenFunctions; using (var file = File.OpenRead(pdbFileName)) rewrittenFunctions = PdbFile.LoadFunctions(file, true, out rewrittenAge, out rewrittenGuid); rewritten = rewrittenFunctions.Single(f => f.token == method.MetadataToken.ToUInt32()); Assert.AreEqual(originalAge, rewrittenAge); Assert.AreEqual(originalGuid, rewrittenGuid); }
public static SourceLocation GetSourceLocation(this ClrMethod method, int ilOffset) { PdbReader reader = GetReaderForMethod(method); PdbFunction function = reader.GetFunctionFromToken(method.MetadataToken); return(FindNearestLine(function, ilOffset)); }
private void ConvertVariables(PdbFunction function) { foreach (var scope in function.Scopes) { ConvertScope(scope); } }
private IEnumerable <IPrimarySourceLocation> MapMethodBodyLocationToSourceLocations(IILLocation mbLocation) { PdbFunction pdbFunction = null; var doc = mbLocation.Document as MethodBodyDocument; if (doc == null || !this.pdbFunctionMap.TryGetValue(doc.MethodToken, out pdbFunction)) { yield break; } if (pdbFunction.lines == null) { yield break; } foreach (PdbLines pdbLines in pdbFunction.lines) { foreach (var pdbLine in pdbLines.lines) { PdbSource pdbSourceFile = pdbLines.file; if (pdbSourceFile == null) { continue; } PdbSourceDocument psDoc = this.GetPrimarySourceDocumentFor(pdbSourceFile); yield return(new PdbSourceLineLocation(psDoc, (int)pdbLine.lineBegin, pdbLine.colBegin, (int)pdbLine.lineEnd, pdbLine.colEnd)); } } }
private PdbFunction /*?*/ GetPdbFunctionFor(IMethodBody methodBody) { PdbFunction result = null; uint methodToken = GetTokenFor(methodBody); this.pdbFunctionMap.TryGetValue(methodToken, out result); return(result); }
private void ReadSources(PdbFunction function) { if (function.lines == null) { return; } sources.AddRange(function.lines.Select(l => new Source(l))); }
private void ReadIteratorScopes(PdbFunction function) { if (function.iteratorScopes == null) { return; } iteratorScopes.AddRange(function.iteratorScopes.Select(s => new IteratorScope(s))); }
private static IEnumerable <SequencePoint> ReadSequencePoints(PdbFunction function) { if (function.lines == null) { return(Enumerable.Empty <SequencePoint>()); } return(function.lines.SelectMany(lines => ReadSequencePoints(lines))); }
internal static void AssertFunction(PdbFunction originalFunction, PdbFunction function) { Assert.AreEqual(originalFunction.token, function.token); AssertLines(originalFunction.lines, function.lines); AssertScopes(originalFunction.scopes, function.scopes); AssertConstants(originalFunction.constants, function.constants); Assert.AreEqual(originalFunction.slotToken, function.slotToken); AssertSlots(originalFunction.slots, function.slots); Assert.AreEqual(originalFunction.iteratorClass, function.iteratorClass); AssertIteratorScopes(originalFunction.iteratorScopes, function.iteratorScopes); }
internal Function(PdbFunction function) : this() { this.Token = (int)function.token; this.VariablesToken = (int)function.slotToken; this.IteratorTypeName = function.iteratorClass ?? string.Empty; ReadIteratorScopes(function); ReadSources(function); this.ReadScope(function.slots, function.constants, function.scopes); }
/// <inheritdoc/> public override bool Equals(object obj) { PdbFunction other = obj as PdbFunction; if (other == null) { return(false); } return(Token == other.Token && SourceFilename == other.SourceFilename && StartLine == other.StartLine && EndLine == other.EndLine); }
private void ConvertSequencePoints(PdbFunction function, SourceFile file, SourceMethodBuilder builder) { foreach (var line in function.Lines.SelectMany(lines => lines.Lines)) { builder.MarkSequencePoint( (int)line.Offset, file.CompilationUnit.SourceFile, (int)line.LineBegin, line.ColBegin, line.LineBegin == 0xfeefee); } }
void ReadSequencePoints(PdbFunction function, InstructionMapper mapper) { if (function.lines == null) { return; } foreach (PdbLines lines in function.lines) { ReadLines(lines, mapper); } }
void ReadSequencePoints(PdbFunction function, MethodSymbols symbols) { if (function.lines == null) { return; } foreach (PdbLines lines in function.lines) { ReadLines(lines, symbols); } }
void ReadSequencePoints(PdbFunction function, IDictionary instructions) { if (function.lines == null) { return; } foreach (PdbLines lines in function.lines) { ReadLines(lines, instructions); } }
/// <summary> /// Returns zero or more lexical scopes into which the CLR IL operations in the given method body is organized. /// </summary> public IEnumerable <ILocalScope> GetLocalScopes(IMethodBody methodBody) { PdbFunction /*?*/ pdbFunction = this.GetPdbFunctionFor(methodBody); if (pdbFunction == null) { return(Enumerable <ILocalScope> .Empty); } List <ILocalScope> scopes = new List <ILocalScope>(); this.FillInScopesAndSubScopes(methodBody, pdbFunction.scopes, scopes); return(scopes.AsReadOnly()); }
void ReadSequencePoints(PdbFunction function, MethodDebugInformation info) { if (function.lines == null) { return; } info.sequence_points = new Collection <SequencePoint> (); foreach (PdbLines lines in function.lines) { ReadLines(lines, info); } }
public static SourceLocation GetSourceLocation(this ClrStackFrame frame) { PdbReader reader = GetReaderForMethod(frame.Method); if (reader == null) { return(null); } PdbFunction function = reader.GetFunctionFromToken(frame.Method.MetadataToken); int ilOffset = FindIlOffset(frame); return(FindNearestLine(function, ilOffset)); }
public static FileAndLineNumber FileAndLineNumber(this ClrStackFrame frame) { PdbReader reader = GetReaderForFrame(frame); if (reader == null) { return(new FileAndLineNumber()); } PdbFunction function = reader.GetFunctionFromToken(frame.Method.MetadataToken); int ilOffset = FindIlOffset(frame); return(FindNearestLine(function, ilOffset)); }
private PdbFunction GetPdbFunctionFor(ILocalDefinition localDefinition) { PdbFunction /*?*/ result = null; foreach (ILocation location in localDefinition.Locations) { MethodBodyLocation /*?*/ mbLocation = location as MethodBodyLocation; if (mbLocation != null) { this.pdbFunctionMap.TryGetValue(mbLocation.Document.MethodToken, out result); break; } } return(result); }
void ConvertFunction(PdbFunction function) { var method = new SourceMethod { Name = function.name, Token = (int)function.token }; var file = GetSourceFile(mdb, function); var builder = mdb.OpenMethod(file.CompilationUnit, 0, method); ConvertSequencePoints(function, file, builder); ConvertVariables(function); mdb.CloseMethod(); }
void ConvertSequencePoints(PdbFunction function, SourceFile file, SourceMethodBuilder builder) { if (function.lines == null) { return; } foreach (var line in function.lines.SelectMany(lines => lines.lines)) { builder.MarkSequencePoint( (int)line.offset, file.CompilationUnit.SourceFile, (int)line.lineBegin, (int)line.colBegin, line.lineBegin == 0xfeefee); } }
void ReadSequencePoints(PdbFunction function, MethodSymbols symbols) { if (function.lines == null) { return; } { // foreach(var lines in function.lines) var __enumerator8 = (function.lines).GetEnumerator(); while (__enumerator8.MoveNext()) { var lines = (PdbLines)__enumerator8.Current; ReadLines(lines, symbols); } } }
void ReadSequencePoints(PdbFunction function, InstructionMapper mapper) { if (function.lines == null) { return; } { // foreach(var lines in function.lines) var __enumerator4 = (function.lines).GetEnumerator(); while (__enumerator4.MoveNext()) { var lines = (PdbLines)__enumerator4.Current; ReadLines(lines, mapper); } } }
/// <summary> /// Returns zero or more namespace scopes into which the namespace type containing the given method body has been nested. /// These scopes determine how simple names are looked up inside the method body. There is a separate scope for each dotted /// component in the namespace type name. For istance namespace type x.y.z will have two namespace scopes, the first is for the x and the second /// is for the y. /// </summary> public IEnumerable <INamespaceScope> GetNamespaceScopes(IMethodBody methodBody) { PdbFunction /*?*/ pdbFunction = this.GetPdbFunctionFor(methodBody); if (pdbFunction != null && pdbFunction.usingCounts != null) { if (pdbFunction.namespaceScopes != null) { return(pdbFunction.namespaceScopes); } foreach (PdbScope pdbScope in pdbFunction.scopes) { return(pdbFunction.namespaceScopes = this.GetNamespaceScopes(pdbFunction.usingCounts, pdbScope).AsReadOnly()); } } return(IteratorHelper.GetEmptyEnumerable <INamespaceScope>()); }
private SourceFile GetSourceFile(MonoSymbolWriter mdbArg, PdbFunction function) { var name = (from l in function.Lines where l.File != null select l.File.Name).First(); SourceFile file; if (files.TryGetValue(name, out file)) { return(file); } var entry = mdbArg.DefineDocument(name); var unit = mdbArg.DefineCompilationUnit(entry); file = new SourceFile(unit, entry); files.Add(name, file); return(file); }
private static PdbFunction FindFunction(PdbFunction[] funcs, ushort sec, uint off) { match.segment = sec; match.address = off; int item = Array.BinarySearch(funcs, match, PdbFunction.byAddress); if (item >= 0) { return funcs[item]; } return null; }
SourceFile GetSourceFile(MonoSymbolWriter mdb, PdbFunction function) { var name = (from l in function.lines where l.file != null select l.file.name).First (); SourceFile file; if (files.TryGetValue (name, out file)) return file; var entry = mdb.DefineDocument (name); var unit = mdb.DefineCompilationUnit (entry); file = new SourceFile (unit, entry); files.Add (name, file); return file; }
void ReadSequencePoints (PdbFunction function, InstructionMapper mapper) { if (function.lines == null) return; foreach (PdbLines lines in function.lines) ReadLines (lines, mapper); }
void ConvertFunction(PdbFunction function) { if (function.lines == null) return; var method = new SourceMethod { Name = function.name, Token = (int) function.token }; var file = GetSourceFile (mdb, function); var builder = mdb.OpenMethod (file.CompilationUnit, 0, method); ConvertSequencePoints (function, file, builder); ConvertVariables (function); mdb.CloseMethod (); }
void ReadSequencePoints (PdbFunction function, MethodSymbols symbols) { if (function.lines == null) return; foreach (PdbLines lines in function.lines) ReadLines (lines, symbols); }
void ConvertVariables(PdbFunction function) { foreach (var scope in function.scopes) ConvertScope (scope); }
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; } }
void ConvertSequencePoints(PdbFunction function, SourceFile file, SourceMethodBuilder builder) { foreach (var line in function.lines.SelectMany (lines => lines.lines)) builder.MarkSequencePoint ( (int) line.offset, file.CompilationUnit.SourceFile, (int) line.lineBegin, (int) line.colBegin, line.lineBegin == 0xfeefee); }