コード例 #1
0
ファイル: BlobTests.cs プロジェクト: mauriciolsrj/corefx
        public void WriteContentToStream()
        {
            var builder = new BlobBuilder(16);

            for (int i = 0; i < 20; i++)
            {
                builder.WriteByte((byte)i);
            }

            var stream = new MemoryStream();

            builder.WriteContentTo(stream);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
            }, stream.ToArray());

            builder.WriteByte(0xff);

            builder.WriteContentTo(stream);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0xff,
            }, stream.ToArray());
        }
コード例 #2
0
ファイル: BlobTests.cs プロジェクト: mauriciolsrj/corefx
        public void WriteContentToBlobBuilder()
        {
            var builder1 = new BlobBuilder(16);

            for (int i = 0; i < 20; i++)
            {
                builder1.WriteByte((byte)i);
            }

            var builder2 = new BlobBuilder(256);

            builder1.WriteContentTo(builder2);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
            }, builder2.ToArray());

            builder1.WriteByte(0xff);

            builder1.WriteContentTo(builder2);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0xff,
            }, builder2.ToArray());
        }
コード例 #3
0
ファイル: BlobTests.cs プロジェクト: mauriciolsrj/corefx
        public unsafe void Write_Errors()
        {
            var builder = new BlobBuilder(16);

            Assert.Throws <ArgumentNullException>(() => builder.WriteUTF16((char[])null));
            Assert.Throws <ArgumentNullException>(() => builder.WriteUTF16((string)null));
            Assert.Throws <ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true));
            Assert.Throws <ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true));
            Assert.Throws <ArgumentNullException>(() => builder.TryWriteBytes((Stream)null, 0));
            Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(null));
            Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(null, 0, 0));
            Assert.Throws <ArgumentNullException>(() => builder.WriteBytes((byte *)null, 0));
            Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray <byte>)));
            Assert.Throws <ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray <byte>), 0, 0));

            var bw = default(BlobWriter);

            Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo(ref bw));
            Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((Stream)null));
            Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((BlobBuilder)null));

            Assert.Throws <ArgumentOutOfRangeException>(() => builder.TryWriteBytes(new MemoryStream(), -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(0, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 1, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, 1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 1, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 0, 1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray <byte> .Empty, 1, -1));
        }
コード例 #4
0
ファイル: BlobTests.cs プロジェクト: mauriciolsrj/corefx
        public void WriteContentToStream_Errors()
        {
            var builder = new BlobBuilder(16);

            builder.WriteByte(1);

            Assert.Throws <ArgumentNullException>(() => builder.WriteContentTo((Stream)null));
            Assert.Throws <NotSupportedException>(() => builder.WriteContentTo(new MemoryStream(new byte[] { 1 }, writable: false)));
        }
コード例 #5
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle
            )
        {
            // Create executable with the managed metadata from the specified MetadataBuilder.
            var peHeaderBuilder = new PEHeaderBuilder(
                imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll
                );

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly,
                deterministicIdProvider: content => s_contentId);

            // Write executable into the specified stream.
            var           peBlob    = new BlobBuilder();
            BlobContentId contentId = peBuilder.Serialize(peBlob);

            peBlob.WriteContentTo(peStream);
        }
コード例 #6
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle,
            Blob mvidFixup       = default(Blob),
            byte[] privateKeyOpt = null)
        {
            var peBuilder = new ManagedPEBuilder(
                entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            var contentId = peBuilder.Serialize(peBlob);

            if (!mvidFixup.IsDefault)
            {
                new BlobWriter(mvidFixup).WriteGuid(contentId.Guid);
            }

            if (privateKeyOpt != null)
            {
                peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt));
            }

            peBlob.WriteContentTo(peStream);
        }
コード例 #7
0
 public PermissionSetEncoder AddPermission(string typeName, BlobBuilder arguments)
 {
     Builder.WriteSerializedString(typeName);
     Builder.WriteCompressedInteger(arguments.Count);
     arguments.WriteContentTo(Builder);
     return(new PermissionSetEncoder(Builder));
 }
コード例 #8
0
        public unsafe void NativeResources()
        {
            var peStream        = new MemoryStream();
            var ilBuilder       = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            var peBuilder = new ManagedPEBuilder(
                PEHeaderBuilder.CreateLibraryHeader(),
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                nativeResources: new TestResourceSectionBuilder(),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            var contentId = peBuilder.Serialize(peBlob);

            peBlob.WriteContentTo(peStream);

            peStream.Position = 0;
            var peReader      = new PEReader(peStream);
            var sectionHeader = peReader.PEHeaders.SectionHeaders.Single(s => s.Name == ".rsrc");

            var image = peReader.GetEntireImage();

            var reader = new BlobReader(image.Pointer + sectionHeader.PointerToRawData, sectionHeader.SizeOfRawData);

            Assert.Equal(0x12345678, reader.ReadInt32());
            Assert.Equal(sectionHeader.PointerToRawData, reader.ReadInt32());
            Assert.Equal(sectionHeader.VirtualAddress, reader.ReadInt32());
        }
コード例 #9
0
        private static void SerializeHelperLibrary(string assemblyName, string rootNamespace, string path)
        {
            var ilBuilder       = new BlobBuilder();
            var metadataBuilder = new MetadataBuilder();

            EmitHelperLibraryMetadata(assemblyName, rootNamespace, metadataBuilder, ilBuilder);

            // Following code does not work:
            //
            //   var peHeaderBuilder = PEHeaderBuilder.CreateLibraryHeader();
            //
            // PEHeaderBuilder.CreateLibraryHeader() method does not set Characteristics.ExecutableImage bit.
            // If we serialize an assembly without setting it, .NET Core runtime refuses to load.
            // So, we explicitly set it by using PEHeaderBuilder constructor.

            var peHeaderBuilder =
                new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll);
            var peBuilder = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(metadataBuilder), ilBuilder);

            var peBlob = new BlobBuilder();

            peBuilder.Serialize(peBlob);

            using (var stream = File.Create(path))
            {
                peBlob.WriteContentTo(stream);
            }
        }
コード例 #10
0
    public override bool Execute()
    {
        if (string.IsNullOrEmpty(RuntimeConfigFile))
        {
            Log.LogError($"'{nameof(RuntimeConfigFile)}' is required.");
        }

        if (string.IsNullOrEmpty(OutputFile))
        {
            Log.LogError($"'{nameof(OutputFile)}' is required.");
        }

        Dictionary <string, string> configProperties = ConvertInputToDictionary(RuntimeConfigFile);

        if (ReservedProperties.Length != 0)
        {
            CheckDuplicateProperties(configProperties, ReservedProperties);
        }

        var blobBuilder = new BlobBuilder();

        ConvertDictionaryToBlob(configProperties, blobBuilder);

        using var stream = File.OpenWrite(OutputFile);
        blobBuilder.WriteContentTo(stream);

        return(!Log.HasLoggedErrors);
    }
コード例 #11
0
 public PermissionSetEncoder <T> AddPermission(string typeName, BlobBuilder arguments)
 {
     Builder.WriteSerializedString(typeName);
     //return new NamedArgumentsBuilder<T>(_continuation, propertyCount, CountFormat.Compressed);
     Builder.WriteCompressedInteger((uint)arguments.Count);
     arguments.WriteContentTo(Builder);
     return(new PermissionSetEncoder <T>(_continuation, _count - 1));
 }
コード例 #12
0
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public void WriteBytes(BlobBuilder source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            source.WriteContentTo(ref this);
        }
コード例 #13
0
ファイル: SectionBuilder.cs プロジェクト: z1c0/corert
        /// <summary>
        /// Relocate the produced PE file and output the result into a given stream.
        /// </summary>
        /// <param name="peFile">Blob builder representing the complete PE file</param>
        /// <param name="defaultImageBase">Default load address for the image</param>
        /// <param name="corHeaderBuilder">COR header</param>
        /// <param name="corHeaderFileOffset">File position of the COR header</param>
        /// <param name="outputStream">Stream to receive the relocated PE file</param>
        public void RelocateOutputFile(
            BlobBuilder peFile,
            ulong defaultImageBase,
            CorHeaderBuilder corHeaderBuilder,
            int corHeaderFileOffset,
            Stream outputStream)
        {
            RelocationHelper relocationHelper = new RelocationHelper(outputStream, defaultImageBase, peFile);

            if (corHeaderBuilder != null)
            {
                relocationHelper.CopyToFilePosition(corHeaderFileOffset);
                UpdateCorHeader(corHeaderBuilder);
                BlobBuilder corHeaderBlob = new BlobBuilder();
                corHeaderBuilder.WriteTo(corHeaderBlob);
                int writtenSize = corHeaderBlob.Count;
                corHeaderBlob.WriteContentTo(outputStream);
                relocationHelper.AdvanceOutputPos(writtenSize);

                // Just skip the bytes that were emitted by the COR header writer
                byte[] skipBuffer = new byte[writtenSize];
                relocationHelper.CopyBytesToBuffer(skipBuffer, writtenSize);
            }

            // Traverse relocations in all sections in their RVA order
            foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced))
            {
                int rvaToFilePosDelta = section.FilePosWhenPlaced - section.RVAWhenPlaced;
                foreach (ObjectDataRelocations objectDataRelocs in section.Relocations)
                {
                    foreach (Relocation relocation in objectDataRelocs.Relocs)
                    {
                        // Process a single relocation
                        int relocationRVA     = section.RVAWhenPlaced + objectDataRelocs.Offset + relocation.Offset;
                        int relocationFilePos = relocationRVA + rvaToFilePosDelta;

                        // Flush parts of PE file before the relocation to the output stream
                        relocationHelper.CopyToFilePosition(relocationFilePos);

                        // Look up relocation target
                        SymbolTarget relocationTarget = _symbolMap[relocation.Target];
                        Section      targetSection    = _sections[relocationTarget.SectionIndex];
                        int          targetRVA        = targetSection.RVAWhenPlaced + relocationTarget.Offset;

                        // Apply the relocation
                        relocationHelper.ProcessRelocation(relocation.RelocType, relocationRVA, targetRVA);
                    }
                }
            }

            // Flush remaining PE file blocks after the last relocation
            relocationHelper.CopyRestOfFile();
        }
コード例 #14
0
        public void SerializeToStream(Stream peStream)
        {
            var peHeaderBuilder = new PEHeaderBuilder();
            var peBuilder       = new ManagedPEBuilder(peHeaderBuilder, new MetadataRootBuilder(_metadataBuilder), _ilBuilder,
                                                       deterministicIdProvider: content => s_contentId);

            var peBlob    = new BlobBuilder();
            var contentId = peBuilder.Serialize(peBlob);

            new BlobWriter(_mvidFixup).WriteGuid(contentId.Guid);
            peBlob.WriteContentTo(peStream);
        }
コード例 #15
0
ファイル: PEBuilderTests.cs プロジェクト: mauriciolsrj/corefx
        private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle)
        {
            var mappedFieldDataBuilder     = new BlobBuilder();
            var managedResourceDataBuilder = new BlobBuilder();

            var peBuilder = new PEBuilder(
                machine: 0,
                sectionAlignment: 0x2000,
                fileAlignment: 0x200,
                imageBase: 0x00400000,
                majorLinkerVersion: 0x30, // (what is ref.emit using?)
                minorLinkerVersion: 0,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: 4,
                minorSubsystemVersion: 0,
                subsystem: Subsystem.WindowsCui,
                dllCharacteristics: DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware,
                imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage,
                sizeOfStackReserve: 0x00100000,
                sizeOfStackCommit: 0x1000,
                sizeOfHeapReserve: 0x00100000,
                sizeOfHeapCommit: 0x1000);

            var peDirectoriesBuilder = new PEDirectoriesBuilder();

            peBuilder.AddManagedSections(
                peDirectoriesBuilder,
                new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false),
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceDataBuilder,
                nativeResourceSectionSerializer: null,
                strongNameSignatureSize: 0,
                entryPoint: entryPointHandle,
                pdbPathOpt: null,
                nativePdbContentId: default(ContentId),
                portablePdbContentId: default(ContentId),
                corFlags: CorFlags.ILOnly);

            var       peBlob = new BlobBuilder();
            ContentId peContentId;

            peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId);

            peBlob.WriteContentTo(peStream);
        }
コード例 #16
0
        public void EmitToStream(Stream stream)
        {
            foreach (var typeDef in _emittedTypes)
            {
                MethodDefinitionHandle?firstMethodHandle = null;

                foreach (var methodDef in typeDef.Methods)
                {
                    int bodyOffset = _methodBodyStream.AddMethodBody(methodDef.Code);

                    BlobHandle signature = MakeSignatureHandle(methodDef.Signature);

                    MethodDefinitionHandle methodHandle = _metadataBuilder.AddMethodDefinition(
                        MethodAttributes.PrivateScope | MethodAttributes.Static,
                        MethodImplAttributes.IL | MethodImplAttributes.Managed,
                        _metadataBuilder.GetOrAddString(methodDef.Name),
                        signature,
                        bodyOffset,
                        parameterList: default(ParameterHandle));

                    if (firstMethodHandle == null)
                    {
                        firstMethodHandle = methodHandle;
                    }
                }

                _metadataBuilder.AddTypeDefinition(
                    default(TypeAttributes),
                    default(StringHandle),
                    _metadataBuilder.GetOrAddString(typeDef.Name),
                    typeDef.IsValueType ?
                    MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.ValueType)) :
                    MakeTypeRefHandle(_typeSystemContext.GetWellKnownType(WellKnownType.Object)),
                    fieldList: MetadataTokens.FieldDefinitionHandle(1),
                    methodList: firstMethodHandle.Value);
            }

            BlobBuilder peBlob = new BlobBuilder();

            new ManagedPEBuilder(PEHeaderBuilder.CreateLibraryHeader(), new MetadataRootBuilder(_metadataBuilder), _methodBodyStream.Builder).Serialize(peBlob);

            peBlob.WriteContentTo(stream);

            // Clear some variables to catch any caller trying to emit data after writing the output file
            _emittedTypes     = null;
            _metadataBuilder  = null;
            _methodBodyStream = default(MethodBodyStreamEncoder);
        }
コード例 #17
0
        private ImmutableArray <Diagnostic> EmitAssembly(BoundProgram program)
        {
            var header              = new PEHeaderBuilder();
            var metadataBuilder     = new MetadataBuilder();
            var metadataRootBuilder = new MetadataRootBuilder(metadataBuilder);
            var blobBuilder         = new BlobBuilder();
            var peBuilder           = new ManagedPEBuilder(header, metadataRootBuilder, blobBuilder);

            peBuilder.Serialize(blobBuilder);

            // TODO: Produce portable assembly contents here
            using (var stream = new StreamWriter(program.PackageName + ".dll"))
            {
                blobBuilder.WriteContentTo(stream.BaseStream);
            }

            return(ImmutableArray <Diagnostic> .Empty);
        }
コード例 #18
0
        private void GenerateWinMD(MetadataBuilder metadataBuilder, string outputFile)
        {
            Logger.Log("Writing " + outputFile);
            var managedPeBuilder = new ManagedPEBuilder(
                new PEHeaderBuilder(
                    machine: Machine.I386,
                    imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll | Characteristics.Bit32Machine),
                new MetadataRootBuilder(metadataBuilder, "WindowsRuntime 1.4"),
                new BlobBuilder(),
                flags: CorFlags.ILOnly);

            var peBlob = new BlobBuilder();

            managedPeBuilder.Serialize(peBlob);

            using var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
            peBlob.WriteContentTo(fs);
        }
コード例 #19
0
        /// <summary>
        /// Relocate the contents of the metadata blob, which contains two tables with embedded RVAs.
        /// </summary>
        public void RelocateMetadataBlob(Stream outputStream)
        {
            long initialStreamLength = outputStream.Length;

            outputStream.Position = 0;

            // The output is already a valid PE file so use that to access the output metadata blob
            PEReader peReader = new PEReader(outputStream);

            // Create a patched up metadata blob whose RVAs are correct w.r.t the output image
            BlobBuilder relocatedMetadataBlob = MetadataRvaFixupBuilder.Relocate(peReader, RelocateRVA);

            Debug.Assert(_metadataFileOffset > 0);
            outputStream.Position = _metadataFileOffset;

            // Splice the new metadata blob back into the output stream
            relocatedMetadataBlob.WriteContentTo(outputStream);
            Debug.Assert(initialStreamLength == outputStream.Length);
        }
コード例 #20
0
        public PermissionSetEncoder AddPermission(string typeName, BlobBuilder encodedArguments)
        {
            if (typeName is null)
            {
                Throw.ArgumentNull(nameof(typeName));
            }
            if (encodedArguments is null)
            {
                Throw.ArgumentNull(nameof(encodedArguments));
            }

            if (encodedArguments.Count > BlobWriterImpl.MaxCompressedIntegerValue)
            {
                Throw.BlobTooLarge(nameof(encodedArguments));
            }

            Builder.WriteSerializedString(typeName);
            Builder.WriteCompressedInteger(encodedArguments.Count);
            encodedArguments.WriteContentTo(Builder);
            return(this);
        }
コード例 #21
0
ファイル: PEBuilderTests.cs プロジェクト: z77ma/runtime
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle,
            Blob mvidFixup              = default(Blob),
            byte[] privateKeyOpt        = null,
            bool publicSigned           = false,
            Machine machine             = 0,
            BlobBuilder?mappedFieldData = null)
        {
            var peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage,
                                                      machine: machine);

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                new MetadataRootBuilder(metadataBuilder),
                ilBuilder,
                entryPoint: entryPointHandle,
                flags: CorFlags.ILOnly | (privateKeyOpt != null || publicSigned ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId,
                mappedFieldData: mappedFieldData);

            var peBlob = new BlobBuilder();

            var contentId = peBuilder.Serialize(peBlob);

            if (!mvidFixup.IsDefault)
            {
                new BlobWriter(mvidFixup).WriteGuid(contentId.Guid);
            }

            if (privateKeyOpt != null)
            {
                peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt));
            }

            peBlob.WriteContentTo(peStream);
        }
コード例 #22
0
        private static void WritePEImage(
            Stream peStream,
            MetadataBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            MethodDefinitionHandle entryPointHandle,
            byte[] privateKeyOpt = null)
        {
            var mappedFieldDataBuilder     = new BlobBuilder();
            var managedResourceDataBuilder = new BlobBuilder();

            var peBuilder = new ManagedPEBuilder(
                entryPointHandle.IsNil ? PEHeaderBuilder.CreateLibraryHeader() : PEHeaderBuilder.CreateExecutableHeader(),
                new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false),
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceDataBuilder,
                nativeResourceSectionSerializer: null,
                strongNameSignatureSize: 128,
                entryPoint: entryPointHandle,
                pdbPathOpt: null,
                nativePdbContentId: default(ContentId),
                portablePdbContentId: default(ContentId),
                corFlags: CorFlags.ILOnly | (privateKeyOpt != null ? CorFlags.StrongNameSigned : 0),
                deterministicIdProvider: content => s_contentId);

            var peBlob = new BlobBuilder();

            ContentId contentId;

            peBuilder.Serialize(peBlob, out contentId);

            if (privateKeyOpt != null)
            {
                peBuilder.Sign(peBlob, content => SigningUtilities.CalculateRsaSignature(content, privateKeyOpt));
            }

            peBlob.WriteContentTo(peStream);
        }
コード例 #23
0
    public override bool Execute()
    {
        if (string.IsNullOrEmpty(RuntimeConfigFile))
        {
            Log.LogError($"'{nameof(RuntimeConfigFile)}' is required.");
            return(false);
        }

        if (string.IsNullOrEmpty(OutputFile))
        {
            Log.LogError($"'{nameof(OutputFile)}' is required.");
            return(false);
        }

        if (!TryConvertInputToDictionary(RuntimeConfigFile, out Dictionary <string, string>?configProperties))
        {
            return(false);
        }

        if (RuntimeConfigReservedProperties.Length != 0)
        {
            if (!CheckReservedProperties(configProperties, RuntimeConfigReservedProperties))
            {
                return(false);
            }
        }

        var blobBuilder = new BlobBuilder();

        ConvertDictionaryToBlob(configProperties, blobBuilder);

        Directory.CreateDirectory(Path.GetDirectoryName(OutputFile !) !);
        using var stream = File.OpenWrite(OutputFile);
        blobBuilder.WriteContentTo(stream);

        return(!Log.HasLoggedErrors);
    }
コード例 #24
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteImportTable(Stream peStream, int importTableRva, int importAddressTableRva)
        {
            var writer = new BlobBuilder(SizeOfImportTable);
            int ilRVA = importTableRva + 40;
            int hintRva = ilRVA + (_is32bit ? 12 : 16);
            int nameRva = hintRva + 12 + 2;

            // Import table
            writer.WriteUInt32((uint)ilRVA); // 4
            writer.WriteUInt32(0); // 8
            writer.WriteUInt32(0); // 12
            writer.WriteUInt32((uint)nameRva); // 16
            writer.WriteUInt32((uint)importAddressTableRva); // 20
            writer.WriteBytes(0, 20); // 40

            // Import Lookup table
            if (_is32bit)
            {
                writer.WriteUInt32((uint)hintRva); // 44
                writer.WriteUInt32(0); // 48
                writer.WriteUInt32(0); // 52
            }
            else
            {
                writer.WriteUInt64((uint)hintRva); // 48
                writer.WriteUInt64(0); // 56
            }

            // Hint table
            writer.WriteUInt16(0); // Hint 54|58

            foreach (char ch in CorEntryPointName)
            {
                writer.WriteByte((byte)ch); // 65|69
            }

            writer.WriteByte(0); // 66|70
            Debug.Assert(writer.Count == SizeOfImportTable);

            writer.WriteContentTo(peStream);
        }
コード例 #25
0
ファイル: PeWriter.cs プロジェクト: Rookieek/roslyn
        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;
            }

            ContentId nativePdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(ContentId);

            // the writer shall not be used after this point for writing:
            nativePdbWriterOpt = null;

            var metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer();

            var peBuilder = new PEBuilder(
                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,
                deterministicIdProvider: isDeterministic ? new Func<BlobBuilder, ContentId>(content => ContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) : null);

            ContentId portablePdbContentId;
            if (mdWriter.EmitStandaloneDebugMetadata)
            {
                Debug.Assert(getPortablePdbStreamOpt != null);

                var debugMetadataBuilder = new BlobBuilder();
                var debugMetadataSerializer = mdWriter.GetStandaloneDebugMetadataSerializer(metadataSerializer.MetadataSizes, debugEntryPointHandle);
                debugMetadataSerializer.SerializeMetadata(debugMetadataBuilder, peBuilder.IdProvider, out portablePdbContentId);

                // write to Portable PDB stream:
                Stream portablePdbStream = getPortablePdbStreamOpt();
                if (portablePdbStream != null)
                {
                    debugMetadataBuilder.WriteContentTo(portablePdbStream);
                }
            }
            else
            {
                portablePdbContentId = default(ContentId);
            }

            var peDirectoriesBuilder = new PEDirectoriesBuilder();

            peBuilder.AddManagedSections(
                peDirectoriesBuilder,
                metadataSerializer,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                CreateNativeResourceSectionSerializer(context.Module),
                CalculateStrongNameSignatureSize(context.Module),
                entryPointHandle,
                pdbPathOpt,
                nativePdbContentId,
                portablePdbContentId,
                properties.CorFlags);

            var peBlob = new BlobBuilder();
            ContentId peContentId;
            peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId);

            // Patch MVID
            if (!mvidFixup.IsDefault)
            {
                var mvidWriter = new BlobWriter(mvidFixup);
                mvidWriter.WriteBytes(peContentId.Guid);
                Debug.Assert(mvidWriter.RemainingBytes == 0);
            }

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when (!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return true;
        }
コード例 #26
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteRuntimeStartupStub(Stream peStream, int importAddressTableRva)
        {
            var writer = new BlobBuilder(16);
            // entry point code, consisting of a jump indirect to _CorXXXMain
            if (_is32bit)
            {
                //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 4 byte boundary.
                for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 4) - peStream.Position); i < n; i++)
                {
                    writer.WriteByte(0);
                }

                writer.WriteUInt16(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //4
                writer.WriteUInt32((uint)importAddressTableRva + (uint)_properties.BaseAddress); //8
            }
            else
            {
                //emit 0's (nops) to pad the entry point code so that the target address is aligned on a 8 byte boundary.
                for (uint i = 0, n = (uint)(BitArithmeticUtilities.Align((uint)peStream.Position, 8) - peStream.Position); i < n; i++)
                {
                    writer.WriteByte(0);
                }

                writer.WriteUInt32(0);
                writer.WriteUInt16(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //8
                writer.WriteUInt64((ulong)importAddressTableRva + _properties.BaseAddress); //16
            }

            writer.WriteContentTo(peStream);
        }
コード例 #27
0
ファイル: BlobTests.cs プロジェクト: ESgarbi/corefx
        public void WriteContentToStream_Errors()
        {
            var builder = new BlobBuilder(16);
            builder.WriteByte(1);

            Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((Stream)null));
            Assert.Throws<NotSupportedException>(() => builder.WriteContentTo(new MemoryStream(new byte[] { 1 }, writable: false)));
        }
コード例 #28
0
ファイル: PEBuilderTests.cs プロジェクト: RoryVL/roslyn
        private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder, MethodDefinitionHandle entryPointHandle)
        {
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceDataBuilder = new BlobBuilder();

            var peBuilder = new PEBuilder(
                machine: 0,
                sectionAlignment: 0x2000,
                fileAlignment: 0x200,
                imageBase: 0x00400000,
                majorLinkerVersion: 0x30, // (what is ref.emit using?)
                minorLinkerVersion: 0,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: 4,
                minorSubsystemVersion: 0,
                subsystem: Subsystem.WindowsCui,
                dllCharacteristics: DllCharacteristics.DynamicBase | DllCharacteristics.NxCompatible | DllCharacteristics.NoSeh | DllCharacteristics.TerminalServerAware,
                imageCharacteristics: entryPointHandle.IsNil ? Characteristics.Dll : Characteristics.ExecutableImage,
                sizeOfStackReserve: 0x00100000,
                sizeOfStackCommit: 0x1000,
                sizeOfHeapReserve: 0x00100000,
                sizeOfHeapCommit: 0x1000);

            var peDirectoriesBuilder = new PEDirectoriesBuilder();

            peBuilder.AddManagedSections(
                peDirectoriesBuilder,
                new TypeSystemMetadataSerializer(metadataBuilder, "v4.0.30319", isMinimalDelta: false),
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceDataBuilder,
                nativeResourceSectionSerializer: null,
                strongNameSignatureSize: 0,
                entryPoint: entryPointHandle,
                pdbPathOpt: null,
                nativePdbContentId: default(ContentId),
                portablePdbContentId: default(ContentId),
                corFlags: CorFlags.ILOnly);

            var peBlob = new BlobBuilder();
            ContentId peContentId;
            peBuilder.Serialize(peBlob, peDirectoriesBuilder, out peContentId);

            peBlob.WriteContentTo(peStream);
        }
コード例 #29
0
ファイル: BlobTests.cs プロジェクト: ESgarbi/corefx
        public void WriteContentToBlobBuilder()
        {
            var builder1 = new BlobBuilder(16);
            for (int i = 0; i < 20; i++)
            {
                builder1.WriteByte((byte)i);
            }

            var builder2 = new BlobBuilder(256);
            builder1.WriteContentTo(builder2);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
            }, builder2.ToArray());

            builder1.WriteByte(0xff);

            builder1.WriteContentTo(builder2);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0xff,
            }, builder2.ToArray());
        }
コード例 #30
0
ファイル: BlobTests.cs プロジェクト: ESgarbi/corefx
        public unsafe void Write_Errors()
        {
            var builder = new BlobBuilder(16);
            Assert.Throws<ArgumentNullException>(() => builder.WriteUTF16((char[])null));
            Assert.Throws<ArgumentNullException>(() => builder.WriteUTF16((string)null));
            Assert.Throws<ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true));
            Assert.Throws<ArgumentNullException>(() => builder.WriteUTF8(null, allowUnpairedSurrogates: true));
            Assert.Throws<ArgumentNullException>(() => builder.TryWriteBytes((Stream)null, 0));
            Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(null));
            Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(null, 0, 0));
            Assert.Throws<ArgumentNullException>(() => builder.WriteBytes((byte*)null, 0));
            Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray<byte>)));
            Assert.Throws<ArgumentNullException>(() => builder.WriteBytes(default(ImmutableArray<byte>), 0, 0));

            var bw = default(BlobWriter);
            Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo(ref bw));
            Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((Stream)null));
            Assert.Throws<ArgumentNullException>(() => builder.WriteContentTo((BlobBuilder)null));

            Assert.Throws<ArgumentOutOfRangeException>(() => builder.TryWriteBytes(new MemoryStream(), -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(0, -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 1, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, 1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(new byte[] { }, 0, -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 1, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 0, 1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteBytes(ImmutableArray<byte>.Empty, 1, -1));
        }
コード例 #31
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private static void WriteNameTable(Stream peStream)
        {
            var writer = new BlobBuilder(SizeOfNameTable);
            foreach (char ch in CorEntryPointDll)
            {
                writer.WriteByte((byte)ch);
            }

            writer.WriteByte(0);
            writer.WriteUInt16(0);
            Debug.Assert(writer.Count == SizeOfNameTable);

            writer.WriteContentTo(peStream);
        }
コード例 #32
0
ファイル: BlobTests.cs プロジェクト: ESgarbi/corefx
        public void WriteContentToStream()
        {
            var builder = new BlobBuilder(16);
            for (int i = 0; i < 20; i++)
            {
                builder.WriteByte((byte)i);
            }

            var stream = new MemoryStream();
            builder.WriteContentTo(stream);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
            }, stream.ToArray());

            builder.WriteByte(0xff);

            builder.WriteContentTo(stream);
            AssertEx.Equal(new byte[]
            {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
                0xff,
            }, stream.ToArray());
        }
コード例 #33
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private static void WriteCorHeader(Stream peStream, CorHeader corHeader)
        {
            var writer = new BlobBuilder(CorHeaderSize);
            writer.WriteUInt32(CorHeaderSize);
            writer.WriteUInt16(corHeader.MajorRuntimeVersion);
            writer.WriteUInt16(corHeader.MinorRuntimeVersion); 
            writer.WriteUInt32((uint)corHeader.MetadataDirectory.RelativeVirtualAddress); 
            writer.WriteUInt32((uint)corHeader.MetadataDirectory.Size);
            writer.WriteUInt32((uint)corHeader.Flags);
            writer.WriteUInt32((uint)corHeader.EntryPointTokenOrRelativeVirtualAddress);
            writer.WriteUInt32((uint)(corHeader.ResourcesDirectory.Size == 0 ? 0 : corHeader.ResourcesDirectory.RelativeVirtualAddress)); // 28
            writer.WriteUInt32((uint)corHeader.ResourcesDirectory.Size);
            writer.WriteUInt32((uint)(corHeader.StrongNameSignatureDirectory.Size == 0 ? 0 : corHeader.StrongNameSignatureDirectory.RelativeVirtualAddress)); // 36
            writer.WriteUInt32((uint)corHeader.StrongNameSignatureDirectory.Size);
            writer.WriteUInt32((uint)corHeader.CodeManagerTableDirectory.RelativeVirtualAddress); 
            writer.WriteUInt32((uint)corHeader.CodeManagerTableDirectory.Size); 
            writer.WriteUInt32((uint)corHeader.VtableFixupsDirectory.RelativeVirtualAddress); 
            writer.WriteUInt32((uint)corHeader.VtableFixupsDirectory.Size); 
            writer.WriteUInt32((uint)corHeader.ExportAddressTableJumpsDirectory.RelativeVirtualAddress);
            writer.WriteUInt32((uint)corHeader.ExportAddressTableJumpsDirectory.Size);
            writer.WriteUInt64(0);
            Debug.Assert(writer.Count == CorHeaderSize);
            Debug.Assert(writer.Count % 4 == 0);

            writer.WriteContentTo(peStream);
        }
コード例 #34
0
ファイル: PeWriter.cs プロジェクト: XieShuquan/roslyn
        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.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((uint)MetadataTokens.GetToken(debugEntryPointHandle));
            }

            if (nativePdbWriterOpt != null)
            {
                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
                }

                // embedded text not currently supported for native PDB and we should have validated that
                Debug.Assert(!mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments.Any());
            }

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

            var deterministicIdProvider = isDeterministic ?
                new Func<IEnumerable<Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) :
                null;

            BlobBuilder portablePdbToEmbed = null;
            if (mdWriter.EmitStandaloneDebugMetadata)
            {
                mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);

                var portablePdbBlob = new BlobBuilder();
                var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes, debugEntryPointHandle, deterministicIdProvider);
                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)
                    {
                        portablePdbBlob.WriteContentTo(portablePdbStream);
                    }
                }
            }

            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 (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }

                if (portablePdbToEmbed != null)
                {
                    debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion);
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

            var peBuilder = new ManagedPEBuilder(
                peHeaderBuilder,
                metadataRootBuilder,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                CreateNativeResourceSectionSerializer(context.Module),
                debugDirectoryBuilder,
                CalculateStrongNameSignatureSize(context.Module),
                entryPointHandle,
                properties.CorFlags,
                deterministicIdProvider);

            var peBlob = new BlobBuilder();
            var peContentId = peBuilder.Serialize(peBlob);

            PatchModuleVersionIds(mvidFixup, mvidStringFixup, peContentId.Guid);

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when (!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return true;
        }
コード例 #35
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteRelocSection(Stream peStream, SectionHeader relocSection, int entryPointAddress)
        {
            peStream.Position = relocSection.PointerToRawData;
            var writer = new BlobBuilder(relocSection.SizeOfRawData);
            writer.WriteUInt32((((uint)entryPointAddress + 2) / 0x1000) * 0x1000);
            writer.WriteUInt32(_properties.Requires64bits && !_properties.RequiresAmdInstructionSet ? 14u : 12u);
            uint offsetWithinPage = ((uint)entryPointAddress + 2) % 0x1000;
            uint relocType = _properties.Requires64bits ? 10u : 3u;
            ushort s = (ushort)((relocType << 12) | offsetWithinPage);
            writer.WriteUInt16(s);
            if (_properties.Requires64bits && !_properties.RequiresAmdInstructionSet)
            {
                writer.WriteUInt32(relocType << 12);
            }

            writer.WriteUInt16(0); // next chunk's RVA
            writer.PadTo(relocSection.SizeOfRawData);
            writer.WriteContentTo(peStream);
        }
コード例 #36
0
 public ExceptionRegionEncoder WriteInstructions(BlobBuilder codeBuilder, out int bodyOffset)
 {
     bodyOffset = WriteHeader(codeBuilder.Count);
     codeBuilder.WriteContentTo(Builder);
     return(CreateExceptionEncoder());
 }
コード例 #37
0
 public ExceptionRegionEncoder WriteInstructions(BlobBuilder buffer, out int offset)
 {
     offset = WriteHeader(buffer.Count);
     buffer.WriteContentTo(Builder);
     return(CreateExceptionEncoder());
 }
コード例 #38
0
        public static void Convert(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream)
        {
            var metadataBuilder = new MetadataBuilder();
            ImmutableArray <int> typeSystemRowCounts;
            var debugEntryPointToken = default(MethodDefinitionHandle);
            var pdbId = default(BlobContentId);

            try
            {
                using (var peReader = new PEReader(peStream))
                {
                    pdbId = ReadPdbId(peReader);

                    var symReader = SymReaderFactory.CreateWindowsPdbReader(sourcePdbStream, peReader);

                    var metadataReader = peReader.GetMetadataReader();
                    var metadataModel  = new MetadataModel(metadataReader);

                    typeSystemRowCounts  = metadataModel.GetRowCounts();
                    debugEntryPointToken = ReadEntryPointHandle(symReader);

                    // documents:
                    var documentIndex = new Dictionary <string, DocumentHandle>(StringComparer.Ordinal);
                    var documents     = symReader.GetDocuments();
                    metadataBuilder.SetCapacity(TableIndex.Document, documents.Length);

                    bool vbSemantics = false;

                    foreach (var document in documents)
                    {
                        string name     = document.GetName();
                        Guid   language = document.GetLanguage();

                        // TODO:
                        // won't work for IL-merged assmemblies
                        vbSemantics |= language == SymReaderHelpers.VisualBasicLanguageGuid;

                        var rid = metadataBuilder.AddDocument(
                            name: metadataBuilder.GetOrAddDocumentName(name),
                            hashAlgorithm: metadataBuilder.GetOrAddGuid(document.GetHashAlgorithm()),
                            hash: metadataBuilder.GetOrAddBlob(document.GetChecksum()),
                            language: metadataBuilder.GetOrAddGuid(language));

                        documentIndex.Add(name, rid);
                    }

                    var lastLocalVariableHandle = default(LocalVariableHandle);
                    var lastLocalConstantHandle = default(LocalConstantHandle);

                    var importStringsByMethod = new Dictionary <int, ImmutableArray <string> >();
                    var importScopesByMethod  = new Dictionary <int, ImportScopeHandle>();

                    // Maps import scope content to import scope handles
                    var importScopeIndex = new Dictionary <ImportScopeInfo, ImportScopeHandle>();
                    var importScopes     = new List <ImportScopeInfo>();

                    // reserve slot for module import scope:
                    importScopes.Add(default(ImportScopeInfo));

                    var externAliasImports   = new List <ImportInfo>();
                    var externAliasStringSet = new HashSet <string>(StringComparer.Ordinal);

                    string vbDefaultNamespace    = null;
                    var    vbProjectLevelImports = new List <ImportInfo>();

                    // first pass:
                    foreach (var methodHandle in metadataReader.MethodDefinitions)
                    {
                        int methodToken = MetadataTokens.GetToken(methodHandle);
                        ImmutableArray <ImmutableArray <ImportInfo> > importGroups;

                        if (vbSemantics)
                        {
                            var importStrings = CustomDebugInfoReader.GetVisualBasicImportStrings(
                                methodToken,
                                symReader,
                                getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr));

                            if (importStrings.IsEmpty)
                            {
                                // no debug info
                                continue;
                            }

                            var vbFileLevelImports = ArrayBuilder <ImportInfo> .GetInstance();

                            foreach (var importString in importStrings)
                            {
                                if (TryParseImportString(importString, out var import, vbSemantics: true))
                                {
                                    if (import.Kind == ImportTargetKind.DefaultNamespace)
                                    {
                                        vbDefaultNamespace = import.Target;
                                    }
                                    else if (import.Scope == VBImportScopeKind.Project)
                                    {
                                        vbProjectLevelImports.Add(import);
                                    }
                                    else
                                    {
                                        vbFileLevelImports.Add(import);
                                    }
                                }
                            }

                            importGroups = ImmutableArray.Create(vbFileLevelImports.ToImmutableAndFree());
                        }
                        else
                        {
                            var importStringGroups = CustomDebugInfoReader.GetCSharpGroupedImportStrings(
                                methodToken,
                                symReader,
                                getMethodCustomDebugInfo: (token, sr) => sr.GetCustomDebugInfo(token, methodVersion: 1),
                                getMethodImportStrings: (token, sr) => GetImportStrings(token, importStringsByMethod, sr),
                                externAliasStrings: out var localExternAliasStrings);

                            if (importStringGroups.IsDefault)
                            {
                                // no debug info
                                continue;
                            }

                            if (!localExternAliasStrings.IsDefault)
                            {
                                foreach (var externAlias in localExternAliasStrings)
                                {
                                    if (externAliasStringSet.Add(externAlias) &&
                                        TryParseImportString(externAlias, out var import, vbSemantics: false))
                                    {
                                        externAliasImports.Add(import);
                                    }
                                }
                            }

                            importGroups = ImmutableArray.CreateRange(importStringGroups.Select(g => ParseImportStrings(g, vbSemantics: false)));
                        }

                        var importScopeHandle = DefineImportScope(importGroups, importScopeIndex, importScopes);
                        importScopesByMethod.Add(methodToken, importScopeHandle);
                    }

                    // import scopes:
                    metadataBuilder.AddImportScope(
                        parentScope: default(ImportScopeHandle),
                        imports: SerializeModuleImportScope(metadataBuilder, externAliasImports, vbProjectLevelImports, vbDefaultNamespace, metadataModel));

                    for (int i = 1; i < importScopes.Count; i++)
                    {
                        metadataBuilder.AddImportScope(
                            parentScope: importScopes[i].Parent,
                            imports: SerializeImportsBlob(metadataBuilder, importScopes[i].Imports, metadataModel));
                    }

                    var dynamicNames = new Dictionary <string, DynamicLocalInfo>();
                    var dynamicSlots = new Dictionary <int, DynamicLocalInfo>();

                    // methods:
                    metadataBuilder.SetCapacity(TableIndex.MethodDebugInformation, metadataReader.MethodDefinitions.Count);
                    foreach (var methodHandle in metadataReader.MethodDefinitions)
                    {
                        var methodDef   = metadataReader.GetMethodDefinition(methodHandle);
                        int methodToken = MetadataTokens.GetToken(methodHandle);

                        var symMethod = symReader.GetMethod(methodToken);
                        if (symMethod == null)
                        {
                            metadataBuilder.AddMethodDebugInformation(default(DocumentHandle), sequencePoints: default(BlobHandle));
                            continue;
                        }

                        // method debug info:
                        int localSignatureRowId;
                        if (methodDef.RelativeVirtualAddress != 0)
                        {
                            var methodBody = peReader.GetMethodBody(methodDef.RelativeVirtualAddress);
                            localSignatureRowId = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetRowNumber(methodBody.LocalSignature);
                        }
                        else
                        {
                            localSignatureRowId = 0;
                        }

                        var symSequencePoints = symMethod.GetSequencePoints().ToImmutableArray();

                        DocumentHandle singleDocumentHandle;
                        BlobHandle     sequencePointsBlob = SerializeSequencePoints(metadataBuilder, localSignatureRowId, symSequencePoints, documentIndex, out singleDocumentHandle);

                        metadataBuilder.AddMethodDebugInformation(
                            document: singleDocumentHandle,
                            sequencePoints: sequencePointsBlob);

                        // state machine and async info:
                        var symAsyncMethod = symMethod.AsAsyncMethod();
                        if (symAsyncMethod != null)
                        {
                            var kickoffToken = MetadataTokens.Handle(symAsyncMethod.GetKickoffMethod());
                            metadataBuilder.AddStateMachineMethod(
                                moveNextMethod: methodHandle,
                                kickoffMethod: (MethodDefinitionHandle)kickoffToken);

                            metadataBuilder.AddCustomDebugInformation(
                                parent: methodHandle,
                                kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.AsyncMethodSteppingInformationBlob),
                                value: SerializeAsyncMethodSteppingInfo(metadataBuilder, symAsyncMethod, MetadataTokens.GetRowNumber(methodHandle)));
                        }

                        // custom debug information:
                        var dynamicLocals = default(ImmutableArray <DynamicLocalInfo>);

                        byte[] customDebugInfoBytes = symReader.GetCustomDebugInfo(methodToken, methodVersion: 1);
                        if (customDebugInfoBytes != null)
                        {
                            foreach (var record in CustomDebugInfoReader.GetCustomDebugInfoRecords(customDebugInfoBytes))
                            {
                                switch (record.Kind)
                                {
                                case CustomDebugInfoKind.DynamicLocals:
                                    dynamicLocals = CustomDebugInfoReader.DecodeDynamicLocalsRecord(record.Data);
                                    break;

                                case CustomDebugInfoKind.StateMachineHoistedLocalScopes:
                                    metadataBuilder.AddCustomDebugInformation(
                                        parent: methodHandle,
                                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap),
                                        value: SerializeStateMachineHoistedLocalsBlob(metadataBuilder, CustomDebugInfoReader.DecodeStateMachineHoistedLocalScopesRecord(record.Data)));
                                    break;

                                case CustomDebugInfoKind.EditAndContinueLocalSlotMap:
                                    metadataBuilder.AddCustomDebugInformation(
                                        parent: methodHandle,
                                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLocalSlotMap),
                                        value: metadataBuilder.GetOrAddBlob(record.Data));
                                    break;

                                case CustomDebugInfoKind.EditAndContinueLambdaMap:
                                    metadataBuilder.AddCustomDebugInformation(
                                        parent: methodHandle,
                                        kind: metadataBuilder.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap),
                                        value: metadataBuilder.GetOrAddBlob(record.Data));
                                    break;
                                }
                            }
                        }

                        var rootScope = symMethod.GetRootScope();
                        if (rootScope.GetNamespaces().Length == 0 || rootScope.GetLocals().Length == 0 || rootScope.GetConstants().Length == 0)
                        {
                            dynamicNames.Clear();
                            dynamicSlots.Clear();

                            foreach (var dynamicLocal in dynamicLocals)
                            {
                                if (dynamicLocal.SlotId == 0)
                                {
                                    // All dynamic constants have slot id == 0,
                                    // but a variable can also have slot id == 0
                                    if (!dynamicNames.ContainsKey(dynamicLocal.LocalName))
                                    {
                                        dynamicNames.Add(dynamicLocal.LocalName, dynamicLocal);
                                    }
                                    else
                                    {
                                        // TODO: warning
                                    }
                                }
                                else if (!dynamicSlots.ContainsKey(dynamicLocal.SlotId))
                                {
                                    dynamicSlots.Add(dynamicLocal.SlotId, dynamicLocal);
                                }
                                else
                                {
                                    // TODO: warning
                                }
                            }

                            foreach (ISymUnmanagedScope scope in rootScope.GetChildren())
                            {
                                SerializeScope(
                                    metadataBuilder,
                                    metadataModel,
                                    methodHandle,
                                    importScopesByMethod[methodToken],
                                    scope,
                                    dynamicSlots,
                                    dynamicNames,
                                    vbSemantics,
                                    ref lastLocalVariableHandle,
                                    ref lastLocalConstantHandle);
                            }
                        }
                        else
                        {
                            // TODO: warning:
                            // "Root scope must be empty (method 0x{0:x8})", MetadataTokens.GetToken(methodHandle))
                        }
                    }
                }
            }
            catch (COMException e)
            {
                // TODO: loc
                throw new BadImageFormatException("Invalid PDB format: " + e.Message, e);
            }

            var         serializer  = new PortablePdbBuilder(metadataBuilder, typeSystemRowCounts, debugEntryPointToken, idProvider: _ => pdbId);
            BlobBuilder blobBuilder = new BlobBuilder();

            serializer.Serialize(blobBuilder);
            blobBuilder.WriteContentTo(targetPdbStream);
        }
コード例 #39
0
ファイル: BlobWriter.cs プロジェクト: Rickinio/roslyn
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public void WriteBytes(BlobBuilder source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            source.WriteContentTo(ref this);
        }
コード例 #40
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteTextSection(
            Stream peStream,
            SectionHeader textSection,
            int importTableRva,
            int importAddressTableRva,
            int entryPointToken,
            BlobBuilder metadataWriter,
            BlobBuilder ilWriter,
            BlobBuilder mappedFieldDataWriter,
            BlobBuilder managedResourceWriter,
            MetadataSizes metadataSizes,
            ContentId nativePdbContentId,
            ContentId portablePdbContentId,
            out long metadataPosition)
        {
            // TODO: zero out all bytes:
            peStream.Position = textSection.PointerToRawData;

            if (_properties.RequiresStartupStub)
            {
                WriteImportAddressTable(peStream, importTableRva);
            }

            var corHeader = CreateCorHeader(metadataSizes, textSection.RelativeVirtualAddress, entryPointToken);
            WriteCorHeader(peStream, corHeader);

            // IL:
            ilWriter.Align(4);
            ilWriter.WriteContentTo(peStream);

            // metadata:
            metadataPosition = peStream.Position;
            Debug.Assert(metadataWriter.Count % 4 == 0);
            metadataWriter.WriteContentTo(peStream);

            // managed resources:
            Debug.Assert(managedResourceWriter.Count % 4 == 0);
            managedResourceWriter.WriteContentTo(peStream);

            // strong name signature:
            WriteSpaceForHash(peStream, metadataSizes.StrongNameSignatureSize);

            if (EmitPdb)
            {
                WriteDebugTable(peStream, textSection, nativePdbContentId, portablePdbContentId, metadataSizes);
            }

            if (_properties.RequiresStartupStub)
            {
                WriteImportTable(peStream, importTableRva, importAddressTableRva);
                WriteNameTable(peStream);
                WriteRuntimeStartupStub(peStream, importAddressTableRva);
            }

            // mapped field data:            
            mappedFieldDataWriter.WriteContentTo(peStream);

            // TODO: zero out all bytes:
            int alignedPosition = textSection.PointerToRawData + textSection.SizeOfRawData;
            if (peStream.Position != alignedPosition)
            {
                peStream.Position = alignedPosition - 1;
                peStream.WriteByte(0);
            }
        }
コード例 #41
0
 public ExceptionRegionEncoder WriteInstructions(BlobBuilder codeBuilder, out int bodyOffset)
 {
     bodyOffset = WriteHeader(codeBuilder.Count);
     codeBuilder.WriteContentTo(Builder);
     return CreateExceptionEncoder();
 }
コード例 #42
0
ファイル: PeWriter.cs プロジェクト: noahfalk/roslyn
        private void WriteImportAddressTable(Stream peStream, int importTableRva)
        {
            var writer = new BlobBuilder(SizeOfImportAddressTable);
            int ilRVA = importTableRva + 40;
            int hintRva = ilRVA + (_is32bit ? 12 : 16);

            // Import Address Table
            if (_is32bit)
            {
                writer.WriteUInt32((uint)hintRva); // 4
                writer.WriteUInt32(0); // 8
            }
            else
            {
                writer.WriteUInt64((uint)hintRva); // 8
                writer.WriteUInt64(0); // 16
            }

            Debug.Assert(writer.Count == SizeOfImportAddressTable);
            writer.WriteContentTo(peStream);
        }
コード例 #43
0
ファイル: PeWriter.cs プロジェクト: stark-lang/stark
        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 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))
            {
                strongNameProvider.SignBuilder(peBuilder, peBlob, privateKeyOpt.Value);
            }

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when(!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return(true);
        }
コード例 #44
0
        public PermissionSetEncoder AddPermission(string typeName, BlobBuilder encodedArguments)
        {
            if (typeName == null)
            {
                Throw.ArgumentNull(nameof(typeName));
            }

            if (encodedArguments == null)
            {
                Throw.ArgumentNull(nameof(encodedArguments));
            }

            if (encodedArguments.Count > BlobWriterImpl.MaxCompressedIntegerValue)
            {
                Throw.BlobTooLarge(nameof(encodedArguments));
            }

            Builder.WriteSerializedString(typeName);
            Builder.WriteCompressedInteger(encodedArguments.Count);
            encodedArguments.WriteContentTo(Builder);
            return new PermissionSetEncoder(Builder);
        }