/// <summary> /// Internal function to write out a line map report if asked to /// </summary> /// <remarks></remarks> private void WriteReport(Internals.AssemblyLineMap AssemblyLineMap) { //only write it if requested if (this.CreateMapReport) { Log.LogMessage("Creating symbol buffer report"); using (var tw = new StreamWriter(this.OutFilename + ".linemapreport", false)) { tw.Write(CreatePDBReport(AssemblyLineMap).ToString()); tw.Flush(); } } }
/// <summary> /// Create a line map report buffer from the PDB for the given executable file /// </summary> /// <remarks></remarks> private StringBuilder CreatePDBReport(Internals.AssemblyLineMap AssemblyLineMap) { var sb = new StringBuilder(); sb.AppendLine("========"); sb.AppendLine("SYMBOLS:"); sb.AppendLine("========"); sb.AppendLine(string.Format(" {0,-10} {1,-10} {2} ", "Token", "Address", "Symbol")); sb.AppendLine(string.Format(" {0,-10} {1,-10} {2} ", "-----", "-------", "------")); var symbols = AssemblyLineMap.Symbols.Values.Select(s => { var lineex = AssemblyLineMap.AddressToLineMap.Where(l => l.Address == s.Address).FirstOrDefault(); var name = lineex?.ObjectName; name = (!string.IsNullOrEmpty(name) ? name + "." : "") + s.Name; return(new Internals.AssemblyLineMap.SymbolInfo(name, s.Address, s.Token)); }).ToList(); symbols.Sort((x, y) => x.Name.CompareTo(y.Name)); foreach (var symbolEx in symbols) { sb.AppendLine(string.Format(" {0,-10:X} {1,-10} {2}", symbolEx.Token, symbolEx.Address, symbolEx.Name)); } sb.AppendLine("========"); sb.AppendLine("LINE NUMBERS:"); sb.AppendLine("========"); sb.AppendLine(string.Format(" {0,-10} {1,-11} {2,-10} {3}", "Address", "Line number", "Token", "Symbol/FileName")); sb.AppendLine(string.Format(" {0,-10} {1,-11} {2,-10} {3}", "-------", "-----------", "-----", "---------------")); //Order by line and then by address for reporting AssemblyLineMap.AddressToLineMap.Sort((x, y) => { if (x.SourceFile.CompareTo(y.SourceFile) < 0) { return(-1); } else if (x.SourceFile.CompareTo(y.SourceFile) > 0) { return(1); } else if (x.Line < y.Line) { return(-1); } else if (x.Line > y.Line) { return(1); } else if (x.Address < y.Address) { return(-1); } else if (x.Address > y.Address) { return(1); } else { return(0); } }); // let the symbol run till the next transition is detected Internals.AssemblyLineMap.SymbolInfo sym = null; foreach (var lineex in AssemblyLineMap.AddressToLineMap) { // find the symbol for this line number foreach (var symbolex in AssemblyLineMap.Symbols.Values) { if (symbolex.Address == lineex.Address) { // found the symbol for this line sym = symbolex; break; } } //if (lineex.Line == 138) System.Diagnostics.Debugger.Break(); var name = lineex.SourceFile + ":" + lineex.ObjectName + (sym != null ? "." + sym.Name : ""); var token = sym != null ? sym.Token : 0; sb.AppendLine(string.Format(" {0,-10} {1,-11} {2,-10:X} {3}", lineex.Address, lineex.Line, token, name)); } sb.AppendLine("========"); sb.AppendLine("NAMES:"); sb.AppendLine("========"); sb.AppendLine(string.Format(" {0,-10} {1}", "Index", "Name")); sb.AppendLine(string.Format(" {0,-10} {1}", "-----", "----")); for (int i = 0; i < AssemblyLineMap.Names.Count; i++) { sb.AppendLine(string.Format(" {0,-10} {1}", i, AssemblyLineMap.Names[i])); } return(sb); }