// internal for testing internal static byte[] SerializeCustomDebugMetadata(ArrayBuilder <BlobBuilder> recordWriters) { if (recordWriters.Count == 0) { return(null); } BlobBuilder cmw = BlobBuilder.GetInstance(); cmw.WriteByte(CDI.CdiVersion); cmw.WriteByte((byte)recordWriters.Count); // count cmw.Align(4); foreach (BlobBuilder recordWriter in recordWriters) { recordWriter.WriteTo(cmw); } var result = cmw.ToArray(); cmw.Free(); return(result); }
private void WriteDebugTable(Stream peStream, SectionHeader textSection, ContentId nativePdbContentId, ContentId portablePdbContentId, MetadataSizes metadataSizes) { Debug.Assert(nativePdbContentId.IsDefault ^ portablePdbContentId.IsDefault); var writer = new BlobBuilder(); // characteristics: writer.WriteUInt32(0); // PDB stamp & version if (portablePdbContentId.IsDefault) { writer.WriteBytes(nativePdbContentId.Stamp); writer.WriteUInt32(0); } else { writer.WriteBytes(portablePdbContentId.Stamp); writer.WriteUInt32('P' << 24 | 'M' << 16 | 0x00 << 8 | 0x01); } // type: const int ImageDebugTypeCodeView = 2; writer.WriteUInt32(ImageDebugTypeCodeView); // size of data: writer.WriteUInt32((uint)ComputeSizeOfDebugDirectoryData()); uint dataOffset = (uint)ComputeOffsetToDebugTable(metadataSizes) + ImageDebugDirectoryBaseSize; // PointerToRawData (RVA of the data): writer.WriteUInt32((uint)textSection.RelativeVirtualAddress + dataOffset); // AddressOfRawData (position of the data in the PE stream): writer.WriteUInt32((uint)textSection.PointerToRawData + dataOffset); writer.WriteByte((byte)'R'); writer.WriteByte((byte)'S'); writer.WriteByte((byte)'D'); writer.WriteByte((byte)'S'); // PDB id: writer.WriteBytes(nativePdbContentId.Guid ?? portablePdbContentId.Guid); // age writer.WriteUInt32(PdbWriter.Age); // UTF-8 encoded zero-terminated path to PDB writer.WriteUTF8(_pdbPathOpt); writer.WriteByte(0); writer.WriteTo(peStream); writer.Free(); }