Ejemplo n.º 1
0
        private static void SerializeStateMachineLocalScopes(IMethodBody methodBody, ArrayBuilder <BlobWriter> customDebugInfo)
        {
            var scopes = methodBody.StateMachineHoistedLocalScopes;

            if (scopes.IsDefaultOrEmpty)
            {
                return;
            }

            uint numberOfScopes = (uint)scopes.Length;
            var  cmw            = new BlobWriter();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(CDI.CdiKindStateMachineHoistedLocalScopes);
            cmw.Align(4);
            cmw.WriteUint(12 + numberOfScopes * 8);
            cmw.WriteUint(numberOfScopes);
            foreach (var scope in scopes)
            {
                if (scope.IsDefault)
                {
                    cmw.WriteUint(0);
                    cmw.WriteUint(0);
                }
                else
                {
                    // Dev12 C# emits end-inclusive range
                    cmw.WriteUint((uint)scope.StartOffset);
                    cmw.WriteUint((uint)scope.EndOffset - 1);
                }
            }

            customDebugInfo.Add(cmw);
        }
Ejemplo n.º 2
0
        private static void WriteAligned(BlobWriter source, BlobWriter target)
        {
            int length = source.Length;

            source.WriteTo(target);
            target.Write(0, BitArithmeticUtilities.Align(length, 4) - length);
        }
Ejemplo n.º 3
0
        public void WriteData(BlobWriter resourceWriter)
        {
            if (_fileReference == null)
            {
                try
                {
                    using (Stream stream = _streamProvider())
                    {
                        if (stream == null)
                        {
                            throw new InvalidOperationException(CodeAnalysisResources.ResourceStreamProviderShouldReturnNonNullStream);
                        }

                        var count = (int)(stream.Length - stream.Position);
                        resourceWriter.WriteInt(count);

                        resourceWriter.Write(stream, count);
                        resourceWriter.Align(8);
                    }
                }
                catch (Exception e)
                {
                    throw new ResourceException(_name, e);
                }
            }
        }
Ejemplo n.º 4
0
        // internal for testing
        internal static byte[] SerializeCustomDebugMetadata(ArrayBuilder <PooledBlobBuilder> recordWriters)
        {
            if (recordWriters.Count == 0)
            {
                return(null);
            }

            int records = 0;

            foreach (var rec in recordWriters)
            {
                records += rec.Count;
            }

            var result = new byte[
                sizeof(byte) +                  // version
                sizeof(byte) +                  // record count
                sizeof(ushort) +                // padding
                records                         // records
                         ];

            var cmw = new BlobWriter(result);

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte((byte)recordWriters.Count); // count
            cmw.WriteInt16(0);
            foreach (var recordWriter in recordWriters)
            {
                cmw.WriteBytes(recordWriter);
            }

            return(result);
        }
Ejemplo n.º 5
0
        public void WriteData(BlobWriter resourceWriter)
        {
            if (_fileReference == null)
            {
                try
                {
                    using (Stream stream = _streamProvider())
                    {
                        if (stream == null)
                        {
                            throw new InvalidOperationException(CodeAnalysisResources.ResourceStreamProviderShouldReturnNonNullStream);
                        }

                        var count = (int)(stream.Length - stream.Position);
                        resourceWriter.WriteInt(count);

                        var position = (int)resourceWriter.Position;
                        resourceWriter.Position = (uint)(position + count);
                        resourceWriter.Align(8);

                        var buffer = resourceWriter.Buffer;
                        stream.Read(buffer, position, count);
                    }
                }
                catch (Exception e)
                {
                    throw new ResourceException(_name, e);
                }
            }
        }
Ejemplo n.º 6
0
        private static BlobWriter SerializeRecord(byte kind, Action <BlobWriter> data)
        {
            var cmw = new BlobWriter();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(kind);
            cmw.WriteByte(0);

            // alignment size (will be patched)
            int alignmentSizeAndLengthPosition = cmw.Position;

            cmw.WriteByte(0);

            // length (will be patched)
            cmw.WriteUint(0);

            data(cmw);

            int  length        = cmw.Position;
            int  alignedLength = 4 * ((length + 3) / 4);
            byte alignmentSize = (byte)(alignedLength - length);

            for (int i = 0; i < alignmentSize; i++)
            {
                cmw.WriteByte(0);
            }

            cmw.Position = alignmentSizeAndLengthPosition;
            cmw.WriteByte(alignmentSize);
            cmw.WriteUint((uint)alignedLength);

            cmw.Position = length;
            return(cmw);
        }
Ejemplo n.º 7
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
                {
                    ThrowValueArgumentOutOfRange();
                }
            }
        }
Ejemplo n.º 8
0
        private static PooledBlobBuilder SerializeRecord(
            byte kind,
            EditAndContinueMethodDebugInformation debugInfo,
            Action <EditAndContinueMethodDebugInformation, BlobBuilder> recordSerializer)
        {
            var cmw = PooledBlobBuilder.GetInstance();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(kind);
            cmw.WriteByte(0);

            // alignment size and length (will be patched)
            var alignmentSizeAndLengthWriter = new BlobWriter(cmw.ReserveBytes(sizeof(byte) + sizeof(uint)));

            recordSerializer(debugInfo, cmw);

            int  length        = cmw.Count;
            int  alignedLength = 4 * ((length + 3) / 4);
            byte alignmentSize = (byte)(alignedLength - length);

            cmw.WriteBytes(0, alignmentSize);

            // fill in alignment size and length:
            alignmentSizeAndLengthWriter.WriteByte(alignmentSize);
            alignmentSizeAndLengthWriter.WriteUInt32((uint)alignedLength);

            return(cmw);
        }
Ejemplo n.º 9
0
        private static PooledBlobBuilder SerializeRecord <T>(
            CustomDebugInfoKind kind,
            T debugInfo,
            Action <T, BlobBuilder> recordSerializer)
        {
            PooledBlobBuilder cmw = PooledBlobBuilder.GetInstance();

            cmw.WriteByte(CustomDebugInfoConstants.Version);
            cmw.WriteByte((byte)kind);
            cmw.WriteByte(0);

            // alignment size and length (will be patched)
            BlobWriter alignmentSizeAndLengthWriter = new BlobWriter(cmw.ReserveBytes(sizeof(byte) + sizeof(uint)));

            recordSerializer(debugInfo, cmw);

            int  length        = cmw.Count;
            int  alignedLength = 4 * ((length + 3) / 4);
            byte alignmentSize = (byte)(alignedLength - length);

            cmw.WriteBytes(0, alignmentSize);

            // fill in alignment size and length:
            alignmentSizeAndLengthWriter.WriteByte(alignmentSize);
            alignmentSizeAndLengthWriter.WriteUInt32((uint)alignedLength);

            return(cmw);
        }
Ejemplo n.º 10
0
        private static void PatchModuleVersionIds(
            Blob guidFixup,
            Blob guidSectionFixup,
            Blob stringFixup,
            Guid mvid
            )
        {
            if (!guidFixup.IsDefault)
            {
                var writer = new BlobWriter(guidFixup);
                writer.WriteGuid(mvid);
                Debug.Assert(writer.RemainingBytes == 0);
            }

            if (!guidSectionFixup.IsDefault)
            {
                var writer = new BlobWriter(guidSectionFixup);
                writer.WriteGuid(mvid);
                Debug.Assert(writer.RemainingBytes == 0);
            }

            if (!stringFixup.IsDefault)
            {
                var writer = new BlobWriter(stringFixup);
                writer.WriteUserString(mvid.ToString());
                Debug.Assert(writer.RemainingBytes == 0);
            }
        }
Ejemplo n.º 11
0
        public void WriteTo(BlobWriter stream, out int guidHeapStartOffset)
        {
            WriteAligned(_stringWriter, stream);
            WriteAligned(_userStringWriter, stream);

            guidHeapStartOffset = stream.Position;

            WriteAligned(_guidWriter, stream);
            WriteAligned(_blobWriter, stream);
        }
Ejemplo n.º 12
0
        private void SerializeReferenceToPreviousMethodWithUsingInfo(ArrayBuilder <BlobWriter> customDebugInfo)
        {
            BlobWriter cmw = new BlobWriter(12);

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(CDI.CdiKindForwardInfo);
            cmw.Align(4);
            cmw.WriteUint(12);
            cmw.WriteUint((uint)_previousMethodTokenWithUsingInfo);
            customDebugInfo.Add(cmw);
        }
Ejemplo n.º 13
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 new ArgumentNullException(nameof(destination));
            }

            foreach (var chunk in GetChunks())
            {
                destination.WriteBytes(chunk._buffer, 0, chunk.Length);
            }
        }
Ejemplo n.º 14
0
        private BlobBuilder SerializeMvidSection(SectionLocation location)
        {
            var sectionBuilder = new BlobBuilder();

            // The guid will be filled in later:
            _mvidSectionFixup = sectionBuilder.ReserveBytes(SizeOfGuid);
            var mvidWriter = new BlobWriter(_mvidSectionFixup);

            mvidWriter.WriteBytes(0, _mvidSectionFixup.Length);
            Debug.Assert(mvidWriter.RemainingBytes == 0);

            return(sectionBuilder);
        }
Ejemplo n.º 15
0
        public int GetConstantBlobIndex(object value)
        {
            string str = value as string;

            if (str != null)
            {
                return(this.GetBlobIndex(str));
            }

            var writer = new BlobWriter();

            writer.WriteConstant(value);
            return(this.GetBlobIndex(writer));
        }
Ejemplo n.º 16
0
 internal PdbLogger(bool logging)
 {
     _logging = logging;
     if (logging)
     {
         _logData = BlobWriter.GetInstance();
         _hashAlgorithm = new SHA1CryptoServiceProvider();
         Debug.Assert(_hashAlgorithm.SupportsTransform);
     }
     else
     {
         _logData = null;
         _hashAlgorithm = null;
     }
 }
Ejemplo n.º 17
0
        private void SerializeNamespaceScopeMetadata(EmitContext context, IMethodBody methodBody, ArrayBuilder <BlobWriter> customDebugInfo)
        {
            if (context.Module.GenerateVisualBasicStylePdb)
            {
                return;
            }

            if (ShouldForwardToPreviousMethodWithUsingInfo(context, methodBody))
            {
                Debug.Assert(!ReferenceEquals(_previousMethodBodyWithUsingInfo, methodBody));
                SerializeReferenceToPreviousMethodWithUsingInfo(customDebugInfo);
                return;
            }

            List <ushort> usingCounts = new List <ushort>();
            var           cmw         = new BlobWriter();

            for (IImportScope scope = methodBody.ImportScope; scope != null; scope = scope.Parent)
            {
                usingCounts.Add((ushort)scope.GetUsedNamespaces().Length);
            }

            // ACASEY: This originally wrote (uint)12, (ushort)1, (ushort)0 in the
            // case where usingCounts was empty, but I'm not sure why.
            if (usingCounts.Count > 0)
            {
                uint streamLength;
                cmw.WriteByte(CDI.CdiVersion);
                cmw.WriteByte(CDI.CdiKindUsingInfo);
                cmw.Align(4);

                cmw.WriteUint(streamLength = BitArithmeticUtilities.Align((uint)usingCounts.Count * 2 + 10, 4));
                cmw.WriteUshort((ushort)usingCounts.Count);
                foreach (ushort uc in usingCounts)
                {
                    cmw.WriteUshort(uc);
                }

                cmw.Align(4);
                Debug.Assert(streamLength == cmw.Length);
                customDebugInfo.Add(cmw);
            }

            if (_methodBodyWithModuleInfo != null && !ReferenceEquals(_methodBodyWithModuleInfo, methodBody))
            {
                SerializeReferenceToMethodWithModuleInfo(customDebugInfo);
            }
        }
Ejemplo n.º 18
0
        public static void SerializeWin32Resources(BlobBuilder builder, ResourceSection resourceSections, int resourcesRva)
        {
            var sectionWriter = new BlobWriter(builder.ReserveBytes(resourceSections.SectionBytes.Length));

            sectionWriter.WriteBytes(resourceSections.SectionBytes);

            var readStream = new MemoryStream(resourceSections.SectionBytes);
            var reader     = new BinaryReader(readStream);

            foreach (int addressToFixup in resourceSections.Relocations)
            {
                sectionWriter.Offset       = addressToFixup;
                reader.BaseStream.Position = addressToFixup;
                sectionWriter.WriteUInt32(reader.ReadUInt32() + (uint)resourcesRva);
            }
        }
        private void WriteBlobHeap(BlobBuilder builder)
        {
            var writer = new BlobWriter(builder.ReserveBytes(_blobHeapSize));

            // Perf consideration: With large heap the following loop may cause a lot of cache misses
            // since the order of entries in _blobs dictionary depends on the hash of the array values,
            // which is not correlated to the heap index. If we observe such issue we should order
            // the entries by heap position before running this loop.
            foreach (var entry in _blobs)
            {
                int heapOffset = MetadataTokens.GetHeapOffset(entry.Value);
                var blob       = entry.Key;

                writer.Offset = heapOffset;
                writer.WriteCompressedInteger(blob.Length);
                writer.WriteBytes(blob);
            }
        }
Ejemplo n.º 20
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
         {
             ThrowValueArgumentOutOfRange();
         }
     }
 }
Ejemplo n.º 21
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
         {
             ThrowValueArgumentOutOfRange();
         }
     }
 }
Ejemplo n.º 22
0
        // internal for testing
        internal static byte[] SerializeCustomDebugMetadata(ArrayBuilder <BlobWriter> recordWriters)
        {
            if (recordWriters.Count == 0)
            {
                return(null);
            }

            BlobWriter cmw = BlobWriter.GetInstance();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte((byte)recordWriters.Count); // count
            cmw.Align(4);
            foreach (BlobWriter recordWriter in recordWriters)
            {
                recordWriter.WriteTo(cmw);
            }

            var result = cmw.ToArray();

            cmw.Free();
            return(result);
        }
Ejemplo n.º 23
0
        public void WritePrimitive()
        {
            var writer = new BlobWriter(4);

            writer.WriteUInt32(0x11223344);
            writer.WriteUInt16(0x5566);
            writer.WriteByte(0x77);
            writer.WriteUInt64(0x8899aabbccddeeff);
            writer.WriteInt32(-1);
            writer.WriteInt16(-2);
            writer.WriteSByte(-3);
            writer.WriteBoolean(true);
            writer.WriteBoolean(false);
            writer.WriteInt64(unchecked((long)0xfedcba0987654321));
            writer.WriteDateTime(new DateTime(0x1112223334445556));
            writer.WriteDecimal(102030405060.70m);
            writer.WriteDouble(double.NaN);
            writer.WriteSingle(float.NegativeInfinity);

            AssertEx.Equal(new byte[] 
            {
                0x44, 0x33, 0x22, 0x11,
                0x66, 0x55,
                0x77,
                0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
                0xff, 0xff, 0xff, 0xff, 
                0xfe, 0xff,
                0xfd,
                0x01,
                0x00,
                0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE,
                0x56, 0x55, 0x44, 0x34, 0x33, 0x22, 0x12, 0x11,
                0x02, 0xD6, 0xE0, 0x9A, 0x94, 0x47, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
                0x00, 0x00, 0x80, 0xFF
            }, writer.ToArray());
        }
Ejemplo n.º 24
0
        private static void SerializeReferenceToIteratorClass(string iteratorClassName, ArrayBuilder <BlobWriter> customDebugInfo)
        {
            if (iteratorClassName == null)
            {
                return;
            }
            var cmw = new BlobWriter();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(CDI.CdiKindForwardIterator);
            cmw.Align(4);
            uint length = 10 + (uint)iteratorClassName.Length * 2;

            if ((length & 3) != 0)
            {
                length += 4 - (length & 3);
            }
            cmw.WriteUint(length);
            cmw.WriteUTF16(iteratorClassName);
            cmw.WriteShort(0);
            cmw.Align(4);
            Debug.Assert(cmw.Position == length);
            customDebugInfo.Add(cmw);
        }
Ejemplo n.º 25
0
 internal int GetBlobIndex(BlobWriter stream)
 {
     // TODO: avoid making a copy if the blob exists in the index
     return(GetBlobIndex(stream.ToImmutableArray()));
 }
Ejemplo n.º 26
0
        private static void SerializeDynamicLocalInfo(IMethodBody methodBody, ArrayBuilder <BlobWriter> customDebugInfo)
        {
            if (!methodBody.HasDynamicLocalVariables)
            {
                return; //There are no dynamic locals
            }

            var dynamicLocals = ArrayBuilder <ILocalDefinition> .GetInstance();

            foreach (ILocalDefinition local in methodBody.LocalVariables)
            {
                if (local.IsDynamic)
                {
                    dynamicLocals.Add(local);
                }
            }

            int dynamicVariableCount = dynamicLocals.Count;

            foreach (var currentScope in methodBody.LocalScopes)
            {
                foreach (var localConstant in currentScope.Constants)
                {
                    if (localConstant.IsDynamic)
                    {
                        dynamicLocals.Add(localConstant);
                    }
                }
            }

            Debug.Assert(dynamicLocals.Any()); // There must be at least one dynamic local if this point is reached

            const int blobSize = 200;          //DynamicAttribute - 64, DynamicAttributeLength - 4, SlotIndex -4, IdentifierName - 128
            var       cmw      = new BlobWriter();

            cmw.WriteByte(CDI.CdiVersion);
            cmw.WriteByte(CDI.CdiKindDynamicLocals);
            cmw.Align(4);
            // size = Version,Kind + size + cBuckets + (dynamicCount * sizeOf(Local Blob))
            cmw.WriteUint(4 + 4 + 4 + (uint)dynamicLocals.Count * blobSize);//Size of the Dynamic Block
            cmw.WriteUint((uint)dynamicLocals.Count);

            int localIndex = 0;

            foreach (ILocalDefinition local in dynamicLocals)
            {
                if (local.Name.Length > 63)//Ignore and push empty information
                {
                    cmw.WriteBytes(0, blobSize);
                    continue;
                }

                var dynamicTransformFlags = local.DynamicTransformFlags;
                if (!dynamicTransformFlags.IsDefault && dynamicTransformFlags.Length <= 64)
                {
                    byte[] flag = new byte[64];
                    for (int k = 0; k < dynamicTransformFlags.Length; k++)
                    {
                        if ((bool)dynamicTransformFlags[k].Value)
                        {
                            flag[k] = 1;
                        }
                    }
                    cmw.WriteBytes(flag);                              //Written Flag
                    cmw.WriteUint((uint)dynamicTransformFlags.Length); //Written Length
                }
                else
                {
                    cmw.WriteBytes(0, 68); //Empty flag array and size.
                }

                if (localIndex < dynamicVariableCount)
                {
                    // Dynamic variable
                    cmw.WriteUint((uint)local.SlotIndex);
                }
                else
                {
                    // Dynamic constant
                    cmw.WriteUint(0);
                }

                char[] localName = new char[64];
                local.Name.CopyTo(0, localName, 0, local.Name.Length);
                cmw.WriteUTF16(localName);

                localIndex++;
            }

            dynamicLocals.Free();
            customDebugInfo.Add(cmw);
        }
Ejemplo n.º 27
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));
 }
Ejemplo n.º 28
0
        private void WriteDirectory(Directory directory, BlobWriter writer, uint offset, uint level, uint sizeOfDirectoryTree, uint virtualAddressBase, BlobWriter dataWriter)
        {
            writer.WriteUint(0); // Characteristics
            writer.WriteUint(0); // Timestamp
            writer.WriteUint(0); // Version
            writer.WriteUshort(directory.NumberOfNamedEntries);
            writer.WriteUshort(directory.NumberOfIdEntries);
            uint n = (uint)directory.Entries.Count;
            uint k = offset + 16 + n * 8;
            for (int i = 0; i < n; i++)
            {
                int id;
                string name;
                uint nameOffset = (uint)dataWriter.Position + sizeOfDirectoryTree;
                uint directoryOffset = k;
                Directory subDir = directory.Entries[i] as Directory;
                if (subDir != null)
                {
                    id = subDir.ID;
                    name = subDir.Name;
                    if (level == 0)
                    {
                        k += SizeOfDirectory(subDir);
                    }
                    else
                    {
                        k += 16 + 8 * (uint)subDir.Entries.Count;
                    }
                }
                else
                {
                    //EDMAURER write out an IMAGE_RESOURCE_DATA_ENTRY followed
                    //immediately by the data that it refers to. This results
                    //in a layout different than that produced by pulling the resources
                    //from an OBJ. In that case all of the data bits of a resource are
                    //contiguous in .rsrc$02. After processing these will end up at
                    //the end of .rsrc following all of the directory
                    //info and IMAGE_RESOURCE_DATA_ENTRYs
                    IWin32Resource r = (IWin32Resource)directory.Entries[i];
                    id = level == 0 ? r.TypeId : level == 1 ? r.Id : (int)r.LanguageId;
                    name = level == 0 ? r.TypeName : level == 1 ? r.Name : null;
                    dataWriter.WriteUint(virtualAddressBase + sizeOfDirectoryTree + 16 + (uint)dataWriter.Position);
                    byte[] data = new List<byte>(r.Data).ToArray();
                    dataWriter.WriteUint((uint)data.Length);
                    dataWriter.WriteUint(r.CodePage);
                    dataWriter.WriteUint(0);
                    dataWriter.WriteBytes(data);
                    while ((dataWriter.Length % 4) != 0)
                    {
                        dataWriter.WriteByte(0);
                    }
                }

                if (id >= 0)
                {
                    writer.WriteInt(id);
                }
                else
                {
                    if (name == null)
                    {
                        name = string.Empty;
                    }

                    writer.WriteUint(nameOffset | 0x80000000);
                    dataWriter.WriteUshort((ushort)name.Length);
                    dataWriter.WriteUTF16(name);
                }

                if (subDir != null)
                {
                    writer.WriteUint(directoryOffset | 0x80000000);
                }
                else
                {
                    writer.WriteUint(nameOffset);
                }
            }

            k = offset + 16 + n * 8;
            for (int i = 0; i < n; i++)
            {
                Directory subDir = directory.Entries[i] as Directory;
                if (subDir != null)
                {
                    this.WriteDirectory(subDir, writer, k, level + 1, sizeOfDirectoryTree, virtualAddressBase, dataWriter);
                    if (level == 0)
                    {
                        k += SizeOfDirectory(subDir);
                    }
                    else
                    {
                        k += 16 + 8 * (uint)subDir.Entries.Count;
                    }
                }
            }
        }
Ejemplo n.º 29
0
        private void WriteRelocSection(Stream peStream)
        {
            if (!_emitRuntimeStartupStub)
            {
                //No need to write out a reloc section, but there is still a need to pad out the peStream so that it is an even multiple of module.FileAlignment
                if (_relocSection.PointerToRawData != peStream.Position)
                { //for example, the resource section did not end bang on the alignment boundary
                    peStream.Position = _relocSection.PointerToRawData - 1;
                    peStream.WriteByte(0);
                }
                return;
            }

            peStream.Position = _relocSection.PointerToRawData;
            var writer = new BlobWriter(_module.FileAlignment);
            writer.WriteUint(((_ntHeader.AddressOfEntryPoint + 2) / 0x1000) * 0x1000);
            writer.WriteUint(_module.Requires64bits && !_module.RequiresAmdInstructionSet ? 14u : 12u);
            uint offsetWithinPage = (_ntHeader.AddressOfEntryPoint + 2) % 0x1000;
            uint relocType = _module.Requires64bits ? 10u : 3u;
            ushort s = (ushort)((relocType << 12) | offsetWithinPage);
            writer.WriteUshort(s);
            if (_module.Requires64bits && !_module.RequiresAmdInstructionSet)
            {
                writer.WriteUint(relocType << 12);
            }

            writer.WriteUshort(0); // next chunk's RVA
            writer.Position = (int)_module.FileAlignment;
            writer.WriteTo(peStream);
        }
Ejemplo n.º 30
0
        private void WriteDebugTable(Stream peStream, ContentId nativePdbContentId, MetadataSizes metadataSizes)
        {
            if (!EmitPdb)
            {
                return;
            }

            var writer = new BlobWriter();

            // characteristics:
            writer.WriteUint(0);

            // PDB stamp
            writer.WriteBytes(nativePdbContentId.Stamp);

            // version
            writer.WriteUint(0);

            // type: 
            const int ImageDebugTypeCodeView = 2;
            writer.WriteUint(ImageDebugTypeCodeView);

            // size of data:
            writer.WriteUint((uint)ComputeSizeOfDebugDirectoryData());

            uint dataOffset = (uint)ComputeOffsetToDebugTable(metadataSizes) + ImageDebugDirectoryBaseSize;

            // PointerToRawData (RVA of the data):
            writer.WriteUint(_textSection.RelativeVirtualAddress + dataOffset);

            // AddressOfRawData (position of the data in the PE stream):
            writer.WriteUint(_textSection.PointerToRawData + dataOffset);

            writer.WriteByte((byte)'R');
            writer.WriteByte((byte)'S');
            writer.WriteByte((byte)'D');
            writer.WriteByte((byte)'S');

            // PDB id:
            writer.WriteBytes(nativePdbContentId.Guid);

            // age
            writer.WriteUint(PdbWriter.Age);

            // UTF-8 encoded zero-terminated path to PDB
            writer.WriteUTF8(_pdbPathOpt);
            writer.WriteByte(0);

            writer.WriteTo(peStream);
            writer.Free();
        }
Ejemplo n.º 31
0
 private static void WriteMetadata(Stream peStream, BlobWriter metadataStream)
 {
     metadataStream.WriteTo(peStream);
     while (peStream.Position % 4 != 0)
     {
         peStream.WriteByte(0);
     }
 }
Ejemplo n.º 32
0
 public void EmptyWrites()
 {
     var writer = new BlobWriter(16);
     writer.WriteBytes(1, 16);
     writer.WriteBytes(new byte[] { });
     writer.WriteBytes(2, 0);
     writer.WriteUTF8("", allowUnpairedSurrogates: false);
     writer.WriteUTF16("");
     Assert.Equal(16, writer.Length);
 }
Ejemplo n.º 33
0
        private static void TestCompressedSignedInteger(byte[] expected, int value)
        {
            var writer = new BlobWriter(4);
            writer.WriteCompressedSignedInteger(value);
            AssertEx.Equal(expected, writer.ToArray());

            var builder = new BlobBuilder();
            builder.WriteCompressedSignedInteger(value);
            AssertEx.Equal(expected, builder.ToArray());
        }
Ejemplo n.º 34
0
        private void WriteRuntimeStartupStub(Stream peStream, int importAddressTableRva)
        {
            var writer = new BlobWriter(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.WriteUshort(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //4
                writer.WriteUint((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.WriteUint(0);
                writer.WriteUshort(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //8
                writer.WriteUlong((ulong)importAddressTableRva + _properties.BaseAddress); //16
            }

            writer.WriteTo(peStream);
        }
Ejemplo n.º 35
0
        private void WriteRelocSection(Stream peStream, SectionHeader relocSection, int entryPointAddress)
        {
            peStream.Position = relocSection.PointerToRawData;
            var writer = new BlobWriter(relocSection.SizeOfRawData);
            writer.WriteUint((((uint)entryPointAddress + 2) / 0x1000) * 0x1000);
            writer.WriteUint(_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.WriteUshort(s);
            if (_properties.Requires64bits && !_properties.RequiresAmdInstructionSet)
            {
                writer.WriteUint(relocType << 12);
            }

            writer.WriteUshort(0); // next chunk's RVA
            writer.Position = relocSection.SizeOfRawData;
            writer.WriteTo(peStream);
        }
Ejemplo n.º 36
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
            {
                // TODO: message
                throw new ArgumentException();
            }
        }
Ejemplo n.º 37
0
        private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt)
        {
            // TODO: we can precalculate the exact size of IL stream
            var ilWriter = new BlobWriter(32 * 1024);
            var metadataWriter = new BlobWriter(16 * 1024);
            var mappedFieldDataWriter = new BlobWriter();
            var managedResourceWriter = new BlobWriter(1024);

            var debugMetadataWriterOpt = (getPortablePdbStreamOpt != null) ? new BlobWriter(16 * 1024) : null;

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

            int sectionCount = 1;
            if (_properties.RequiresStartupStub) sectionCount++; //.reloc
            if (!IteratorHelper.EnumerableIsEmpty(_nativeResourcesOpt) || _nativeResourceSectionOpt != null) sectionCount++; //.rsrc;

            int sizeOfPeHeaders = ComputeSizeOfPeHeaders(sectionCount);
            int textSectionRva = BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.SectionAlignment);

            int moduleVersionIdOffsetInMetadataStream;
            int methodBodyStreamRva = textSectionRva + OffsetToILStream;

            int entryPointToken;
            MetadataSizes metadataSizes;
            mdWriter.SerializeMetadataAndIL(
                metadataWriter,
                debugMetadataWriterOpt,
                nativePdbWriterOpt,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                methodBodyStreamRva,
                mdSizes => CalculateMappedFieldDataStreamRva(textSectionRva, mdSizes),
                out moduleVersionIdOffsetInMetadataStream,
                out entryPointToken,
                out metadataSizes);

            ContentId nativePdbContentId;
            if (nativePdbWriterOpt != null)
            {
                if (entryPointToken != 0)
                {
                    nativePdbWriterOpt.SetEntryPoint((uint)entryPointToken);
                }

                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
                }

                nativePdbContentId = nativePdbWriterOpt.GetContentId();

                // the writer shall not be used after this point for writing:
                nativePdbWriterOpt = null;
            }
            else
            {
                nativePdbContentId = default(ContentId);
            }

            // Only the size of the fixed part of the debug table goes here.
            DirectoryEntry debugDirectory = default(DirectoryEntry);
            DirectoryEntry importTable = default(DirectoryEntry);
            DirectoryEntry importAddressTable = default(DirectoryEntry);
            int entryPointAddress = 0;

            if (EmitPdb)
            {
                debugDirectory = new DirectoryEntry(textSectionRva + ComputeOffsetToDebugTable(metadataSizes), ImageDebugDirectoryBaseSize);
            }

            if (_properties.RequiresStartupStub)
            {
                importAddressTable = new DirectoryEntry(textSectionRva, SizeOfImportAddressTable);
                entryPointAddress = CalculateMappedFieldDataStreamRva(textSectionRva, metadataSizes) - (_is32bit ? 6 : 10); // TODO: constants
                importTable = new DirectoryEntry(textSectionRva + ComputeOffsetToImportTable(metadataSizes), (_is32bit ? 66 : 70) + 13); // TODO: constants
            }

            var corHeaderDirectory = new DirectoryEntry(textSectionRva + SizeOfImportAddressTable, size: CorHeaderSize);

            long ntHeaderTimestampPosition;
            long metadataPosition;

            List<SectionHeader> sectionHeaders = CreateSectionHeaders(metadataSizes, sectionCount);

            CoffHeader coffHeader;
            NtHeader ntHeader;
            FillInNtHeader(sectionHeaders, entryPointAddress, corHeaderDirectory, importTable, importAddressTable, debugDirectory, out coffHeader, out ntHeader);

            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return false;
            }

            WriteHeaders(peStream, ntHeader, coffHeader, sectionHeaders, out ntHeaderTimestampPosition);

            WriteTextSection(
                peStream,
                sectionHeaders[0],
                importTable.RelativeVirtualAddress,
                importAddressTable.RelativeVirtualAddress,
                entryPointToken,
                metadataWriter,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                metadataSizes,
                nativePdbContentId,
                out metadataPosition);

            var resourceSection = sectionHeaders.FirstOrDefault(s => s.Name == ResourceSectionName);
            if (resourceSection != null)
            {
                WriteResourceSection(peStream, resourceSection);
            }

            var relocSection = sectionHeaders.FirstOrDefault(s => s.Name == RelocationSectionName);
            if (relocSection != null)
            {
                WriteRelocSection(peStream, relocSection, entryPointAddress);
            }

            if (_deterministic)
            {
                var mvidPosition = metadataPosition + moduleVersionIdOffsetInMetadataStream;
                WriteDeterministicGuidAndTimestamps(peStream, mvidPosition, ntHeaderTimestampPosition);
            }

            return true;
        }
Ejemplo n.º 38
0
        private void WriteHeaders(Stream peStream, NtHeader ntHeader, CoffHeader coffHeader, List<SectionHeader> sectionHeaders, out long ntHeaderTimestampPosition)
        {
            var writer = new BlobWriter(1024);

            // MS-DOS stub (128 bytes)
            writer.WriteBytes(s_dosHeader);

            // PE Signature "PE\0\0" 
            writer.WriteUint(0x00004550);

            // COFF Header (20 bytes)
            writer.WriteUshort((ushort)coffHeader.Machine);
            writer.WriteUshort((ushort)coffHeader.NumberOfSections);
            ntHeaderTimestampPosition = writer.Position + peStream.Position;
            writer.WriteUint((uint)coffHeader.TimeDateStamp);
            writer.WriteUint((uint)coffHeader.PointerToSymbolTable);
            writer.WriteUint((uint)coffHeader.NumberOfSymbols);
            writer.WriteUshort((ushort)(_is32bit ? 224 : 240)); // SizeOfOptionalHeader
            writer.WriteUshort((ushort)coffHeader.Characteristics);

            // PE Headers:
            writer.WriteUshort((ushort)(_is32bit ? PEMagic.PE32 : PEMagic.PE32Plus)); // 2
            writer.WriteByte(ntHeader.MajorLinkerVersion); // 3
            writer.WriteByte(ntHeader.MinorLinkerVersion); // 4
            writer.WriteUint((uint)ntHeader.SizeOfCode); // 8
            writer.WriteUint((uint)ntHeader.SizeOfInitializedData); // 12
            writer.WriteUint((uint)ntHeader.SizeOfUninitializedData); // 16
            writer.WriteUint((uint)ntHeader.AddressOfEntryPoint); // 20
            writer.WriteUint((uint)ntHeader.BaseOfCode); // 24

            if (_is32bit)
            {
                writer.WriteUint((uint)ntHeader.BaseOfData); // 28
                writer.WriteUint((uint)ntHeader.ImageBase); // 32
            }
            else
            {
                writer.WriteUlong(ntHeader.ImageBase); // 32
            }

            // NT additional fields:
            writer.WriteUint((uint)ntHeader.SectionAlignment); // 36
            writer.WriteUint((uint)ntHeader.FileAlignment); // 40
            writer.WriteUshort(ntHeader.MajorOperatingSystemVersion); // 42
            writer.WriteUshort(ntHeader.MinorOperatingSystemVersion); // 44
            writer.WriteUshort(ntHeader.MajorImageVersion); // 46
            writer.WriteUshort(ntHeader.MinorImageVersion); // 48
            writer.WriteUshort(ntHeader.MajorSubsystemVersion); // MajorSubsystemVersion 50
            writer.WriteUshort(ntHeader.MinorSubsystemVersion); // MinorSubsystemVersion 52

            // Win32VersionValue (reserved, should be 0)
            writer.WriteUint(0); // 56

            writer.WriteUint((uint)ntHeader.SizeOfImage); // 60
            writer.WriteUint((uint)ntHeader.SizeOfHeaders); // 64
            writer.WriteUint(ntHeader.Checksum); // 68            
            writer.WriteUshort((ushort)ntHeader.Subsystem); // 70
            writer.WriteUshort((ushort)ntHeader.DllCharacteristics);

            if (_is32bit)
            {
                writer.WriteUint((uint)ntHeader.SizeOfStackReserve); // 76
                writer.WriteUint((uint)ntHeader.SizeOfStackCommit); // 80
                writer.WriteUint((uint)ntHeader.SizeOfHeapReserve); // 84
                writer.WriteUint((uint)ntHeader.SizeOfHeapCommit); // 88
            }
            else
            {
                writer.WriteUlong(ntHeader.SizeOfStackReserve); // 80
                writer.WriteUlong(ntHeader.SizeOfStackCommit); // 88
                writer.WriteUlong(ntHeader.SizeOfHeapReserve); // 96
                writer.WriteUlong(ntHeader.SizeOfHeapCommit); // 104
            }

            // LoaderFlags
            writer.WriteUint(0); // 92|108

            // The number of data-directory entries in the remainder of the header.
            writer.WriteUint(16); //  96|112

            // directory entries:
            writer.WriteUint((uint)ntHeader.ExportTable.RelativeVirtualAddress); // 100|116
            writer.WriteUint((uint)ntHeader.ExportTable.Size); // 104|120
            writer.WriteUint((uint)ntHeader.ImportTable.RelativeVirtualAddress); // 108|124
            writer.WriteUint((uint)ntHeader.ImportTable.Size); // 112|128
            writer.WriteUint((uint)ntHeader.ResourceTable.RelativeVirtualAddress); // 116|132
            writer.WriteUint((uint)ntHeader.ResourceTable.Size); // 120|136
            writer.WriteUint((uint)ntHeader.ExceptionTable.RelativeVirtualAddress); // 124|140
            writer.WriteUint((uint)ntHeader.ExceptionTable.Size); // 128|144
            writer.WriteUint((uint)ntHeader.CertificateTable.RelativeVirtualAddress); // 132|148
            writer.WriteUint((uint)ntHeader.CertificateTable.Size); // 136|152
            writer.WriteUint((uint)ntHeader.BaseRelocationTable.RelativeVirtualAddress); // 140|156
            writer.WriteUint((uint)ntHeader.BaseRelocationTable.Size); // 144|160
            writer.WriteUint((uint)ntHeader.DebugTable.RelativeVirtualAddress); // 148|164
            writer.WriteUint((uint)ntHeader.DebugTable.Size); // 152|168
            writer.WriteUint((uint)ntHeader.CopyrightTable.RelativeVirtualAddress); // 156|172
            writer.WriteUint((uint)ntHeader.CopyrightTable.Size); // 160|176
            writer.WriteUint((uint)ntHeader.GlobalPointerTable.RelativeVirtualAddress); // 164|180
            writer.WriteUint((uint)ntHeader.GlobalPointerTable.Size); // 168|184
            writer.WriteUint((uint)ntHeader.ThreadLocalStorageTable.RelativeVirtualAddress); // 172|188
            writer.WriteUint((uint)ntHeader.ThreadLocalStorageTable.Size); // 176|192
            writer.WriteUint((uint)ntHeader.LoadConfigTable.RelativeVirtualAddress); // 180|196
            writer.WriteUint((uint)ntHeader.LoadConfigTable.Size); // 184|200
            writer.WriteUint((uint)ntHeader.BoundImportTable.RelativeVirtualAddress); // 188|204
            writer.WriteUint((uint)ntHeader.BoundImportTable.Size); // 192|208
            writer.WriteUint((uint)ntHeader.ImportAddressTable.RelativeVirtualAddress); // 196|212
            writer.WriteUint((uint)ntHeader.ImportAddressTable.Size); // 200|216
            writer.WriteUint((uint)ntHeader.DelayImportTable.RelativeVirtualAddress); // 204|220
            writer.WriteUint((uint)ntHeader.DelayImportTable.Size); // 208|224
            writer.WriteUint((uint)ntHeader.CliHeaderTable.RelativeVirtualAddress); // 212|228
            writer.WriteUint((uint)ntHeader.CliHeaderTable.Size); // 216|232
            writer.WriteUlong(0); // 224|240

            // Section Headers
            foreach (var sectionHeader in sectionHeaders)
            {
                WriteSectionHeader(sectionHeader, writer);
            }

            writer.WriteTo(peStream);
        }
Ejemplo n.º 39
0
 private static void WriteMappedFieldData(Stream peStream, BlobWriter dataStream)
 {
     dataStream.WriteTo(peStream);
     while (peStream.Position % 4 != 0)
     {
         peStream.WriteByte(0);
     }
 }
Ejemplo n.º 40
0
        private void WriteHeaders(Stream peStream, out long ntHeaderTimestampPosition)
        {
            IModule module = _module;
            NtHeader ntHeader = _ntHeader;
            var writer = _headerWriter;

            // MS-DOS stub (128 bytes)
            writer.WriteBytes(s_dosHeader); // TODO: provide an option to suppress the second half of the DOS header?

            // PE Signature (4 bytes)
            writer.WriteUint(0x00004550); /* "PE\0\0" */

            // COFF Header 20 bytes
            writer.WriteUshort((ushort)module.Machine);
            writer.WriteUshort(ntHeader.NumberOfSections);
            ntHeaderTimestampPosition = writer.Position + peStream.Position;
            writer.WriteUint(ntHeader.TimeDateStamp);
            writer.WriteUint(ntHeader.PointerToSymbolTable);
            writer.WriteUint(0); // NumberOfSymbols
            writer.WriteUshort((ushort)(!module.Requires64bits ? 224 : 240)); // SizeOfOptionalHeader
            // ushort characteristics = 0x0002|0x0004|0x0008; // executable | no COFF line nums | no COFF symbols (as required by the standard)
            ushort characteristics = 0x0002; // executable (as required by the Linker team).
            if (module.Kind == ModuleKind.DynamicallyLinkedLibrary || module.Kind == ModuleKind.WindowsRuntimeMetadata)
            {
                characteristics |= 0x2000;
            }

            if (module.Requires32bits)
            {
                characteristics |= 0x0100; // 32 bit machine (The standard says to always set this, the linker team says otherwise)
                                           //The loader team says that this is not used for anything in the OS. 
            }
            else
            {
                characteristics |= 0x0020; // large address aware (the standard says never to set this, the linker team says otherwise).
                                           //The loader team says that this is not overridden for managed binaries and will be respected if set.
            }

            writer.WriteUshort(characteristics);

            // PE Header (224 bytes if 32 bits, 240 bytes if 64 bit)
            if (!module.Requires64bits)
            {
                writer.WriteUshort(0x10B); // Magic = PE32  // 2
            }
            else
            {
                writer.WriteUshort(0x20B); // Magic = PE32+ // 2
            }

            writer.WriteByte(module.LinkerMajorVersion); // 3
            writer.WriteByte(module.LinkerMinorVersion); // 4
            writer.WriteUint(ntHeader.SizeOfCode); // 8
            writer.WriteUint(ntHeader.SizeOfInitializedData); // 12
            writer.WriteUint(ntHeader.SizeOfUninitializedData); // 16
            writer.WriteUint(ntHeader.AddressOfEntryPoint); // 20
            writer.WriteUint(ntHeader.BaseOfCode); // 24
            if (!module.Requires64bits)
            {
                writer.WriteUint(ntHeader.BaseOfData); // 28
                writer.WriteUint((uint)module.BaseAddress); // 32
            }
            else
            {
                writer.WriteUlong(module.BaseAddress); // 32
            }

            writer.WriteUint(0x2000); // SectionAlignment 36
            writer.WriteUint(module.FileAlignment); // 40
            writer.WriteUshort(4); // MajorOperatingSystemVersion 42
            writer.WriteUshort(0); // MinorOperatingSystemVersion 44
            writer.WriteUshort(0); // MajorImageVersion 46
            writer.WriteUshort(0); // MinorImageVersion 48
            writer.WriteUshort(module.MajorSubsystemVersion); // MajorSubsystemVersion 50
            writer.WriteUshort(module.MinorSubsystemVersion); // MinorSubsystemVersion 52
            writer.WriteUint(0); // Win32VersionValue 56
            writer.WriteUint(ntHeader.SizeOfImage); // 60
            writer.WriteUint(ntHeader.SizeOfHeaders); // 64
            writer.WriteUint(0); // CheckSum 68
            switch (module.Kind)
            {
                case ModuleKind.ConsoleApplication:
                case ModuleKind.DynamicallyLinkedLibrary:
                case ModuleKind.WindowsRuntimeMetadata:
                    writer.WriteUshort(3); // 70
                    break;
                case ModuleKind.WindowsApplication:
                    writer.WriteUshort(2); // 70
                    break;
                default:
                    writer.WriteUshort(0); //
                    break;
            }

            writer.WriteUshort(module.DllCharacteristics);

            if (!module.Requires64bits)
            {
                writer.WriteUint((uint)module.SizeOfStackReserve); // 76
                writer.WriteUint((uint)module.SizeOfStackCommit); // 80
                writer.WriteUint((uint)module.SizeOfHeapReserve); // 84
                writer.WriteUint((uint)module.SizeOfHeapCommit); // 88
            }
            else
            {
                writer.WriteUlong(module.SizeOfStackReserve); // 80
                writer.WriteUlong(module.SizeOfStackCommit); // 88
                writer.WriteUlong(module.SizeOfHeapReserve); // 96
                writer.WriteUlong(module.SizeOfHeapCommit); // 104
            }

            writer.WriteUint(0); // LoaderFlags 92|108
            writer.WriteUint(16); // numberOfDataDirectories 96|112

            writer.WriteUint(ntHeader.ExportTable.RelativeVirtualAddress); // 100|116
            writer.WriteUint(ntHeader.ExportTable.Size); // 104|120
            writer.WriteUint(ntHeader.ImportTable.RelativeVirtualAddress); // 108|124
            writer.WriteUint(ntHeader.ImportTable.Size); // 112|128
            writer.WriteUint(ntHeader.ResourceTable.RelativeVirtualAddress); // 116|132
            writer.WriteUint(ntHeader.ResourceTable.Size); // 120|136
            writer.WriteUint(ntHeader.ExceptionTable.RelativeVirtualAddress); // 124|140
            writer.WriteUint(ntHeader.ExceptionTable.Size); // 128|144
            writer.WriteUint(ntHeader.CertificateTable.RelativeVirtualAddress); // 132|148
            writer.WriteUint(ntHeader.CertificateTable.Size); // 136|152
            writer.WriteUint(ntHeader.BaseRelocationTable.RelativeVirtualAddress); // 140|156
            writer.WriteUint(ntHeader.BaseRelocationTable.Size); // 144|160
            writer.WriteUint(ntHeader.DebugTable.RelativeVirtualAddress); // 148|164
            writer.WriteUint(ntHeader.DebugTable.Size); // 152|168
            writer.WriteUint(ntHeader.CopyrightTable.RelativeVirtualAddress); // 156|172
            writer.WriteUint(ntHeader.CopyrightTable.Size); // 160|176
            writer.WriteUint(ntHeader.GlobalPointerTable.RelativeVirtualAddress); // 164|180
            writer.WriteUint(ntHeader.GlobalPointerTable.Size); // 168|184
            writer.WriteUint(ntHeader.ThreadLocalStorageTable.RelativeVirtualAddress); // 172|188
            writer.WriteUint(ntHeader.ThreadLocalStorageTable.Size); // 176|192
            writer.WriteUint(ntHeader.LoadConfigTable.RelativeVirtualAddress); // 180|196
            writer.WriteUint(ntHeader.LoadConfigTable.Size); // 184|200
            writer.WriteUint(ntHeader.BoundImportTable.RelativeVirtualAddress); // 188|204
            writer.WriteUint(ntHeader.BoundImportTable.Size); // 192|208
            writer.WriteUint(ntHeader.ImportAddressTable.RelativeVirtualAddress); // 196|212
            writer.WriteUint(ntHeader.ImportAddressTable.Size); // 200|216
            writer.WriteUint(ntHeader.DelayImportTable.RelativeVirtualAddress); // 204|220
            writer.WriteUint(ntHeader.DelayImportTable.Size); // 208|224
            writer.WriteUint(ntHeader.CliHeaderTable.RelativeVirtualAddress); // 212|228
            writer.WriteUint(ntHeader.CliHeaderTable.Size); // 216|232
            writer.WriteUlong(0); // 224|240

            // Section Headers
            WriteSectionHeader(_textSection, writer);
            WriteSectionHeader(_rdataSection, writer);
            WriteSectionHeader(_sdataSection, writer);
            WriteSectionHeader(_coverSection, writer);
            WriteSectionHeader(_resourceSection, writer);
            WriteSectionHeader(_relocSection, writer);
            WriteSectionHeader(_tlsSection, writer);

            writer.WriteTo(peStream);
            _headerWriter = _emptyStream;
        }
Ejemplo n.º 41
0
 private static void WriteManagedResources(Stream peStream, BlobWriter managedResourceStream)
 {
     managedResourceStream.WriteTo(peStream);
     while (peStream.Position % 4 != 0)
     {
         peStream.WriteByte(0);
     }
 }
Ejemplo n.º 42
0
        private static void WriteSectionHeader(SectionHeader sectionHeader, BlobWriter writer)
        {
            if (sectionHeader.VirtualSize == 0)
            {
                return;
            }

            for (int j = 0, m = sectionHeader.Name.Length; j < 8; j++)
            {
                if (j < m)
                {
                    writer.WriteByte((byte)sectionHeader.Name[j]);
                }
                else
                {
                    writer.WriteByte(0);
                }
            }

            writer.WriteUint(sectionHeader.VirtualSize);
            writer.WriteUint(sectionHeader.RelativeVirtualAddress);
            writer.WriteUint(sectionHeader.SizeOfRawData);
            writer.WriteUint(sectionHeader.PointerToRawData);
            writer.WriteUint(sectionHeader.PointerToRelocations);
            writer.WriteUint(sectionHeader.PointerToLinenumbers);
            writer.WriteUshort(sectionHeader.NumberOfRelocations);
            writer.WriteUshort(sectionHeader.NumberOfLinenumbers);
            writer.WriteUint(sectionHeader.Characteristics);
        }
Ejemplo n.º 43
0
        private void WriteRuntimeStartupStub(Stream peStream)
        {
            var writer = new BlobWriter(16);
            // entry point code, consisting of a jump indirect to _CorXXXMain
            if (!_module.Requires64bits)
            {
                //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.WriteUshort(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //4
                writer.WriteUint(_ntHeader.ImportAddressTable.RelativeVirtualAddress + (uint)_module.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.WriteUint(0);
                writer.WriteUshort(0);
                writer.WriteByte(0xff);
                writer.WriteByte(0x25); //8
                writer.WriteUlong(_ntHeader.ImportAddressTable.RelativeVirtualAddress + _module.BaseAddress); //16
            }
            writer.WriteTo(peStream);
        }
Ejemplo n.º 44
0
        private void WriteTextSection(
            Stream peStream,
            CorHeader corHeader,
            BlobWriter metadataWriter,
            BlobWriter ilStream,
            BlobWriter mappedFieldDataWriter,
            BlobWriter managedResourceWriter,
            MetadataSizes metadataSizes,
            ContentId pdbContentId,
            out long metadataPosition)
        {
            peStream.Position = _textSection.PointerToRawData;
            if (_emitRuntimeStartupStub)
            {
                this.WriteImportAddressTable(peStream);
            }

            WriteCorHeader(peStream, corHeader);
            WriteIL(peStream, ilStream);

            metadataPosition = peStream.Position;
            WriteMetadata(peStream, metadataWriter);

            WriteManagedResources(peStream, managedResourceWriter);
            WriteSpaceForHash(peStream, (int)corHeader.StrongNameSignature.Size);
            WriteDebugTable(peStream, pdbContentId, metadataSizes);

            if (_emitRuntimeStartupStub)
            {
                WriteImportTable(peStream);
                WriteNameTable(peStream);
                WriteRuntimeStartupStub(peStream);
            }

            WriteMappedFieldData(peStream, mappedFieldDataWriter);
        }
Ejemplo n.º 45
0
        private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt)
        {
            // TODO: we can precalculate the exact size of IL stream
            var ilWriter = new BlobWriter(32 * 1024);
            var metadataWriter = new BlobWriter(16 * 1024);
            var mappedFieldDataWriter = new BlobWriter();
            var managedResourceWriter = new BlobWriter(1024);

            var debugMetadataWriterOpt = (getPortablePdbStreamOpt != null) ? new BlobWriter(16 * 1024) : null;

            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(_module.PersistentIdentifier == default(Guid));

            int moduleVersionIdOffsetInMetadataStream;
            var calculateMethodBodyStreamRva = new Func<MetadataSizes, int>(mdSizes =>
            {
                FillInTextSectionHeader(mdSizes);
                return (int)_textSection.RelativeVirtualAddress + _sizeOfImportAddressTable + 72;
            });

            int entryPointToken;
            MetadataSizes metadataSizes;
            mdWriter.SerializeMetadataAndIL(
                metadataWriter,
                debugMetadataWriterOpt,
                nativePdbWriterOpt,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                calculateMethodBodyStreamRva,
                CalculateMappedFieldDataStreamRva,
                out moduleVersionIdOffsetInMetadataStream,
                out entryPointToken,
                out metadataSizes);

            ContentId nativePdbContentId;
            if (nativePdbWriterOpt != null)
            {
                if (entryPointToken != 0)
                {
                    nativePdbWriterOpt.SetEntryPoint((uint)entryPointToken);
                }

                var assembly = _module.AsAssembly;
                if (assembly != null && assembly.Kind == ModuleKind.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(_module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(_module.GetSymbolToLocationMap());
#endif
                }

                nativePdbContentId = nativePdbWriterOpt.GetContentId();

                // the writer shall not be used after this point for writing:
                nativePdbWriterOpt = null;
            }
            else
            {
                nativePdbContentId = default(ContentId);
            }

            FillInSectionHeaders();

            // fill in header fields.
            FillInNtHeader(metadataSizes, CalculateMappedFieldDataStreamRva(metadataSizes));
            var corHeader = CreateCorHeader(metadataSizes, entryPointToken);

            // write to PE stream.
            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return false;
            }

            long ntHeaderTimestampPosition;
            long metadataPosition;

            WriteHeaders(peStream, out ntHeaderTimestampPosition);

            WriteTextSection(
                peStream,
                corHeader,
                metadataWriter,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                metadataSizes,
                nativePdbContentId,
                out metadataPosition);

            WriteRdataSection(peStream);
            WriteSdataSection(peStream);
            WriteCoverSection(peStream);
            WriteTlsSection(peStream);
            WriteResourceSection(peStream);
            WriteRelocSection(peStream);

            if (_deterministic)
            {
                var mvidPosition = metadataPosition + moduleVersionIdOffsetInMetadataStream;
                WriteDeterministicGuidAndTimestamps(peStream, mvidPosition, ntHeaderTimestampPosition);
            }

            return true;
        }
Ejemplo n.º 46
0
        private void WriteImportAddressTable(Stream peStream)
        {
            var writer = new BlobWriter(16);
            bool use32bitAddresses = !_module.Requires64bits;
            uint importTableRVA = _ntHeader.ImportTable.RelativeVirtualAddress;
            uint ilRVA = importTableRVA + 40;
            uint hintRva = ilRVA + (use32bitAddresses ? 12u : 16u);

            // Import Address Table
            if (use32bitAddresses)
            {
                writer.WriteUint(hintRva); // 4
                writer.WriteUint(0); // 8
            }
            else
            {
                writer.WriteUlong(hintRva); // 8
                writer.WriteUlong(0); // 16
            }

            writer.WriteTo(peStream);
        }
 internal void WriteTo(BlobWriter stream)
 {
     stream.Write(_buffer, 0, _length);
 }
Ejemplo n.º 48
0
        private void WriteImportTable(Stream peStream)
        {
            var writer = new BlobWriter(70);
            bool use32bitAddresses = !_module.Requires64bits;
            uint importTableRVA = _ntHeader.ImportTable.RelativeVirtualAddress;
            uint ilRVA = importTableRVA + 40;
            uint hintRva = ilRVA + (use32bitAddresses ? 12u : 16u);
            uint nameRva = hintRva + 12 + 2;

            // Import table
            writer.WriteUint(ilRVA); // 4
            writer.WriteUint(0); // 8
            writer.WriteUint(0); // 12
            writer.WriteUint(nameRva); // 16
            writer.WriteUint(_ntHeader.ImportAddressTable.RelativeVirtualAddress); // 20
            writer.Position += 20; // 40

            // Import Lookup table
            if (use32bitAddresses)
            {
                writer.WriteUint(hintRva); // 44
                writer.WriteUint(0); // 48
                writer.WriteUint(0); // 52
            }
            else
            {
                writer.WriteUlong(hintRva); // 48
                writer.WriteUlong(0); // 56
            }

            // Hint table
            writer.WriteUshort(0); // Hint 54|58
            string entryPointName =
                (_module.Kind == ModuleKind.DynamicallyLinkedLibrary || _module.Kind == ModuleKind.WindowsRuntimeMetadata)
                ? "_CorDllMain" : "_CorExeMain";

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

            writer.WriteByte(0); // 66|70

            writer.WriteTo(peStream);
        }
Ejemplo n.º 49
0
 internal void WriteTo(BlobWriter stream)
 {
     stream.Write(_buffer, 0, _length);
 }
Ejemplo n.º 50
0
        private static void WriteNameTable(Stream peStream)
        {
            var writer = new BlobWriter(14);
            foreach (char ch in "mscoree.dll")
            {
                writer.WriteByte((byte)ch); // 11
            }

            writer.WriteByte(0); // 12
            writer.WriteUshort(0); // 14
            writer.WriteTo(peStream);
        }
Ejemplo n.º 51
0
 private static void WriteCorHeader(Stream peStream, CorHeader corHeader)
 {
     var writer = new BlobWriter(72);
     writer.WriteUint(72); // Number of bytes in this header  4
     writer.WriteUshort(corHeader.MajorRuntimeVersion); // 6 
     writer.WriteUshort(corHeader.MinorRuntimeVersion); // 8
     writer.WriteUint(corHeader.MetadataDirectory.RelativeVirtualAddress); // 12
     writer.WriteUint(corHeader.MetadataDirectory.Size); // 16
     writer.WriteUint((uint)corHeader.Flags); // 20
     writer.WriteUint(corHeader.EntryPointToken); // 24
     writer.WriteUint(corHeader.Resources.Size == 0 ? 0u : corHeader.Resources.RelativeVirtualAddress); // 28
     writer.WriteUint(corHeader.Resources.Size); // 32
     writer.WriteUint(corHeader.StrongNameSignature.Size == 0 ? 0u : corHeader.StrongNameSignature.RelativeVirtualAddress); // 36
     writer.WriteUint(corHeader.StrongNameSignature.Size); // 40
     writer.WriteUint(corHeader.CodeManagerTable.RelativeVirtualAddress); // 44
     writer.WriteUint(corHeader.CodeManagerTable.Size); // 48
     writer.WriteUint(corHeader.VTableFixups.RelativeVirtualAddress); // 52
     writer.WriteUint(corHeader.VTableFixups.Size); // 56
     writer.WriteUint(corHeader.ExportAddressTableJumps.RelativeVirtualAddress); // 60
     writer.WriteUint(corHeader.ExportAddressTableJumps.Size); // 64
     writer.WriteUlong(0); // 72
     writer.WriteTo(peStream);
 }
Ejemplo n.º 52
0
 private static void WriteIL(Stream peStream, BlobWriter ilStream)
 {
     ilStream.WriteTo(peStream);
     while (peStream.Position % 4 != 0)
     {
         peStream.WriteByte(0);
     }
 }
Ejemplo n.º 53
0
 internal void WriteTo(BlobWriter stream)
 {
     stream.Write(this.Buffer, 0, (int)this.Length);
 }
Ejemplo n.º 54
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);
 }
Ejemplo n.º 55
0
        public static bool WritePeToStream(
            EmitContext context,
            CommonMessageProvider messageProvider,
            Func <Stream> getPeStream,
            Func <Stream> getPortablePdbStreamOpt,
            PdbWriter nativePdbWriterOpt,
            string pdbPathOpt,
            bool allowMissingMethodBodies,
            bool isDeterministic,
            CancellationToken cancellationToken)
        {
            // If PDB writer is given, we have to have PDB path.
            Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null);

            var mdWriter = FullMetadataWriter.Create(context, messageProvider, allowMissingMethodBodies, isDeterministic, getPortablePdbStreamOpt != null, cancellationToken);

            var properties = context.Module.Properties;

            nativePdbWriterOpt?.SetMetadataEmitter(mdWriter);

            // Since we are producing a full assembly, we should not have a module version ID
            // imposed ahead-of time. Instead we will compute a deterministic module version ID
            // based on the contents of the generated stream.
            Debug.Assert(properties.PersistentIdentifier == default(Guid));

            var ilBuilder = new BlobBuilder(32 * 1024);
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceBuilder = new BlobBuilder(1024);

            Blob mvidFixup;

            mdWriter.BuildMetadataAndIL(
                nativePdbWriterOpt,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                out mvidFixup);

            MethodDefinitionHandle entryPointHandle;
            MethodDefinitionHandle debugEntryPointHandle;

            mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle);

            if (!debugEntryPointHandle.IsNil)
            {
                nativePdbWriterOpt?.SetEntryPoint((uint)MetadataTokens.GetToken(debugEntryPointHandle));
            }

            if (nativePdbWriterOpt != null)
            {
                var assembly = mdWriter.Module.AsAssembly;
                if (assembly != null && assembly.Kind == OutputKind.WindowsRuntimeMetadata)
                {
                    // Dev12: If compiling to winmdobj, we need to add to PDB source spans of
                    //        all types and members for better error reporting by WinMDExp.
                    nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap());
#endif
                }
            }

            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return(false);
            }

            BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default(BlobContentId);

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

            ushort portablePdbVersion = 0;
            var    metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer();

            var peHeaderBuilder = new PEHeaderBuilder(
                machine: properties.Machine,
                sectionAlignment: properties.SectionAlignment,
                fileAlignment: properties.FileAlignment,
                imageBase: properties.BaseAddress,
                majorLinkerVersion: properties.LinkerMajorVersion,
                minorLinkerVersion: properties.LinkerMinorVersion,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: properties.MajorSubsystemVersion,
                minorSubsystemVersion: properties.MinorSubsystemVersion,
                subsystem: properties.Subsystem,
                dllCharacteristics: properties.DllCharacteristics,
                imageCharacteristics: properties.ImageCharacteristics,
                sizeOfStackReserve: properties.SizeOfStackReserve,
                sizeOfStackCommit: properties.SizeOfStackCommit,
                sizeOfHeapReserve: properties.SizeOfHeapReserve,
                sizeOfHeapCommit: properties.SizeOfHeapCommit);

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

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

                var debugMetadataBuilder    = new BlobBuilder();
                var debugMetadataSerializer = mdWriter.GetStandaloneDebugMetadataSerializer(metadataSerializer.MetadataSizes, debugEntryPointHandle, deterministicIdProvider);
                debugMetadataSerializer.SerializeMetadata(debugMetadataBuilder, out pdbContentId);
                portablePdbVersion = debugMetadataSerializer.FormatVersion;

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

            DebugDirectoryBuilder debugDirectoryBuilder;
            if (pdbPathOpt != null || isDeterministic)
            {
                debugDirectoryBuilder = new DebugDirectoryBuilder();
                if (pdbPathOpt != null)
                {
                    string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt);
                    debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion);
                }

                if (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

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

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

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

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

            return(true);
        }
Ejemplo n.º 56
0
        public void WriteContentToBlobWriter()
        {
            var builder = new BlobBuilder(16);
            for (int i = 0; i < 20; i++)
            {
                builder.WriteByte((byte)i);
            }

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

            builder.WriteByte(0xff);

            builder.WriteContentTo(ref writer);
            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,
            }, writer.ToArray());
        }