| File: PEWriter\ExtendedPEBuilder.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis; namespace Microsoft.Cci { /// <summary> /// This PEBuilder adds an .mvid section. /// </summary> internal sealed class ExtendedPEBuilder : ManagedPEBuilder { private const string MvidSectionName = ".mvid"; public const int SizeOfGuid = 16; // When the section is built with a placeholder, the placeholder blob is saved for later fixing up. private Blob _mvidSectionFixup = default(Blob); // Only include the .mvid section in ref assemblies private readonly bool _withMvidSection; 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; } protected override ImmutableArray<Section> CreateSections() { var baseSections = base.CreateSections(); if (_withMvidSection) { var builder = ArrayBuilder<Section>.GetInstance(baseSections.Length + 1); builder.Add(new Section(MvidSectionName, SectionCharacteristics.MemRead | SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemDiscardable)); builder.AddRange(baseSections); return builder.ToImmutableAndFree(); } else { return baseSections; } } protected override BlobBuilder SerializeSection(string name, SectionLocation location) { if (name.Equals(MvidSectionName, StringComparison.Ordinal)) { Debug.Assert(_withMvidSection); return SerializeMvidSection(); } return base.SerializeSection(name, location); } internal BlobContentId Serialize(BlobBuilder peBlob, out Blob mvidSectionFixup) { var result = base.Serialize(peBlob); mvidSectionFixup = _mvidSectionFixup; return result; } private BlobBuilder SerializeMvidSection() { var sectionBuilder = new BlobBuilder(); // The guid will be filled in later: _mvidSectionFixup = sectionBuilder.ReserveBytes(SizeOfGuid); var mvidWriter = new BlobWriter(_mvidSectionFixup); mvidWriter.WriteBytes(0, _mvidSectionFixup.Length); Debug.Assert(mvidWriter.RemainingBytes == 0); return sectionBuilder; } } }