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));
        }
        public void BlobEncoder_MethodSpecificationSignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            var s = e.MethodSpecificationSignature(genericArgumentCount: 0);
            AssertEx.Equal(new byte[] { 0x0A, 0x00 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            e.MethodSpecificationSignature(genericArgumentCount: 1234);
            AssertEx.Equal(new byte[] { 0x0A, 0x84, 0xD2 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: ushort.MaxValue + 1));
        }
        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();
        }
Beispiel #4
0
        public void CountClear()
        {
            var builder = new BlobBuilder();
            Assert.Equal(0, builder.Count);

            builder.WriteByte(1);
            Assert.Equal(1, builder.Count);

            builder.WriteInt32(4);
            Assert.Equal(5, builder.Count);

            builder.Clear();
            Assert.Equal(0, builder.Count);

            builder.WriteInt64(1);
            Assert.Equal(8, builder.Count);

            AssertEx.Equal(new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, builder.ToArray());
        }
Beispiel #5
0
        public void LiteralEncoder_TaggedScalar()
        {
            var b = new BlobBuilder();
            var e = new LiteralEncoder(b);

            Assert.Same(b, e.Builder);

            CustomAttributeElementTypeEncoder elementType;
            ScalarEncoder scalar;

            e.TaggedScalar(out elementType, out scalar);

            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, elementType.Builder);
            Assert.Same(b, scalar.Builder);
            b.Clear();

            e.TaggedScalar(
                et => Assert.Same(b, et.Builder),
                s => Assert.Same(b, s.Builder));

            Assert.Throws <ArgumentNullException>(() => e.TaggedScalar(null, s => { }));
            Assert.Throws <ArgumentNullException>(() => e.TaggedScalar(et => { }, null));
        }
        public void SerializeTableHeader()
        {
            var builder = new BlobBuilder();

            builder.WriteByte(0xff);
            ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxSmallExceptionRegions, hasSmallRegions: true);
            AssertEx.Equal(new byte[] 
            {
                0xff, 0x00, 0x00, 0x00, // padding
                0x01, // flags
                0xf4, // size
                0x00, 0x00
            }, builder.ToArray());
            builder.Clear();

            builder.WriteByte(0xff);
            ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxExceptionRegions, hasSmallRegions: false);
            AssertEx.Equal(new byte[]
            {
                0xff, 0x00, 0x00, 0x00, // padding
                0x41, // flags
                0xf4, 0xff, 0xff, // size
            }, builder.ToArray());
        }
        public void SerializeTableHeader()
        {
            var builder = new BlobBuilder();

            builder.WriteByte(0xff);
            ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxSmallExceptionRegions, hasSmallRegions: true);
            AssertEx.Equal(new byte[]
            {
                0xff, 0x00, 0x00, 0x00, // padding
                0x01,                   // flags
                0xf4,                   // size
                0x00, 0x00
            }, builder.ToArray());
            builder.Clear();

            builder.WriteByte(0xff);
            ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxExceptionRegions, hasSmallRegions: false);
            AssertEx.Equal(new byte[]
            {
                0xff, 0x00, 0x00, 0x00, // padding
                0x41,                   // flags
                0xf4, 0xff, 0xff,       // size
            }, builder.ToArray());
        }
Beispiel #8
0
        public void LiteralEncoder_TaggedVector()
        {
            var b = new BlobBuilder();
            var e = new LiteralEncoder(b);

            Assert.Same(b, e.Builder);

            CustomAttributeArrayTypeEncoder arrayType;
            VectorEncoder vector;

            e.TaggedVector(out arrayType, out vector);

            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, arrayType.Builder);
            Assert.Same(b, vector.Builder);
            b.Clear();

            e.TaggedVector(
                at => Assert.Same(b, at.Builder),
                v => Assert.Same(b, v.Builder));

            Assert.Throws <ArgumentNullException>(() => e.TaggedVector(null, v => { }));
            Assert.Throws <ArgumentNullException>(() => e.TaggedVector(at => { }, null));
        }
Beispiel #9
0
        public void WriteUTF8_Substring()
        {
            var writer = new BlobBuilder(4);
            writer.WriteUTF8("abc", 0, 0, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new byte[0], writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 0, 1, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'a' }, writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 0, 2, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'a', (byte)'b' }, writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 0, 3, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'a', (byte)'b', (byte)'c' }, writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 1, 0, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new byte[0], writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 1, 1, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'b' }, writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 1, 2, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'b', (byte)'c' }, writer.ToArray());
            writer.Clear();

            writer.WriteUTF8("abc", 2, 1, allowUnpairedSurrogates: true, prependSize: false);
            AssertEx.Equal(new[] { (byte)'c' }, writer.ToArray());
            writer.Clear();
        }
Beispiel #10
0
        public void CustomAttributeNamedArgumentsEncoder_Count()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeNamedArgumentsEncoder(b);
            Assert.Same(b, e.Builder);

            e.Count(0);
            AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray());
            b.Clear();

            e.Count(ushort.MaxValue);
            AssertEx.Equal(new byte[] { 0xff, 0xff }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(ushort.MaxValue + 1));
        }
Beispiel #11
0
        private static void EmitHelperLibraryMetadata(string assemblyName, string rootNamespace,
                                                      MetadataBuilder metadata,
                                                      BlobBuilder ilBuilder)
        {
            // Dynamically get mscorlib assembly information for executing runtime
            var mscorlibName = typeof(object).GetTypeInfo().Assembly.GetName();

            // Create module version identifier
            var mvid = Guid.NewGuid();

            metadata.AddModule(
                0,
                metadata.GetOrAddString($"{assemblyName}.dll"),
                metadata.GetOrAddGuid(mvid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString(assemblyName),
                new Version(1, 0, 0, 0),
                default(StringHandle),
                default(BlobHandle),
                default(AssemblyFlags),
                AssemblyHashAlgorithm.Sha1);

            // Add mscorlib assembly reference and related type references
            var mscorlibRef = metadata.AddAssemblyReference(
                metadata.GetOrAddString("mscorlib"),
                mscorlibName.Version,
                default(StringHandle),
                metadata.GetOrAddBlob(mscorlibName.GetPublicKeyToken()),
                default(AssemblyFlags),
                default(BlobHandle));

            var objectTypeRef = metadata.AddTypeReference(
                mscorlibRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Object"));

            var consoleTypeRef = metadata.AddTypeReference(
                mscorlibRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Console"));

            // Create method signature of System.Console.WriteLine reference
            var consoleWriteLineSignature = new BlobBuilder();

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

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

            // Create constructor signature for TestClass
            var parameterlessCtorSignature = new BlobBuilder();

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

            var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

            // Create constructor of TestClass
            var objectCtorMemberRef = metadata.AddMemberReference(
                objectTypeRef,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex);

            // Create TestClass.TestMethod signature
            var testMethodSignature = new BlobBuilder();

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


            // Create an IL stream and serialize each methods
            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

            // Create constructor body by composing IL codes

            // TestClass::.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);

            var ctorBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            // Create TestClass.TestMethod body by composing IL codes

            // TestClass::TestMethod
            il = new InstructionEncoder(codeBuilder);

            // ldstr "hello"
            il.LoadString(metadata.GetOrAddUserString("Hello world from serialized assembly!"));

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

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

            var testMethodBodyOffset = methodBodyStream.AddMethodBody(il);

            // Create TestClass.TestMethod method definition
            var testMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString("TestMethod"),
                metadata.GetOrAddBlob(testMethodSignature),
                testMethodBodyOffset,
                default(ParameterHandle));

            // Create TestClass constructor definition
            var ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                default(ParameterHandle));

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

            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout |
                TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString(rootNamespace),
                metadata.GetOrAddString("TestClass"),
                objectTypeRef,
                MetadataTokens.FieldDefinitionHandle(1),
                testMethodDef);
        }
Beispiel #12
0
        public void GetBlobs()
        {
            var builder = new BlobBuilder(16);
            builder.WriteBytes(1, 100);

            var blobs = builder.GetBlobs().ToArray();
            Assert.Equal(2, blobs.Length);
            Assert.Equal(16, blobs[0].Length);
            Assert.Equal(100 - 16, blobs[1].Length);

            builder.WriteByte(1);

            blobs = builder.GetBlobs().ToArray();
            Assert.Equal(3, blobs.Length);
            Assert.Equal(16, blobs[0].Length);
            Assert.Equal(16, blobs[0].GetBytes().Array.Length);
            Assert.Equal(100 - 16, blobs[1].Length);
            Assert.Equal(100 - 16, blobs[1].GetBytes().Array.Length);
            Assert.Equal(1, blobs[2].Length);
            Assert.Equal(100 - 16, blobs[2].GetBytes().Array.Length);

            builder.Clear();

            blobs = builder.GetBlobs().ToArray();
            Assert.Equal(1, blobs.Length);
            Assert.Equal(0, blobs[0].Length);

            // Clear uses the first buffer:
            Assert.Equal(16, blobs[0].GetBytes().Array.Length);
        }
        public void PermissionSetEncoder_AddPermission()
        {
            var b = new BlobBuilder();
            var e = new PermissionSetEncoder(b);

            var s = e.AddPermission("ABCD", ImmutableArray.Create<byte>(1, 2, 3));
            Assert.Same(b, s.Builder);
            AssertEx.Equal(new byte[] { 0x04, 0x41, 0x42, 0x43, 0x44, 0x03, 0x01, 0x02, 0x03 }, b.ToArray());
            b.Clear();

            var args = new BlobBuilder();
            args.WriteBytes(new byte[] { 1, 2, 3 });

            s = e.AddPermission("ABCD", args);
            Assert.Same(b, s.Builder);
            AssertEx.Equal(new byte[] { 0x04, 0x41, 0x42, 0x43, 0x44, 0x03, 0x01, 0x02, 0x03 }, b.ToArray());
            b.Clear();

            s = e.AddPermission("", ImmutableArray.Create<byte>());
            AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray());
            b.Clear();

            s = e.AddPermission("", new BlobBuilder());
            AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentNullException>(() => e.AddPermission(null, ImmutableArray.Create<byte>(1)));
            Assert.Throws<ArgumentNullException>(() => e.AddPermission(null, args));

            Assert.Throws<ArgumentNullException>(() => e.AddPermission("A", default(ImmutableArray<byte>)));
            Assert.Throws<ArgumentNullException>(() => e.AddPermission("A", null));
        }
Beispiel #14
0
        public void NamedArgumentTypeEncoder_SZArray()
        {
            var b = new BlobBuilder();
            var e = new NamedArgumentTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.SZArray();
            AssertEx.Equal(new byte[0], b.ToArray());
            b.Clear();
        }
Beispiel #15
0
        public void SignatureTypeEncoder_Primitives()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.Boolean();
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.Char();
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.SByte();
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.Byte();
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.Int16();
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.UInt16();
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.Int32();
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.UInt32();
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.Int64();
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.UInt64();
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.Single();
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.Double();
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.String();
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            e.IntPtr();
            AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
            b.Clear();

            e.UIntPtr();
            AssertEx.Equal(new byte[] { 0x19 }, b.ToArray());
            b.Clear();

            e.Object();
            AssertEx.Equal(new byte[] { 0x1C }, b.ToArray());
            b.Clear();
        }
        public static void Convert(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream)
        {
            using (var peReader = new PEReader(peStream))
                using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(sourcePdbStream))
                    using (var pdbWriter = new PdbWriter(peReader.GetMetadataReader()))
                    {
                        var metadataReader = peReader.GetMetadataReader();
                        var metadataModel  = new MetadataModel(metadataReader);

                        var pdbReader = pdbReaderProvider.GetMetadataReader();

                        var documentWriters         = new ArrayBuilder <ISymUnmanagedDocumentWriter>(pdbReader.Documents.Count);
                        var symSequencePointBuilder = new SequencePointsBuilder(capacity: 64);
                        var declaredExternAliases   = new HashSet <string>();
                        var importStringsBuilder    = new List <string>();
                        var importCountsPerScope    = new List <int>();
                        var cdiBuilder    = new BlobBuilder();
                        var dynamicLocals = new List <(string LocalName, byte[] Flags, int Count, int SlotIndex)>();

                        // state for calculating import string forwarding:
                        var lastImportScopeHandle          = default(ImportScopeHandle);
                        var lastImportScopeMethodDefHandle = default(MethodDefinitionHandle);
                        var importStringsMap = new Dictionary <ImmutableArray <string>, MethodDefinitionHandle>();

                        var aliasedAssemblyRefs = GetAliasedAssemblyRefs(pdbReader);
                        var kickOffMethodToMoveNextMethodMap = GetStateMachineMethodMap(pdbReader);

                        string vbDefaultNamespace             = MetadataUtilities.GetVisualBasicDefaultNamespace(metadataReader);
                        bool   vbSemantics                    = vbDefaultNamespace != null;
                        string vbDefaultNamespaceImportString = vbSemantics ? "*" + vbDefaultNamespace : null;

                        foreach (var documentHandle in pdbReader.Documents)
                        {
                            var document     = pdbReader.GetDocument(documentHandle);
                            var languageGuid = pdbReader.GetGuid(document.Language);

                            documentWriters.Add(pdbWriter.DefineDocument(
                                                    name: pdbReader.GetString(document.Name),
                                                    language: languageGuid,
                                                    type: s_documentTypeText,
                                                    vendor: GetLanguageVendorGuid(languageGuid),
                                                    algorithmId: pdbReader.GetGuid(document.HashAlgorithm),
                                                    checksum: pdbReader.GetBlobBytes(document.Hash)));
                        }

                        var        localScopeEnumerator = pdbReader.LocalScopes.GetEnumerator();
                        LocalScope currentLocalScope    = NextLocalScope();

                        LocalScope NextLocalScope() =>
                        localScopeEnumerator.MoveNext() ? pdbReader.GetLocalScope(localScopeEnumerator.Current) : default(LocalScope);

                        var firstMethodDefHandle = default(MethodDefinitionHandle);
                        foreach (var methodDebugInfoHandle in pdbReader.MethodDebugInformation)
                        {
                            var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugInfoHandle);
                            var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle();
                            int methodToken     = MetadataTokens.GetToken(methodDefHandle);
                            var methodDef       = metadataReader.GetMethodDefinition(methodDefHandle);

                            // methods without debug info:
                            if (methodDebugInfo.Document.IsNil && methodDebugInfo.SequencePointsBlob.IsNil)
                            {
                                continue;
                            }

                            // methods without method body don't currently have any debug information:
                            if (methodDef.RelativeVirtualAddress == 0)
                            {
                                continue;
                            }

                            var methodBody = peReader.GetMethodBody(methodDef.RelativeVirtualAddress);

                            pdbWriter.OpenMethod(methodToken);

                            var forwardImportScopesToMethodDef = default(MethodDefinitionHandle);
                            Debug.Assert(dynamicLocals.Count == 0);

                            bool isFirstMethodScope = true;
                            while (currentLocalScope.Method == methodDefHandle)
                            {
                                if (isFirstMethodScope)
                                {
                                    if (lastImportScopeHandle == currentLocalScope.ImportScope)
                                    {
                                        // forward to a method that has the same imports:
                                        forwardImportScopesToMethodDef = lastImportScopeMethodDefHandle;
                                    }
                                    else
                                    {
                                        Debug.Assert(importStringsBuilder.Count == 0);
                                        Debug.Assert(declaredExternAliases.Count == 0);
                                        Debug.Assert(importCountsPerScope.Count == 0);

                                        AddImportStrings(importStringsBuilder, importCountsPerScope, declaredExternAliases, pdbReader, metadataModel, currentLocalScope.ImportScope, aliasedAssemblyRefs, vbDefaultNamespaceImportString);
                                        var importStrings = importStringsBuilder.ToImmutableArray();
                                        importStringsBuilder.Clear();

                                        if (importStringsMap.TryGetValue(importStrings, out forwardImportScopesToMethodDef))
                                        {
                                            // forward to a method that has the same imports:
                                            lastImportScopeMethodDefHandle = forwardImportScopesToMethodDef;
                                        }
                                        else
                                        {
                                            // attach import strings to the current method:
                                            WriteImports(pdbWriter, importStrings);
                                            lastImportScopeMethodDefHandle = methodDefHandle;
                                        }

                                        lastImportScopeHandle = currentLocalScope.ImportScope;
                                    }

                                    if (vbSemantics && !forwardImportScopesToMethodDef.IsNil)
                                    {
                                        pdbWriter.UsingNamespace("@" + MetadataTokens.GetToken(forwardImportScopesToMethodDef));
                                    }
                                }
                                else
                                {
                                    pdbWriter.OpenScope(currentLocalScope.StartOffset);
                                }

                                foreach (var localConstantHandle in currentLocalScope.GetLocalConstants())
                                {
                                    var    constant = pdbReader.GetLocalConstant(localConstantHandle);
                                    string name     = pdbReader.GetString(constant.Name);

                                    if (name.Length > MaxEntityNameLength)
                                    {
                                        // TODO: report warning
                                        continue;
                                    }

                                    var(value, signature) = PortableConstantSignature.GetConstantValueAndSignature(pdbReader, localConstantHandle, pdbWriter.MetadataImport);
                                    if (!metadataModel.TryGetStandaloneSignatureHandle(signature, out var constantSignatureHandle))
                                    {
                                        // TODO: report warning

                                        // TODO:
                                        // Currently the EEs require signature to match exactly the type of the value.
                                        // We could relax that and use the type of the value regardless of the signature for primitive types.
                                        // Then we could use any signature here.
                                        continue;
                                    }

                                    pdbWriter.DefineLocalConstant(name, value, MetadataTokens.GetToken(constantSignatureHandle));

                                    var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localConstantHandle);
                                    if (TryGetDynamicLocal(name, 0, dynamicFlags, out var dynamicLocal))
                                    {
                                        dynamicLocals.Add(dynamicLocal);
                                    }
                                }

                                foreach (var localVariableHandle in currentLocalScope.GetLocalVariables())
                                {
                                    var    variable = pdbReader.GetLocalVariable(localVariableHandle);
                                    string name     = pdbReader.GetString(variable.Name);

                                    if (name.Length > MaxEntityNameLength)
                                    {
                                        // TODO: report warning
                                        continue;
                                    }

                                    int localSignatureToken = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetToken(methodBody.LocalSignature);
                                    pdbWriter.DefineLocalVariable(variable.Index, name, variable.Attributes, localSignatureToken);

                                    var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localVariableHandle);
                                    if (TryGetDynamicLocal(name, variable.Index, dynamicFlags, out var dynamicLocal))
                                    {
                                        dynamicLocals.Add(dynamicLocal);
                                    }
                                }

                                if (!isFirstMethodScope)
                                {
                                    pdbWriter.CloseScope(currentLocalScope.EndOffset - (vbSemantics ? 1 : 0));
                                }

                                currentLocalScope  = NextLocalScope();
                                isFirstMethodScope = false;
                            }

                            WriteSequencePoints(pdbWriter, documentWriters, symSequencePointBuilder, methodDebugInfo.GetSequencePoints());

                            // async method data:
                            var asyncData = MetadataUtilities.ReadAsyncMethodData(pdbReader, methodDebugInfoHandle);
                            if (!asyncData.IsNone)
                            {
                                pdbWriter.SetAsyncInfo(
                                    moveNextMethodToken: methodToken,
                                    kickoffMethodToken: MetadataTokens.GetToken(asyncData.KickoffMethod),
                                    catchHandlerOffset: asyncData.CatchHandlerOffset,
                                    yieldOffsets: asyncData.YieldOffsets,
                                    resumeOffsets: asyncData.ResumeOffsets);
                            }

                            // custom debug information:
                            var cdiEncoder = new CustomDebugInfoEncoder(cdiBuilder);
                            if (kickOffMethodToMoveNextMethodMap.TryGetValue(methodDefHandle, out var moveNextHandle))
                            {
                                cdiEncoder.AddReferenceToIteratorClass(GetIteratorTypeName(metadataReader, moveNextHandle));
                            }
                            else
                            {
                                if (!vbSemantics)
                                {
                                    if (forwardImportScopesToMethodDef.IsNil)
                                    {
                                        // record the number of import strings in each scope:
                                        cdiEncoder.AddUsingInfo(importCountsPerScope);

                                        if (!firstMethodDefHandle.IsNil)
                                        {
                                            // forward assembly ref aliases to the first method:
                                            cdiEncoder.AddReferenceToMethodWithModuleInfo(firstMethodDefHandle);
                                        }
                                    }
                                    else
                                    {
                                        // forward all imports to another method:
                                        cdiEncoder.AddReferenceToPreviousMethodWithUsingInfo(forwardImportScopesToMethodDef);
                                    }
                                }

                                var hoistedLocalScopes = GetStateMachineHoistedLocalScopes(pdbReader, methodDefHandle);
                                if (!hoistedLocalScopes.IsDefault)
                                {
                                    cdiEncoder.AddStateMachineLocalScopes(hoistedLocalScopes);
                                }
                            }

                            if (dynamicLocals.Count > 0)
                            {
                                cdiEncoder.AddDynamicLocals(dynamicLocals);
                                dynamicLocals.Clear();
                            }

                            // the following blobs map 1:1
                            CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.TupleElementNames, CustomDebugInfoKind.TupleElementNames);
                            CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap, CustomDebugInfoKind.EditAndContinueLocalSlotMap);
                            CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap, CustomDebugInfoKind.EditAndContinueLambdaMap);

                            cdiBuilder.Clear();

                            if (firstMethodDefHandle.IsNil)
                            {
                                firstMethodDefHandle = methodDefHandle;

                                foreach (var(assemblyRefHandle, alias) in aliasedAssemblyRefs)
                                {
                                    var assemblyRef = metadataReader.GetAssemblyReference(assemblyRefHandle);
                                    pdbWriter.UsingNamespace("Z" + alias + " " + MetadataHelpers.GetAssemblyDisplayName(metadataReader, assemblyRef));
                                }
                            }

                            pdbWriter.CloseMethod(methodBody.GetILReader().Length);
                        }

                        pdbWriter.WriteTo(targetPdbStream);
                    }
        }
Beispiel #17
0
        public void CustomAttributeElementTypeEncoder_PrimitiveType()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeElementTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.PrimitiveType(PrimitiveSerializationTypeCode.Boolean);
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Char);
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.SByte);
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Byte);
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int16);
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt16);
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int32);
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt32);
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int64);
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt64);
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Single);
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Double);
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.String);
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveSerializationTypeCode)255));
        }
Beispiel #18
0
        public void CustomAttributeElementTypeEncoder_Enum()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeElementTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.Enum("abc");
            AssertEx.Equal(new byte[] { 0x55, 0x03, 0x61, 0x62, 0x63 }, b.ToArray());
            b.Clear();

            e.Enum("\ud800"); // unpaired surrogate
            AssertEx.Equal(new byte[] { 0x55, 0x03, 0xED, 0xA0, 0x80 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentNullException>(() => e.Enum(null));
            Assert.Throws<ArgumentException>(() => e.Enum(""));
        }
Beispiel #19
0
        public void CustomAttributeElementTypeEncoder_Primitives()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeElementTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.Boolean();
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.Char();
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.SByte();
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.Byte();
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.Int16();
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.UInt16();
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.Int32();
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.UInt32();
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.Int64();
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.UInt64();
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.Single();
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.Double();
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.String();
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();
        }
Beispiel #20
0
        public void CustomAttributeArrayTypeEncoder_ElementType()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeArrayTypeEncoder(b);
            Assert.Same(b, e.Builder);

            var s = e.ElementType();
            AssertEx.Equal(new byte[] { 0x1D }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();
        }
Beispiel #21
0
        public void CustomAttributeArrayTypeEncoder_ObjectArray()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeArrayTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.ObjectArray();
            AssertEx.Equal(new byte[] { 0x1D, 0x51 }, b.ToArray());
            b.Clear();
        }
Beispiel #22
0
        public void VectorEncoder_Count()
        {
            var b = new BlobBuilder();
            var e = new VectorEncoder(b);
            Assert.Same(b, e.Builder);

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

            s = e.Count(int.MaxValue);
            AssertEx.Equal(new byte[] { 0xFF, 0xFF, 0xFF, 0x7F }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(-1));
        }
Beispiel #23
0
        public void SignatureTypeEncoder_PrimitiveType()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.PrimitiveType(PrimitiveTypeCode.Boolean);
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Char);
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.SByte);
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Byte);
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int16);
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt16);
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int32);
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt32);
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int64);
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt64);
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Single);
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Double);
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.String);
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.IntPtr);
            AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UIntPtr);
            AssertEx.Equal(new byte[] { 0x19 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Object);
            AssertEx.Equal(new byte[] { 0x1C }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255));
        }
Beispiel #24
0
        private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                metadata.GetOrAddGuid(Guid.NewGuid()),
                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));

            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 methodBodies = new MethodBodiesEncoder(ilBuilder);

            var codeBuilder   = new BlobBuilder();
            var branchBuilder = new BranchBuilder();
            InstructionEncoder il;

            //
            // Program::.ctor
            //
            int ctorBodyOffset;

            il = new InstructionEncoder(codeBuilder);

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

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

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

            methodBodies.AddMethodBody().WriteInstructions(codeBuilder, out ctorBodyOffset);
            codeBuilder.Clear();

            //
            // Program::Main
            //
            int mainBodyOffset;

            il = new InstructionEncoder(codeBuilder, branchBuilder);
            var endLabel = il.DefineLabel();

            // .try
            int tryOffset = il.Offset;

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

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

            //   leave.s END
            il.Branch(ILOpCode.Leave, endLabel);

            // .finally
            int handlerOffset = il.Offset;

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

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

            // .endfinally
            il.OpCode(ILOpCode.Endfinally);
            int handlerEnd = il.Offset;

            // END:
            il.MarkLabel(endLabel);

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

            var body = methodBodies.AddMethodBody(exceptionRegionCount: 1);
            var eh   = body.WriteInstructions(codeBuilder, branchBuilder, out mainBodyOffset);

            eh.StartRegions();
            eh.AddFinally(tryOffset, handlerOffset - tryOffset, handlerOffset, handlerEnd - handlerOffset);
            eh.EndRegions();

            codeBuilder.Clear();
            branchBuilder.Clear();

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

            var ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                paramList: 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);
        }
        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();
        }
Beispiel #26
0
        public void ScalarEncoder_Constant()
        {
            var b = new BlobBuilder();
            var e = new ScalarEncoder(b);
            Assert.Same(b, e.Builder);

            e.Constant(null);
            AssertEx.Equal(new byte[] { 0xff }, b.ToArray());
            b.Clear();

            e.Constant("");
            AssertEx.Equal(new byte[] { 0x00 }, b.ToArray());
            b.Clear();

            e.Constant("abc");
            AssertEx.Equal(new byte[] { 0x03, 0x61, 0x62, 0x63 }, b.ToArray());
            b.Clear();

            e.Constant("\ud800"); // unpaired surrogate
            AssertEx.Equal(new byte[] { 0x03, 0xED, 0xA0, 0x80 }, b.ToArray());
            b.Clear();

            e.Constant(true);
            AssertEx.Equal(new byte[] { 0x01 }, b.ToArray());
            b.Clear();

            e.Constant(HandleKind.UserString);
            AssertEx.Equal(new byte[] { 0x70 }, b.ToArray());
            b.Clear();

            e.Constant((byte)0xAB);
            AssertEx.Equal(new byte[] { 0xAB }, b.ToArray());
            b.Clear();

            e.Constant((sbyte)0x12);
            AssertEx.Equal(new byte[] { 0x12 }, b.ToArray());
            b.Clear();

            e.Constant((ushort)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray());
            b.Clear();

            e.Constant((short)0x1234);
            AssertEx.Equal(new byte[] { 0x34, 0x12 }, b.ToArray());
            b.Clear();

            e.Constant((char)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray());
            b.Clear();

            e.Constant(0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray());
            b.Clear();

            e.Constant((uint)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray());
            b.Clear();

            e.Constant(0x1122334455667788);
            AssertEx.Equal(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, b.ToArray());
            b.Clear();

            e.Constant(0xAABBCCDDEEFF1122);
            AssertEx.Equal(new byte[] { 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA }, b.ToArray());
            b.Clear();

            e.Constant(0.1f);
            AssertEx.Equal(new byte[] { 0xCD, 0xCC, 0xCC, 0x3D }, b.ToArray());
            b.Clear();

            e.Constant(0.1);
            AssertEx.Equal(new byte[] { 0x9A, 0x99, 0x99, 0x99, 0x99, 0x99, 0xB9, 0x3F }, b.ToArray());
            b.Clear();
        }
        private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            // Create module and assembly for a console application.
            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: default(BlobHandle),
                flags: 0,
                hashAlgorithm: AssemblyHashAlgorithm.None);

            // Create references to System.Object and System.Console types.
            AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("mscorlib"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(
                    new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }
                    ),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

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

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

            // Get reference to Console.WriteLine(string) method.
            var consoleWriteLineSignature = new BlobBuilder();

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

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

            // Get reference to Object's constructor.
            var parameterlessCtorSignature = new BlobBuilder();

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

            BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

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

            // Create signature for "void Main()" method.
            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;

            // Emit IL for 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();

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

            il = new InstructionEncoder(codeBuilder, flowBuilder);

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

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

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

            int mainBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            // Create method definition for Program::Main
            MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                MethodImplAttributes.IL,
                metadata.GetOrAddString("Main"),
                metadata.GetOrAddBlob(mainSignature),
                mainBodyOffset,
                parameterList: default(ParameterHandle));

            // Create method definition for Program::.ctor
            MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: default(ParameterHandle));

            // Create type definition for the special <Module> type that holds global functions
            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

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

            return(mainMethodDef);
        }
Beispiel #28
0
        public void LiteralEncoder_TaggedScalar()
        {
            var b = new BlobBuilder();
            var e = new LiteralEncoder(b);
            Assert.Same(b, e.Builder);

            CustomAttributeElementTypeEncoder elementType;
            ScalarEncoder scalar;
            e.TaggedScalar(out elementType, out scalar);

            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, elementType.Builder);
            Assert.Same(b, scalar.Builder);
            b.Clear();

            e.TaggedScalar(
                et => Assert.Same(b, et.Builder),
                s => Assert.Same(b, s.Builder));

            Assert.Throws<ArgumentNullException>(() => e.TaggedScalar(null, s => { }));
            Assert.Throws<ArgumentNullException>(() => e.TaggedScalar(et => { }, null));
        }
Beispiel #29
0
        public void NamedArgumentsEncoder_AddArgument()
        {
            var b = new BlobBuilder();
            var e = new NamedArgumentsEncoder(b);
            Assert.Same(b, e.Builder);

            NamedArgumentTypeEncoder type;
            NameEncoder name;
            LiteralEncoder literal;
            e.AddArgument(true, out type, out name, out literal);

            AssertEx.Equal(new byte[] { 0x53 }, b.ToArray());
            Assert.Same(b, type.Builder);
            Assert.Same(b, name.Builder);
            Assert.Same(b, literal.Builder);
            b.Clear();

            e.AddArgument(false,
                t => Assert.Same(b, t.Builder),
                n => Assert.Same(b, n.Builder),
                l => Assert.Same(b, l.Builder));
            AssertEx.Equal(new byte[] { 0x54 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, null, _ => { }, _ => { }));
            Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, _ => { }, null, _ => { }));
            Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, _ => { }, _ => { }, null));
        }
Beispiel #30
0
        // returns the DEBUG_S_TYPE_MDTOKEN_MAP subsection as a byte array
        // DEBUG_S_TYPE_MDTOKEN_MAP subsection contains type-index to mdToken mapping
        //
        // contents of subsection:
        // offset 0,     4   bytes: count of entries in the map
        // offset 4,     8*N bytes: 4 byte type-index + 4 byte 'offset' relative to the start of 'type data'
        // offset 4+8*N, *   bytes: ECMA formatted type signature packed sequentially with no padding
        //
        // 'offset' optimization: for type signatures with size<= 4-bytes
        //                        we can store the signature in offset field such that
        //                        offset = (1 << 31) | (sig[0] << 24 | sig[1] << 16 | sig[2] << 8 | sig[3])
        //                        We chose this bit encoding because sig[0] holds the CorElementType whose
        //                        highest bit is always 0 and the highest bit of offset can be used as a flag
        //                        to indicate that it is not an offset but the signature itself.
        //
        // all entries are sorted by 'offset' field and so offset-based entries are arranged before other
        // (raw-signature) entries (since raw-signature entries are of the form 0x80000000 | signature, and will always be
        // numerically bigger than the offset)
        //
        private DebugInfoBlob GetDebugTypeIndexToTokenMap(ManagedBinaryEmitter pseudoAssembly, ICollection <KeyValuePair <TypeDesc, uint> > completeKnownTypes)
        {
            DebugInfoBlob typeDataBlob            = new DebugInfoBlob();
            DebugInfoBlob typeIndexToTokenMapBlob = new DebugInfoBlob();
            List <KeyValuePair <uint, uint> > sigInOffsetEntries = new List <KeyValuePair <uint, uint> >();

            typeIndexToTokenMapBlob.WriteDWORD(checked ((uint)completeKnownTypes.Count));
            BlobBuilder blobBuilder = new BlobBuilder();

            foreach (var entry in completeKnownTypes)
            {
                uint typeIndex = entry.Value;
                blobBuilder.Clear();
                pseudoAssembly.EncodeSignatureForType(entry.Key, blobBuilder);

                // if signature fits in 4-bytes, store it in sigInOffsetEntries
                // otherwise store it in the type-data blob
                if (blobBuilder.Count <= 4)
                {
                    uint sigInOffset = 0x80000000;
                    int  i           = 0;

                    // This is a slightly confusing approach, but this is how one iterates through the bytes in a blobBuilder without flattening it to a byte[]
                    foreach (Blob blob in blobBuilder.GetBlobs())
                    {
                        foreach (byte b in blob.GetBytes())
                        {
                            sigInOffset |= ((uint)b) << (8 * (3 - i));
                            i++;
                        }
                    }

                    // sigInOffsetEntries will be later sorted and appended to typeIndexToTokenMapBlob
                    sigInOffsetEntries.Add(new KeyValuePair <uint, uint>(typeIndex, sigInOffset));
                }
                else
                {
                    typeIndexToTokenMapBlob.WriteDWORD(typeIndex);
                    typeIndexToTokenMapBlob.WriteDWORD(typeDataBlob.Size());
                    typeDataBlob.WriteBuffer(blobBuilder);
                }
            }

            // sort sigInOffsetEntries based on sigInOffset
            sigInOffsetEntries.Sort((KeyValuePair <uint, uint> left, KeyValuePair <uint, uint> right) =>
            {
                if (left.Value < right.Value)
                {
                    return(-1);
                }
                if (left.Value == right.Value)
                {
                    return(0);
                }
                return(1);
            });

            // write the sorted sigInOffsetEntries
            foreach (KeyValuePair <uint, uint> sigInOffsetEntry in sigInOffsetEntries)
            {
                typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Key);
                typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Value);
            }

            // add typeDataBlob to the end of m_typeIndexToTokenMapBlob
            typeIndexToTokenMapBlob.WriteBuffer(typeDataBlob.ToArray());

            return(typeIndexToTokenMapBlob);
        }
Beispiel #31
0
        private static MethodDefinitionHandle EmitMethod(string assemblyName,
                                                         MetadataBuilder metadata,
                                                         BlobBuilder ilBuilder,
                                                         string name,
                                                         Func <MetadataBuilder, BlobBuilder> signatureCallback,
                                                         string[] paramNames)
        {
            BlobBuilder methodSignature = signatureCallback(metadata);

            // Create module and assembly
            metadata.AddModule(
                0,
                metadata.GetOrAddString(assemblyName + ".dll"),
                metadata.GetOrAddGuid(s_guid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString(assemblyName),
                version: new Version(1, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: default(BlobHandle),
                flags: 0,
                hashAlgorithm: AssemblyHashAlgorithm.None);

            // Create references to System.Object and System.Console types.
            AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("System.Runtime"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: default(BlobHandle),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

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

            // Get reference to Object's constructor.
            var parameterlessCtorSignature = new BlobBuilder();

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

            BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

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

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

            // Emit IL for 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();

            // Emit IL for a method
            il = new InstructionEncoder(codeBuilder);
            il.OpCode(ILOpCode.Ldnull);
            il.OpCode(ILOpCode.Throw);

            int methodBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            // Create parameters for a method definition
            int             nextParameterIndex = 1;
            ParameterHandle pFirst             = default(ParameterHandle);

            for (int i = 0; i < paramNames.Length; i++)
            {
                ParameterHandle p = metadata.AddParameter(
                    ParameterAttributes.None,
                    metadata.GetOrAddString(paramNames[i]),
                    i + 1);
                nextParameterIndex++;

                if (i == 0)
                {
                    pFirst = p;
                }
            }

            // Create method definition
            MethodDefinitionHandle methodDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                MethodImplAttributes.IL,
                metadata.GetOrAddString(name),
                metadata.GetOrAddBlob(methodSignature),
                methodBodyOffset,
                parameterList: pFirst);

            // Create method definition for Program::.ctor
            MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: MetadataTokens.ParameterHandle(nextParameterIndex));

            // Create type definition for the special <Module> type that holds global functions
            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            // Create type definition for ConsoleApplication.Program
            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString(assemblyName),
                metadata.GetOrAddString("Program"),
                baseType: systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: methodDef);

            return(methodDef);
        }
        internal void Convert(PEReader peReader, MetadataReader pdbReader, PdbWriter <TDocumentWriter> pdbWriter, PdbConversionOptions options)
        {
            if (!SymReaderHelpers.TryReadPdbId(peReader, out var pePdbId, out int peAge))
            {
                throw new InvalidDataException(ConverterResources.SpecifiedPEFileHasNoAssociatedPdb);
            }

            if (!new BlobContentId(pdbReader.DebugMetadataHeader.Id).Equals(pePdbId))
            {
                throw new InvalidDataException(ConverterResources.PdbNotMatchingDebugDirectory);
            }

            string vbDefaultNamespace             = MetadataUtilities.GetVisualBasicDefaultNamespace(pdbReader);
            bool   vbSemantics                    = vbDefaultNamespace != null;
            string vbDefaultNamespaceImportString = string.IsNullOrEmpty(vbDefaultNamespace) ? null : "*" + vbDefaultNamespace;

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

            var documentWriters         = new ArrayBuilder <TDocumentWriter>(pdbReader.Documents.Count);
            var documentNames           = new ArrayBuilder <string>(pdbReader.Documents.Count);
            var symSequencePointBuilder = new SequencePointsBuilder(capacity: 64);
            var declaredExternAliases   = new HashSet <string>();
            var importStringsBuilder    = new List <string>();
            var importGroups            = new List <int>();
            var cdiBuilder          = new BlobBuilder();
            var dynamicLocals       = new List <(string LocalName, byte[] Flags, int Count, int SlotIndex)>();
            var tupleLocals         = new List <(string LocalName, int SlotIndex, int ScopeStart, int ScopeEnd, ImmutableArray <string> Names)>();
            var openScopeEndOffsets = new Stack <int>();

            // state for calculating import string forwarding:
            var lastImportScopeHandle          = default(ImportScopeHandle);
            var vbLastImportScopeNamespace     = default(string);
            var lastImportScopeMethodDefHandle = default(MethodDefinitionHandle);
            var importStringsMap = new Dictionary <ImmutableArray <string>, MethodDefinitionHandle>(SequenceComparer <string> .Instance);

            var aliasedAssemblyRefs = GetAliasedAssemblyRefs(pdbReader);

            foreach (var documentHandle in pdbReader.Documents)
            {
                var document     = pdbReader.GetDocument(documentHandle);
                var languageGuid = pdbReader.GetGuid(document.Language);
                var name         = pdbReader.GetString(document.Name);
                documentNames.Add(name);

                documentWriters.Add(pdbWriter.DefineDocument(
                                        name: name,
                                        language: languageGuid,
                                        type: s_documentTypeText,
                                        vendor: GetLanguageVendorGuid(languageGuid),
                                        algorithmId: pdbReader.GetGuid(document.HashAlgorithm),
                                        checksum: pdbReader.GetBlobBytes(document.Hash)));
            }

            var        localScopeEnumerator = pdbReader.LocalScopes.GetEnumerator();
            LocalScope?currentLocalScope    = NextLocalScope();

            LocalScope?NextLocalScope() =>
            localScopeEnumerator.MoveNext() ? pdbReader.GetLocalScope(localScopeEnumerator.Current) : default(LocalScope?);

            // Handle of the method that is gonna contain list of AssemblyRef aliases.
            // Other methods will forward to it.
            var methodDefHandleWithAssemblyRefAliases = default(MethodDefinitionHandle);

            foreach (var methodDebugInfoHandle in pdbReader.MethodDebugInformation)
            {
                var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugInfoHandle);
                var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle();
                int methodToken     = MetadataTokens.GetToken(methodDefHandle);
                var methodDef       = metadataReader.GetMethodDefinition(methodDefHandle);
#if DEBUG
                var declaringTypeDef = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType());
                var typeName         = metadataReader.GetString(declaringTypeDef.Name);
                var methodName       = metadataReader.GetString(methodDef.Name);
#endif
                bool methodOpened = false;

                var methodBodyOpt = (methodDef.RelativeVirtualAddress != 0 && (methodDef.ImplAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Managed) ?
                                    peReader.GetMethodBody(methodDef.RelativeVirtualAddress) : null;

                var  vbCurrentMethodNamespace = vbSemantics ? GetMethodNamespace(metadataReader, methodDef) : null;
                var  moveNextHandle           = metadataModel.FindStateMachineMoveNextMethod(methodDefHandle, vbSemantics);
                bool isKickOffMethod          = !moveNextHandle.IsNil;

                var forwardImportScopesToMethodDef = default(MethodDefinitionHandle);
                Debug.Assert(dynamicLocals.Count == 0);
                Debug.Assert(tupleLocals.Count == 0);
                Debug.Assert(openScopeEndOffsets.Count == 0);

                void LazyOpenMethod()
                {
                    if (!methodOpened)
                    {
#if DEBUG
                        Debug.WriteLine($"Open Method '{typeName}::{methodName}' {methodToken:X8}");
#endif
                        pdbWriter.OpenMethod(methodToken);
                        methodOpened = true;
                    }
                }

                void CloseOpenScopes(int currentScopeStartOffset)
                {
                    // close all open scopes that end before this scope starts:
                    while (openScopeEndOffsets.Count > 0 && currentScopeStartOffset >= openScopeEndOffsets.Peek())
                    {
                        int scopeEnd = openScopeEndOffsets.Pop();
                        Debug.WriteLine($"Close Scope [.., {scopeEnd})");

                        // Note that the root scope end is not end-inclusive in VB:
                        pdbWriter.CloseScope(AdjustEndScopeOffset(scopeEnd, isEndInclusive: vbSemantics && openScopeEndOffsets.Count > 0));
                    }
                }

                bool isFirstMethodScope = true;
                while (currentLocalScope.HasValue && currentLocalScope.Value.Method == methodDefHandle)
                {
                    // kickoff methods don't have any scopes emitted to Windows PDBs
                    if (methodBodyOpt == null)
                    {
                        ReportDiagnostic(PdbDiagnosticId.MethodAssociatedWithLocalScopeHasNoBody, MetadataTokens.GetToken(localScopeEnumerator.Current));
                    }
                    else if (!isKickOffMethod)
                    {
                        LazyOpenMethod();

                        var localScope = currentLocalScope.Value;
                        CloseOpenScopes(localScope.StartOffset);

                        Debug.WriteLine($"Open Scope [{localScope.StartOffset}, {localScope.EndOffset})");
                        pdbWriter.OpenScope(localScope.StartOffset);
                        openScopeEndOffsets.Push(localScope.EndOffset);

                        if (isFirstMethodScope)
                        {
                            if (lastImportScopeHandle == localScope.ImportScope && vbLastImportScopeNamespace == vbCurrentMethodNamespace)
                            {
                                // forward to a method that has the same imports:
                                forwardImportScopesToMethodDef = lastImportScopeMethodDefHandle;
                            }
                            else
                            {
                                Debug.Assert(importStringsBuilder.Count == 0);
                                Debug.Assert(declaredExternAliases.Count == 0);
                                Debug.Assert(importGroups.Count == 0);

                                AddImportStrings(importStringsBuilder, importGroups, declaredExternAliases, pdbReader, metadataModel, localScope.ImportScope, aliasedAssemblyRefs, vbDefaultNamespaceImportString, vbCurrentMethodNamespace, vbSemantics);
                                var importStrings = importStringsBuilder.ToImmutableArray();
                                importStringsBuilder.Clear();

                                if (importStringsMap.TryGetValue(importStrings, out forwardImportScopesToMethodDef))
                                {
                                    // forward to a method that has the same imports:
                                    lastImportScopeMethodDefHandle = forwardImportScopesToMethodDef;
                                }
                                else
                                {
                                    // attach import strings to the current method:
                                    WriteImports(pdbWriter, importStrings);
                                    lastImportScopeMethodDefHandle  = methodDefHandle;
                                    importStringsMap[importStrings] = methodDefHandle;
                                }

                                lastImportScopeHandle      = localScope.ImportScope;
                                vbLastImportScopeNamespace = vbCurrentMethodNamespace;
                            }

                            if (vbSemantics && !forwardImportScopesToMethodDef.IsNil)
                            {
                                pdbWriter.UsingNamespace("@" + MetadataTokens.GetToken(forwardImportScopesToMethodDef));
                            }

                            // This is the method that's gonna have AssemblyRef aliases attached:
                            if (methodDefHandleWithAssemblyRefAliases.IsNil)
                            {
                                foreach (var(assemblyRefHandle, alias) in aliasedAssemblyRefs)
                                {
                                    var assemblyRef = metadataReader.GetAssemblyReference(assemblyRefHandle);
                                    pdbWriter.UsingNamespace("Z" + alias + " " + AssemblyDisplayNameBuilder.GetAssemblyDisplayName(metadataReader, assemblyRef));
                                }
                            }
                        }

                        foreach (var localVariableHandle in localScope.GetLocalVariables())
                        {
                            var    variable = pdbReader.GetLocalVariable(localVariableHandle);
                            string name     = pdbReader.GetString(variable.Name);

                            if (name.Length > MaxEntityNameLength)
                            {
                                ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localVariableHandle));
                                continue;
                            }

                            if (methodBodyOpt.LocalSignature.IsNil)
                            {
                                ReportDiagnostic(PdbDiagnosticId.MethodContainingLocalVariablesHasNoLocalSignature, methodToken);
                                continue;
                            }

                            // TODO: translate hoisted variable scopes to dummy VB hoisted state machine locals (https://github.com/dotnet/roslyn/issues/8473)

                            pdbWriter.DefineLocalVariable(variable.Index, name, variable.Attributes, MetadataTokens.GetToken(methodBodyOpt.LocalSignature));

                            var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localVariableHandle);
                            if (TryGetDynamicLocal(name, variable.Index, dynamicFlags, out var dynamicLocal))
                            {
                                dynamicLocals.Add(dynamicLocal);
                            }

                            var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localVariableHandle);
                            if (!tupleElementNames.IsDefaultOrEmpty)
                            {
                                tupleLocals.Add((name, SlotIndex: variable.Index, ScopeStart: 0, ScopeEnd: 0, Names: tupleElementNames));
                            }
                        }

                        foreach (var localConstantHandle in localScope.GetLocalConstants())
                        {
                            var    constant = pdbReader.GetLocalConstant(localConstantHandle);
                            string name     = pdbReader.GetString(constant.Name);

                            if (name.Length > MaxEntityNameLength)
                            {
                                ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localConstantHandle));
                                continue;
                            }

                            var(value, signature) = PortableConstantSignature.GetConstantValueAndSignature(pdbReader, localConstantHandle, metadataReader.GetQualifiedTypeName);
                            if (!metadataModel.TryGetStandaloneSignatureHandle(signature, out var constantSignatureHandle))
                            {
                                // Signature will be unspecified. At least we store the name and the value.
                                constantSignatureHandle = default(StandaloneSignatureHandle);
                            }

                            pdbWriter.DefineLocalConstant(name, value, MetadataTokens.GetToken(constantSignatureHandle));

                            var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localConstantHandle);
                            if (TryGetDynamicLocal(name, 0, dynamicFlags, out var dynamicLocal))
                            {
                                dynamicLocals.Add(dynamicLocal);
                            }

                            var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localConstantHandle);
                            if (!tupleElementNames.IsDefaultOrEmpty)
                            {
                                // Note that the end offset of tuple locals is always end-exclusive, regardless of whether the PDB uses VB semantics or not.
                                tupleLocals.Add((name, SlotIndex: -1, ScopeStart: localScope.StartOffset, ScopeEnd: localScope.EndOffset, Names: tupleElementNames));
                            }
                        }
                    }

                    currentLocalScope  = NextLocalScope();
                    isFirstMethodScope = false;
                }

                bool hasAnyScopes = !isFirstMethodScope;

                CloseOpenScopes(int.MaxValue);
                if (openScopeEndOffsets.Count > 0)
                {
                    ReportDiagnostic(PdbDiagnosticId.LocalScopeRangesNestingIsInvalid, methodToken);
                    openScopeEndOffsets.Clear();
                }

                if (!methodDebugInfo.SequencePointsBlob.IsNil)
                {
                    LazyOpenMethod();
                    WriteSequencePoints(pdbWriter, documentWriters, symSequencePointBuilder, methodDebugInfo.GetSequencePoints(), methodToken);
                }

                // async method data:
                var asyncData = MetadataUtilities.ReadAsyncMethodData(pdbReader, methodDebugInfoHandle);
                if (!asyncData.IsNone)
                {
                    LazyOpenMethod();
                    pdbWriter.SetAsyncInfo(
                        moveNextMethodToken: methodToken,
                        kickoffMethodToken: MetadataTokens.GetToken(asyncData.KickoffMethod),
                        catchHandlerOffset: asyncData.CatchHandlerOffset,
                        yieldOffsets: asyncData.YieldOffsets.ToArray(),
                        resumeOffsets: asyncData.ResumeOffsets.ToArray());
                }

                // custom debug information:
                var cdiEncoder = new CustomDebugInfoEncoder(cdiBuilder);
                if (isKickOffMethod)
                {
                    cdiEncoder.AddStateMachineTypeName(GetIteratorTypeName(metadataReader, moveNextHandle));
                }
                else
                {
                    if (!vbSemantics && hasAnyScopes)
                    {
                        if (forwardImportScopesToMethodDef.IsNil)
                        {
                            // record the number of import strings in each scope:
                            cdiEncoder.AddUsingGroups(importGroups);

                            if (!methodDefHandleWithAssemblyRefAliases.IsNil)
                            {
                                // forward assembly ref aliases to the first method:
                                cdiEncoder.AddForwardModuleInfo(methodDefHandleWithAssemblyRefAliases);
                            }
                        }
                        else
                        {
                            // forward all imports to another method:
                            cdiEncoder.AddForwardMethodInfo(forwardImportScopesToMethodDef);
                        }
                    }

                    var hoistedLocalScopes = GetStateMachineHoistedLocalScopes(pdbReader, methodDefHandle);
                    if (!hoistedLocalScopes.IsDefault)
                    {
                        cdiEncoder.AddStateMachineHoistedLocalScopes(hoistedLocalScopes);
                    }

                    if (dynamicLocals.Count > 0)
                    {
                        cdiEncoder.AddDynamicLocals(dynamicLocals);
                        dynamicLocals.Clear();
                    }

                    if (tupleLocals.Count > 0)
                    {
                        cdiEncoder.AddTupleElementNames(tupleLocals);
                        tupleLocals.Clear();
                    }
                }

                importGroups.Clear();

                // the following blobs map 1:1
                CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap, CustomDebugInfoKind.EditAndContinueLocalSlotMap);
                CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap, CustomDebugInfoKind.EditAndContinueLambdaMap);

                if (cdiEncoder.RecordCount > 0)
                {
                    LazyOpenMethod();
                    pdbWriter.DefineCustomMetadata(cdiEncoder.ToArray());
                }

                cdiBuilder.Clear();

                if (methodOpened && aliasedAssemblyRefs.Length > 0 && !isKickOffMethod && methodDefHandleWithAssemblyRefAliases.IsNil)
                {
                    methodDefHandleWithAssemblyRefAliases = methodDefHandle;
                }

                if (methodOpened)
                {
                    Debug.WriteLine($"Close Method {methodToken:X8}");
                    pdbWriter.CloseMethod();
                }
            }

            if (!pdbReader.DebugMetadataHeader.EntryPoint.IsNil)
            {
                pdbWriter.SetEntryPoint(MetadataTokens.GetToken(pdbReader.DebugMetadataHeader.EntryPoint));
            }

            var sourceLinkHandle = pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition, PortableCustomDebugInfoKinds.SourceLink);
            if (!sourceLinkHandle.IsNil)
            {
                if ((options & PdbConversionOptions.SuppressSourceLinkConversion) == 0)
                {
                    ConvertSourceServerData(pdbReader.GetStringUTF8(sourceLinkHandle), pdbWriter, documentNames);
                }
                else
                {
                    pdbWriter.SetSourceLinkData(pdbReader.GetBlobBytes(sourceLinkHandle));
                }
            }

            SymReaderHelpers.GetWindowsPdbSignature(pdbReader.DebugMetadataHeader.Id, out var guid, out var stamp, out var age);
            pdbWriter.UpdateSignature(guid, stamp, age);
        }
        public void ArrayShapeEncoder_Shape()
        {
            var b = new BlobBuilder();
            var e = new ArrayShapeEncoder(b);

            Assert.Same(b, e.Builder);

            e.Shape(ushort.MaxValue, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty);
            AssertEx.Equal(new byte[]
            {
                0xC0, 0x00, 0xFF, 0xFF,
                0x00,
                0x00
            }, b.ToArray());
            b.Clear();

            e.Shape(3, ImmutableArray.Create(0x0A), ImmutableArray <int> .Empty);
            AssertEx.Equal(new byte[]
            {
                0x03,
                0x01, 0x0A,
                0x00
            }, b.ToArray());
            b.Clear();

            e.Shape(3, ImmutableArray.Create(0x0A, 0x0B), ImmutableArray.Create(0x02, 0x03));
            AssertEx.Equal(new byte[]
            {
                0x03,
                0x02, 0x0A, 0x0B,
                0x02, 0x04, 0x06
            }, b.ToArray());
            b.Clear();

            e.Shape(3, ImmutableArray <int> .Empty, ImmutableArray.Create(-2, -1));
            AssertEx.Equal(new byte[]
            {
                0x03,
                0x00,
                0x02, 0x7D, 0x7F
            }, b.ToArray());
            b.Clear();

            e.Shape(3, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue), ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue, BlobWriterImpl.MaxSignedCompressedIntegerValue));
            AssertEx.Equal(new byte[]
            {
                0x03,
                0x01, 0xDF, 0xFF, 0xFF, 0xFF,
                0x02, 0xC0, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFE
            }, b.ToArray());
            b.Clear();

            Assert.Throws <ArgumentNullException>(() => e.Shape(1, default(ImmutableArray <int>), ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(0, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(-1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(ushort.MaxValue + 1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(1, 2, 3), ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(1, 2, 3)));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(-1), ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue + 1), ImmutableArray <int> .Empty));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue - 1)));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MaxSignedCompressedIntegerValue + 1)));
        }
 public void Free()
 {
     _builder.Clear();  // frees all but first chunk
     s_pool.Free(this); // return first chunk to pool
 }
        public void CustomAttributeElementTypeEncoder_Primitives()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeElementTypeEncoder(b);

            Assert.Same(b, e.Builder);

            e.Boolean();
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.Char();
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.SByte();
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.Byte();
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.Int16();
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.UInt16();
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.Int32();
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.UInt32();
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.Int64();
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.UInt64();
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.Single();
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.Double();
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.String();
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();
        }
Beispiel #36
0
        public void LiteralEncoder_TaggedVector()
        {
            var b = new BlobBuilder();
            var e = new LiteralEncoder(b);
            Assert.Same(b, e.Builder);

            CustomAttributeArrayTypeEncoder arrayType;
            VectorEncoder vector;
            e.TaggedVector(out arrayType, out vector);

            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, arrayType.Builder);
            Assert.Same(b, vector.Builder);
            b.Clear();

            e.TaggedVector(
                at => Assert.Same(b, at.Builder), 
                v => Assert.Same(b, v.Builder));

            Assert.Throws<ArgumentNullException>(() => e.TaggedVector(null, v => { }));
            Assert.Throws<ArgumentNullException>(() => e.TaggedVector(at => { }, null));
        }
        public void SignatureTypeEncoder_Primitives()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);

            Assert.Same(b, e.Builder);

            e.Boolean();
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.Char();
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.SByte();
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.Byte();
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.Int16();
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.UInt16();
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.Int32();
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.UInt32();
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.Int64();
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.UInt64();
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.Single();
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.Double();
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.String();
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            e.IntPtr();
            AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
            b.Clear();

            e.UIntPtr();
            AssertEx.Equal(new byte[] { 0x19 }, b.ToArray());
            b.Clear();

            e.Object();
            AssertEx.Equal(new byte[] { 0x1C }, b.ToArray());
            b.Clear();
        }
Beispiel #38
0
        //
        // returns the DEBUG_S_FUNC_MDTOKEN_MAP subsection as a byte array
        // DEBUG_S_FUNC_MDTOKEN_MAP subsection contains method RVA to mdToken mapping
        //
        // contents of subsection:
        // offset 0,     4   bytes: count of entries in the map
        // offset 4,     8*N bytes: 4 byte RVA + 4 byte 'offset' relative to the start of 'method data'
        // offset 4+8*N, *   bytes: all method data packed sequentially with no padding. method data consists of
        //                          1 byte 'count' of generic parameters, 3 bytes of method's rid and 'count'
        //                          variable sized ECMA formatted TypeSpec signatures for each generic parameter
        //
        // Compiler places the CTLToken (for a method) or the lexical funclet order (if a method has 1 or more funclets),
        // which binder uses to compute the RVA.
        //
        // all entries are sorted by 'offset' field.
        //
        // 'offset' optimization: if the method has no generic parameters, we don't need to pass in a signature
        //                        and can encode the mdToken of method in 'offset'
        //                        We do this by setting the high bit of 'offset' and then storing rid part of
        //                        token in last 3 bytes of 'offset'
        //
        internal DebugInfoBlob GetDebugMethodRVAToTokenMap(ManagedBinaryEmitter pseudoAssembly, IEnumerable <IMethodBodyNode> emittedMethods, out List <Relocation> debugRelocations)
        {
            DebugInfoBlob methodRVAToTokenMap = new DebugInfoBlob();
            DebugInfoBlob methodDataBlob      = new DebugInfoBlob();

            debugRelocations = new List <Relocation>();
            BlobBuilder blobBuilder = new BlobBuilder();

            uint entryCount = 0;

            methodRVAToTokenMap.WriteDWORD(0); // Placeholder for count of entries in map. Will be udpated later.

            List <EmittedMethodWithILToken> tokenInOffsetEntries = new List <EmittedMethodWithILToken>();

            foreach (IMethodBodyNode emitted in emittedMethods)
            {
                if (!(emitted.Method.GetTypicalMethodDefinition() is Internal.TypeSystem.Ecma.EcmaMethod))
                {
                    continue;
                }

                EntityHandle methodHandle = pseudoAssembly.EmitMetadataHandleForTypeSystemEntity(emitted.Method.GetTypicalMethodDefinition());
                Debug.Assert(methodHandle.Kind == HandleKind.MemberReference);
                uint methodToken    = (uint)MetadataTokens.GetToken(methodHandle);
                uint methodTokenRid = methodToken & 0xFFFFFF;

                if (!(emitted.Method.HasInstantiation || emitted.Method.OwningType.HasInstantiation))
                {
                    tokenInOffsetEntries.Add(new EmittedMethodWithILToken(emitted, methodTokenRid));
                    continue;
                }

                uint cGenericArguments = checked ((uint)emitted.Method.Instantiation.Length + (uint)emitted.Method.OwningType.Instantiation.Length);

                // Debugger format does not allow the debugging of methods that have more than 255 generic parameters (spread between the type and method instantiation)
                if (cGenericArguments > 0xFF)
                {
                    continue;
                }

                blobBuilder.Clear();

                // write the signature for each generic parameter of class
                foreach (TypeDesc instantiationType in emitted.Method.OwningType.Instantiation)
                {
                    pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder);
                }

                // write the signature for each generic parameter of the method
                foreach (TypeDesc instantiationType in emitted.Method.Instantiation)
                {
                    pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder);
                }

                Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted, methodDataBlob.Size(), ref entryCount);

                methodDataBlob.WriteDWORD(cGenericArguments << 24 | methodTokenRid);
                methodDataBlob.WriteBuffer(blobBuilder);
            }

            // sort tokenInOffsetEntries based on tokenInOffset
            tokenInOffsetEntries.Sort();

            foreach (EmittedMethodWithILToken emitted in tokenInOffsetEntries)
            {
                Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted.EmittedMethod, emitted.IlTokenRid | 0x80000000, ref entryCount);
            }

            methodRVAToTokenMap.SetDWORDAtBlobIndex(0, entryCount); // // Update placeholder for count of entries in map
            methodRVAToTokenMap.WriteBuffer(methodDataBlob);

            return(methodRVAToTokenMap);
        }
Beispiel #39
0
        public void NameEncoder_Name()
        {
            var b = new BlobBuilder();
            var e = new NameEncoder(b);
            Assert.Same(b, e.Builder);

            e.Name("abc");
            AssertEx.Equal(new byte[] { 0x03, 0x61, 0x62, 0x63 }, b.ToArray());
            b.Clear();

            e.Name("\ud800"); // unpaired surrogate
            AssertEx.Equal(new byte[] { 0x03, 0xED, 0xA0, 0x80 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentNullException>(() => e.Name(null));
            Assert.Throws<ArgumentException>(() => e.Name(""));
        }
        public void SignatureTypeEncoder_PrimitiveType()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);

            Assert.Same(b, e.Builder);

            e.PrimitiveType(PrimitiveTypeCode.Boolean);
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Char);
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.SByte);
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Byte);
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int16);
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt16);
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int32);
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt32);
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Int64);
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UInt64);
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Single);
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Double);
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.String);
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.IntPtr);
            AssertEx.Equal(new byte[] { 0x18 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.UIntPtr);
            AssertEx.Equal(new byte[] { 0x19 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveTypeCode.Object);
            AssertEx.Equal(new byte[] { 0x1C }, b.ToArray());
            b.Clear();

            Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255));
        }
        public void BlobEncoder_CustomAttributeSignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            FixedArgumentsEncoder fixedArgs;
            CustomAttributeNamedArgumentsEncoder namedArgs;
            e.CustomAttributeSignature(out fixedArgs, out namedArgs);

            AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray());
            Assert.Same(b, fixedArgs.Builder);
            Assert.Same(b, namedArgs.Builder);
            b.Clear();

            e.CustomAttributeSignature(
                f => Assert.Same(b, f.Builder),
                n => Assert.Same(b, namedArgs.Builder));

            AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(null, n => { }));
            Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(f => { }, null));
        }
        public void ScalarEncoder_Constant()
        {
            var b = new BlobBuilder();
            var e = new ScalarEncoder(b);

            Assert.Same(b, e.Builder);

            e.Constant(null);
            AssertEx.Equal(new byte[] { 0xff }, b.ToArray());
            b.Clear();

            e.Constant("");
            AssertEx.Equal(new byte[] { 0x00 }, b.ToArray());
            b.Clear();

            e.Constant("abc");
            AssertEx.Equal(new byte[] { 0x03, 0x61, 0x62, 0x63 }, b.ToArray());
            b.Clear();

            e.Constant("\ud800"); // unpaired surrogate
            AssertEx.Equal(new byte[] { 0x03, 0xED, 0xA0, 0x80 }, b.ToArray());
            b.Clear();

            e.Constant(true);
            AssertEx.Equal(new byte[] { 0x01 }, b.ToArray());
            b.Clear();

            e.Constant(HandleKind.UserString);
            AssertEx.Equal(new byte[] { 0x70 }, b.ToArray());
            b.Clear();

            e.Constant((byte)0xAB);
            AssertEx.Equal(new byte[] { 0xAB }, b.ToArray());
            b.Clear();

            e.Constant((sbyte)0x12);
            AssertEx.Equal(new byte[] { 0x12 }, b.ToArray());
            b.Clear();

            e.Constant((ushort)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray());
            b.Clear();

            e.Constant((short)0x1234);
            AssertEx.Equal(new byte[] { 0x34, 0x12 }, b.ToArray());
            b.Clear();

            e.Constant((char)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray());
            b.Clear();

            e.Constant(0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray());
            b.Clear();

            e.Constant((uint)0xABCD);
            AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray());
            b.Clear();

            e.Constant(0x1122334455667788);
            AssertEx.Equal(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, b.ToArray());
            b.Clear();

            e.Constant(0xAABBCCDDEEFF1122);
            AssertEx.Equal(new byte[] { 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA }, b.ToArray());
            b.Clear();

            e.Constant(0.1f);
            AssertEx.Equal(new byte[] { 0xCD, 0xCC, 0xCC, 0x3D }, b.ToArray());
            b.Clear();

            e.Constant(0.1);
            AssertEx.Equal(new byte[] { 0x9A, 0x99, 0x99, 0x99, 0x99, 0x99, 0xB9, 0x3F }, b.ToArray());
            b.Clear();
        }
        public void BlobEncoder_LocalVariableSignature()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

            var s = e.LocalVariableSignature(variableCount: 0);
            AssertEx.Equal(new byte[] { 0x07, 0x00 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            s = e.LocalVariableSignature(variableCount: 1000000);
            AssertEx.Equal(new byte[] { 0x07, 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(BlobWriterImpl.MaxCompressedIntegerValue + 1));
        }
        public void CustomAttributeElementTypeEncoder_PrimitiveType()
        {
            var b = new BlobBuilder();
            var e = new CustomAttributeElementTypeEncoder(b);

            Assert.Same(b, e.Builder);

            e.PrimitiveType(PrimitiveSerializationTypeCode.Boolean);
            AssertEx.Equal(new byte[] { 0x02 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Char);
            AssertEx.Equal(new byte[] { 0x03 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.SByte);
            AssertEx.Equal(new byte[] { 0x04 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Byte);
            AssertEx.Equal(new byte[] { 0x05 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int16);
            AssertEx.Equal(new byte[] { 0x06 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt16);
            AssertEx.Equal(new byte[] { 0x07 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int32);
            AssertEx.Equal(new byte[] { 0x08 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt32);
            AssertEx.Equal(new byte[] { 0x09 }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Int64);
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.UInt64);
            AssertEx.Equal(new byte[] { 0x0B }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Single);
            AssertEx.Equal(new byte[] { 0x0C }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.Double);
            AssertEx.Equal(new byte[] { 0x0D }, b.ToArray());
            b.Clear();

            e.PrimitiveType(PrimitiveSerializationTypeCode.String);
            AssertEx.Equal(new byte[] { 0x0E }, b.ToArray());
            b.Clear();

            Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveSerializationTypeCode)255));
        }
        public void BlobEncoder_PermissionSetArguments()
        {
            var b = new BlobBuilder();
            var e = new BlobEncoder(b);

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

            s = e.PermissionSetArguments(argumentCount: 1000000);
            AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(BlobWriterImpl.MaxCompressedIntegerValue + 1));
        }
        public void MethodSignatureEncoder_Parameters()
        {
            var b = new BlobBuilder();
            var e = new MethodSignatureEncoder(b, hasVarArgs: false);

            ReturnTypeEncoder returnType;
            ParametersEncoder parameters;
            e.Parameters(0, out returnType, out parameters);
            AssertEx.Equal(new byte[] { 0x00 }, b.ToArray());
            Assert.Same(b, parameters.Builder);
            Assert.Same(b, returnType.Builder);
            b.Clear();

            e.Parameters(1000000, out returnType, out parameters);
            AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray());
            b.Clear();

            e.Parameters(10,
                rt => Assert.Same(b, rt.Builder),
                ps => Assert.Same(b, ps.Builder));
            AssertEx.Equal(new byte[] { 0x0A }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.Parameters(-1, out returnType, out parameters));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.Parameters(BlobWriterImpl.MaxCompressedIntegerValue + 1, out returnType, out parameters));
            Assert.Throws<ArgumentNullException>(() => e.Parameters(0, null, ps => { }));
            Assert.Throws<ArgumentNullException>(() => e.Parameters(0, rt => { }, null));
        }
        public void LocalVariableTypeEncoder_Type()
        {
            var b = new BlobBuilder();
            var e = new LocalVariableTypeEncoder(b);

            var s = e.Type();
            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            s = e.Type(isByRef: true);
            AssertEx.Equal(new byte[] { 0x10 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            s = e.Type(isPinned: true);
            AssertEx.Equal(new byte[] { 0x45 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            s = e.Type(isByRef: true, isPinned: true);
            AssertEx.Equal(new byte[] { 0x45, 0x10 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();
        }
Beispiel #48
0
        private static MethodDefinitionHandle ComplexEmit(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                metadata.GetOrAddGuid(Guid.NewGuid()),
                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(isValueType: false, typeRefDefSpec: dictionaryTypeRef, genericArgumentCount: 2);
                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().TypeDefOrRefOrSpec(isValueType: false, typeRefDefSpec: baseClassTypeDef))));

            var methodBodies = new MethodBodiesEncoder(ilBuilder);

            var buffer = new BlobBuilder();
            InstructionEncoder il;

            //
            // Foo
            //
            int fooBodyOffset;

            il = new InstructionEncoder(buffer);

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

            methodBodies.AddMethodBody().WriteInstructions(buffer, out fooBodyOffset);
            buffer.Clear();

            // 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));
        }
        public void ParameterTypeEncoder_Type()
        {
            var b = new BlobBuilder();
            var e = new ParameterTypeEncoder(b);

            var s = e.Type();
            AssertEx.Equal(new byte[0], b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();

            s = e.Type(isByRef: true);
            AssertEx.Equal(new byte[] { 0x10 }, b.ToArray());
            Assert.Same(b, s.Builder);
            b.Clear();
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            // Emit number of dictionaries in table
            objDataBuilder.AddSymbol(this);
            IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries();

            objDataBuilder.EmitInt(dictionariesEmitted.Count);
            DebugInfoBlob signatureData = new DebugInfoBlob();

            BlobBuilder          signatureBlobBuilder = new BlobBuilder();
            BlobBuilder          signatureLenBuilder  = new BlobBuilder();
            ManagedBinaryEmitter pseudoAssembly       = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly;

            foreach (GenericDictionaryNode dictionary in dictionariesEmitted)
            {
                objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB);
                objDataBuilder.EmitUInt(signatureData.Size());

                signatureBlobBuilder.Clear();

                int typeDictLen   = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length;
                int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length;
                signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen);

                if (typeDictLen != 0)
                {
                    foreach (TypeDesc type in dictionary.TypeInstantiation)
                    {
                        pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder);
                    }
                }

                if (methodDictLen != 0)
                {
                    foreach (TypeDesc type in dictionary.MethodInstantiation)
                    {
                        pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder);
                    }
                }

                int blobSize = signatureBlobBuilder.Count;

                signatureLenBuilder.Clear();
                signatureLenBuilder.WriteCompressedInteger(blobSize);

                // Prepend the signature data with a length
                signatureData.WriteBuffer(signatureLenBuilder);
                // And then attach the actual signature data
                signatureData.WriteBuffer(signatureBlobBuilder);
            }

            // Attach signature information to end after all of the rva/offset pairs
            objDataBuilder.EmitBytes(signatureData.ToArray());

            return(objDataBuilder.ToObjectData());
        }
 public void Free()
 {
     _builder.Clear();
 }