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); }
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); }
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); }
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); }
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); }
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); }
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))); }