Пример #1
0
        public void BlobEncoder_MethodSignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            var s = e.MethodSignature();
            AssertEx.Equal(new byte[] { 0x00 }, b.ToArray());
            Assert.Same(b, s.Builder);
            Assert.False(s.HasVarArgs);
            b.Clear();

            s = e.MethodSignature(
                convention: SignatureCallingConvention.StdCall,
                genericParameterCount: 1234,
                isInstanceMethod: true);

            AssertEx.Equal(new byte[] { 0x32, 0x84, 0xD2 }, b.ToArray());
            Assert.False(s.HasVarArgs);
            b.Clear();

            s = e.MethodSignature(
                convention: SignatureCallingConvention.VarArgs,
                genericParameterCount: 1,
                isInstanceMethod: false);

            AssertEx.Equal(new byte[] { 0x15, 0x01 }, b.ToArray());
            Assert.True(s.HasVarArgs);
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: ushort.MaxValue + 1));
        }
        private static void WriteFakeILWithBranches(BlobBuilder builder, ControlFlowBuilder branchBuilder, int size)
        {
            Assert.Equal(0, builder.Count);

            const byte filling = 0x01;
            int ilOffset = 0;
            foreach (var branch in branchBuilder.Branches)
            {
                builder.WriteBytes(filling, branch.ILOffset - ilOffset);

                Assert.Equal(branch.ILOffset, builder.Count);
                builder.WriteByte((byte)branch.OpCode);

                int operandSize = branch.OpCode.GetBranchOperandSize();
                if (operandSize == 1)
                {
                    builder.WriteSByte(-1);
                }
                else
                {
                    builder.WriteInt32(-1);
                }

                ilOffset = branch.ILOffset + sizeof(byte) + operandSize;
            }

            builder.WriteBytes(filling, size - ilOffset);
            Assert.Equal(size, builder.Count);
        }
Пример #3
0
        internal static ExceptionRegionEncoder SerializeTableHeader(BlobBuilder builder, int exceptionRegionCount, bool hasSmallRegions)
        {
            Debug.Assert(exceptionRegionCount > 0);

            const byte EHTableFlag = 0x01;
            const byte FatFormatFlag = 0x40;

            bool hasSmallFormat = hasSmallRegions && IsSmallRegionCount(exceptionRegionCount);
            int dataSize = GetExceptionTableSize(exceptionRegionCount, hasSmallFormat);

            builder.Align(4);
            if (hasSmallFormat)
            {
                builder.WriteByte(EHTableFlag);
                builder.WriteByte(unchecked((byte)dataSize));
                builder.WriteInt16(0);
            }
            else
            {
                Debug.Assert(dataSize <= 0x00ffffff);
                builder.WriteByte(EHTableFlag | FatFormatFlag);
                builder.WriteByte(unchecked((byte)dataSize));
                builder.WriteUInt16(unchecked((ushort)(dataSize >> 8)));
            }

            return new ExceptionRegionEncoder(builder, hasSmallFormat);
        }
Пример #4
0
        /// <summary>
        /// Serialized the metadata root content into the given <see cref="BlobBuilder"/>.
        /// </summary>
        /// <param name="builder">Builder to write to.</param>
        /// <param name="methodBodyStreamRva">
        /// The relative virtual address of the start of the method body stream.
        /// Used to calculate the final value of RVA fields of MethodDef table.
        /// </param>
        /// <param name="mappedFieldDataStreamRva">
        /// The relative virtual address of the start of the field init data stream.
        /// Used to calculate the final value of RVA fields of FieldRVA table.
        /// </param>
        /// <exception cref="ArgumentNullException"><paramref name="builder"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="methodBodyStreamRva"/> or <paramref name="mappedFieldDataStreamRva"/> is negative.</exception>
        public void Serialize(BlobBuilder builder, int methodBodyStreamRva, int mappedFieldDataStreamRva)
        {
            if (builder == null)
            {
                Throw.ArgumentNull(nameof(builder));
            }

            if (methodBodyStreamRva < 0)
            {
                Throw.ArgumentOutOfRange(nameof(methodBodyStreamRva));
            }

            if (mappedFieldDataStreamRva < 0)
            {
                Throw.ArgumentOutOfRange(nameof(mappedFieldDataStreamRva));
            }

            // header:
            MetadataBuilder.SerializeMetadataHeader(builder, MetadataVersion, _serializedMetadata.Sizes);

            // #~ or #- stream:
            _tablesAndHeaps.SerializeMetadataTables(builder, _serializedMetadata.Sizes, _serializedMetadata.StringMap, methodBodyStreamRva, mappedFieldDataStreamRva);

            // #Strings, #US, #Guid and #Blob streams:
            _tablesAndHeaps.WriteHeapsTo(builder, _serializedMetadata.StringHeap);
        }
Пример #5
0
 private string ReadVersion(BlobBuilder metadata)
 {
     using (var provider = MetadataReaderProvider.FromMetadataImage(metadata.ToImmutableArray()))
     {
         return provider.GetMetadataReader().MetadataVersion;
     }
 }
Пример #6
0
        public void WriteData(BlobBuilder 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.WriteInt32(count);

                        int bytesWritten = resourceWriter.TryWriteBytes(stream, count);
                        if (bytesWritten != count)
                        {
                            throw new EndOfStreamException(
                                    string.Format(CultureInfo.CurrentUICulture, CodeAnalysisResources.ResourceStreamEndedUnexpectedly, bytesWritten, count));
                        }
                        resourceWriter.Align(8);
                    }
                }
                catch (Exception e)
                {
                    throw new ResourceException(_name, e);
                }
            }
        }
        public void Baseline()
        {
            var mdBuilder = new MetadataBuilder();

            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder);
            var mdBlob = new BlobBuilder();
            rootBuilder.Serialize(mdBlob, 0, 0);

            // validate sizes table rows that reference guids:
            using (var mdProvider = MetadataReaderProvider.FromMetadataImage(mdBlob.ToImmutableArray()))
            {
                var mdReader = mdProvider.GetMetadataReader();

                Assert.Equal(2 + 3 * 2 + 2, mdReader.ModuleTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.TypeRefTable.RowSize);
                Assert.Equal(4 + 2 + 2 + 2 + 2 + 2, mdReader.TypeDefTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.FieldTable.RowSize);
                Assert.Equal(8 + 2 + 2 + 2, mdReader.MethodDefTable.RowSize);
                Assert.Equal(4 + 2, mdReader.ParamTable.RowSize);
                Assert.Equal(2 + 2, mdReader.InterfaceImplTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MemberRefTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.ConstantTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.CustomAttributeTable.RowSize);
                Assert.Equal(2 + 2, mdReader.FieldMarshalTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.DeclSecurityTable.RowSize);
                Assert.Equal(6 + 2, mdReader.ClassLayoutTable.RowSize);
                Assert.Equal(4 + 2, mdReader.FieldLayoutTable.RowSize);
                Assert.Equal(2, mdReader.StandAloneSigTable.RowSize);
                Assert.Equal(2 + 2, mdReader.EventMapTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.EventTable.RowSize);
                Assert.Equal(2 + 2, mdReader.PropertyMapTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.PropertyTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MethodSemanticsTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MethodImplTable.RowSize);
                Assert.Equal(2, mdReader.ModuleRefTable.RowSize);
                Assert.Equal(2, mdReader.TypeSpecTable.RowSize);
                Assert.Equal(2 + 2 + 2 + 2, mdReader.ImplMapTable.RowSize);
                Assert.Equal(4 + 2, mdReader.FieldRvaTable.RowSize);
                Assert.Equal(16 + 2 + 2 + 2, mdReader.AssemblyTable.RowSize);
                Assert.Equal(12 + 2 + 2 + 2 + 2, mdReader.AssemblyRefTable.RowSize);
                Assert.Equal(4 + 2 + 2, mdReader.FileTable.RowSize);
                Assert.Equal(8 + 2 + 2 + 2, mdReader.ExportedTypeTable.RowSize);
                Assert.Equal(8 + 2 + 2, mdReader.ManifestResourceTable.RowSize);
                Assert.Equal(2 + 2, mdReader.NestedClassTable.RowSize);
                Assert.Equal(4 + 2 + 2, mdReader.GenericParamTable.RowSize);
                Assert.Equal(2 + 2, mdReader.MethodSpecTable.RowSize);
                Assert.Equal(2 + 2, mdReader.GenericParamConstraintTable.RowSize);
                Assert.Equal(2 + 2 + 2 + 2, mdReader.DocumentTable.RowSize);
                Assert.Equal(2 + 2, mdReader.MethodDebugInformationTable.RowSize);
                Assert.Equal(2 + 2 + 2 + 2 + 4 + 4, mdReader.LocalScopeTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.LocalVariableTable.RowSize);
                Assert.Equal(2 + 2, mdReader.LocalConstantTable.RowSize);
                Assert.Equal(2 + 2, mdReader.ImportScopeTable.RowSize);
                Assert.Equal(2 + 2, mdReader.StateMachineMethodTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.CustomDebugInformationTable.RowSize);
            }
        }
Пример #8
0
        public void Serialize_Errors()
        {
            var mdBuilder = new MetadataBuilder();
            var pdbBuilder = new PortablePdbBuilder(mdBuilder, MetadataRootBuilder.EmptyRowCounts, default(MethodDefinitionHandle));
            var builder = new BlobBuilder();

            Assert.Throws<ArgumentNullException>(() => pdbBuilder.Serialize(null));
        }
Пример #9
0
        public void BlobEncoder_FieldSignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            var s = e.FieldSignature();
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            Assert.Same(b, s.Builder);
        }
Пример #10
0
        public BlobEncoder(BlobBuilder builder)
        {
            if (builder == null)
            {
                Throw.BuilderArgumentNull();
            }

            Builder = builder;
        }
Пример #11
0
 public SerializedMetadata(
     MetadataSizes sizes,
     BlobBuilder stringHeap,
     ImmutableArray<int> stringMap)
 {
     Sizes = sizes;
     StringHeap = stringHeap;
     StringMap = stringMap;
 }
Пример #12
0
 public SerializedSection(BlobBuilder builder, string name, SectionCharacteristics characteristics, int relativeVirtualAddress, int sizeOfRawData, int pointerToRawData)
 {
     Name = name;
     Characteristics = characteristics;
     Builder = builder;
     RelativeVirtualAddress = relativeVirtualAddress;
     SizeOfRawData = sizeOfRawData;
     PointerToRawData = pointerToRawData;
 }
        public void Add_Small()
        {
            var builder = new BlobBuilder();
            var encoder = new ExceptionRegionEncoder(builder, hasSmallFormat: true);

            encoder.Add(ExceptionRegionKind.Catch, 1, 2, 4, 5, catchType: MetadataTokens.TypeDefinitionHandle(1));

            AssertEx.Equal(new byte[]
            {
                0x00, 0x00,            // kind
                0x01, 0x00,            // try offset
                0x02,                  // try length
                0x04, 0x00,            // handler offset
                0x05,                  // handler length
                0x01, 0x00, 0x00, 0x02 // catch type
            }, builder.ToArray());
            builder.Clear();

            encoder.Add(ExceptionRegionKind.Filter, 0xffff, 0xff, 0xffff, 0xff, filterOffset: int.MaxValue);

            AssertEx.Equal(new byte[]
            {
                0x01, 0x00,            // kind
                0xff, 0xff,            // try offset
                0xff,                  // try length
                0xff, 0xff,            // handler offset
                0xff,                  // handler length
                0xff, 0xff, 0xff, 0x7f // filter offset
            }, builder.ToArray());
            builder.Clear();

            encoder.Add(ExceptionRegionKind.Fault, 0xffff, 0xff, 0xffff, 0xff);

            AssertEx.Equal(new byte[]
            {
                0x04, 0x00,            // kind
                0xff, 0xff,            // try offset
                0xff,                  // try length
                0xff, 0xff,            // handler offset
                0xff,                  // handler length
                0x00, 0x00, 0x00, 0x00
            }, builder.ToArray());
            builder.Clear();

            encoder.Add(ExceptionRegionKind.Finally, 0, 0, 0, 0);

            AssertEx.Equal(new byte[]
            {
                0x02, 0x00,            // kind
                0x00, 0x00,            // try offset
                0x00,                  // try length
                0x00, 0x00,            // handler offset
                0x00,                  // handler length
                0x00, 0x00, 0x00, 0x00
            }, builder.ToArray());
            builder.Clear();
        }
Пример #14
0
        public void Ctor()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var ie = new InstructionEncoder(code, flow);
            Assert.Same(ie.CodeBuilder, code);
            Assert.Same(ie.ControlFlowBuilder, flow);

            Assert.Throws<ArgumentNullException>(() => new InstructionEncoder(null));
        }
Пример #15
0
        public void Serialize_Errors()
        {
            var mdBuilder = new MetadataBuilder();
            var rootBuilder = new MetadataRootBuilder(mdBuilder);
            var builder = new BlobBuilder();

            Assert.Throws<ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1));
        }
Пример #16
0
        /// <summary>
        /// Creates an encoder backed by code and control-flow builders.
        /// </summary>
        /// <param name="codeBuilder">Builder to write encoded instructions to.</param>
        /// <param name="controlFlowBuilder">
        /// Builder tracking labels, branches and exception handlers.
        /// Must be specified to be able to use some of the control-flow factory methods of <see cref="InstructionEncoder"/>,
        /// such as <see cref="Branch(ILOpCode, LabelHandle)"/>, <see cref="DefineLabel"/>, <see cref="MarkLabel(LabelHandle)"/> etc.
        /// </param>
        public InstructionEncoder(BlobBuilder codeBuilder, ControlFlowBuilder controlFlowBuilder = null)
        {
            if (codeBuilder == null)
            {
                Throw.BuilderArgumentNull();
            }

            CodeBuilder = codeBuilder;
            ControlFlowBuilder = controlFlowBuilder;
        }
Пример #17
0
        private void TestContentEquals(byte[] left, byte[] right)
        {
            var builder1 = new BlobBuilder(0);
            builder1.WriteBytes(left);

            var builder2 = new BlobBuilder(0);
            builder2.WriteBytes(right);

            bool expected = ByteSequenceComparer.Equals(left, right);
            Assert.Equal(expected, builder1.ContentEquals(builder2));
        }
Пример #18
0
        public void Ctor()
        {
            var builder = new BlobBuilder();
            Assert.Equal(BlobBuilder.DefaultChunkSize, builder.ChunkCapacity);

            builder = new BlobBuilder(0);
            Assert.Equal(BlobBuilder.MinChunkSize, builder.ChunkCapacity);

            builder = new BlobBuilder(10001);
            Assert.Equal(10001, builder.ChunkCapacity);
        }
        private static BlobBuilder BuildMetadataImage()
        {
            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder, "v9.9.9.9");

            var builder = new BlobBuilder();
            rootBuilder.Serialize(builder, 0, 0);

            return builder;
        }
Пример #20
0
        public void SerializeMetadata(BlobBuilder builder, Func<BlobBuilder, ContentId> idProvider, out ContentId contentId)
        {
            SerializeMetadataImpl(builder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0);

            contentId = idProvider(builder);

            // fill in the id:
            var idWriter = new BlobWriter(_pdbIdBlob);
            idWriter.WriteBytes(contentId.Guid);
            idWriter.WriteBytes(contentId.Stamp);
            Debug.Assert(idWriter.RemainingBytes == 0);
        }
Пример #21
0
 internal MethodBodyEncoder(
     BlobBuilder builder,
     ushort maxStack,
     int exceptionRegionCount,
     StandaloneSignatureHandle localVariablesSignature,
     MethodBodyAttributes attributes)
 {
     Builder = builder;
     _maxStack = maxStack;
     _localVariablesSignature = localVariablesSignature;
     _attributes = (byte)attributes;
     _exceptionRegionCount = exceptionRegionCount;
 }
Пример #22
0
        public void ContentEquals()
        {
            var builder = new BlobBuilder();
            Assert.True(builder.ContentEquals(builder));
            Assert.False(builder.ContentEquals(null));

            TestContentEquals(new byte[] { }, new byte[] { });
            TestContentEquals(new byte[] { 1 }, new byte[] { });
            TestContentEquals(new byte[] { }, new byte[] { 1 });
            TestContentEquals(new byte[] { 1 }, new byte[] { 1 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });

            TestContentEquals(
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 },
                new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });
        }
        internal void SerializeMetadataTables(BlobBuilder writer)
        {
            var sizes = new Sizes(_blobHeapSize, _guidWriter.Count);

            SerializeHeader(writer, sizes);

            // tables:
            SerializeDocumentTable(writer, sizes);
            SerializeMethodTable(writer, sizes);

            // heaps:
            writer.LinkSuffix(_guidWriter);
            WriteBlobHeap(writer);
        }
Пример #24
0
        public void TokenInstructions()
        {
            var builder = new BlobBuilder();
            var il = new InstructionEncoder(builder);
            Assert.Equal(0, il.Offset);

            il.Token(MetadataTokens.TypeDefinitionHandle(0x123456));
            Assert.Equal(4, il.Offset);

            il.Token(0x7F7E7D7C);
            Assert.Equal(8, il.Offset);

            il.LoadString(MetadataTokens.UserStringHandle(0x010203));
            Assert.Equal(13, il.Offset);

            il.Call(MetadataTokens.MethodDefinitionHandle(0xA0A1A2));
            Assert.Equal(18, il.Offset);

            il.Call(MetadataTokens.MethodSpecificationHandle(0xB0B1B2));
            Assert.Equal(23, il.Offset);

            il.Call(MetadataTokens.MemberReferenceHandle(0xC0C1C2));
            Assert.Equal(28, il.Offset);

            il.Call((EntityHandle)MetadataTokens.MethodDefinitionHandle(0xD0D1D2));
            Assert.Equal(33, il.Offset);

            il.Call((EntityHandle)MetadataTokens.MethodSpecificationHandle(0xE0E1E2));
            Assert.Equal(38, il.Offset);

            il.Call((EntityHandle)MetadataTokens.MemberReferenceHandle(0xF0F1F2));
            Assert.Equal(43, il.Offset);

            il.CallIndirect(MetadataTokens.StandaloneSignatureHandle(0x001122));
            Assert.Equal(48, il.Offset);

            AssertEx.Equal(new byte[]
            {
                0x56, 0x34, 0x12, 0x02,
                0x7C, 0x7D, 0x7E, 0x7F,
                (byte)ILOpCode.Ldstr, 0x03, 0x02, 0x01, 0x70,
                (byte)ILOpCode.Call, 0xA2, 0xA1, 0xA0, 0x06,
                (byte)ILOpCode.Call, 0xB2, 0xB1, 0xB0, 0x2B,
                (byte)ILOpCode.Call, 0xC2, 0xC1, 0xC0, 0x0A,
                (byte)ILOpCode.Call, 0xD2, 0xD1, 0xD0, 0x06,
                (byte)ILOpCode.Call, 0xE2, 0xE1, 0xE0, 0x2B,
                (byte)ILOpCode.Call, 0xF2, 0xF1, 0xF0, 0x0A,
                (byte)ILOpCode.Calli, 0x22, 0x11, 0x00, 0x11
            }, builder.ToArray());
        }
Пример #25
0
        public void Complex()
        {
            using (var peStream = new MemoryStream())
            {
                var ilBuilder = new BlobBuilder();
                var metadataBuilder = new MetadataBuilder();
                var entryPoint = ComplexEmit(metadataBuilder, ilBuilder);

                WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);

                // peStream.Position = 0;
                // File.WriteAllBytes(@"c:\temp\test.dll", peStream.ToArray());
            }
        }
Пример #26
0
        /// <summary>
        /// Serialized #Pdb stream.
        /// </summary>
        protected override void SerializeStandalonePdbStream(BlobBuilder builder)
        {
            int startPosition = builder.Count;

            // the id will be filled in later
            _pdbIdBlob = builder.ReserveBytes(MetadataSizes.PdbIdSize);
            
            builder.WriteInt32(_entryPoint.IsNil ? 0 : MetadataTokens.GetToken(_entryPoint));

            builder.WriteUInt64(MetadataSizes.ExternalTablesMask);
            MetadataWriterUtilities.SerializeRowCounts(builder, MetadataSizes.ExternalRowCounts);

            int endPosition = builder.Count;
            Debug.Assert(MetadataSizes.CalculateStandalonePdbStreamSize() == endPosition - startPosition);
        }
Пример #27
0
        public void BasicValidation()
        {
            using (var peStream = new MemoryStream())
            {
                var ilBuilder = new BlobBuilder();
                var metadataBuilder = new MetadataBuilder();
                var entryPoint = BasicValidationEmit(metadataBuilder, ilBuilder);
                WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);

                peStream.Position = 0;
                var r = new PEReader(peStream);
                var h = r.PEHeaders;
                var mdReader = r.GetMetadataReader();
            }
        }
        public void AddMethodBody_Errors()
        {
            var streamBuilder = new BlobBuilder();
            var il = new InstructionEncoder(new BlobBuilder());

            Assert.Throws<ArgumentNullException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(default(InstructionEncoder)));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il, -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il, ushort.MaxValue + 1));

            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, maxStack: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, maxStack: ushort.MaxValue + 1));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, exceptionRegionCount: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, exceptionRegionCount: 699051));
        }
Пример #29
0
        public void BlobEncoder_PropertySignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            var s = e.PropertySignature();
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            Assert.Same(b, s.Builder);
            Assert.False(s.HasVarArgs);
            b.Clear();

            s = e.PropertySignature(isInstanceProperty: true);
            AssertEx.Equal(new byte[] { 0x28 }, b.ToArray());
            Assert.False(s.HasVarArgs);
            b.Clear();
        }
Пример #30
0
        public BlobBuilder(int size = DefaultChunkSize)
        {
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }

            // the writer assumes little-endian architecture:
            if (!BitConverter.IsLittleEndian)
            {
                throw new PlatformNotSupportedException();
            }

            _nextOrPrevious = this;
            _buffer = new byte[Math.Max(MinChunkSize, size)];
        }
Пример #31
0
 public CustomAttributeArrayTypeEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #32
0
 public FixedArgumentsEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #33
0
 public GenericTypeArgumentsEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #34
0
        /// <summary>
        /// Serialize the export symbol table into the export section.
        /// </summary>
        /// <param name="location">RVA and file location of the .edata section</param>
        private BlobBuilder SerializeExportSection(SectionLocation sectionLocation)
        {
            _exportSymbols.MergeSort((es1, es2) => StringComparer.Ordinal.Compare(es1.Name, es2.Name));

            BlobBuilder builder = new BlobBuilder();

            int minOrdinal = int.MaxValue;
            int maxOrdinal = int.MinValue;

            // First, emit the name table and store the name RVA's for the individual export symbols
            // Also, record the ordinal range.
            foreach (ExportSymbol symbol in _exportSymbols)
            {
                symbol.NameRVAWhenPlaced = sectionLocation.RelativeVirtualAddress + builder.Count;
                builder.WriteUTF8(symbol.Name);
                builder.WriteByte(0);

                if (symbol.Ordinal < minOrdinal)
                {
                    minOrdinal = symbol.Ordinal;
                }
                if (symbol.Ordinal > maxOrdinal)
                {
                    maxOrdinal = symbol.Ordinal;
                }
            }

            // Emit the DLL name
            int dllNameRVA = sectionLocation.RelativeVirtualAddress + builder.Count;

            builder.WriteUTF8(_dllNameForExportDirectoryTable);
            builder.WriteByte(0);

            int[] addressTable = new int[maxOrdinal - minOrdinal + 1];

            // Emit the name pointer table; it should be alphabetically sorted.
            // Also, we can now fill in the export address table as we've detected its size
            // in the previous pass.
            builder.Align(4);
            int namePointerTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count;

            foreach (ExportSymbol symbol in _exportSymbols)
            {
                builder.WriteInt32(symbol.NameRVAWhenPlaced);
                SymbolTarget symbolTarget  = _symbolMap[symbol.Symbol];
                Section      symbolSection = _sections[symbolTarget.SectionIndex];
                Debug.Assert(symbolSection.RVAWhenPlaced != 0);
                addressTable[symbol.Ordinal - minOrdinal] = symbolSection.RVAWhenPlaced + symbolTarget.Offset;
            }

            // Emit the ordinal table
            int ordinalTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count;

            foreach (ExportSymbol symbol in _exportSymbols)
            {
                builder.WriteUInt16((ushort)(symbol.Ordinal - minOrdinal));
            }

            // Emit the address table
            builder.Align(4);
            int addressTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count;

            foreach (int addressTableEntry in addressTable)
            {
                builder.WriteInt32(addressTableEntry);
            }

            // Emit the export directory table
            builder.Align(4);
            int exportDirectoryTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count;

            // +0x00: reserved
            builder.WriteInt32(0);
            // +0x04: TODO: time/date stamp
            builder.WriteInt32(0);
            // +0x08: major version
            builder.WriteInt16(0);
            // +0x0A: minor version
            builder.WriteInt16(0);
            // +0x0C: DLL name RVA
            builder.WriteInt32(dllNameRVA);
            // +0x10: ordinal base
            builder.WriteInt32(minOrdinal);
            // +0x14: number of entries in the address table
            builder.WriteInt32(addressTable.Length);
            // +0x18: number of name pointers
            builder.WriteInt32(_exportSymbols.Count);
            // +0x1C: export address table RVA
            builder.WriteInt32(addressTableRVA);
            // +0x20: name pointer RVV
            builder.WriteInt32(namePointerTableRVA);
            // +0x24: ordinal table RVA
            builder.WriteInt32(ordinalTableRVA);
            int exportDirectorySize = sectionLocation.RelativeVirtualAddress + builder.Count - exportDirectoryTableRVA;

            _exportDirectoryEntry = new DirectoryEntry(relativeVirtualAddress: exportDirectoryTableRVA, size: exportDirectorySize);

            return(builder);
        }
Пример #35
0
        /// <summary>
        /// Emit the .reloc section based on file relocation information in the individual blocks.
        /// We rely on the fact that the .reloc section is emitted last so that, by the time
        /// it's getting serialized, all other sections that may contain relocations have already
        /// been laid out.
        /// </summary>
        private BlobBuilder SerializeRelocationSection(SectionLocation sectionLocation)
        {
            // There are 12 bits for the relative offset
            const int RelocationTypeShift      = 12;
            const int MaxRelativeOffsetInBlock = (1 << RelocationTypeShift) - 1;

            // Even though the format doesn't dictate it, it seems customary
            // to align the base RVA's on 4K boundaries.
            const int BaseRVAAlignment = 1 << RelocationTypeShift;

            BlobBuilder   builder         = new BlobBuilder();
            int           baseRVA         = 0;
            List <ushort> offsetsAndTypes = null;

            Section relocSection = FindSection(R2RPEBuilder.RelocSectionName);

            if (relocSection != null)
            {
                relocSection.FilePosWhenPlaced = sectionLocation.PointerToRawData;
                relocSection.RVAWhenPlaced     = sectionLocation.RelativeVirtualAddress;
                builder = relocSection.Content;
            }

            // Traverse relocations in all sections in their RVA order
            // By now, all "normal" sections with relocations should already have been laid out
            foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced))
            {
                foreach (PlacedObjectData placedObjectData in section.PlacedObjectDataToRelocate)
                {
                    for (int relocIndex = 0; relocIndex < placedObjectData.Relocs.Length; relocIndex++)
                    {
                        RelocType relocType     = placedObjectData.Relocs[relocIndex].RelocType;
                        RelocType fileRelocType = Relocation.GetFileRelocationType(relocType);
                        if (fileRelocType != RelocType.IMAGE_REL_BASED_ABSOLUTE)
                        {
                            int relocationRVA = section.RVAWhenPlaced + placedObjectData.Offset + placedObjectData.Relocs[relocIndex].Offset;
                            if (offsetsAndTypes != null && relocationRVA - baseRVA > MaxRelativeOffsetInBlock)
                            {
                                // Need to flush relocation block as the current RVA is too far from base RVA
                                FlushRelocationBlock(builder, baseRVA, offsetsAndTypes);
                                offsetsAndTypes = null;
                            }
                            if (offsetsAndTypes == null)
                            {
                                // Create new relocation block
                                baseRVA         = relocationRVA & -BaseRVAAlignment;
                                offsetsAndTypes = new List <ushort>();
                            }
                            ushort offsetAndType = (ushort)(((ushort)fileRelocType << RelocationTypeShift) | (relocationRVA - baseRVA));
                            offsetsAndTypes.Add(offsetAndType);
                        }
                    }
                }
            }

            if (offsetsAndTypes != null)
            {
                FlushRelocationBlock(builder, baseRVA, offsetsAndTypes);
            }

            if (builder.Count != 0)
            {
                _relocationDirectoryEntry = new DirectoryEntry(sectionLocation.RelativeVirtualAddress, builder.Count);
            }

            return(builder);
        }
Пример #36
0
 protected override void Build(ref EntityMoveNode data, BlobBuilder _, ITreeNode <INodeDataBuilder>[] __)
 {
     data.Velocity = Velocity;
 }
Пример #37
0
        private static MethodDefinitionHandle ComplexEmit(MetadataBuilder metadata, BlobBuilder ilBuilder, out Blob mvidFixup)
        {
            var mvid = metadata.ReserveGuid();

            mvidFixup = mvid.Content;

            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                mvid.Handle,
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString("ConsoleApplication"),
                version: new Version(0, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: default(BlobHandle),
                flags: default(AssemblyFlags),
                hashAlgorithm: AssemblyHashAlgorithm.Sha1);

            var mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("mscorlib"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            // TypeRefs:

            var systemObjectTypeRef              = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object"));
            var dictionaryTypeRef                = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Collections.Generic"), metadata.GetOrAddString("Dictionary`2"));
            var strignBuilderTypeRef             = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Text"), metadata.GetOrAddString("StringBuilder"));
            var typeTypeRef                      = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Type"));
            var int32TypeRef                     = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Int32"));
            var runtimeTypeHandleRef             = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("RuntimeTypeHandle"));
            var invalidOperationExceptionTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("InvalidOperationException"));

            // TypeDefs:

            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            var baseClassTypeDef = metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Abstract,
                metadata.GetOrAddString("Lib"),
                metadata.GetOrAddString("BaseClass"),
                systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            var derivedClassTypeDef = metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("Lib"),
                metadata.GetOrAddString("DerivedClass"),
                baseClassTypeDef,
                fieldList: MetadataTokens.FieldDefinitionHandle(4),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            // FieldDefs:

            // Field1
            var baseClassNumberFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Private,
                metadata.GetOrAddString("_number"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Int32())));

            // Field2
            var baseClassNegativeFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("negative"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Boolean())));

            // Field3
            var derivedClassSumCacheFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_sumCache"),
                metadata.GetOrAddBlob(BuildSignature(e =>
            {
                var inst = e.FieldSignature().GenericInstantiation(genericType: dictionaryTypeRef, genericArgumentCount: 2, isValueType: false);
                inst.AddArgument().Int32();
                inst.AddArgument().Object();
            })));

            // Field4
            var derivedClassCountFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_count"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().SZArray().Int32())));

            // Field5
            var derivedClassBCFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_bc"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Type(type: baseClassTypeDef, isValueType: false))));

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var buffer = new BlobBuilder();
            var il     = new InstructionEncoder(buffer);

            //
            // Foo
            //
            il.LoadString(metadata.GetOrAddUserString("asdsad"));
            il.OpCode(ILOpCode.Newobj);
            il.Token(invalidOperationExceptionTypeRef);
            il.OpCode(ILOpCode.Throw);

            int fooBodyOffset = methodBodyStream.AddMethodBody(il);

            // Method1
            var derivedClassFooMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.PrivateScope | MethodAttributes.Private | MethodAttributes.HideBySig,
                MethodImplAttributes.IL,
                metadata.GetOrAddString("Foo"),
                metadata.GetOrAddBlob(BuildSignature(e =>
                                                     e.MethodSignature(isInstanceMethod: true).Parameters(0, returnType => returnType.Void(), parameters => { }))),
                fooBodyOffset,
                default(ParameterHandle));

            return(default(MethodDefinitionHandle));
        }
Пример #38
0
        private static FieldDefinitionHandle FieldRVAValidationEmit(MetadataBuilder metadata, BlobBuilder mappedRVAData, double doubleToWriteAsData)
        {
            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                metadata.GetOrAddGuid(s_guid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString("ConsoleApplication"),
                version: new Version(1, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)),
                flags: AssemblyFlags.PublicKey,
                hashAlgorithm: AssemblyHashAlgorithm.Sha1);

            var mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("mscorlib"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            var systemObjectTypeRef = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Object"));

            mappedRVAData.WriteDouble(doubleToWriteAsData);

            var rvaFieldSignature = new BlobBuilder();

            new BlobEncoder(rvaFieldSignature).
            FieldSignature().Double();

            var fieldRVADef = metadata.AddFieldDefinition(
                FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.HasFieldRVA,
                metadata.GetOrAddString("RvaField"),
                metadata.GetOrAddBlob(rvaFieldSignature));

            metadata.AddFieldRelativeVirtualAddress(fieldRVADef, 0);

            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("ConsoleApplication"),
                metadata.GetOrAddString("Program"),
                systemObjectTypeRef,
                fieldList: fieldRVADef,
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            return(fieldRVADef);
        }
Пример #39
0
 public ParametersEncoder(BlobBuilder builder, bool hasVarArgs)
 {
     Builder    = builder;
     HasVarArgs = hasVarArgs;
 }
Пример #40
0
 public NamedArgumentTypeEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #41
0
 public CustomAttributeNamedArgumentsEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #42
0
 public NameEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #43
0
 public VectorEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #44
0
 public ScalarEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #45
0
 public MethodSignatureEncoder(BlobBuilder builder, bool hasVarArgs)
 {
     Builder    = builder;
     HasVarArgs = hasVarArgs;
 }
Пример #46
0
 public CustomAttributeElementTypeEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
        //[MethodImpl(MethodImplOptions.NoInlining)]
        void GenerateLoop(int brushNodeIndex0,
                          int brushNodeIndex1,
                          ref BlobArray <SurfaceInfo> surfaceInfos,
                          ref BrushTreeSpacePlanes brushTreeSpacePlanes,
                          NativeArray <PlaneVertexIndexPair> foundIndices0,
                          ref int foundIndices0Length,
                          //ref HashedVertices              hashedVertices,
                          NativeList <BlobAssetReference <BrushIntersectionLoops> > .ParallelWriter outputSurfaces)
        {
            // Why is the unity NativeSort slower than bubble sort?
            for (int i = 0; i < foundIndices0Length - 1; i++)
            {
                for (int j = i + 1; j < foundIndices0Length; j++)
                {
                    var x = foundIndices0[i];
                    var y = foundIndices0[j];
                    if (x.planeIndex > y.planeIndex)
                    {
                        continue;
                    }
                    if (x.planeIndex == y.planeIndex)
                    {
                        if (x.vertexIndex <= y.vertexIndex)
                        {
                            continue;
                        }
                    }

                    var t = x;
                    foundIndices0[i] = foundIndices0[j];
                    foundIndices0[j] = t;
                }
            }


            var planeIndexOffsetsLength = 0;
            var planeIndexOffsets       = stackalloc PlaneIndexOffsetLength[foundIndices0Length];
            var uniqueIndicesLength     = 0;
            var uniqueIndices           = stackalloc ushort[foundIndices0Length];

            // Now that our indices are sorted by planeIndex, we can segment them by start/end offset
            var previousPlaneIndex  = foundIndices0[0].planeIndex;
            var previousVertexIndex = foundIndices0[0].vertexIndex;

            uniqueIndices[uniqueIndicesLength] = previousVertexIndex;
            uniqueIndicesLength++;
            var loopStart = 0;

            for (int i = 1; i < foundIndices0Length; i++)
            {
                var indices = foundIndices0[i];

                var planeIndex  = indices.planeIndex;
                var vertexIndex = indices.vertexIndex;

                // TODO: why do we have soooo many duplicates sometimes?
                if (planeIndex == previousPlaneIndex &&
                    vertexIndex == previousVertexIndex)
                {
                    continue;
                }

                if (planeIndex != previousPlaneIndex)
                {
                    var currLength = (uniqueIndicesLength - loopStart);
                    if (currLength > 2)
                    {
                        planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                        {
                            length     = (ushort)currLength,
                            offset     = (ushort)loopStart,
                            planeIndex = previousPlaneIndex
                        };
                        planeIndexOffsetsLength++;
                    }
                    loopStart = uniqueIndicesLength;
                }

                uniqueIndices[uniqueIndicesLength] = vertexIndex;
                uniqueIndicesLength++;
                previousVertexIndex = vertexIndex;
                previousPlaneIndex  = planeIndex;
            }
            {
                var currLength = (uniqueIndicesLength - loopStart);
                if (currLength > 2)
                {
                    planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                    {
                        length     = (ushort)currLength,
                        offset     = (ushort)loopStart,
                        planeIndex = previousPlaneIndex
                    };
                    planeIndexOffsetsLength++;
                }
            }

            var maxLength = 0;

            for (int i = 0; i < planeIndexOffsetsLength; i++)
            {
                maxLength = math.max(maxLength, planeIndexOffsets[i].length);
            }

            // For each segment, we now sort our vertices within each segment,
            // making the assumption that they are convex
            var sortedStack = stackalloc int2[maxLength * 2];
            var vertices    = hashedVertices.GetUnsafeReadOnlyPtr();

            for (int n = planeIndexOffsetsLength - 1; n >= 0; n--)
            {
                var planeIndexOffset = planeIndexOffsets[n];
                var length           = planeIndexOffset.length;
                var offset           = planeIndexOffset.offset;
                var planeIndex       = planeIndexOffset.planeIndex;

                // TODO: use plane information instead
                SortIndices(vertices, sortedStack, uniqueIndices, offset, length, brushTreeSpacePlanes.treeSpacePlanes[planeIndex].xyz);
            }


            var totalLoopsSize = 16 + (planeIndexOffsetsLength * UnsafeUtility.SizeOf <BrushIntersectionLoop>());
            var totalSize      = totalLoopsSize;

            for (int j = 0; j < planeIndexOffsetsLength; j++)
            {
                var planeIndexLength = planeIndexOffsets[j];
                var loopLength       = planeIndexLength.length;
                totalSize += (loopLength * UnsafeUtility.SizeOf <float3>());
            }

            var     builder     = new BlobBuilder(Allocator.Temp, totalSize);
            ref var root        = ref builder.ConstructRoot <BrushIntersectionLoops>();
Пример #48
0
 public ParameterTypeEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #49
0
 protected override unsafe void Build(ref SetTransformRotationNode data, BlobBuilder builder, ITreeNode <INodeDataBuilder>[] tree)
 {
     RotationReader.Allocate(ref builder, ref data.RotationProperty, this, tree);
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), null, 1, null));
            }

            if (!_emissionCompleted)
            {
                foreach (ISignatureEmitter emitter in _signatureEmitters)
                {
                    emitter.MaterializeSignature();
                }

                _emissionCompleted = true;
            }

            MetadataBuilder metadataBuilder = new MetadataBuilder();

            AssemblyHashAlgorithm hashAlgorithm         = AssemblyHashAlgorithm.None;
            BlobHandle            publicKeyBlob         = default(BlobHandle);
            AssemblyFlags         manifestAssemblyFlags = default(AssemblyFlags);
            Version manifestAssemblyVersion             = new Version(0, 0, 0, 0);

            if ((factory.CompositeImageSettings != null) && factory.CompilationModuleGroup.IsCompositeBuildMode)
            {
                if (factory.CompositeImageSettings.PublicKey != null)
                {
                    hashAlgorithm          = AssemblyHashAlgorithm.Sha1;
                    publicKeyBlob          = metadataBuilder.GetOrAddBlob(factory.CompositeImageSettings.PublicKey);
                    manifestAssemblyFlags |= AssemblyFlags.PublicKey;
                }

                if (factory.CompositeImageSettings.AssemblyVersion != null)
                {
                    manifestAssemblyVersion = factory.CompositeImageSettings.AssemblyVersion;
                }
            }

            string manifestMetadataAssemblyName = "ManifestMetadata";

            metadataBuilder.AddAssembly(
                metadataBuilder.GetOrAddString(manifestMetadataAssemblyName),
                manifestAssemblyVersion,
                culture: default(StringHandle),
                publicKey: publicKeyBlob,
                flags: manifestAssemblyFlags,
                hashAlgorithm: hashAlgorithm);

            metadataBuilder.AddModule(
                0,
                metadataBuilder.GetOrAddString(manifestMetadataAssemblyName),
                default(GuidHandle), default(GuidHandle), default(GuidHandle));

            // Module type
            metadataBuilder.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadataBuilder.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            foreach (var idAndAssemblyName in _moduleIdToAssemblyNameMap.OrderBy(x => x.Key))
            {
                AssemblyName  assemblyName  = idAndAssemblyName.Value;
                AssemblyFlags assemblyFlags = 0;
                byte[]        publicKeyOrToken;
                if ((assemblyName.Flags & AssemblyNameFlags.PublicKey) != 0)
                {
                    assemblyFlags   |= AssemblyFlags.PublicKey;
                    publicKeyOrToken = assemblyName.GetPublicKey();
                }
                else
                {
                    publicKeyOrToken = assemblyName.GetPublicKeyToken();
                }
                if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0)
                {
                    assemblyFlags |= AssemblyFlags.Retargetable;
                }

                AssemblyReferenceHandle newHandle = metadataBuilder.AddAssemblyReference(
                    name: metadataBuilder.GetOrAddString(assemblyName.Name),
                    version: assemblyName.Version,
                    culture: metadataBuilder.GetOrAddString(assemblyName.CultureName),
                    publicKeyOrToken: metadataBuilder.GetOrAddBlob(publicKeyOrToken),
                    flags: assemblyFlags,
                    hashValue: default(BlobHandle) /* TODO */);
            }

            MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadataBuilder);
            BlobBuilder         metadataBlobBuilder = new BlobBuilder();

            metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0);

            return(new ObjectData(
                       data: metadataBlobBuilder.ToArray(),
                       relocs: Array.Empty <Relocation>(),
                       alignment: 1,
                       definedSymbols: new ISymbolDefinitionNode[] { this }));
        }
Пример #51
0
        private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                metadata.GetOrAddGuid(s_guid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString("ConsoleApplication"),
                version: new Version(1, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)),
                flags: AssemblyFlags.PublicKey,
                hashAlgorithm: AssemblyHashAlgorithm.Sha1);

            var mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("mscorlib"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            var systemObjectTypeRef = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Object"));

            var systemConsoleTypeRefHandle = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Console"));

            var consoleWriteLineSignature = new BlobBuilder();

            new BlobEncoder(consoleWriteLineSignature).
            MethodSignature().
            Parameters(1,
                       returnType => returnType.Void(),
                       parameters => parameters.AddParameter().Type().String());

            var consoleWriteLineMemberRef = metadata.AddMemberReference(
                systemConsoleTypeRefHandle,
                metadata.GetOrAddString("WriteLine"),
                metadata.GetOrAddBlob(consoleWriteLineSignature));

            var parameterlessCtorSignature = new BlobBuilder();

            new BlobEncoder(parameterlessCtorSignature).
            MethodSignature(isInstanceMethod: true).
            Parameters(0, returnType => returnType.Void(), parameters => { });

            var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

            var objectCtorMemberRef = metadata.AddMemberReference(
                systemObjectTypeRef,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex);

            var mainSignature = new BlobBuilder();

            new BlobEncoder(mainSignature).
            MethodSignature().
            Parameters(0, returnType => returnType.Void(), parameters => { });

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

            //
            // Program::.ctor
            //
            il = new InstructionEncoder(codeBuilder);

            // ldarg.0
            il.LoadArgument(0);

            // call instance void [mscorlib]System.Object::.ctor()
            il.Call(objectCtorMemberRef);

            // ret
            il.OpCode(ILOpCode.Ret);

            int ctorBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            //
            // Program::Main
            //
            var flowBuilder = new ControlFlowBuilder();

            il = new InstructionEncoder(codeBuilder, flowBuilder);

            var tryStart     = il.DefineLabel();
            var tryEnd       = il.DefineLabel();
            var finallyStart = il.DefineLabel();
            var finallyEnd   = il.DefineLabel();

            flowBuilder.AddFinallyRegion(tryStart, tryEnd, finallyStart, finallyEnd);

            // .try
            il.MarkLabel(tryStart);

            //   ldstr "hello"
            il.LoadString(metadata.GetOrAddUserString("hello"));

            //   call void [mscorlib]System.Console::WriteLine(string)
            il.Call(consoleWriteLineMemberRef);

            //   leave.s END
            il.Branch(ILOpCode.Leave_s, finallyEnd);
            il.MarkLabel(tryEnd);

            // .finally
            il.MarkLabel(finallyStart);

            //   ldstr "world"
            il.LoadString(metadata.GetOrAddUserString("world"));

            //   call void [mscorlib]System.Console::WriteLine(string)
            il.Call(consoleWriteLineMemberRef);

            // .endfinally
            il.OpCode(ILOpCode.Endfinally);
            il.MarkLabel(finallyEnd);

            // ret
            il.OpCode(ILOpCode.Ret);

            int mainBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();
            flowBuilder.Clear();

            var mainMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString("Main"),
                metadata.GetOrAddBlob(mainSignature),
                mainBodyOffset,
                parameterList: default(ParameterHandle));

            var ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: default(ParameterHandle));

            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("ConsoleApplication"),
                metadata.GetOrAddString("Program"),
                systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            return(mainMethodDef);
        }
Пример #52
0
 public LocalVariableTypeEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
        /// <summary>
        /// Serializes .text section data into a specified <paramref name="builder"/>.
        /// </summary>
        /// <param name="builder">An empty builder to serialize section data to.</param>
        /// <param name="relativeVirtualAddess">Relative virtual address of the section within the containing PE file.</param>
        /// <param name="entryPointTokenOrRelativeVirtualAddress">Entry point token or RVA (<see cref="CorHeader.EntryPointTokenOrRelativeVirtualAddress"/>)</param>
        /// <param name="corFlags">COR Flags (<see cref="CorHeader.Flags"/>).</param>
        /// <param name="baseAddress">Base address of the PE image.</param>
        /// <param name="metadataBuilder"><see cref="BlobBuilder"/> containing metadata. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param>
        /// <param name="ilBuilder"><see cref="BlobBuilder"/> containing IL stream. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param>
        /// <param name="mappedFieldDataBuilderOpt"><see cref="BlobBuilder"/> containing mapped field data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param>
        /// <param name="resourceBuilderOpt"><see cref="BlobBuilder"/> containing managed resource data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param>
        /// <param name="debugDataBuilderOpt"><see cref="BlobBuilder"/> containing PE debug table and data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param>
        /// <param name="strongNameSignature">Blob reserved in the <paramref name="builder"/> for strong name signature.</param>
        public void Serialize(
            BlobBuilder builder,
            int relativeVirtualAddess,
            int entryPointTokenOrRelativeVirtualAddress,
            CorFlags corFlags,
            ulong baseAddress,
            BlobBuilder metadataBuilder,
            BlobBuilder ilBuilder,
            BlobBuilder?mappedFieldDataBuilderOpt,
            BlobBuilder?resourceBuilderOpt,
            BlobBuilder?debugDataBuilderOpt,
            out Blob strongNameSignature)
        {
            Debug.Assert(builder.Count == 0);
            Debug.Assert(metadataBuilder.Count == MetadataSize);
            Debug.Assert(metadataBuilder.Count % 4 == 0);
            Debug.Assert(ilBuilder.Count == ILStreamSize);
            Debug.Assert((mappedFieldDataBuilderOpt?.Count ?? 0) == MappedFieldDataSize);
            Debug.Assert((resourceBuilderOpt?.Count ?? 0) == ResourceDataSize);
            Debug.Assert((resourceBuilderOpt?.Count ?? 0) % 4 == 0);

            // TODO: avoid recalculation
            int importTableRva        = GetImportTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress;
            int importAddressTableRva = GetImportAddressTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress;

            if (RequiresStartupStub)
            {
                WriteImportAddressTable(builder, importTableRva);
            }

            WriteCorHeader(builder, relativeVirtualAddess, entryPointTokenOrRelativeVirtualAddress, corFlags);

            // IL:
            ilBuilder.Align(4);
            builder.LinkSuffix(ilBuilder);

            // metadata:
            builder.LinkSuffix(metadataBuilder);

            // managed resources:
            if (resourceBuilderOpt != null)
            {
                builder.LinkSuffix(resourceBuilderOpt);
            }

            // strong name signature:
            strongNameSignature = builder.ReserveBytes(StrongNameSignatureSize);

            // The bytes are required to be 0 for the purpose of calculating hash of the PE content
            // when strong name signing.
            new BlobWriter(strongNameSignature).WriteBytes(0, StrongNameSignatureSize);

            // debug directory and data:
            if (debugDataBuilderOpt != null)
            {
                builder.LinkSuffix(debugDataBuilderOpt);
            }

            if (RequiresStartupStub)
            {
                WriteImportTable(builder, importTableRva, importAddressTableRva);
                WriteNameTable(builder);
                WriteRuntimeStartupStub(builder, importAddressTableRva, baseAddress);
            }

            // mapped field data:
            if (mappedFieldDataBuilderOpt != null)
            {
                builder.LinkSuffix(mappedFieldDataBuilderOpt);
            }

            Debug.Assert(builder.Count == ComputeSizeOfTextSection());
        }
Пример #54
0
 protected internal override void Serialize(BlobBuilder builder, SectionLocation location)
 {
     throw new NotImplementedException();
 }
Пример #55
0
 protected override void Build(ref NodeA data, BlobBuilder _, ITreeNode <INodeDataBuilder>[] __) => data.A = A;
Пример #56
0
 protected internal override void Serialize(BlobBuilder builder, SectionLocation location)
 {
     builder.WriteInt32(0x12345678);
     builder.WriteInt32(location.PointerToRawData);
     builder.WriteInt32(location.RelativeVirtualAddress);
 }
Пример #57
0
 protected override void AllocateData(ref BlobBuilder builder, ref BlobVariable <T> blobVariable)
 {
     builder.Allocate(ref blobVariable, CustomValue);
 }
Пример #58
0
 public PermissionSetEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #59
0
 public LiteralsEncoder(BlobBuilder builder)
 {
     Builder = builder;
 }
Пример #60
0
        /// <exception cref="InvalidOperationException" />
        internal void CopyCodeAndFixupBranches(BlobBuilder srcBuilder, BlobBuilder dstBuilder)
        {
            var branch      = _branches[0];
            int branchIndex = 0;

            // offset within the source builder
            int srcOffset = 0;

            // current offset within the current source blob
            int srcBlobOffset = 0;

            foreach (Blob srcBlob in srcBuilder.GetBlobs())
            {
                Debug.Assert(
                    srcBlobOffset == 0 ||
                    srcBlobOffset == 1 && srcBlob.Buffer[0] == 0xff ||
                    srcBlobOffset == 4 && srcBlob.Buffer[0] == 0xff && srcBlob.Buffer[1] == 0xff && srcBlob.Buffer[2] == 0xff && srcBlob.Buffer[3] == 0xff);

                while (true)
                {
                    // copy bytes preceding the next branch, or till the end of the blob:
                    int chunkSize = Math.Min(branch.ILOffset - srcOffset, srcBlob.Length - srcBlobOffset);
                    dstBuilder.WriteBytes(srcBlob.Buffer, srcBlobOffset, chunkSize);
                    srcOffset     += chunkSize;
                    srcBlobOffset += chunkSize;

                    // there is no branch left in the blob:
                    if (srcBlobOffset == srcBlob.Length)
                    {
                        srcBlobOffset = 0;
                        break;
                    }

                    Debug.Assert(srcBlob.Buffer[srcBlobOffset] == (byte)branch.OpCode);

                    int  operandSize        = branch.OpCode.GetBranchOperandSize();
                    bool isShortInstruction = operandSize == 1;

                    // Note: the 4B operand is contiguous since we wrote it via BlobBuilder.WriteInt32()
                    Debug.Assert(
                        srcBlobOffset + 1 == srcBlob.Length ||
                        (isShortInstruction ?
                         srcBlob.Buffer[srcBlobOffset + 1] == 0xff :
                         BitConverter.ToUInt32(srcBlob.Buffer, srcBlobOffset + 1) == 0xffffffff));

                    // write branch opcode:
                    dstBuilder.WriteByte(srcBlob.Buffer[srcBlobOffset]);

                    // write branch operand:
                    int  branchDistance;
                    bool isShortDistance = branch.IsShortBranchDistance(_labels, out branchDistance);

                    if (isShortInstruction && !isShortDistance)
                    {
                        // We could potentially implement algortihm that automatically fixes up the branch instructions as well to accomodate bigger distances,
                        // however an optimal algorithm would be rather complex (something like: calculate topological ordering of crossing branch instructions
                        // and then use fixed point to eliminate cycles). If the caller doesn't care about optimal IL size they can use long branches whenever the
                        // distance is unknown upfront. If they do they probably already implement more sophisticad algorithm for IL layout optimization already.
                        throw new InvalidOperationException(SR.Format(SR.DistanceBetweenInstructionAndLabelTooBig, branch.OpCode, srcOffset, branchDistance));
                    }

                    if (isShortInstruction)
                    {
                        dstBuilder.WriteSByte((sbyte)branchDistance);
                    }
                    else
                    {
                        dstBuilder.WriteInt32(branchDistance);
                    }

                    srcOffset += sizeof(byte) + operandSize;

                    // next branch:
                    branchIndex++;
                    if (branchIndex == _branches.Count)
                    {
                        branch = new BranchInfo(int.MaxValue, default(LabelHandle), 0);
                    }
                    else
                    {
                        branch = _branches[branchIndex];
                    }

                    // the branch starts at the very end and its operand is in the next blob:
                    if (srcBlobOffset == srcBlob.Length - 1)
                    {
                        srcBlobOffset = operandSize;
                        break;
                    }

                    // skip fake branch instruction:
                    srcBlobOffset += sizeof(byte) + operandSize;
                }
            }
        }