Ejemplo n.º 1
0
        public unsafe void GetDebugDirectoryGuidAndStampAndAge(out Guid guid, out uint stamp, out uint age)
        {
            // See symwrite.cpp - the data byte[] doesn't depend on the content of metadata tables or IL.
            // The writer only sets two values of the ImageDebugDirectory struct.
            //
            //   IMAGE_DEBUG_DIRECTORY *pIDD
            //
            //   if ( pIDD == NULL ) return E_INVALIDARG;
            //   memset( pIDD, 0, sizeof( *pIDD ) );
            //   pIDD->Type = IMAGE_DEBUG_TYPE_CODEVIEW;
            //   pIDD->SizeOfData = cTheData;

            ImageDebugDirectory debugDir = new ImageDebugDirectory();
            uint dataLength;

            try
            {
                _symWriter.GetDebugInfo(ref debugDir, 0, out dataLength, IntPtr.Zero);
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }

            byte[] data = new byte[dataLength];
            fixed(byte *pb = data)
            {
                try
                {
                    _symWriter.GetDebugInfo(ref debugDir, dataLength, out dataLength, (IntPtr)pb);
                }
                catch (Exception ex)
                {
                    throw new PdbWritingException(ex);
                }
            }

            // Data has the following structure:
            // struct RSDSI
            // {
            //     DWORD dwSig;                 // "RSDS"
            //     GUID guidSig;                // GUID
            //     DWORD age;                   // age
            //     char szPDB[0];               // zero-terminated UTF8 file name passed to the writer
            // };
            const int GuidSize = 16;

            byte[] guidBytes = new byte[GuidSize];
            Buffer.BlockCopy(data, 4, guidBytes, 0, guidBytes.Length);

            guid = new Guid(guidBytes);

            // Retrieve the timestamp the PDB writer generates when creating a new PDB stream.
            // Note that ImageDebugDirectory.TimeDateStamp is not set by GetDebugInfo,
            // we need to go thru IPdbWriter interface to get it.
            ((IPdbWriter)_symWriter).GetSignatureAge(out stamp, out age);
        }
Ejemplo n.º 2
0
        public byte[] GetDebugInfo(ref IMAGE_DEBUG_DIRECTORY idd)
        {
            InitWriter();
            uint cData;

            symUnmanagedWriter.GetDebugInfo(ref idd, 0, out cData, null);
            byte[] buf = new byte[cData];
            symUnmanagedWriter.GetDebugInfo(ref idd, (uint)buf.Length, out cData, buf);
            return(buf);
        }
Ejemplo n.º 3
0
        public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY pIDD)
        {
            uint size;

            writer.GetDebugInfo(out pIDD, 0, out size, null);
            var buffer = new byte[size];

            writer.GetDebugInfo(out pIDD, size, out size, buffer);
            return(buffer);
        }
Ejemplo n.º 4
0
        public byte[] GetDebugInfo()
        {
            int length;
            ImageDebugDirectory idd;

            writer.GetDebugInfo(out idd, 0, out length, null);
            byte[] info = new byte[length];
            writer.GetDebugInfo(out idd, length, out length, info);
            return(info);
        }
Ejemplo n.º 5
0
        public byte[] GetDebugInfo(out ImageDebugDirectory idd)
        {
            int size;

            // get size of debug info
            m_writer.GetDebugInfo(out idd, 0, out size, null);

            byte[] debug_info = new byte[size];
            m_writer.GetDebugInfo(out idd, size, out size, debug_info);

            return(debug_info);
        }
Ejemplo n.º 6
0
        public unsafe PeDebugDirectory GetDebugDirectory()
        {
            ImageDebugDirectory debugDir = new ImageDebugDirectory();
            uint dataCount = 0;

            try
            {
                _symWriter.GetDebugInfo(ref debugDir, 0, out dataCount, IntPtr.Zero);
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }

            // See symwrite.cpp - the data don't depend on the content of metadata tables or IL
            //
            // struct RSDSI
            // {
            //     DWORD dwSig;                 // "RSDS"
            //     GUID guidSig;
            //     DWORD age;
            //     char szPDB[0];               // zero-terminated UTF8 file name
            // };
            //
            byte[] data = new byte[dataCount];

            fixed(byte *pb = data)
            {
                try
                {
                    _symWriter.GetDebugInfo(ref debugDir, dataCount, out dataCount, (IntPtr)pb);
                }
                catch (Exception ex)
                {
                    throw new PdbWritingException(ex);
                }
            }

            PeDebugDirectory result = new PeDebugDirectory();

            result.AddressOfRawData = (uint)debugDir.AddressOfRawData;
            result.Characteristics  = (uint)debugDir.Characteristics;
            result.Data             = data;
            result.MajorVersion     = (ushort)debugDir.MajorVersion;
            result.MinorVersion     = (ushort)debugDir.MinorVersion;
            result.PointerToRawData = (uint)debugDir.PointerToRawData;
            result.SizeOfData       = (uint)debugDir.SizeOfData;
            result.TimeDateStamp    = (uint)debugDir.TimeDateStamp;
            result.Type             = (uint)debugDir.Type;

            return(result);
        }
        public override unsafe bool GetDebugInfo(ChecksumAlgorithm pdbChecksumAlgorithm, ref uint pdbAge, out Guid guid, out uint stamp, out IMAGE_DEBUG_DIRECTORY pIDD, out byte[] codeViewData)
        {
            pIDD         = default;
            codeViewData = null;

            if (isDeterministic)
            {
                ((ISymUnmanagedWriter3)writer).Commit();
                var oldPos = pdbStream.Position;
                pdbStream.Position = 0;
                var checksumBytes = Hasher.Hash(pdbChecksumAlgorithm, pdbStream, pdbStream.Length);
                pdbStream.Position = oldPos;
                if (writer is ISymUnmanagedWriter8 writer8)
                {
                    RoslynContentIdProvider.GetContentId(checksumBytes, out guid, out stamp);
                    writer8.UpdateSignature(guid, stamp, pdbAge);
                    return(true);
                }
                else if (writer is ISymUnmanagedWriter7 writer7)
                {
                    fixed(byte *p = checksumBytes)
                    writer7.UpdateSignatureByHashingContent(new IntPtr(p), (uint)checksumBytes.Length);
                }
            }

            writer.GetDebugInfo(out pIDD, 0, out uint size, null);
            codeViewData = new byte[size];
            writer.GetDebugInfo(out pIDD, size, out size, codeViewData);

            if (writer is IPdbWriter comPdbWriter)
            {
                var guidBytes = new byte[16];
                Array.Copy(codeViewData, 4, guidBytes, 0, 16);
                guid = new Guid(guidBytes);
                comPdbWriter.GetSignatureAge(out stamp, out uint age);
                Debug.Assert(age == pdbAge);
                pdbAge = age;
                return(true);
            }

            Debug.Fail($"COM PDB writer doesn't impl {nameof(IPdbWriter)}");
            guid  = default;
            stamp = 0;
            return(false);
        }
Ejemplo n.º 8
0
        public unsafe ContentId GetContentId()
        {
            if (_deterministic)
            {
                // Call to GetDebugInfo fails for SymWriter initialized using InitializeDeterministic.
                // We already have all the info we need though.

                // TODO (https://github.com/dotnet/roslyn/issues/926): calculate sha1 hash
                var id = new ContentId(
                    new byte[] { 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, },
                    new byte[] { 0x12, 0x12, 0x12, 0x12 });

                try
                {
                    Debug.Assert(BitConverter.IsLittleEndian);
                    ((ISymUnmanagedWriter6)_symWriter).SetSignature(BitConverter.ToUInt32(id.Stamp, 0), new Guid(id.Guid));
                }
                catch (Exception ex)
                {
                    throw new PdbWritingException(ex);
                }

                return(id);
            }

            // See symwrite.cpp - the data byte[] doesn't depend on the content of metadata tables or IL.
            // The writer only sets two values of the ImageDebugDirectory struct.
            //
            //   IMAGE_DEBUG_DIRECTORY *pIDD
            //
            //   if ( pIDD == NULL ) return E_INVALIDARG;
            //   memset( pIDD, 0, sizeof( *pIDD ) );
            //   pIDD->Type = IMAGE_DEBUG_TYPE_CODEVIEW;
            //   pIDD->SizeOfData = cTheData;

            ImageDebugDirectory debugDir = new ImageDebugDirectory();
            uint dataLength;

            try
            {
                _symWriter.GetDebugInfo(ref debugDir, 0, out dataLength, IntPtr.Zero);
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }

            byte[] data = new byte[dataLength];
            fixed(byte *pb = data)
            {
                try
                {
                    _symWriter.GetDebugInfo(ref debugDir, dataLength, out dataLength, (IntPtr)pb);
                }
                catch (Exception ex)
                {
                    throw new PdbWritingException(ex);
                }
            }

            // Data has the following structure:
            // struct RSDSI
            // {
            //     DWORD dwSig;                 // "RSDS"
            //     GUID guidSig;                // GUID
            //     DWORD age;                   // age
            //     char szPDB[0];               // zero-terminated UTF8 file name passed to the writer
            // };
            const int GuidSize = 16;

            byte[] guidBytes = new byte[GuidSize];
            Buffer.BlockCopy(data, 4, guidBytes, 0, guidBytes.Length);

            // Retrieve the timestamp the PDB writer generates when creating a new PDB stream.
            // Note that ImageDebugDirectory.TimeDateStamp is not set by GetDebugInfo,
            // we need to go thru IPdbWriter interface to get it.
            uint stamp;
            uint age;

            ((IPdbWriter)_symWriter).GetSignatureAge(out stamp, out age);
            Debug.Assert(age == Age);

            Debug.Assert(BitConverter.IsLittleEndian);
            return(new ContentId(guidBytes, BitConverter.GetBytes(stamp)));
        }