public void MetadataVersion_Empty()
        {
            var version = "";

            var mdBuilder = new MetadataBuilder();

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

            var rootBuilder = new MetadataRootBuilder(mdBuilder, version);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x04, 0x00, 0x00, 0x00,

                // padded version:
                0x00, 0x00, 0x00, 0x00,
            }, builder.Slice(12, -132));

            Assert.Equal(version, ReadVersion(builder));
        }
Example #2
0
 public ExtendedPEBuilder(
     PEHeaderBuilder header,
     MetadataRootBuilder metadataRootBuilder,
     BlobBuilder ilStream,
     BlobBuilder mappedFieldData,
     BlobBuilder managedResources,
     ResourceSectionBuilder nativeResources,
     DebugDirectoryBuilder debugDirectoryBuilder,
     int strongNameSignatureSize,
     MethodDefinitionHandle entryPoint,
     CorFlags flags,
     Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider,
     bool withMvidSection
     )
     : base(
         header,
         metadataRootBuilder,
         ilStream,
         mappedFieldData,
         managedResources,
         nativeResources,
         debugDirectoryBuilder,
         strongNameSignatureSize,
         entryPoint,
         flags,
         deterministicIdProvider
         )
 {
     _withMvidSection = withMvidSection;
 }
Example #3
0
        public void MetadataVersion()
        {
            var version = "\u1234\ud800";

            var mdBuilder = new MetadataBuilder();

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

            var rootBuilder = new MetadataRootBuilder(mdBuilder, version);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x08, 0x00, 0x00, 0x00,

                // padded version:
                0xE1, 0x88, 0xB4, 0xED, 0xA0, 0x80, 0x00, 0x00,
            }, builder.Slice(12, -132));

            // the default decoder replaces bad byte sequences by U+FFFD
            Assert.Equal("\u1234\ufffd\ufffd", ReadVersion(builder));
        }
        public void Serialize_Errors()
        {
            var mdBuilder   = new MetadataBuilder();
            var rootBuilder = new MetadataRootBuilder(mdBuilder);
            var builder     = new BlobBuilder();

            Assert.Throws <ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1));
        }
        public void Serialize_Errors()
        {
            var mdBuilder = new MetadataBuilder();
            var rootBuilder = new MetadataRootBuilder(mdBuilder);
            var builder = new BlobBuilder();

            Assert.Throws<ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1));
        }
        public void ManagedPEBuilder_Errors()
        {
            var hdr = new PEHeaderBuilder();
            var ms  = new MetadataRootBuilder(new MetadataBuilder());
            var il  = new BlobBuilder();

            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(null, ms, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, null, il));
            Assert.Throws <ArgumentNullException>(() => new ManagedPEBuilder(hdr, ms, null));
            Assert.Throws <ArgumentOutOfRangeException>(() => new ManagedPEBuilder(hdr, ms, il, strongNameSignatureSize: -1));
        }
        // Generate only the metadata blob as a byte[]
        public byte[] EmitToMetadataBlob()
        {
            MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder);
            BlobBuilder         metadataBlobBuilder = new BlobBuilder();

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

            // Clear some variables to catch any caller trying to emit data after writing the output file
            _metadataBuilder = null;

            return(metadataBlobBuilder.ToArray());
        }
Example #8
0
        private static BlobBuilder BuildMetadataImage()
        {
            var mdBuilder = new MetadataBuilder();

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

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

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            return(builder);
        }
Example #9
0
        public void BlahBlahBlah()
        {
            var peHeader = PEHeaderBuilder.CreateLibraryHeader();

            var meta = new MetadataBuilder();

            var module = meta.AddModule(1,
                                        meta.GetOrAddString("Module1"),
                                        meta.GetOrAddGuid(Guid.Parse("11112222-3333-4444-5555-666677778888")),
                                        meta.GetOrAddGuid(Guid.Parse("88887777-6666-5555-4444-333322221111")),
                                        meta.GetOrAddGuid(Guid.Parse("22223333-4444-5555-6666-777788889999"))
                                        );

            var tObject = meta.AddTypeReference(
                EntityHandle.ModuleDefinition,
                meta.GetOrAddString("System"),
                meta.GetOrAddString("Object"));

            var fields  = new FieldDefinitionHandle();  //EMPTY!!
            var methods = new MethodDefinitionHandle(); //EMPTY!!

            meta.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public,
                meta.GetOrAddString("Namespace1"),
                meta.GetOrAddString("Class1"),
                tObject,
                fields,
                methods);

            meta.GetOrAddString("Module1");



            var metadataRoot = new MetadataRootBuilder(meta);

            var ilBlob = new BlobBuilder();

            ilBlob.WriteByte(0);
            ilBlob.WriteByte(42);

            var pe = new ManagedPEBuilder(peHeader, metadataRoot, ilBlob);

            var blob = new BlobBuilder();

            pe.Serialize(blob);

            Assembly.Load(blob.ToArray());
        }
Example #10
0
        /// <summary>
        /// Assembles this instance.
        /// </summary>
        public void Assemble()
        {
            // TODO: Complete this so that it actually generate the hello world sample
            // TODO: Use the data generated from the parser instead of hard coding here
            PEHeaderBuilder header   = new PEHeaderBuilder();
            MetadataBuilder metadata = new MetadataBuilder();

            metadata.AddAssembly(metadata.GetOrAddString("HelloWorld"), new Version(), default(StringHandle), default(BlobHandle), (System.Reflection.AssemblyFlags) 0, AssemblyHashAlgorithm.None);
            MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadata);
            BlobBuilder         stream           = new BlobBuilder();
            ManagedPEBuilder    managedPEBuilder = new ManagedPEBuilder(header, metadataRootBuilder, stream);
            BlobBuilder         output           = new BlobBuilder();

            managedPEBuilder.Serialize(output);
            File.WriteAllBytes(@"C:\Temp\HelloWorld.dll", output.ToArray());
        }
Example #11
0
        public ManagedPEBuilder(
            PEHeaderBuilder header,
            MetadataRootBuilder metadataRootBuilder,
            BlobBuilder ilStream,
            BlobBuilder mappedFieldData                 = null,
            BlobBuilder managedResources                = null,
            ResourceSectionBuilder nativeResources      = null,
            DebugDirectoryBuilder debugDirectoryBuilder = null,
            int strongNameSignatureSize                 = DefaultStrongNameSignatureSize,
            MethodDefinitionHandle entryPoint           = default(MethodDefinitionHandle),
            CorFlags flags = CorFlags.ILOnly,
            Func <IEnumerable <Blob>, BlobContentId> deterministicIdProvider = null)
            : base(header, deterministicIdProvider)
        {
            if (header == null)
            {
                Throw.ArgumentNull(nameof(header));
            }

            if (metadataRootBuilder == null)
            {
                Throw.ArgumentNull(nameof(metadataRootBuilder));
            }

            if (ilStream == null)
            {
                Throw.ArgumentNull(nameof(ilStream));
            }

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

            _metadataRootBuilder      = metadataRootBuilder;
            _ilStream                 = ilStream;
            _mappedFieldDataOpt       = mappedFieldData;
            _managedResourcesOpt      = managedResources;
            _nativeResourcesOpt       = nativeResources;
            _strongNameSignatureSize  = strongNameSignatureSize;
            _entryPointOpt            = entryPoint;
            _debugDirectoryBuilderOpt = debugDirectoryBuilder ?? CreateDefaultDebugDirectoryBuilder();
            _corFlags                 = flags;

            _peDirectoriesBuilder = new PEDirectoriesBuilder();
        }
Example #12
0
        private ImmutableArray <Diagnostic> EmitAssembly(BoundProgram program)
        {
            var header              = new PEHeaderBuilder();
            var metadataBuilder     = new MetadataBuilder();
            var metadataRootBuilder = new MetadataRootBuilder(metadataBuilder);
            var blobBuilder         = new BlobBuilder();
            var peBuilder           = new ManagedPEBuilder(header, metadataRootBuilder, blobBuilder);

            peBuilder.Serialize(blobBuilder);

            // TODO: Produce portable assembly contents here
            using (var stream = new StreamWriter(program.PackageName + ".dll"))
            {
                blobBuilder.WriteContentTo(stream.BaseStream);
            }

            return(ImmutableArray <Diagnostic> .Empty);
        }
        public void MetadataVersion()
        {
            var version = "\u1234\ud800";

            var mdBuilder = new MetadataBuilder();

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

            var rootBuilder = new MetadataRootBuilder(mdBuilder, version);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x08, 0x00, 0x00, 0x00,

                // padded version:
                // [ E1 88 B4 ] -> U+1234
                // [ ED ] -> invalid (ED cannot be followed by A0) -> U+FFFD
                // [ A0 ] -> invalid (not ASCII, not valid leading byte) -> U+FFFD
                // [ 80 ] -> invalid (not ASCII, not valid leading byte) -> U+FFFD
                0xE1, 0x88, 0xB4, 0xED, 0xA0, 0x80, 0x00, 0x00,
            }, builder.Slice(12, -132));

            // the default decoder replaces bad byte sequences by U+FFFD
            if (PlatformDetection.IsNetCore)
            {
                Assert.Equal("\u1234\ufffd\ufffd\ufffd", ReadVersion(builder));
            }
            else
            {
                // Versions of .NET prior to Core 3.0 didn't follow Unicode recommendations for U+FFFD substitution,
                // so they sometimes emitted too few replacement chars.
                Assert.Equal("\u1234\ufffd\ufffd", ReadVersion(builder));
            }
        }
Example #14
0
        public void GetOrAddDocumentName2()
        {
            var mdBuilder = new MetadataBuilder();

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

            var n1  = mdBuilder.GetOrAddDocumentName("");
            var n2  = mdBuilder.GetOrAddDocumentName("/a/b/c");
            var n3  = mdBuilder.GetOrAddDocumentName(@"\a\b\cc");
            var n4  = mdBuilder.GetOrAddDocumentName(@"/a/b\c");
            var n5  = mdBuilder.GetOrAddDocumentName(@"/\a/\b\\//c");
            var n6  = mdBuilder.GetOrAddDocumentName(@"a/");
            var n7  = mdBuilder.GetOrAddDocumentName(@"/");
            var n8  = mdBuilder.GetOrAddDocumentName(@"\\");
            var n9  = mdBuilder.GetOrAddDocumentName("\ud800"); // unpaired surrogate
            var n10 = mdBuilder.GetOrAddDocumentName("\0");

            var root        = new MetadataRootBuilder(mdBuilder);
            var rootBuilder = new BlobBuilder();

            root.Serialize(rootBuilder, 0, 0);
            var mdImage = rootBuilder.ToImmutableArray();

            using (var provider = MetadataReaderProvider.FromMetadataImage(mdImage))
            {
                var mdReader = provider.GetMetadataReader();
                Assert.Equal("", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n1))));
                Assert.Equal("/a/b/c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n2))));
                Assert.Equal(@"\a\b\cc", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n3))));
                Assert.Equal(@"/a/b\c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n4))));
                Assert.Equal(@"/\a/\b\\//c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n5))));
                Assert.Equal(@"a/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n6))));
                Assert.Equal(@"/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n7))));
                Assert.Equal(@"\\", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n8))));
                Assert.Equal("\uFFFd\uFFFd", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n9))));
                Assert.Equal("\0", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n10))));
            }
        }
        public void MetadataVersion_Default()
        {
            var mdBuilder = new MetadataBuilder();

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

            var rootBuilder = new MetadataRootBuilder(mdBuilder);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,
            }, builder.Slice(12, -132));

            Assert.Equal(rootBuilder.MetadataVersion, ReadVersion(builder));
        }
        public byte[] GenerateAssemblyBytes()
        {
            var name = _currentAssembly.GetName();

            var assemblyHandle = _metadataBuilder.AddAssembly(
                GetString(name.Name),
                name.Version,
                GetString(name.CultureName),
                GetBlob(name.GetPublicKey()),
                _assemblyNameFlagsConvert(name.Flags),
                _assemblyHashAlgorithmConvert(name.HashAlgorithm));

            CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies());
            CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData());

            CreateModules(_currentAssembly.GetModules());
            CreateTypes(_currentAssembly.GetTypes());

            var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint);


            var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder);
            var header = PEHeaderBuilder.CreateLibraryHeader();

            var peBuilder = new ManagedPEBuilder(
                header,
                metadataRootBuilder,
                _ilBuilder,
                debugDirectoryBuilder: _debugDirectoryBuilder,
                entryPoint: entryPoint);

            var peImageBuilder = new BlobBuilder();

            peBuilder.Serialize(peImageBuilder);

            return(peImageBuilder.ToArray());
        }
        public void EncHeaders()
        {
            var mdBuilder = new MetadataBuilder();

            mdBuilder.AddEncLogEntry(MetadataTokens.MethodDefinitionHandle(1), EditAndContinueOperation.AddMethod);

            var rootBuilder = new MetadataRootBuilder(mdBuilder);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // signature:
                0x42, 0x53, 0x4A, 0x42,
                // major version (1)
                0x01, 0x00,
                // minor version (1)
                0x01, 0x00,
                // reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,

                // flags (0):
                0x00, 0x00,

                // stream count:
                0x06, 0x00,

                // stream headers:
                0x7C, 0x00, 0x00, 0x00,
                0x28, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'-', 0x00, 0x00,

                0xA4, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00,

                0xA8, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'U', (byte)'S', 0x00,

                0xAC, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00,

                0xAC, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00,

                0xB0, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'J', (byte)'T', (byte)'D', 0x00, 0x00, 0x00, 0x00,

                // --------
                // #-
                // --------

                // Reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // Major Version (2)
                0x02,

                // Minor Version (0)
                0x00,

                // Heap Sizes
                0xA7,

                // Reserved (1)
                0x01,

                // Present tables
                0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,

                // Sorted tables
                0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00,

                // Rows
                0x01, 0x00, 0x00, 0x00,

                //
                // EncLog Table (token, operation)
                //

                0x01, 0x00, 0x00, 0x06,
                0x01, 0x00, 0x00, 0x00,

                // Padding and alignment
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #Strings
                // --------

                0x00, 0x00, 0x00, 0x00,

                // --------
                // #US
                // --------
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #GUID
                // --------

                // --------
                // #Blob
                // --------

                0x00, 0x00, 0x00, 0x00,

                // --------
                // #JTD
                // --------
            }, builder.ToArray());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), null, 1, null));
            }

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

                _emissionCompleted = true;
            }

            MetadataBuilder metadataBuilder = new MetadataBuilder();

            string manifestMetadataAssemblyName = "ManifestMetadata";

            metadataBuilder.AddAssembly(
                metadataBuilder.GetOrAddString(manifestMetadataAssemblyName),
                new Version(0, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: default(BlobHandle),
                flags: default(AssemblyFlags),
                hashAlgorithm: AssemblyHashAlgorithm.None);

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

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

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

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

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

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

            return(new ObjectData(
                       data: metadataBlobBuilder.ToArray(),
                       relocs: Array.Empty <Relocation>(),
                       alignment: 1,
                       definedSymbols: new ISymbolDefinitionNode[] { this }));
        }
        public void MetadataVersion_Default()
        {
            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder);

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

            AssertEx.Equal(new byte[] 
            {
                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,
            }, builder.Slice(12, -132));

            Assert.Equal(rootBuilder.MetadataVersion, ReadVersion(builder));
        }
        public void MetadataVersion_MaxLength()
        {
            var version = new string('x', 254);

            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder, version);

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

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x00, 0x01, 0x00, 0x00,

                // padded version:
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
                0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00
            }, builder.Slice(12, -132));

            Assert.Equal(version, ReadVersion(builder));
        }
        public void MetadataVersion()
        {
            var version = "\u1234\ud800";

            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder, version);

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

            AssertEx.Equal(new byte[]
            {
                // padded version length:
                0x08, 0x00, 0x00, 0x00,

                // padded version:
                0xE1, 0x88, 0xB4, 0xED, 0xA0, 0x80, 0x00, 0x00,
            }, builder.Slice(12, -132));

            // the default decoder replaces bad byte sequences by U+FFFD
            Assert.Equal("\u1234\ufffd\ufffd", ReadVersion(builder));
        }
        public void Headers()
        {
            var mdBuilder = new MetadataBuilder();
            var rootBuilder = new MetadataRootBuilder(mdBuilder);

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

            AssertEx.Equal(new byte[]
            {
                // signature:
                0x42, 0x53, 0x4A, 0x42,
                // major version (1)
                0x01, 0x00,
                // minor version (1)
                0x01, 0x00,
                // reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,

                // flags (0):
                0x00, 0x00,

                // stream count:
                0x05, 0x00,

                // stream headers:
                0x6C, 0x00, 0x00, 0x00,
                0x1C, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'~', 0x00, 0x00,

                0x88, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00,

                0x8C, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'U', (byte)'S', 0x00,

                0x90, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00,

                0x90, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00,

                // --------
                // #~
                // --------
                
                // Reserved (0)
                0x00, 0x00, 0x00, 0x00,
                
                // Major Version (2)
                0x02,

                // Minor Version (0)
                0x00,

                // Heap Sizes
                0x00,

                // Reserved (1)
                0x01,

                // Present tables
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                // Sorted tables
                0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00, 

                // Rows (empty)
                // Tables (empty)

                // Padding and alignment
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #Strings
                // --------

                0x00, 0x00, 0x00, 0x00,

                // --------
                // #US
                // --------
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #GUID
                // --------

                // --------
                // #Blob
                // --------

                0x00, 0x00, 0x00, 0x00,
            }, builder.ToArray());
        }
Example #23
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), null, 1, null));
            }

            ComputeLastSetOfModuleIndices();

            MetadataBuilder metadataBuilder = new MetadataBuilder();

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

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

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

            string manifestMetadataAssemblyName = "ManifestMetadata";

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

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

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

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

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

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

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

            return(new ObjectData(
                       data: metadataBlobBuilder.ToArray(),
                       relocs: Array.Empty <Relocation>(),
                       alignment: 1,
                       definedSymbols: new ISymbolDefinitionNode[] { this }));
        }
Example #24
0
        public byte[] GenerateAssemblyBytes()
        {
            if (_currentAssembly.EntryPoint != null)
            {
                // See "<Module>" type definition below.
                throw new NotSupportedException("Entry point is not supported.");
            }

            var name = _currentAssembly.GetName();

            var assemblyPublicKey = name.GetPublicKey();
            var assemblyHandle    = _metadataBuilder.AddAssembly(
                GetString(name.Name),
                name.Version,
                GetString(name.CultureName),
                assemblyPublicKey.Length > 0 ? GetBlob(name.GetPublicKey()) : default(BlobHandle),
                ConvertGeneratedAssemblyNameFlags(name),
                ConvertAssemblyHashAlgorithm(name.HashAlgorithm));

            // Add "<Module>" type definition *before* any type definition.
            //
            // TODO: [osman] methodList argument should be as following:
            //
            //   methodList: entryPoint.IsNil ? MetadataTokens.MethodDefinitionHandle(1) : entryPoint
            //
            // But, in order to work above code, we need to serialize
            // entry point *without* serializing any type definition.
            // This is not needed for libraries since they don't have any entry point.
            _metadataBuilder.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                GetString("<Module>"),
                default(EntityHandle),
                MetadataTokens.FieldDefinitionHandle(1),
                MetadataTokens.MethodDefinitionHandle(1));

            CreateReferencedAssemblies(_currentAssembly.GetReferencedAssemblies());
            CreateCustomAttributes(assemblyHandle, _currentAssembly.GetCustomAttributesData());

            CreateModules(_currentAssembly.GetModules());
            CreateTypes(_currentAssembly.GetTypes());

            var entryPoint = GetMethodDefinitionHandle(_currentAssembly.EntryPoint);

            var metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder);

            // Without Characteristics.ExecutableImage flag, .NET runtime refuses
            // to load an assembly even it's a DLL. PEHeaderBuilder.CreateLibraryHeader
            // does not set this flag. So, we set it explicitly.
            var header = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage |
                                             (entryPoint.IsNil ? Characteristics.Dll : 0));

            var peBuilder = new ManagedPEBuilder(
                header,
                metadataRootBuilder,
                _ilBuilder,
                debugDirectoryBuilder: _debugDirectoryBuilder,
                entryPoint: entryPoint);

            var peImageBuilder = new BlobBuilder();

            peBuilder.Serialize(peImageBuilder);

            return(peImageBuilder.ToArray());
        }
        public void Headers()
        {
            var mdBuilder   = new MetadataBuilder();
            var rootBuilder = new MetadataRootBuilder(mdBuilder);

            var builder = new BlobBuilder();

            rootBuilder.Serialize(builder, 0, 0);

            AssertEx.Equal(new byte[]
            {
                // signature:
                0x42, 0x53, 0x4A, 0x42,
                // major version (1)
                0x01, 0x00,
                // minor version (1)
                0x01, 0x00,
                // reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,

                // flags (0):
                0x00, 0x00,

                // stream count:
                0x05, 0x00,

                // stream headers:
                0x6C, 0x00, 0x00, 0x00,
                0x1C, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'~', 0x00, 0x00,

                0x88, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00,

                0x8C, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'U', (byte)'S', 0x00,

                0x90, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00,

                0x90, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00,

                // --------
                // #~
                // --------

                // Reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // Major Version (2)
                0x02,

                // Minor Version (0)
                0x00,

                // Heap Sizes
                0x00,

                // Reserved (1)
                0x01,

                // Present tables
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

                // Sorted tables
                0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00,

                // Rows (empty)
                // Tables (empty)

                // Padding and alignment
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #Strings
                // --------

                0x00, 0x00, 0x00, 0x00,

                // --------
                // #US
                // --------
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #GUID
                // --------

                // --------
                // #Blob
                // --------

                0x00, 0x00, 0x00, 0x00,
            }, builder.ToArray());
        }
Example #26
0
        /// <summary>
        /// Emits this dynamic assembly to a Portable Executable file image.
        /// </summary>
        /// <returns>An <see cref="AssemblyBuilderEmitResult"/> instance containing the
        /// emitted PE image.</returns>
        /// <remarks>
        /// This method can be called only once. Any subsequent calls will throw an exception.
        /// </remarks>
        public AssemblyBuilderEmitResult emit()
        {
            if (m_isPEFileCreated)
            {
                throw new InvalidOperationException("The PE file for this assembly has already been created.");
            }

            m_isPEFileCreated = true;

            var         tokenMap = new TokenMapping(m_metadataContext.fieldDefRowCount, m_metadataContext.methodDefRowCount);
            BlobBuilder ilStream;

            lock (m_typeBuildersLock) {
                var typeBuilders             = m_typeBuilders.asReadOnlyArrayView();
                int currentMethodBodyAddress = 0;

                for (int i = 0; i < typeBuilders.length; i++)
                {
                    currentMethodBodyAddress = typeBuilders[i].assignMethodBodyAddresses(currentMethodBodyAddress);
                }

                var genParamEntries = new DynamicArray <GenericParameter>();

                using (var mdBuilder = m_metadataContext.getMetadataBuilder()) {
                    for (int i = 0; i < typeBuilders.length; i++)
                    {
                        typeBuilders[i].writeTypeMetadata(mdBuilder.value, tokenMap);
                    }
                    for (int i = 0; i < typeBuilders.length; i++)
                    {
                        typeBuilders[i].writeMethodImplEntries(mdBuilder.value, tokenMap);
                    }
                }

                for (int i = 0; i < typeBuilders.length; i++)
                {
                    typeBuilders[i].appendGenParamEntries(tokenMap, ref genParamEntries);
                }

                m_metadataContext.emitMethodSpecTable(tokenMap);
                _sortAndWriteGenParamEntries(ref genParamEntries);

                ilStream = new BlobBuilder(currentMethodBodyAddress);

                for (int i = 0; i < typeBuilders.length; i++)
                {
                    typeBuilders[i].writeMethodBodies(ilStream, tokenMap);
                }
            }

            BlobBuilder            peFileBlob = new BlobBuilder();
            MethodDefinitionHandle entryPoint = default;

            if (!m_entryPoint.IsNil)
            {
                entryPoint = (MethodDefinitionHandle)tokenMap.getMappedHandle(m_entryPoint);
            }

            using (var mdBuilder = m_metadataContext.getMetadataBuilder()) {
                var metadataRootBuilder = new MetadataRootBuilder(mdBuilder.value, null, true);
                var peHeader            = m_peHeader ?? new PEHeaderBuilder(Machine.I386);
                var peBuilder           = new ManagedPEBuilder(peHeader, metadataRootBuilder, ilStream, entryPoint: entryPoint);
                peBuilder.Serialize(peFileBlob);
            }

            return(new AssemblyBuilderEmitResult(peFileBlob.ToArray(), tokenMap));
        }
Example #27
0
        public static bool WritePeToStream(
            EmitContext context,
            CommonMessageProvider messageProvider,
            Func <Stream> getPeStream,
            Func <Stream> getPortablePdbStreamOpt,
            PdbWriter nativePdbWriterOpt,
            string pdbPathOpt,
            bool allowMissingMethodBodies,
            bool isDeterministic,
            CancellationToken cancellationToken)
        {
            // If PDB writer is given, we have to have PDB path.
            Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null);

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

            ModulePropertiesForSerialization properties = context.Module.SerializationProperties;

            nativePdbWriterOpt?.SetMetadataEmitter(mdWriter);

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

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

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

            mdWriter.GetEntryPoints(out MethodDefinitionHandle entryPointHandle, out MethodDefinitionHandle debugEntryPointHandle);

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

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

                // embedded text not currently supported for native PDB and we should have validated that
                Debug.Assert(!mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments.Any());
            }

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

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

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

            ushort portablePdbVersion = 0;
            MetadataRootBuilder metadataRootBuilder = mdWriter.GetRootBuilder();

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

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

            BlobBuilder portablePdbToEmbed = null;
            if (mdWriter.EmitStandaloneDebugMetadata)
            {
                mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);

                BlobBuilder        portablePdbBlob    = new BlobBuilder();
                PortablePdbBuilder portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, deterministicIdProvider);
                pdbContentId       = portablePdbBuilder.Serialize(portablePdbBlob);
                portablePdbVersion = portablePdbBuilder.FormatVersion;

                if (getPortablePdbStreamOpt == null)
                {
                    // embed to debug directory:
                    portablePdbToEmbed = portablePdbBlob;
                }
                else
                {
                    // write to Portable PDB stream:
                    Stream portablePdbStream = getPortablePdbStreamOpt();
                    if (portablePdbStream != null)
                    {
                        portablePdbBlob.WriteContentTo(portablePdbStream);
                    }
                }
            }

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

                if (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }

                if (portablePdbToEmbed != null)
                {
                    debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion);
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

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

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

            PatchModuleVersionIds(mvidFixup, mvidStringFixup, peContentId.Guid);

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

            return(true);
        }
Example #28
0
        public void GetOrAddDocumentName2()
        {
            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var n1 = mdBuilder.GetOrAddDocumentName("");
            var n2 = mdBuilder.GetOrAddDocumentName("/a/b/c");
            var n3 = mdBuilder.GetOrAddDocumentName(@"\a\b\cc");
            var n4 = mdBuilder.GetOrAddDocumentName(@"/a/b\c");
            var n5 = mdBuilder.GetOrAddDocumentName(@"/\a/\b\\//c");
            var n6 = mdBuilder.GetOrAddDocumentName(@"a/");
            var n7 = mdBuilder.GetOrAddDocumentName(@"/");
            var n8 = mdBuilder.GetOrAddDocumentName(@"\\");
            var n9 = mdBuilder.GetOrAddDocumentName("\ud800"); // unpaired surrogate
            var n10 = mdBuilder.GetOrAddDocumentName("\0");

            var root = new MetadataRootBuilder(mdBuilder);
            var rootBuilder = new BlobBuilder();
            root.Serialize(rootBuilder, 0, 0);
            var mdImage = rootBuilder.ToImmutableArray();

            using (var provider = MetadataReaderProvider.FromMetadataImage(mdImage))
            {
                var mdReader = provider.GetMetadataReader();
                Assert.Equal("", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n1))));
                Assert.Equal("/a/b/c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n2))));
                Assert.Equal(@"\a\b\cc", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n3))));
                Assert.Equal(@"/a/b\c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n4))));
                Assert.Equal(@"/\a/\b\\//c", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n5))));
                Assert.Equal(@"a/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n6))));
                Assert.Equal(@"/", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n7))));
                Assert.Equal(@"\\", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n8))));
                Assert.Equal("\uFFFd\uFFFd", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n9))));
                Assert.Equal("\0", mdReader.GetString(MetadataTokens.DocumentNameBlobHandle(MetadataTokens.GetHeapOffset(n10))));
            }
        }
        public void EncHeaders()
        {
            var mdBuilder = new MetadataBuilder();
            mdBuilder.AddEncLogEntry(MetadataTokens.MethodDefinitionHandle(1), EditAndContinueOperation.AddMethod);

            var rootBuilder = new MetadataRootBuilder(mdBuilder);

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

            AssertEx.Equal(new byte[]
            {
                // signature:
                0x42, 0x53, 0x4A, 0x42,
                // major version (1)
                0x01, 0x00,
                // minor version (1)
                0x01, 0x00,
                // reserved (0)
                0x00, 0x00, 0x00, 0x00,

                // padded version length:
                0x0C, 0x00, 0x00, 0x00,

                // padded version:
                (byte)'v', (byte)'4', (byte)'.', (byte)'0', (byte)'.', (byte)'3', (byte)'0', (byte)'3', (byte)'1', (byte)'9', 0x00, 0x00,

                // flags (0):
                0x00, 0x00,

                // stream count:
                0x06, 0x00,

                // stream headers:
                0x7C, 0x00, 0x00, 0x00,
                0x28, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'-', 0x00, 0x00,

                0xA4, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'S', (byte)'t', (byte)'r', (byte)'i', (byte)'n', (byte)'g', (byte)'s', 0x00, 0x00, 0x00, 0x00,

                0xA8, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'U', (byte)'S', 0x00,

                0xAC, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'G', (byte)'U', (byte)'I', (byte)'D', 0x00, 0x00, 0x00,

                0xAC, 0x00, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'B', (byte)'l', (byte)'o', (byte)'b', 0x00, 0x00, 0x00,

                0xB0, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00,
                (byte)'#', (byte)'J', (byte)'T', (byte)'D', 0x00, 0x00, 0x00, 0x00,

                // --------
                // #-
                // --------
                
                // Reserved (0)
                0x00, 0x00, 0x00, 0x00,
                
                // Major Version (2)
                0x02,

                // Minor Version (0)
                0x00,

                // Heap Sizes
                0xA7,

                // Reserved (1)
                0x01,

                // Present tables
                0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,

                // Sorted tables
                0x00, 0xFA, 0x01, 0x33, 0x00, 0x16, 0x00, 0x00, 

                // Rows
                0x01, 0x00, 0x00, 0x00,

                //
                // EncLog Table (token, operation)
                //

                0x01, 0x00, 0x00, 0x06,
                0x01, 0x00, 0x00, 0x00,

                // Padding and alignment
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #Strings
                // --------

                0x00, 0x00, 0x00, 0x00,

                // --------
                // #US
                // --------
                0x00, 0x00, 0x00, 0x00,

                // --------
                // #GUID
                // --------

                // --------
                // #Blob
                // --------

                0x00, 0x00, 0x00, 0x00,
                
                // --------
                // #JTD
                // --------
            }, builder.ToArray());
        }
Example #30
0
        public static byte[] MakeRefasm(MetadataReader metaReader, PEReader peReader, LoggerBase logger, IImportFilter filter = null)
        {
            var metaBuilder = new MetadataBuilder();

            var importer = new MetadataImporter(metaReader, metaBuilder, logger);

            if (filter != null)
            {
                importer.Filter = filter;
                logger.Info?.Invoke("Using custom entity filter");
            }
            else if (importer.IsInternalsVisible())
            {
                importer.Filter = new AllowPublicAndInternals();
                logger.Info?.Invoke("InternalsVisibleTo attributes found, using AllowPublicAndInternals entity filter");
            }
            else
            {
                importer.Filter = new AllowPublic();
                logger.Info?.Invoke("Using AllowPublic entity filter");
            }

            var mvidBlob = importer.Import();

            logger.Debug?.Invoke($"Building reference assembly");

            var metaRootBuilder = new MetadataRootBuilder(metaBuilder, metaReader.MetadataVersion, true);

            var peHeaderBuilder = new PEHeaderBuilder(
                peReader.PEHeaders.CoffHeader.Machine,
                peReader.PEHeaders.PEHeader.SectionAlignment,
                peReader.PEHeaders.PEHeader.FileAlignment,
                peReader.PEHeaders.PEHeader.ImageBase,
                peReader.PEHeaders.PEHeader.MajorLinkerVersion,
                peReader.PEHeaders.PEHeader.MinorLinkerVersion,
                peReader.PEHeaders.PEHeader.MajorOperatingSystemVersion,
                peReader.PEHeaders.PEHeader.MinorOperatingSystemVersion,
                peReader.PEHeaders.PEHeader.MajorImageVersion,
                peReader.PEHeaders.PEHeader.MinorImageVersion,
                peReader.PEHeaders.PEHeader.MajorSubsystemVersion,
                peReader.PEHeaders.PEHeader.MinorSubsystemVersion,
                peReader.PEHeaders.PEHeader.Subsystem,
                peReader.PEHeaders.PEHeader.DllCharacteristics,
                peReader.PEHeaders.CoffHeader.Characteristics,
                peReader.PEHeaders.PEHeader.SizeOfStackReserve,
                peReader.PEHeaders.PEHeader.SizeOfStackCommit,
                peReader.PEHeaders.PEHeader.SizeOfHeapReserve,
                peReader.PEHeaders.PEHeader.SizeOfHeapCommit
                );

            var ilStream = new BlobBuilder();

            var peBuilder = new ManagedPEBuilder(peHeaderBuilder, metaRootBuilder, ilStream,
                                                 deterministicIdProvider: blobs =>
            {
                var hasher = IncrementalHash.CreateHash(HashAlgorithmName.SHA256) ?? throw new Exception("Cannot create hasher");

                foreach (var segment in blobs.Select(b => b.GetBytes()))
                {
                    hasher.AppendData(segment.Array, segment.Offset, segment.Count);
                }

                return(BlobContentId.FromHash(hasher.GetHashAndReset()));
            });

            var blobBuilder = new BlobBuilder();
            var contentId   = peBuilder.Serialize(blobBuilder);

            mvidBlob.CreateWriter().WriteGuid(contentId.Guid);

            return(blobBuilder.ToArray());
        }