public void AddReproducibleEntry() { var b = new DebugDirectoryBuilder(); b.AddReproducibleEntry(); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); var bytes = blob.ToArray(); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x00, 0x00, 0x00, 0x00, // Version 0x10, 0x00, 0x00, 0x00, // Type 0x00, 0x00, 0x00, 0x00, // SizeOfData 0x00, 0x00, 0x00, 0x00, // AddressOfRawData 0x00, 0x00, 0x00, 0x00, // PointerToRawData }, bytes); using (var pinned = new PinnedBlob(bytes)) { var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size)); Assert.Equal(1, actual.Length); Assert.Equal(0u, actual[0].Stamp); Assert.Equal(0, actual[0].MajorVersion); Assert.Equal(0, actual[0].MinorVersion); Assert.Equal(DebugDirectoryEntryType.Reproducible, actual[0].Type); Assert.Equal(0, actual[0].DataSize); Assert.Equal(0, actual[0].DataRelativeVirtualAddress); Assert.Equal(0, actual[0].DataPointer); } }
public void TryOpenAssociatedPortablePdb_WindowsSpecificPath() { var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"C:def.xyz", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { string pathQueried = null; Func <string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; return(null); }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Equal(Path.Combine("pedir", "def.xyz"), pathQueried); } }
public void TryOpenAssociatedPortablePdb_ExpectedExceptionFromStreamProvider_NoFallback() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { MetadataReaderProvider pdbProvider; string pdbPath; Assert.Throws <IOException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new IOException(); }, out pdbProvider, out pdbPath)); AssertEx.Throws <BadImageFormatException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new BadImageFormatException("Bang!"); }, out pdbProvider, out pdbPath), e => Assert.Equal("Bang!", e.Message)); // file doesn't exist and no embedded => return false Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new FileNotFoundException(); }, out pdbProvider, out pdbPath)); } }
public void TryOpenAssociatedPortablePdb_BadStreamProvider() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { MetadataReaderProvider pdbProvider; string pdbPath; // pass-thru: AssertExtensions.Throws <ArgumentException>(null, () => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new ArgumentException(); }, out pdbProvider, out pdbPath)); Assert.Throws <InvalidOperationException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return(new TestStream(canRead: false, canWrite: true, canSeek: true)); }, out pdbProvider, out pdbPath)); Assert.Throws <InvalidOperationException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return(new TestStream(canRead: true, canWrite: true, canSeek: false)); }, out pdbProvider, out pdbPath)); } }
public void TryOpenAssociatedPortablePdb_DuplicateEntries_CodeView() { var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0); ddBuilder.AddReproducibleEntry(); ddBuilder.AddCodeViewEntry(@"/a/b/c.pdb", id, portablePdbVersion: 0x0100, age: 0x1234); ddBuilder.AddCodeViewEntry(@"/a/b/d.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { string pathQueried = null; Func <string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; return(null); }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Equal(PathUtilities.CombinePathWithRelativePath("pedir", "c.pdb"), pathQueried); } }
public void TryOpenAssociatedPortablePdb_ExpectedExceptionFromStreamProvider_FallbackOnEmbedded_Valid() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); ddBuilder.AddEmbeddedPortablePdbEntry(pdbBuilder, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { MetadataReaderProvider pdbProvider; string pdbPath; Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new IOException(); }, out pdbProvider, out pdbPath)); Assert.Null(pdbPath); Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count); Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new BadImageFormatException(); }, out pdbProvider, out pdbPath)); Assert.Null(pdbPath); Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count); Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new FileNotFoundException(); }, out pdbProvider, out pdbPath)); Assert.Null(pdbPath); Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count); } }
public ExtendedPEBuilder( PEHeaderBuilder header, MetadataRootBuilder metadataRootBuilder, BlobBuilder ilStream, BlobBuilder mappedFieldData, BlobBuilder managedResources, ResourceSectionBuilder nativeResources, DebugDirectoryBuilder debugDirectoryBuilder, int strongNameSignatureSize, MethodDefinitionHandle entryPoint, CorFlags flags, Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider, bool withMvidSection ) : base( header, metadataRootBuilder, ilStream, mappedFieldData, managedResources, nativeResources, debugDirectoryBuilder, strongNameSignatureSize, entryPoint, flags, deterministicIdProvider ) { _withMvidSection = withMvidSection; }
public void MultipleEntries() { var b = new DebugDirectoryBuilder(); var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678); b.AddReproducibleEntry(); b.AddCodeViewEntry("x", id, 0); b.AddReproducibleEntry(); b.AddCodeViewEntry("y", id, 0xABCD); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x00, 0x00, 0x00, 0x00, // Version 0x10, 0x00, 0x00, 0x00, // Type 0x00, 0x00, 0x00, 0x00, // SizeOfData 0x00, 0x00, 0x00, 0x00, // AddressOfRawData 0x00, 0x00, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0x78, 0x56, 0x34, 0x12, // Stamp 0x00, 0x00, 0x00, 0x00, // Version 0x02, 0x00, 0x00, 0x00, // Type 0x1A, 0x00, 0x00, 0x00, // SizeOfData 0xC0, 0x10, 0x00, 0x00, // AddressOfRawData 0xC0, 0x20, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x00, 0x00, 0x00, 0x00, // Version 0x10, 0x00, 0x00, 0x00, // Type 0x00, 0x00, 0x00, 0x00, // SizeOfData 0x00, 0x00, 0x00, 0x00, // AddressOfRawData 0x00, 0x00, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0x78, 0x56, 0x34, 0x12, // Stamp 0xCD, 0xAB, 0x4D, 0x50, // Version 0x02, 0x00, 0x00, 0x00, // Type 0x1A, 0x00, 0x00, 0x00, // SizeOfData 0xDA, 0x10, 0x00, 0x00, // AddressOfRawData 0xDA, 0x20, 0x00, 0x00, // PointerToRawData // data (byte)'R', (byte)'S', (byte)'D', (byte)'S', 0x6E, 0xE6, 0x88, 0x3C, 0xB9, 0xE0, 0x08, 0x45, 0x92, 0x90, 0x11, 0xE0, 0xDB, 0x51, 0xA1, 0xC5, // GUID 0x01, 0x00, 0x00, 0x00, // age (byte)'x', 0x00, // path // data (byte)'R', (byte)'S', (byte)'D', (byte)'S', 0x6E, 0xE6, 0x88, 0x3C, 0xB9, 0xE0, 0x08, 0x45, 0x92, 0x90, 0x11, 0xE0, 0xDB, 0x51, 0xA1, 0xC5, // GUID 0x01, 0x00, 0x00, 0x00, // age (byte)'y', 0x00, // path }, blob.ToArray()); }
public void Hello() { var metadata = new MetadataBuilder(0, 0, 0, 0); var location = Assembly.GetExecutingAssembly().Location; var pdbPath = Path.ChangeExtension(location, "pdb"); using (var fileStream = new FileStream(pdbPath, FileMode.Open)) { var readerProvider = MetadataReaderProvider.FromPortablePdbStream(fileStream, MetadataStreamOptions.Default); var reader = readerProvider.GetMetadataReader(MetadataReaderOptions.ApplyWindowsRuntimeProjections, null); var debugDir = new DebugDirectoryBuilder(); debugDir.AddEmbeddedPortablePdbEntry(null, 0); var blob = new BlobBuilder(); var methodHandle = new MethodDefinitionHandle(); var pdb = new PortablePdbBuilder(metadata, ImmutableArray <int> .Empty, methodHandle, null); var blobContentId = pdb.Serialize(blob); blob.ToArray(); } }
public static void AddPdbChecksumEntry(this DebugDirectoryBuilder builder, string algorithmName, ImmutableArray <byte> checksum) { InitializeReflection(); int dataSize = WritePdbChecksumData((BlobBuilder)s_dataBuilderField.GetValue(builder), algorithmName, checksum); s_addEntry(builder, PdbChecksumEntryType, 0x00000001, 0x00000000, dataSize); }
public void AddCodeViewEntry2() { var b = new DebugDirectoryBuilder(); var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678); b.AddCodeViewEntry("foo.pdb" + new string('\0', 260 - "foo.pdb".Length - 1), id, 0xABCD, 0x99); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); var bytes = blob.ToArray(); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x78, 0x56, 0x34, 0x12, // Stamp 0xCD, 0xAB, 0x4D, 0x50, // Version 0x02, 0x00, 0x00, 0x00, // Type 0x1C, 0x01, 0x00, 0x00, // SizeOfData 0x6C, 0x10, 0x00, 0x00, // AddressOfRawData 0x6C, 0x20, 0x00, 0x00, // PointerToRawData // data (byte)'R', (byte)'S', (byte)'D', (byte)'S', 0x6E, 0xE6, 0x88, 0x3C, 0xB9, 0xE0, 0x08, 0x45, 0x92, 0x90, 0x11, 0xE0, 0xDB, 0x51, 0xA1, 0xC5, // GUID 0x99, 0x00, 0x00, 0x00, // age (byte)'f', (byte)'o', (byte)'o', (byte)'.', (byte)'p', (byte)'d', (byte)'b', 0x00, // path // path padding: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, bytes); using (var pinned = new PinnedBlob(bytes)) { var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size)); Assert.Equal(1, actual.Length); Assert.Equal(id.Stamp, actual[0].Stamp); Assert.Equal(0xABCD, actual[0].MajorVersion); Assert.Equal(0x504d, actual[0].MinorVersion); Assert.Equal(DebugDirectoryEntryType.CodeView, actual[0].Type); Assert.True(actual[0].IsPortableCodeView); Assert.Equal(0x0000011c, actual[0].DataSize); Assert.Equal(0x0000106c, actual[0].DataRelativeVirtualAddress); Assert.Equal(0x0000206c, actual[0].DataPointer); } }
public AssemblyGenerator(Assembly assembly) { _debugDirectoryBuilder = new DebugDirectoryBuilder(); _peStream = new MemoryStream(); _ilBuilder = new BlobBuilder(); _metadataBuilder = new MetadataBuilder(); _currentAssembly = assembly; }
public void Empty() { var b = new DebugDirectoryBuilder(); var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); AssertEx.Equal(new byte[0], blob.ToArray()); }
public void AddPdbChecksumEntry_Args() { var builder = new DebugDirectoryBuilder(); AssertExtensions.Throws <ArgumentNullException>("algorithmName", () => builder.AddPdbChecksumEntry(null, ImmutableArray.Create((byte)1))); AssertExtensions.Throws <ArgumentException>("algorithmName", () => builder.AddPdbChecksumEntry("", ImmutableArray.Create((byte)1))); AssertExtensions.Throws <ArgumentNullException>("checksum", () => builder.AddPdbChecksumEntry("XXX", default)); AssertExtensions.Throws <ArgumentException>("checksum", () => builder.AddPdbChecksumEntry("XXX", ImmutableArray <byte> .Empty)); }
public void AddCodeViewEntry2() { var b = new DebugDirectoryBuilder(); var id = new BlobContentId(new Guid("3C88E66E-E0B9-4508-9290-11E0DB51A1C5"), 0x12345678); b.AddCodeViewEntry("foo.pdb" + new string('\0', 260 - "foo.pdb".Length - 1), id, 0xABCD); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); var bytes = blob.ToArray(); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x78, 0x56, 0x34, 0x12, // Stamp 0xCD, 0xAB, 0x4D, 0x50, // Version 0x02, 0x00, 0x00, 0x00, // Type 0x1C, 0x01, 0x00, 0x00, // SizeOfData 0x6C, 0x10, 0x00, 0x00, // AddressOfRawData 0x6C, 0x20, 0x00, 0x00, // PointerToRawData // data (byte)'R', (byte)'S', (byte)'D', (byte)'S', 0x6E, 0xE6, 0x88, 0x3C, 0xB9, 0xE0, 0x08, 0x45, 0x92, 0x90, 0x11, 0xE0, 0xDB, 0x51, 0xA1, 0xC5, // GUID 0x01, 0x00, 0x00, 0x00, // age (byte)'f', (byte)'o', (byte)'o', (byte)'.', (byte)'p', (byte)'d', (byte)'b', 0x00, // path // path padding: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, bytes); using (var pinned = new PinnedBlob(bytes)) { var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size)); Assert.Equal(1, actual.Length); Assert.Equal(id.Stamp, actual[0].Stamp); Assert.Equal(0xABCD, actual[0].MajorVersion); Assert.Equal(0x504d, actual[0].MinorVersion); Assert.Equal(DebugDirectoryEntryType.CodeView, actual[0].Type); Assert.Equal(0x0000011c, actual[0].DataSize); Assert.Equal(0x0000106c, actual[0].DataRelativeVirtualAddress); Assert.Equal(0x0000206c, actual[0].DataPointer); } }
public void AddEmbeddedPortablePdbEntry_Args() { var bb = new BlobBuilder(); var builder = new DebugDirectoryBuilder(); Assert.Throws<ArgumentNullException>(() => builder.AddEmbeddedPortablePdbEntry(null, 0x0100)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x0000)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x00ff)); builder.AddEmbeddedPortablePdbEntry(bb, 0x0100); builder.AddEmbeddedPortablePdbEntry(bb, 0xffff); }
public void AddEmbeddedPortablePdbEntry_Args() { var bb = new BlobBuilder(); var builder = new DebugDirectoryBuilder(); Assert.Throws <ArgumentNullException>(() => builder.AddEmbeddedPortablePdbEntry(null, 0x0100)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x0000)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddEmbeddedPortablePdbEntry(bb, 0x00ff)); builder.AddEmbeddedPortablePdbEntry(bb, 0x0100); builder.AddEmbeddedPortablePdbEntry(bb, 0xffff); }
public void EmbeddedPortablePdb() { var b = new DebugDirectoryBuilder(); var pdb = new BlobBuilder(); pdb.WriteInt64(0x1122334455667788); b.AddEmbeddedPortablePdbEntry(pdb, portablePdbVersion: 0x0100); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0, 0), sectionOffset: 0); var bytes = blob.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x00, 0x01, 0x00, 0x01, // Version 0x11, 0x00, 0x00, 0x00, // Type 0x12, 0x00, 0x00, 0x00, // SizeOfData 0x1C, 0x00, 0x00, 0x00, // AddressOfRawData 0x1C, 0x00, 0x00, 0x00, // PointerToRawData 0x4D, 0x50, 0x44, 0x42, // signature 0x08, 0x00, 0x00, 0x00, // uncompressed size 0xEB, 0x28, 0x4F, 0x0B, 0x75, 0x31, 0x56, 0x12, 0x04, 0x00 // compressed data }, bytes); using (var pinned = new PinnedBlob(bytes)) { var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size)); Assert.Equal(1, actual.Length); Assert.Equal(0u, actual[0].Stamp); Assert.Equal(0x0100, actual[0].MajorVersion); Assert.Equal(0x0100, actual[0].MinorVersion); Assert.Equal(DebugDirectoryEntryType.EmbeddedPortablePdb, actual[0].Type); Assert.False(actual[0].IsPortableCodeView); Assert.Equal(0x00000012, actual[0].DataSize); Assert.Equal(0x0000001c, actual[0].DataRelativeVirtualAddress); Assert.Equal(0x0000001c, actual[0].DataPointer); var provider = new ByteArrayMemoryProvider(bytes); using (var block = provider.GetMemoryBlock(actual[0].DataPointer, actual[0].DataSize)) { var decoded = PEReader.DecodeEmbeddedPortablePdbDebugDirectoryData(block); AssertEx.Equal(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, decoded); } } }
public void AddPdbChecksumEntry() { var b = new DebugDirectoryBuilder(); b.AddPdbChecksumEntry("A", ImmutableArray.Create(new byte[] { 0x01 })); b.AddPdbChecksumEntry("B", ImmutableArray.Create(new byte[] { 0x02, 0x03 })); b.AddPdbChecksumEntry("XYZ", ImmutableArray.Create(new byte[] { 0x04, 0x05, 0x06 })); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x01, 0x00, 0x00, 0x00, // Version 0x13, 0x00, 0x00, 0x00, // Type 0x03, 0x00, 0x00, 0x00, // SizeOfData 0xA4, 0x10, 0x00, 0x00, // AddressOfRawData 0xA4, 0x20, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x01, 0x00, 0x00, 0x00, // Version 0x13, 0x00, 0x00, 0x00, // Type 0x04, 0x00, 0x00, 0x00, // SizeOfData 0xA7, 0x10, 0x00, 0x00, // AddressOfRawData 0xA7, 0x20, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x01, 0x00, 0x00, 0x00, // Version 0x13, 0x00, 0x00, 0x00, // Type 0x07, 0x00, 0x00, 0x00, // SizeOfData 0xAB, 0x10, 0x00, 0x00, // AddressOfRawData 0xAB, 0x20, 0x00, 0x00, // PointerToRawData // data (byte)'A', 0x00, 0x01, // data (byte)'B', 0x00, 0x02, 0x03, // data (byte)'X', (byte)'Y', (byte)'Z', 0x00, 0x04, 0x05, 0x06, }, blob.ToArray()); }
public void AddCodeViewEntry_Args() { var builder = new DebugDirectoryBuilder(); Assert.Throws<ArgumentException>(() => builder.AddCodeViewEntry("", default(BlobContentId), 0x0100)); Assert.Throws<ArgumentException>(() => builder.AddCodeViewEntry("\0", default(BlobContentId), 0x0100)); Assert.Throws<ArgumentException>(() => builder.AddCodeViewEntry("\0xx", default(BlobContentId), 0x0100)); builder.AddCodeViewEntry("foo\0", default(BlobContentId), 0x0100); Assert.Throws<ArgumentNullException>(() => builder.AddCodeViewEntry(null, default(BlobContentId), 0x0100)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0); Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0001)); Assert.Throws<ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x00ff)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0100); builder.AddCodeViewEntry("foo", default(BlobContentId), 0xffff); }
public void AddCodeViewEntry_Args() { var builder = new DebugDirectoryBuilder(); Assert.Throws <ArgumentException>(() => builder.AddCodeViewEntry("", default(BlobContentId), 0x0100)); Assert.Throws <ArgumentException>(() => builder.AddCodeViewEntry("\0", default(BlobContentId), 0x0100)); Assert.Throws <ArgumentException>(() => builder.AddCodeViewEntry("\0xx", default(BlobContentId), 0x0100)); builder.AddCodeViewEntry("foo\0", default(BlobContentId), 0x0100); Assert.Throws <ArgumentNullException>(() => builder.AddCodeViewEntry(null, default(BlobContentId), 0x0100)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0001)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x00ff)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0100); builder.AddCodeViewEntry("foo", default(BlobContentId), 0xffff); }
public AssemblyGenerator(Assembly assembly) { _debugDirectoryBuilder = new DebugDirectoryBuilder(); _peStream = new MemoryStream(); _ilBuilder = new BlobBuilder(); _metadataBuilder = new MetadataBuilder(); _currentAssembly = assembly; _typeHandles = new Dictionary <Guid, EntityHandle>(); _ctorRefHandles = new Dictionary <ConstructorInfo, MemberReferenceHandle>(); _ctorDefHandles = new Dictionary <ConstructorInfo, MethodDefinitionHandle>(); _fieldHandles = new Dictionary <FieldInfo, FieldDefinitionHandle>(); _methodsHandles = new Dictionary <MethodInfo, MethodDefinitionHandle>(); _propertyHandles = new Dictionary <PropertyInfo, PropertyDefinitionHandle>(); _parameterHandles = new Dictionary <ParameterInfo, ParameterHandle>(); }
public static byte[] BuildPEWithDebugDirectory(DebugDirectoryBuilder debugDirectoryBuilder) { var peStream = new MemoryStream(); var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); var peBuilder = new ManagedPEBuilder( PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(metadataBuilder), ilBuilder, debugDirectoryBuilder: debugDirectoryBuilder); var peImageBuilder = new BlobBuilder(); peBuilder.Serialize(peImageBuilder); return peImageBuilder.ToArray(); }
public static byte[] BuildPEWithDebugDirectory(DebugDirectoryBuilder debugDirectoryBuilder) { var peStream = new MemoryStream(); var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); var peBuilder = new ManagedPEBuilder( PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(metadataBuilder), ilBuilder, debugDirectoryBuilder: debugDirectoryBuilder); var peImageBuilder = new BlobBuilder(); peBuilder.Serialize(peImageBuilder); return(peImageBuilder.ToArray()); }
public void AddCodeViewEntry_Args() { var builder = new DebugDirectoryBuilder(); AssertExtensions.Throws <ArgumentException>("pdbPath", () => builder.AddCodeViewEntry("", default(BlobContentId), 0x0100)); AssertExtensions.Throws <ArgumentException>("pdbPath", () => builder.AddCodeViewEntry("\0", default(BlobContentId), 0x0100)); AssertExtensions.Throws <ArgumentException>("pdbPath", () => builder.AddCodeViewEntry("\0xx", default(BlobContentId), 0x0100)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("xx", default(BlobContentId), 0x0100, int.MinValue)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("xx", default(BlobContentId), 0x0100, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("xx", default(BlobContentId), 0x0100, 0)); builder.AddCodeViewEntry("foo\0", default(BlobContentId), 0x0100); builder.AddCodeViewEntry("baz\0", default(BlobContentId), 0x0100, int.MaxValue); Assert.Throws <ArgumentNullException>(() => builder.AddCodeViewEntry(null, default(BlobContentId), 0x0100)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0001)); Assert.Throws <ArgumentOutOfRangeException>(() => builder.AddCodeViewEntry("foo", default(BlobContentId), 0x00ff)); builder.AddCodeViewEntry("foo", default(BlobContentId), 0x0100); builder.AddCodeViewEntry("foo", default(BlobContentId), 0xffff); }
public void AddCustomEntry() { var b = new DebugDirectoryBuilder(); b.AddEntry((DebugDirectoryEntryType)0xA1, version: 0x12345678, stamp: 0xB1C1D1E1); b.AddEntry((DebugDirectoryEntryType)0xA2, version: 0xFFFFFFFF, stamp: 0xFFFFFFFF, (a: 1, b: 2), (builder, data) => { builder.WriteInt32(data.a); builder.WriteInt32(data.b); }); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0x1000, 0x2000), 0x50); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0xE1, 0xD1, 0xC1, 0xB1, // Stamp 0x78, 0x56, 0x34, 0x12, // Version 0xA1, 0x00, 0x00, 0x00, // Type 0x00, 0x00, 0x00, 0x00, // SizeOfData 0x00, 0x00, 0x00, 0x00, // AddressOfRawData 0x00, 0x00, 0x00, 0x00, // PointerToRawData 0x00, 0x00, 0x00, 0x00, // Characteristics 0xFF, 0xFF, 0xFF, 0xFF, // Stamp 0xFF, 0xFF, 0xFF, 0xFF, // Version 0xA2, 0x00, 0x00, 0x00, // Type 0x08, 0x00, 0x00, 0x00, // SizeOfData 0x88, 0x10, 0x00, 0x00, // AddressOfRawData 0x88, 0x20, 0x00, 0x00, // PointerToRawData // data 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, blob.ToArray()); }
public void TryOpenAssociatedPortablePdb_BadPdbFile_FallbackToEmbedded() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); ddBuilder.AddEmbeddedPortablePdbEntry(pdbBuilder, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { string pathQueried = null; Func <string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; // Bad PDB return(new MemoryStream(new byte[] { 0x01 })); }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Null(pdbPath); Assert.Equal(PathUtilities.CombinePathWithRelativePath("pedir", "a.pdb"), pathQueried); Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count); } }
public static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func <Stream> getPeStream, Func <Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool allowMissingMethodBodies, bool isDeterministic, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.Properties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint((uint)MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { var assembly = mdWriter.Module.AsAssembly; if (assembly != null && assembly.Kind == OutputKind.WindowsRuntimeMetadata) { // Dev12: If compiling to winmdobj, we need to add to PDB source spans of // all types and members for better error reporting by WinMDExp. nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap()); } else { #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif } } Stream peStream = getPeStream(); if (peStream == null) { return(false); } BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(BlobContentId); // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; ushort portablePdbVersion = 0; var metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer(); var peHeaderBuilder = new PEHeaderBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit); var deterministicIdProvider = isDeterministic ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) : null; if (mdWriter.EmitStandaloneDebugMetadata) { Debug.Assert(getPortablePdbStreamOpt != null); var debugMetadataBuilder = new BlobBuilder(); var debugMetadataSerializer = mdWriter.GetStandaloneDebugMetadataSerializer(metadataSerializer.MetadataSizes, debugEntryPointHandle, deterministicIdProvider); debugMetadataSerializer.SerializeMetadata(debugMetadataBuilder, out pdbContentId); portablePdbVersion = debugMetadataSerializer.FormatVersion; // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { debugMetadataBuilder.WriteContentTo(portablePdbStream); } } DebugDirectoryBuilder debugDirectoryBuilder; if (pdbPathOpt != null || isDeterministic) { debugDirectoryBuilder = new DebugDirectoryBuilder(); if (pdbPathOpt != null) { string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt); debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion); } if (isDeterministic) { debugDirectoryBuilder.AddReproducibleEntry(); } } else { debugDirectoryBuilder = null; } var peBuilder = new ManagedPEBuilder( peHeaderBuilder, metadataSerializer, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module), entryPointHandle, properties.CorFlags, deterministicIdProvider); var peBlob = new BlobBuilder(); BlobContentId peContentId; peBuilder.Serialize(peBlob, out peContentId); // Patch MVID if (!mvidFixup.IsDefault) { var writer = new BlobWriter(mvidFixup); writer.WriteGuid(peContentId.Guid); Debug.Assert(writer.RemainingBytes == 0); } try { peBlob.WriteContentTo(peStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new PeWritingException(e); } return(true); }
public void TryOpenAssociatedPortablePdb_DuplicateEntries_CodeView() { var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0); ddBuilder.AddReproducibleEntry(); ddBuilder.AddCodeViewEntry(@"/a/b/c.pdb", id, portablePdbVersion: 0x0100); ddBuilder.AddCodeViewEntry(@"/a/b/d.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { string pathQueried = null; Func<string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; return null; }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Equal(PathUtilities.CombinePathWithRelativePath("pedir", "c.pdb"), pathQueried); } }
public void TryOpenAssociatedPortablePdb_BadPdbFile_FallbackToEmbedded() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); ddBuilder.AddEmbeddedPortablePdbEntry(pdbBuilder, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { string pathQueried = null; Func<string, Stream> streamProvider = p => { Assert.Null(pathQueried); pathQueried = p; // Bad PDB return new MemoryStream(new byte[] { 0x01 }); }; MetadataReaderProvider pdbProvider; string pdbPath; Assert.True(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), streamProvider, out pdbProvider, out pdbPath)); Assert.Null(pdbPath); Assert.Equal(PathUtilities.CombinePathWithRelativePath("pedir", "a.pdb"), pathQueried); Assert.Equal(13, pdbProvider.GetMetadataReader().Documents.Count); } }
public void TryOpenAssociatedPortablePdb_ExpectedExceptionFromStreamProvider_NoFallback() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { MetadataReaderProvider pdbProvider; string pdbPath; Assert.Throws<IOException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new IOException(); }, out pdbProvider, out pdbPath)); AssertEx.Throws<BadImageFormatException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new BadImageFormatException("Bang!"); }, out pdbProvider, out pdbPath), e => Assert.Equal("Bang!", e.Message)); // file doesn't exist and no embedded => return false Assert.False(reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new FileNotFoundException(); }, out pdbProvider, out pdbPath)); } }
public void EmbeddedPortablePdb() { var b = new DebugDirectoryBuilder(); var pdb = new BlobBuilder(); pdb.WriteInt64(0x1122334455667788); b.AddEmbeddedPortablePdbEntry(pdb, portablePdbVersion: 0x0100); var blob = new BlobBuilder(); b.Serialize(blob, new SectionLocation(0, 0), sectionOffset: 0); var bytes = blob.ToImmutableArray(); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00, // Characteristics 0x00, 0x00, 0x00, 0x00, // Stamp 0x00, 0x01, 0x00, 0x01, // Version 0x11, 0x00, 0x00, 0x00, // Type 0x12, 0x00, 0x00, 0x00, // SizeOfData 0x1C, 0x00, 0x00, 0x00, // AddressOfRawData 0x1C, 0x00, 0x00, 0x00, // PointerToRawData 0x4D, 0x50, 0x44, 0x42, // signature 0x08, 0x00, 0x00, 0x00, // uncompressed size 0xEB, 0x28, 0x4F, 0x0B, 0x75, 0x31, 0x56, 0x12, 0x04, 0x00 // compressed data }, bytes); using (var pinned = new PinnedBlob(bytes)) { var actual = PEReader.ReadDebugDirectoryEntries(pinned.CreateReader(0, DebugDirectoryEntry.Size)); Assert.Equal(1, actual.Length); Assert.Equal(0u, actual[0].Stamp); Assert.Equal(0x0100, actual[0].MajorVersion); Assert.Equal(0x0100, actual[0].MinorVersion); Assert.Equal(DebugDirectoryEntryType.EmbeddedPortablePdb, actual[0].Type); Assert.Equal(0x00000012, actual[0].DataSize); Assert.Equal(0x0000001c, actual[0].DataRelativeVirtualAddress); Assert.Equal(0x0000001c, actual[0].DataPointer); var provider = new ByteArrayMemoryProvider(bytes); using (var block = provider.GetMemoryBlock(actual[0].DataPointer, actual[0].DataSize)) { var decoded = PEReader.DecodeEmbeddedPortablePdbDebugDirectoryData(block); AssertEx.Equal(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, decoded); } } }
public void Errors() { var b = new DebugDirectoryBuilder(); Assert.Throws <ArgumentNullException>(() => b.AddCodeViewEntry(null, default(BlobContentId), 0)); }
private void Initialize(Assembly assembly) { _metadata = new AssemblyMetadata(assembly); _debugDirectoryBuilder = new DebugDirectoryBuilder(); }
public void Errors() { var b = new DebugDirectoryBuilder(); Assert.Throws<ArgumentNullException>(() => b.AddCodeViewEntry(null, default(BlobContentId), 0)); }
private void Initialize(Assembly assembly, IEnumerable <Assembly> referencedDyncamicAsssemblies) { _metadata = new AssemblyMetadata(assembly, referencedDyncamicAsssemblies); _debugDirectoryBuilder = new DebugDirectoryBuilder(); }
internal static bool WritePeToStream( EmitContext context, CommonMessageProvider messageProvider, Func <Stream> getPeStream, Func <Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt, string pdbPathOpt, bool metadataOnly, bool isDeterministic, bool emitTestCoverageData, RSAParameters?privateKeyOpt, CancellationToken cancellationToken) { // If PDB writer is given, we have to have PDB path. Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null); var mdWriter = FullMetadataWriter.Create(context, messageProvider, metadataOnly, isDeterministic, emitTestCoverageData, getPortablePdbStreamOpt != null, cancellationToken); var properties = context.Module.SerializationProperties; nativePdbWriterOpt?.SetMetadataEmitter(mdWriter); // Since we are producing a full assembly, we should not have a module version ID // imposed ahead-of time. Instead we will compute a deterministic module version ID // based on the contents of the generated stream. Debug.Assert(properties.PersistentIdentifier == default(Guid)); var ilBuilder = new BlobBuilder(32 * 1024); var mappedFieldDataBuilder = new BlobBuilder(); var managedResourceBuilder = new BlobBuilder(1024); Blob mvidFixup, mvidStringFixup; mdWriter.BuildMetadataAndIL( nativePdbWriterOpt, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, out mvidFixup, out mvidStringFixup); MethodDefinitionHandle entryPointHandle; MethodDefinitionHandle debugEntryPointHandle; mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle); if (!debugEntryPointHandle.IsNil) { nativePdbWriterOpt?.SetEntryPoint(MetadataTokens.GetToken(debugEntryPointHandle)); } if (nativePdbWriterOpt != null) { if (context.Module.SourceLinkStreamOpt != null) { nativePdbWriterOpt.EmbedSourceLink(context.Module.SourceLinkStreamOpt); } if (mdWriter.Module.OutputKind == OutputKind.WindowsRuntimeMetadata) { // Dev12: If compiling to winmdobj, we need to add to PDB source spans of // all types and members for better error reporting by WinMDExp. nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap()); } else { #if DEBUG // validate that all definitions are writable // if same scenario would happen in an winmdobj project nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap()); #endif } nativePdbWriterOpt.WriteRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); } Stream peStream = getPeStream(); if (peStream == null) { return(false); } BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default; // the writer shall not be used after this point for writing: nativePdbWriterOpt = null; ushort portablePdbVersion = 0; var metadataRootBuilder = mdWriter.GetRootBuilder(); var peHeaderBuilder = new PEHeaderBuilder( machine: properties.Machine, sectionAlignment: properties.SectionAlignment, fileAlignment: properties.FileAlignment, imageBase: properties.BaseAddress, majorLinkerVersion: properties.LinkerMajorVersion, minorLinkerVersion: properties.LinkerMinorVersion, majorOperatingSystemVersion: 4, minorOperatingSystemVersion: 0, majorImageVersion: 0, minorImageVersion: 0, majorSubsystemVersion: properties.MajorSubsystemVersion, minorSubsystemVersion: properties.MinorSubsystemVersion, subsystem: properties.Subsystem, dllCharacteristics: properties.DllCharacteristics, imageCharacteristics: properties.ImageCharacteristics, sizeOfStackReserve: properties.SizeOfStackReserve, sizeOfStackCommit: properties.SizeOfStackCommit, sizeOfHeapReserve: properties.SizeOfHeapReserve, sizeOfHeapCommit: properties.SizeOfHeapCommit); // TODO: replace SHA1 with non-crypto alg: https://github.com/dotnet/roslyn/issues/24737 var peIdProvider = isDeterministic ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeHash(HashAlgorithmName.SHA1, content))) : null; // We need to calculate the PDB checksum, so we may as well use the calculated hash for PDB ID regardless of whether deterministic build is requested. var portablePdbContentHash = default(ImmutableArray <byte>); BlobBuilder portablePdbToEmbed = null; if (mdWriter.EmitPortableDebugMetadata) { mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments); // The algorithm must be specified for deterministic builds (checked earlier). Debug.Assert(!isDeterministic || context.Module.PdbChecksumAlgorithm.Name != null); var portablePdbIdProvider = (context.Module.PdbChecksumAlgorithm.Name != null) ? new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(portablePdbContentHash = CryptographicHashProvider.ComputeHash(context.Module.PdbChecksumAlgorithm, content))) : null; var portablePdbBlob = new BlobBuilder(); var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, portablePdbIdProvider); pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob); portablePdbVersion = portablePdbBuilder.FormatVersion; if (getPortablePdbStreamOpt == null) { // embed to debug directory: portablePdbToEmbed = portablePdbBlob; } else { // write to Portable PDB stream: Stream portablePdbStream = getPortablePdbStreamOpt(); if (portablePdbStream != null) { try { portablePdbBlob.WriteContentTo(portablePdbStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new SymUnmanagedWriterException(e.Message, e); } } } } DebugDirectoryBuilder debugDirectoryBuilder; if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null) { debugDirectoryBuilder = new DebugDirectoryBuilder(); if (pdbPathOpt != null) { string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt); debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion); if (!portablePdbContentHash.IsDefault) { // Emit PDB Checksum entry for Portable and Embedded PDBs. The checksum is not as useful when the PDB is embedded, // however it allows the client to efficiently validate a standalone Portable PDB that // has been extracted from Embedded PDB and placed next to the PE file. debugDirectoryBuilder.AddPdbChecksumEntry(context.Module.PdbChecksumAlgorithm.Name, portablePdbContentHash); } } if (isDeterministic) { debugDirectoryBuilder.AddReproducibleEntry(); } if (portablePdbToEmbed != null) { debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion); } } else { debugDirectoryBuilder = null; } var strongNameProvider = context.Module.CommonCompilation.Options.StrongNameProvider; var corFlags = properties.CorFlags; var peBuilder = new ExtendedPEBuilder( peHeaderBuilder, metadataRootBuilder, ilBuilder, mappedFieldDataBuilder, managedResourceBuilder, CreateNativeResourceSectionSerializer(context.Module), debugDirectoryBuilder, CalculateStrongNameSignatureSize(context.Module, privateKeyOpt), entryPointHandle, corFlags, peIdProvider, metadataOnly && !context.IncludePrivateMembers); var peBlob = new BlobBuilder(); var peContentId = peBuilder.Serialize(peBlob, out Blob mvidSectionFixup); PatchModuleVersionIds(mvidFixup, mvidSectionFixup, mvidStringFixup, peContentId.Guid); if (privateKeyOpt != null && corFlags.HasFlag(CorFlags.StrongNameSigned)) { Debug.Assert(strongNameProvider.Capability == SigningCapability.SignsPeBuilder); strongNameProvider.SignPeBuilder(peBuilder, peBlob, privateKeyOpt.Value); } try { peBlob.WriteContentTo(peStream); } catch (Exception e) when(!(e is OperationCanceledException)) { throw new PeWritingException(e); } return(true); }
public void TryOpenAssociatedPortablePdb_BadStreamProvider() { var pdbBuilder = new BlobBuilder(); pdbBuilder.WriteBytes(PortablePdbs.DocumentsPdb); var id = new BlobContentId(Guid.Parse("18091B06-32BB-46C2-9C3B-7C9389A2F6C6"), 0x12345678); var ddBuilder = new DebugDirectoryBuilder(); ddBuilder.AddCodeViewEntry(@"/a/b/a.pdb", id, portablePdbVersion: 0x0100); var peStream = new MemoryStream(TestBuilders.BuildPEWithDebugDirectory(ddBuilder)); using (var reader = new PEReader(peStream)) { MetadataReaderProvider pdbProvider; string pdbPath; // pass-thru: Assert.Throws<ArgumentException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { throw new ArgumentException(); }, out pdbProvider, out pdbPath)); Assert.Throws<InvalidOperationException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return new TestStream(canRead: false, canWrite: true, canSeek: true); }, out pdbProvider, out pdbPath)); Assert.Throws<InvalidOperationException>(() => reader.TryOpenAssociatedPortablePdb(Path.Combine("pedir", "file.exe"), _ => { return new TestStream(canRead: true, canWrite: true, canSeek: false); }, out pdbProvider, out pdbPath)); } }