예제 #1
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);
        }
예제 #2
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);
            }
        }
예제 #3
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);
        }
예제 #4
0
        internal int GetBlobIndex(ImmutableArray <byte> blob)
        {
            int result = 0;

            if (blob.Length == 0 || _blobIndex.TryGetValue(blob, out result))
            {
                return(result);
            }

            Debug.Assert(!_streamsAreComplete);
            result = _blobWriter.Position + _blobIndexStartOffset;
            _blobIndex.Add(blob, result);
            _blobWriter.WriteCompressedUInt((uint)blob.Length);
            _blobWriter.WriteBytes(blob);
            return(result);
        }
예제 #5
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);
            }
        }
예제 #7
0
        public int AllocateGuid(Guid guid)
        {
            Debug.Assert(!_streamsAreComplete);

            // The only GUIDs that are serialized are MVID, EncId, and EncBaseId in the
            // Module table. Each of those GUID offsets are relative to the local heap,
            // even for deltas, so there's no need for a GetGuidStreamPosition() method
            // to offset the positions by the size of the original heap in delta metadata.
            // Unlike #Blob, #String and #US streams delta #GUID stream is padded to the
            // size of the previous generation #GUID stream before new GUIDs are added.

            // Metadata Spec:
            // The Guid heap is an array of GUIDs, each 16 bytes wide.
            // Its first element is numbered 1, its second 2, and so on.
            int result = (_guidWriter.Length >> 4) + 1;

            _guidIndex.Add(guid, result);
            _guidWriter.WriteBytes(guid.ToByteArray());

            return(result);
        }
예제 #8
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;
                    }
                }
            }
        }
예제 #9
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();
        }
예제 #10
0
파일: BlobTests.cs 프로젝트: rgani/roslyn
 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);
 }
예제 #11
0
 internal void WriteTo(BlobWriter stream)
 {
     stream.WriteBytes(_buffer, 0, _length);
 }
예제 #12
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);
            }

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

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

            var metadataSerializer = mdWriter.GetTypeSystemMetadataSerializer();

            var peBuilder = new PEBuilder(
                machine: properties.Machine,
                sectionAlignment: properties.SectionAlignment,
                fileAlignment: properties.FileAlignment,
                imageBase: properties.BaseAddress,
                majorLinkerVersion: properties.LinkerMajorVersion,
                minorLinkerVersion: properties.LinkerMinorVersion,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: properties.MajorSubsystemVersion,
                minorSubsystemVersion: properties.MinorSubsystemVersion,
                subsystem: properties.Subsystem,
                dllCharacteristics: properties.DllCharacteristics,
                imageCharacteristics: properties.ImageCharacteristics,
                sizeOfStackReserve: properties.SizeOfStackReserve,
                sizeOfStackCommit: properties.SizeOfStackCommit,
                sizeOfHeapReserve: properties.SizeOfHeapReserve,
                sizeOfHeapCommit: properties.SizeOfHeapCommit,
                deterministicIdProvider: isDeterministic ? new Func <BlobBuilder, ContentId>(content => ContentId.FromHash(CryptographicHashProvider.ComputeSha1(content))) : null);

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

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

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

            var peDirectoriesBuilder = new PEDirectoriesBuilder();

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

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

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

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

            return(true);
        }
예제 #13
0
        public void WriteBytes1()
        {
            var writer = new BlobWriter(4);

            writer.WriteBytes(new byte[] { 1, 2, 3, 4 });
            writer.WriteBytes(new byte[] { });
            writer.WriteBytes(new byte[] { }, 0, 0);
            writer.WriteBytes(new byte[] { 5, 6, 7, 8 });
            writer.WriteBytes(new byte[] { 9 });
            writer.WriteBytes(new byte[] { 0x0a }, 0, 0);
            writer.WriteBytes(new byte[] { 0x0b }, 0, 1);
            writer.WriteBytes(new byte[] { 0x0c }, 1, 0);
            writer.WriteBytes(new byte[] { 0x0d, 0x0e }, 1, 1);

            AssertEx.Equal(new byte[]
            {
                0x01, 0x02, 0x03, 0x04,
                0x05, 0x06, 0x07, 0x08,
                0x09,
                0x0b,
                0x0e
            }, writer.ToArray());
        }
예제 #14
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);
        }
예제 #15
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);
        }
예제 #16
0
파일: BlobBuilder.cs 프로젝트: Eyas/roslyn
        /// <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);
            }
        }
예제 #17
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;
        }
예제 #18
0
        public void WriteBytes2()
        {
            var writer = new BlobWriter(4);

            writer.WriteBytes(0xff, 0);
            writer.WriteBytes(1, 4);
            writer.WriteBytes(0xff, 0);
            writer.WriteBytes(2, 10);
            writer.WriteBytes(0xff, 0);
            writer.WriteBytes(3, 1);
            
            AssertEx.Equal(new byte[]
            {
                0x01, 0x01, 0x01, 0x01,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
                0x03
            }, writer.ToArray());
        }
예제 #19
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);
        }