public void SavePerfMap(string perfMapPath, int perfMapFormatVersion, string dllFileName, TargetDetails details) { string perfMapExtension; if (perfMapFormatVersion == PerfMapWriter.LegacyCrossgen1FormatVersion) { string mvidComponent = null; foreach (AssemblyInfo inputAssembly in _outputInfoBuilder.EnumerateInputAssemblies()) { if (mvidComponent == null) { mvidComponent = inputAssembly.Mvid.ToString(); } else { mvidComponent = "composite"; break; } } perfMapExtension = ".ni.{" + mvidComponent + "}.map"; } else { perfMapExtension = ".ni.r2rmap"; } string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + perfMapExtension); Console.WriteLine("Emitting PerfMap file: {0}", perfMapFileName); PerfMapWriter.Write(perfMapFileName, perfMapFormatVersion, _outputInfoBuilder.EnumerateMethods(), _outputInfoBuilder.EnumerateInputAssemblies(), details); }
public void SavePerfMap(string perfMapPath, string dllFileName, Guid?perfMapMvid) { string mvidComponent = (perfMapMvid.HasValue ? perfMapMvid.Value.ToString() : "composite"); string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + ".ni.{" + mvidComponent + "}.map"); Console.WriteLine("Emitting PerfMap file: {0}", perfMapFileName); PerfMapWriter.Write(perfMapFileName, _outputInfoBuilder.EnumerateMethods()); }
public void SavePerfMap(string perfMapPath, string dllFileName) { string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + ".perf.map"); Console.WriteLine("Emitting PerfMap file: {0}", perfMapFileName); PerfMapWriter.Write(perfMapFileName, _outputInfoBuilder.EnumerateMethods()); }
/// <summary> /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image /// </summary> /// <param name="r2r">The structure containing the info of the ReadyToRun image</param> public void Dump(ReadyToRunReader r2r) { _dumper.Begin(); bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap); if (_options.Header && standardDump) { _dumper.WriteDivider("R2R Header"); _dumper.DumpHeader(true); } bool haveQuery = false; if (_options.Section != null) { haveQuery = true; QuerySection(r2r, _options.Section); } if (_options.RuntimeFunction != null) { haveQuery = true; QueryRuntimeFunction(r2r, _options.RuntimeFunction); } if (_options.Query != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Query", _options.Query, true); } if (_options.Keyword != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false); } if (!haveQuery) { // Dump all sections and methods if no queries specified if (_options.EntryPoints) { _dumper.DumpEntryPoints(); } if (_options.CreatePDB) { string pdbPath = _options.PdbPath; if (String.IsNullOrEmpty(pdbPath)) { pdbPath = Path.GetDirectoryName(r2r.Filename); } var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None); pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r)); } if (_options.CreatePerfmap) { string perfmapPath = _options.PerfmapPath; if (string.IsNullOrEmpty(perfmapPath)) { perfmapPath = Path.ChangeExtension(r2r.Filename, ".map"); PerfMapWriter.Write(perfmapPath, ProduceDebugInfoMethods(r2r)); } } if (standardDump) { _dumper.DumpAllMethods(); _dumper.DumpFixupStats(); } } _dumper.End(); }
/// <summary> /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image /// </summary> /// <param name="r2r">The structure containing the info of the ReadyToRun image</param> public void Dump(ReadyToRunReader r2r) { _dumper.Begin(); bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap); if (_options.Header && standardDump) { _dumper.WriteDivider("R2R Header"); _dumper.DumpHeader(true); } bool haveQuery = false; if (_options.Section != null) { haveQuery = true; QuerySection(r2r, _options.Section); } if (_options.RuntimeFunction != null) { haveQuery = true; QueryRuntimeFunction(r2r, _options.RuntimeFunction); } if (_options.Query != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Query", _options.Query, true); } if (_options.Keyword != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false); } if (!haveQuery) { // Dump all sections and methods if no queries specified if (_options.EntryPoints) { _dumper.DumpEntryPoints(); } TargetArchitecture architecture = r2r.Machine switch { Machine.I386 => TargetArchitecture.X86, Machine.Amd64 => TargetArchitecture.X64, Machine.ArmThumb2 => TargetArchitecture.ARM, Machine.Arm64 => TargetArchitecture.ARM64, _ => throw new NotImplementedException(r2r.Machine.ToString()), }; TargetOS os = r2r.OperatingSystem switch { OperatingSystem.Windows => TargetOS.Windows, OperatingSystem.Linux => TargetOS.Linux, OperatingSystem.Apple => TargetOS.OSX, OperatingSystem.FreeBSD => TargetOS.FreeBSD, OperatingSystem.NetBSD => TargetOS.FreeBSD, _ => throw new NotImplementedException(r2r.OperatingSystem.ToString()), }; TargetDetails details = new TargetDetails(architecture, os, TargetAbi.CoreRT); if (_options.CreatePDB) { string pdbPath = _options.PdbPath; if (String.IsNullOrEmpty(pdbPath)) { pdbPath = Path.GetDirectoryName(r2r.Filename); } var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None, details); pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r)); } if (_options.CreatePerfmap) { string perfmapPath = _options.PerfmapPath; if (string.IsNullOrEmpty(perfmapPath)) { perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap"); } PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details); } if (standardDump) { _dumper.DumpAllMethods(); _dumper.DumpFixupStats(); } } _dumper.End(); }
/// <summary> /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image /// </summary> /// <param name="r2r">The structure containing the info of the ReadyToRun image</param> public void Dump(ReadyToRunReader r2r) { _dumper.Begin(); bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap); if (_options.Header && standardDump) { _dumper.WriteDivider("R2R Header"); _dumper.DumpHeader(true); } bool haveQuery = false; if (_options.Section != null) { haveQuery = true; QuerySection(r2r, _options.Section); } if (_options.RuntimeFunction != null) { haveQuery = true; QueryRuntimeFunction(r2r, _options.RuntimeFunction); } if (_options.Query != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Query", _options.Query, true); } if (_options.Keyword != null) { haveQuery = true; QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false); } if (!haveQuery) { // Dump all sections and methods if no queries specified if (_options.EntryPoints) { _dumper.DumpEntryPoints(); } if (_options.CreatePDB) { string pdbPath = _options.PdbPath; if (String.IsNullOrEmpty(pdbPath)) { pdbPath = Path.GetDirectoryName(r2r.Filename); } var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None); pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r)); } if (_options.CreatePerfmap) { string perfmapPath = _options.PerfmapPath; if (string.IsNullOrEmpty(perfmapPath)) { perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap"); } // TODO: can't seem to find any place that surfaces the ABI. This is for debugging purposes, so may not be as relevant to be correct. TargetDetails details = new TargetDetails(r2r.TargetArchitecture, r2r.TargetOperatingSystem, TargetAbi.CoreRT); PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details); } if (standardDump) { _dumper.DumpAllMethods(); _dumper.DumpFixupStats(); } } _dumper.End(); }
public void EmitPortableExecutable() { bool succeeded = false; try { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); PEHeaderBuilder headerBuilder; int? timeDateStamp; ISymbolNode r2rHeaderExportSymbol; Func <IEnumerable <Blob>, BlobContentId> peIdProvider = null; if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null) { headerBuilder = PEHeaderProvider.Create(Subsystem.Unknown, _nodeFactory.Target); peIdProvider = new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content))); timeDateStamp = null; r2rHeaderExportSymbol = _nodeFactory.Header; } else { PEReader inputPeReader = (_componentModule != null ? _componentModule.PEReader : _nodeFactory.CompilationModuleGroup.CompilationModuleSet.First().PEReader); headerBuilder = PEHeaderProvider.Create(inputPeReader.PEHeaders.PEHeader.Subsystem, _nodeFactory.Target); timeDateStamp = inputPeReader.PEHeaders.CoffHeader.TimeDateStamp; r2rHeaderExportSymbol = null; } Func <RuntimeFunctionsTableNode> getRuntimeFunctionsTable = null; if (_componentModule == null) { getRuntimeFunctionsTable = GetRuntimeFunctionsTable; } R2RPEBuilder r2rPeBuilder = new R2RPEBuilder( _nodeFactory.Target, headerBuilder, r2rHeaderExportSymbol, Path.GetFileName(_objectFilePath), getRuntimeFunctionsTable, _customPESectionAlignment, peIdProvider); NativeDebugDirectoryEntryNode nativeDebugDirectoryEntryNode = null; PerfMapDebugDirectoryEntryNode perfMapDebugDirectoryEntryNode = null; ISymbolDefinitionNode firstImportThunk = null; ISymbolDefinitionNode lastImportThunk = null; ObjectNode lastWrittenObjectNode = null; int nodeIndex = -1; foreach (var depNode in _nodes) { ++nodeIndex; ObjectNode node = depNode as ObjectNode; if (node == null) { continue; } if (node.ShouldSkipEmittingObjectNode(_nodeFactory)) { continue; } ObjectData nodeContents = node.GetData(_nodeFactory); if (node is NativeDebugDirectoryEntryNode nddeNode) { // There should be only one NativeDebugDirectoryEntry. Debug.Assert(nativeDebugDirectoryEntryNode == null); nativeDebugDirectoryEntryNode = nddeNode; } if (node is PerfMapDebugDirectoryEntryNode pmdeNode) { // There should be only one PerfMapDebugDirectoryEntryNode. Debug.Assert(perfMapDebugDirectoryEntryNode is null); perfMapDebugDirectoryEntryNode = pmdeNode; } if (node is ImportThunk importThunkNode) { Debug.Assert(firstImportThunk == null || lastWrittenObjectNode is ImportThunk, "All the import thunks must be in single contiguous run"); if (firstImportThunk == null) { firstImportThunk = importThunkNode; } lastImportThunk = importThunkNode; } string name = null; if (_mapFileBuilder != null) { name = depNode.GetType().ToString(); int firstGeneric = name.IndexOf('['); if (firstGeneric < 0) { firstGeneric = name.Length; } int lastDot = name.LastIndexOf('.', firstGeneric - 1, firstGeneric); if (lastDot > 0) { name = name.Substring(lastDot + 1); } } EmitObjectData(r2rPeBuilder, nodeContents, nodeIndex, name, node.Section); lastWrittenObjectNode = node; if (_outputInfoBuilder != null && node is MethodWithGCInfo methodNode) { _outputInfoBuilder.AddMethod(methodNode, nodeContents.DefinedSymbols[0]); } } r2rPeBuilder.SetCorHeader(_nodeFactory.CopiedCorHeaderNode, _nodeFactory.CopiedCorHeaderNode.Size); r2rPeBuilder.SetDebugDirectory(_nodeFactory.DebugDirectoryNode, _nodeFactory.DebugDirectoryNode.Size); if (firstImportThunk != null) { r2rPeBuilder.AddSymbolForRange(_nodeFactory.DelayLoadMethodCallThunks, firstImportThunk, lastImportThunk); } if (_nodeFactory.Win32ResourcesNode != null) { Debug.Assert(_nodeFactory.Win32ResourcesNode.Size != 0); r2rPeBuilder.SetWin32Resources(_nodeFactory.Win32ResourcesNode, _nodeFactory.Win32ResourcesNode.Size); } if (_outputInfoBuilder != null) { foreach (string inputFile in _inputFiles) { _outputInfoBuilder.AddInputModule(_nodeFactory.TypeSystemContext.GetModuleFromPath(inputFile)); } } using (var peStream = File.Create(_objectFilePath)) { r2rPeBuilder.Write(peStream, timeDateStamp); if (_mapFileBuilder != null) { _mapFileBuilder.SetFileSize(peStream.Length); } if (nativeDebugDirectoryEntryNode is not null) { Debug.Assert(_generatePdbFile); // Compute MD5 hash of the output image and store that in the native DebugDirectory entry using (var md5Hash = MD5.Create()) { peStream.Seek(0, SeekOrigin.Begin); byte[] hash = md5Hash.ComputeHash(peStream); byte[] rsdsEntry = nativeDebugDirectoryEntryNode.GenerateRSDSEntryData(hash); int offsetToUpdate = r2rPeBuilder.GetSymbolFilePosition(nativeDebugDirectoryEntryNode); peStream.Seek(offsetToUpdate, SeekOrigin.Begin); peStream.Write(rsdsEntry); } } if (perfMapDebugDirectoryEntryNode is not null) { Debug.Assert(_generatePerfMapFile && _outputInfoBuilder is not null && _outputInfoBuilder.EnumerateInputAssemblies().Any()); byte[] perfmapSig = PerfMapWriter.PerfMapV1SignatureHelper(_outputInfoBuilder.EnumerateInputAssemblies(), _nodeFactory.Target); byte[] perfMapEntry = perfMapDebugDirectoryEntryNode.GeneratePerfMapEntryData(perfmapSig, _perfMapFormatVersion); int offsetToUpdate = r2rPeBuilder.GetSymbolFilePosition(perfMapDebugDirectoryEntryNode); peStream.Seek(offsetToUpdate, SeekOrigin.Begin); peStream.Write(perfMapEntry); } } if (_outputInfoBuilder != null) { r2rPeBuilder.AddSections(_outputInfoBuilder); if (_generateMapFile) { string mapFileName = Path.ChangeExtension(_objectFilePath, ".map"); _mapFileBuilder.SaveMap(mapFileName); } if (_generateMapCsvFile) { string nodeStatsCsvFileName = Path.ChangeExtension(_objectFilePath, ".nodestats.csv"); string mapCsvFileName = Path.ChangeExtension(_objectFilePath, ".map.csv"); _mapFileBuilder.SaveCsv(nodeStatsCsvFileName, mapCsvFileName); } if (_generatePdbFile) { string path = _pdbPath; if (string.IsNullOrEmpty(path)) { path = Path.GetDirectoryName(_objectFilePath); } _symbolFileBuilder.SavePdb(path, _objectFilePath); } if (_generatePerfMapFile) { string path = _perfMapPath; if (string.IsNullOrEmpty(path)) { path = Path.GetDirectoryName(_objectFilePath); } _symbolFileBuilder.SavePerfMap(path, _perfMapFormatVersion, _objectFilePath); } if (_profileFileBuilder != null) { string path = Path.ChangeExtension(_objectFilePath, ".profile"); _profileFileBuilder.SaveProfile(path); } } succeeded = true; } finally { if (!succeeded) { // If there was an exception while generating the OBJ file, make sure we don't leave the unfinished // object file around. try { File.Delete(_objectFilePath); } catch { } } } }