Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
        }
Beispiel #5
0
        /// <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();
        }
Beispiel #6
0
        /// <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
                    {
                    }
                }
            }
        }