Пример #1
0
        private void WritePDBDataHelper(string dllPath, IEnumerable <MethodInfo> methods)
        {
            // This will try to open the managed PDB if lines info was requested.  This is a
            // likely failure point, so intentionally do this before creating the NGEN PDB file
            // on disk.
            bool isILPDBProvided = false;

            if (_pdbExtraData.HasFlag(PDBExtraData.kPDBLines))
            {
                // line mapping not ported from crossgen yet.
                throw new NotImplementedException();
            }

            string originalDllPath = dllPath;

            // Currently DiaSymReader does not work properly generating NGEN PDBS unless
            // the DLL whose PDB is being generated ends in .ni.*.   Unfortunately, readyToRun
            // images do not follow this convention and end up producing bad PDBS.  To fix
            // this (without changing diasymreader.dll which ships indepdendently of .NET Core)
            // we copy the file to somethign with this convention before generating the PDB
            // and delete it when we are done.
            if (!dllPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase) && !dllPath.EndsWith(".ni.exe", StringComparison.OrdinalIgnoreCase))
            {
                _tempSourceDllName = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".ni" + Path.GetExtension(dllPath));
                File.Copy(dllPath, _tempSourceDllName);
                dllPath = _tempSourceDllName;
            }

            _ngenWriter = CreateNGenWriter(dllPath, _pdbPath + "\\");

            {
                // PDB file is now created.  Get its path and initialize _pdbFilePath so the PDB file
                // can be deleted if we don't make it successfully to the end
                StringBuilder pdbFilePathBuilder = new StringBuilder();
                pdbFilePathBuilder.Capacity = 1024;
                _ngenWriter.QueryPDBNameExW(pdbFilePathBuilder, new IntPtr(pdbFilePathBuilder.Capacity));
                _pdbFilePath = pdbFilePathBuilder.ToString();
            }

            _ngenWriter.OpenModW(originalDllPath, Path.GetFileName(originalDllPath), out _pdbMod);

            WriteStringTable();
            WriteFileChecksums();

            ushort?iCodeSection     = null;
            uint   rvaOfTextSection = 0;

            using (var peReader = new PEReader(new FileStream(dllPath, FileMode.Open), PEStreamOptions.Default))
            {
                var sections = peReader.PEHeaders.SectionHeaders;

                for (int i = 0; i < sections.Length; i++)
                {
                    ushort pdbSectionNumber = checked ((ushort)(i + 1));

                    _ngenWriter.AddSection(pdbSectionNumber, OMF.StandardText, 0, sections[i].SizeOfRawData);
                    if (sections[i].Name == ".text")
                    {
                        iCodeSection     = pdbSectionNumber;
                        rvaOfTextSection = (uint)sections[i].VirtualAddress;
                    }
                    _ngenWriter.ModAddSecContribEx(_pdbMod, pdbSectionNumber, 0, sections[i].SizeOfRawData, (uint)sections[i].SectionCharacteristics, 0, 0);
                }
            }

            // To support lines info, we need a "dummy" section, indexed as 0, for use as a
            // sentinel when MSPDB sets up its section contribution table
            _ngenWriter.AddSection(0,           // Dummy section 0
                                   OMF.SentinelType,
                                   0,
                                   unchecked ((int)0xFFFFFFFF));

            foreach (var method in methods)
            {
                WriteMethodPDBData(iCodeSection.Value, method, Path.GetFileNameWithoutExtension(originalDllPath), rvaOfTextSection, isILPDBProvided);
            }
        }
Пример #2
0
 private extern static void CreateNGenPdbWriter(
     [MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath,
     [MarshalAs(UnmanagedType.LPWStr)] string pdbPath,
     [MarshalAs(UnmanagedType.Interface)] out ISymNGenWriter2 ngenPdbWriter);