internal static void WriteCompressedSignedInteger(ref BlobWriter writer, int value)
        {
            unchecked
            {
                const int b6  = (1 << 6) - 1;
                const int b13 = (1 << 13) - 1;
                const int b28 = (1 << 28) - 1;

                // 0xffffffff for negative value
                // 0x00000000 for non-negative
                int signMask = value >> 31;

                if ((value & ~b6) == (signMask & ~b6))
                {
                    int n = ((value & b6) << 1) | (signMask & 1);
                    writer.WriteByte((byte)n);
                }
                else if ((value & ~b13) == (signMask & ~b13))
                {
                    int n = ((value & b13) << 1) | (signMask & 1);
                    writer.WriteUInt16BE((ushort)(0x8000 | n));
                }
                else if ((value & ~b28) == (signMask & ~b28))
                {
                    int n = ((value & b28) << 1) | (signMask & 1);
                    writer.WriteUInt32BE(0xc0000000 | (uint)n);
                }
                else
                {
                    Throw.ValueArgumentOutOfRange();
                }
            }
        }
Exemplo n.º 2
0
        internal static void WriteCompressedSignedInteger(ref BlobWriter writer, int value)
        {
            unchecked
            {
                const int b6 = (1 << 6) - 1;
                const int b13 = (1 << 13) - 1;
                const int b28 = (1 << 28) - 1;

                // 0xffffffff for negative value
                // 0x00000000 for non-negative
                int signMask = value >> 31;

                if ((value & ~b6) == (signMask & ~b6))
                {
                    int n = ((value & b6) << 1) | (signMask & 1);
                    writer.WriteByte((byte)n);
                }
                else if ((value & ~b13) == (signMask & ~b13))
                {
                    int n = ((value & b13) << 1) | (signMask & 1);
                    writer.WriteUInt16BE((ushort)(0x8000 | n));
                }
                else if ((value & ~b28) == (signMask & ~b28))
                {
                    int n = ((value & b28) << 1) | (signMask & 1);
                    writer.WriteUInt32BE(0xc0000000 | (uint)n);
                }
                else
                {
                    Throw.ValueArgumentOutOfRange();
                }
            }
        }
Exemplo n.º 3
0
        /// <exception cref="ArgumentNullException"><paramref name="destination"/> is default(<see cref="BlobWriter"/>).</exception>
        /// <exception cref="InvalidOperationException">Content is not available, the builder has been linked with another one.</exception>
        public void WriteContentTo(ref BlobWriter destination)
        {
            if (destination.IsDefault)
            {
                Throw.ArgumentNull(nameof(destination));
            }

            foreach (var chunk in GetChunks())
            {
                destination.WriteBytes(chunk._buffer, 0, chunk.Length);
            }
        }
Exemplo n.º 4
0
        public void SerializeMetadata(BlobBuilder builder, Func<BlobBuilder, ContentId> idProvider, out ContentId contentId)
        {
            SerializeMetadataImpl(builder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0);

            contentId = idProvider(builder);

            // fill in the id:
            var idWriter = new BlobWriter(_pdbIdBlob);
            idWriter.WriteBytes(contentId.Guid);
            idWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(idWriter.RemainingBytes == 0);
        }
Exemplo n.º 5
0
 internal static void WriteCompressedInteger(ref BlobWriter writer, uint value)
 {
     unchecked
     {
         if (value <= SingleByteCompressedIntegerMaxValue)
         {
             writer.WriteByte((byte)value);
         }
         else if (value <= TwoByteCompressedIntegerMaxValue)
         {
             writer.WriteUInt16BE((ushort)(0x8000 | value));
         }
         else if (value <= MaxCompressedIntegerValue)
         {
             writer.WriteUInt32BE(0xc0000000 | value);
         }
         else
         {
             Throw.ValueArgumentOutOfRange();
         }
     }
 }
 internal static void WriteCompressedInteger(ref BlobWriter writer, uint value)
 {
     unchecked
     {
         if (value <= SingleByteCompressedIntegerMaxValue)
         {
             writer.WriteByte((byte)value);
         }
         else if (value <= TwoByteCompressedIntegerMaxValue)
         {
             writer.WriteUInt16BE((ushort)(0x8000 | value));
         }
         else if (value <= MaxCompressedIntegerValue)
         {
             writer.WriteUInt32BE(0xc0000000 | value);
         }
         else
         {
             Throw.ValueArgumentOutOfRange();
         }
     }
 }
Exemplo n.º 7
0
        public void Sign(BlobBuilder peImage, Func<IEnumerable<Blob>, byte[]> signatureProvider)
        {
            if (peImage == null)
            {
                throw new ArgumentNullException(nameof(peImage));
            }

            if (signatureProvider == null)
            {
                throw new ArgumentNullException(nameof(signatureProvider));
            }

            var content = GetContentToSign(peImage);
            byte[] signature = signatureProvider(content);

            // signature may be shorter (the rest of the reserved space is padding):
            if (signature == null || signature.Length > _lazyStrongNameSignature.Length)
            {
                throw new InvalidOperationException(SR.SignatureProviderReturnedInvalidSignature);
            }

            // TODO: Native csc also calculates and fills checksum in the PE header
            // Using MapFileAndCheckSum() from imagehlp.dll.

            var writer = new BlobWriter(_lazyStrongNameSignature);
            writer.WriteBytes(signature);
        }
Exemplo n.º 8
0
        internal static void WriteConstant(ref BlobWriter writer, object value)
        {
            if (value == null)
            {
                // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit.
                writer.WriteUInt32(0);
                return;
            }

            var type = value.GetType();
            if (type.GetTypeInfo().IsEnum)
            {
                type = Enum.GetUnderlyingType(type);
            }

            if (type == typeof(bool))
            {
                writer.WriteBoolean((bool)value);
            }
            else if (type == typeof(int))
            {
                writer.WriteInt32((int)value);
            }
            else if (type == typeof(string))
            {
                writer.WriteUTF16((string)value);
            }
            else if (type == typeof(byte))
            {
                writer.WriteByte((byte)value);
            }
            else if (type == typeof(char))
            {
                writer.WriteUInt16((char)value);
            }
            else if (type == typeof(double))
            {
                writer.WriteDouble((double)value);
            }
            else if (type == typeof(short))
            {
                writer.WriteInt16((short)value);
            }
            else if (type == typeof(long))
            {
                writer.WriteInt64((long)value);
            }
            else if (type == typeof(sbyte))
            {
                writer.WriteSByte((sbyte)value);
            }
            else if (type == typeof(float))
            {
                writer.WriteSingle((float)value);
            }
            else if (type == typeof(ushort))
            {
                writer.WriteUInt16((ushort)value);
            }
            else if (type == typeof(uint))
            {
                writer.WriteUInt32((uint)value);
            }
            else if (type == typeof(ulong))
            {
                writer.WriteUInt64((ulong)value);
            }
            else
            {
                throw new ArgumentException(SR.Format(SR.InvalidConstantValueOfType, type));
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Compares the current content of this writer with another one.
 /// </summary>
 public bool ContentEquals(BlobWriter other)
 {
     return Length == other.Length && ByteSequenceComparer.Equals(_buffer, _start, other._buffer, other._start, Length);
 }
Exemplo n.º 10
0
 /// <summary>
 /// Compares the current content of this writer with another one.
 /// </summary>
 public bool ContentEquals(BlobWriter other)
 {
     return(Length == other.Length && ByteSequenceComparer.Equals(_buffer, _start, other._buffer, other._start, Length));
 }
        internal static void WriteConstant(ref BlobWriter writer, object?value)
        {
            if (value == null)
            {
                // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit.
                writer.WriteUInt32(0);
                return;
            }

            var type = value.GetType();

            if (type.GetTypeInfo().IsEnum)
            {
                type = Enum.GetUnderlyingType(type);
            }

            if (type == typeof(bool))
            {
                writer.WriteBoolean((bool)value);
            }
            else if (type == typeof(int))
            {
                writer.WriteInt32((int)value);
            }
            else if (type == typeof(string))
            {
                writer.WriteUTF16((string)value);
            }
            else if (type == typeof(byte))
            {
                writer.WriteByte((byte)value);
            }
            else if (type == typeof(char))
            {
                writer.WriteUInt16((char)value);
            }
            else if (type == typeof(double))
            {
                writer.WriteDouble((double)value);
            }
            else if (type == typeof(short))
            {
                writer.WriteInt16((short)value);
            }
            else if (type == typeof(long))
            {
                writer.WriteInt64((long)value);
            }
            else if (type == typeof(sbyte))
            {
                writer.WriteSByte((sbyte)value);
            }
            else if (type == typeof(float))
            {
                writer.WriteSingle((float)value);
            }
            else if (type == typeof(ushort))
            {
                writer.WriteUInt16((ushort)value);
            }
            else if (type == typeof(uint))
            {
                writer.WriteUInt32((uint)value);
            }
            else if (type == typeof(ulong))
            {
                writer.WriteUInt64((ulong)value);
            }
            else
            {
                throw new ArgumentException(SR.Format(SR.InvalidConstantValueOfType, type));
            }
        }
Exemplo n.º 12
0
        /// <exception cref="ArgumentNullException"><paramref name="destination"/> is default(<see cref="BlobWriter"/>).</exception>
        /// <exception cref="InvalidOperationException">Content is not available, the builder has been linked with another one.</exception>
        public void WriteContentTo(ref BlobWriter destination)
        {
            if (destination.IsDefault)
            {
                Throw.ArgumentNull(nameof(destination));
            }

            foreach (var chunk in GetChunks())
            {
                destination.WriteBytes(chunk._buffer, 0, chunk.Length);
            }
        }
Exemplo n.º 13
0
        public BlobContentId Serialize(BlobBuilder builder)
        {
            // Define and serialize sections in two steps.
            // We need to know about all sections before serializing them.
            var serializedSections = SerializeSections();

            // The positions and sizes of directories are calculated during section serialization.
            var directories = GetDirectories();

            Blob stampFixup;
            WritePESignature(builder);
            WriteCoffHeader(builder, serializedSections, out stampFixup);
            WritePEHeader(builder, directories, serializedSections);
            WriteSectionHeaders(builder, serializedSections);
            builder.Align(Header.FileAlignment);

            foreach (var section in serializedSections)
            {
                builder.LinkSuffix(section.Builder);
                builder.Align(Header.FileAlignment);
            }

            var contentId = IdProvider(builder.GetBlobs());

            // patch timestamp in COFF header:
            var stampWriter = new BlobWriter(stampFixup);
            stampWriter.WriteUInt32(contentId.Stamp);
            Debug.Assert(stampWriter.RemainingBytes == 0);

            return contentId;
        }
Exemplo n.º 14
0
        internal void Sign(BlobBuilder peImage, Blob strongNameSignatureFixup, Func<IEnumerable<Blob>, byte[]> signatureProvider)
        {
            Debug.Assert(peImage != null);
            Debug.Assert(signatureProvider != null);

            int peHeadersSize = Header.ComputeSizeOfPEHeaders(GetSections().Length);
            byte[] signature = signatureProvider(GetContentToSign(peImage, peHeadersSize, Header.FileAlignment, strongNameSignatureFixup));

            // signature may be shorter (the rest of the reserved space is padding):
            if (signature == null || signature.Length > strongNameSignatureFixup.Length)
            {
                throw new InvalidOperationException(SR.SignatureProviderReturnedInvalidSignature);
            }

            uint checksum = CalculateChecksum(peImage, _lazyChecksum);
            new BlobWriter(_lazyChecksum).WriteUInt32(checksum);

            var writer = new BlobWriter(strongNameSignatureFixup);
            writer.WriteBytes(signature);
        }
Exemplo n.º 15
0
        public void Serialize(BlobBuilder builder, PEDirectoriesBuilder headers, out ContentId contentId)
        {
            var serializedSections = SerializeSections();
            Blob stampFixup;

            WritePESignature(builder);
            WriteCoffHeader(builder, serializedSections, out stampFixup);
            WritePEHeader(builder, headers, serializedSections);
            WriteSectionHeaders(builder, serializedSections);
            builder.Align(FileAlignment);

            foreach (var section in serializedSections)
            {
                builder.LinkSuffix(section.Builder);
                builder.Align(FileAlignment);
            }

            contentId = IdProvider(builder);

            // patch timestamp in COFF header:
            var stampWriter = new BlobWriter(stampFixup);
            stampWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(stampWriter.RemainingBytes == 0);
        }