public void Initialize (object emitter, string filename, object ptrIStream, bool fullBuild)
		{
			var writerField = typeof(PdbMetadataWrapper).GetRuntimeFields().First((f) => f.Name == "_writer");
			writer = (MetadataWriter)writerField.GetValue(emitter);

			msw = new MonoSymbolWriter(new UnsafeComStreamWrapper((ComMemoryStream)ptrIStream));
		}
示例#2
0
        private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt)
        {
            // TODO: we can precalculate the exact size of IL stream
            var ilWriter = new BlobBuilder(32 * 1024);
            var metadataWriter = new BlobBuilder(16 * 1024);
            var mappedFieldDataWriter = new BlobBuilder();
            var managedResourceWriter = new BlobBuilder(1024);

            var debugMetadataWriterOpt = (getPortablePdbStreamOpt != null) ? new BlobBuilder(16 * 1024) : null;

            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));

            int sectionCount = 1;
            if (_properties.RequiresStartupStub) sectionCount++; //.reloc
            if (!IteratorHelper.EnumerableIsEmpty(_nativeResourcesOpt) || _nativeResourceSectionOpt != null) sectionCount++; //.rsrc;

            int sizeOfPeHeaders = ComputeSizeOfPeHeaders(sectionCount);
            int textSectionRva = BitArithmeticUtilities.Align(sizeOfPeHeaders, _properties.SectionAlignment);

            int moduleVersionIdOffsetInMetadataStream;
            int methodBodyStreamRva = textSectionRva + OffsetToILStream;

            int entryPointToken;
            MetadataSizes metadataSizes;
            mdWriter.SerializeMetadataAndIL(
                metadataWriter,
                debugMetadataWriterOpt,
                nativePdbWriterOpt,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                methodBodyStreamRva,
                mdSizes => CalculateMappedFieldDataStreamRva(textSectionRva, mdSizes),
                out moduleVersionIdOffsetInMetadataStream,
                out entryPointToken,
                out metadataSizes);

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

                nativePdbContentId = nativePdbWriterOpt.GetContentId();

                // the writer shall not be used after this point for writing:
                nativePdbWriterOpt = null;
            }
            else
            {
                nativePdbContentId = default(ContentId);
            }
            
            // write to Portable PDB stream:
            ContentId portablePdbContentId;
            Stream portablePdbStream = getPortablePdbStreamOpt?.Invoke();
            if (portablePdbStream != null)
            {
                debugMetadataWriterOpt.WriteContentTo(portablePdbStream);

                if (_deterministic)
                {
                    portablePdbContentId = ContentId.FromHash(CryptographicHashProvider.ComputeSha1(portablePdbStream));
                }
                else
                {
                    portablePdbContentId = new ContentId(Guid.NewGuid().ToByteArray(), BitConverter.GetBytes(_timeStamp));
                }
            }
            else
            {
                portablePdbContentId = default(ContentId);
            }

            // Only the size of the fixed part of the debug table goes here.
            DirectoryEntry debugDirectory = default(DirectoryEntry);
            DirectoryEntry importTable = default(DirectoryEntry);
            DirectoryEntry importAddressTable = default(DirectoryEntry);
            int entryPointAddress = 0;

            if (EmitPdb)
            {
                debugDirectory = new DirectoryEntry(textSectionRva + ComputeOffsetToDebugTable(metadataSizes), ImageDebugDirectoryBaseSize);
            }

            if (_properties.RequiresStartupStub)
            {
                importAddressTable = new DirectoryEntry(textSectionRva, SizeOfImportAddressTable);
                entryPointAddress = CalculateMappedFieldDataStreamRva(textSectionRva, metadataSizes) - (_is32bit ? 6 : 10); // TODO: constants
                importTable = new DirectoryEntry(textSectionRva + ComputeOffsetToImportTable(metadataSizes), (_is32bit ? 66 : 70) + 13); // TODO: constants
            }

            var corHeaderDirectory = new DirectoryEntry(textSectionRva + SizeOfImportAddressTable, size: CorHeaderSize);

            long ntHeaderTimestampPosition;
            long metadataPosition;

            List<SectionHeader> sectionHeaders = CreateSectionHeaders(metadataSizes, sectionCount);

            CoffHeader coffHeader;
            NtHeader ntHeader;
            FillInNtHeader(sectionHeaders, entryPointAddress, corHeaderDirectory, importTable, importAddressTable, debugDirectory, out coffHeader, out ntHeader);

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

            WriteHeaders(peStream, ntHeader, coffHeader, sectionHeaders, out ntHeaderTimestampPosition);

            WriteTextSection(
                peStream,
                sectionHeaders[0],
                importTable.RelativeVirtualAddress,
                importAddressTable.RelativeVirtualAddress,
                entryPointToken,
                metadataWriter,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                metadataSizes,
                nativePdbContentId,
                portablePdbContentId,
                out metadataPosition);

            var resourceSection = sectionHeaders.FirstOrDefault(s => s.Name == ResourceSectionName);
            if (resourceSection != null)
            {
                WriteResourceSection(peStream, resourceSection);
            }

            var relocSection = sectionHeaders.FirstOrDefault(s => s.Name == RelocationSectionName);
            if (relocSection != null)
            {
                WriteRelocSection(peStream, relocSection, entryPointAddress);
            }

            if (_deterministic)
            {
                var mvidPosition = metadataPosition + moduleVersionIdOffsetInMetadataStream;
                WriteDeterministicGuidAndTimestamps(peStream, mvidPosition, ntHeaderTimestampPosition);
            }

            return true;
        }
示例#3
0
 internal ReferenceIndexer(MetadataWriter metadataWriter)
     : base(metadataWriter.Context)
 {
     this.metadataWriter = metadataWriter;
 }
示例#4
0
        public void SetMetadataEmitter(MetadataWriter metadataWriter)
        {
            try
            {
                var symWriter = (ISymUnmanagedWriter5)(_symWriterFactory != null ? _symWriterFactory() : CreateSymWriterWorker());

                // Correctness: If the stream is not specified or if it is non-empty the SymWriter appends data to it (provided it contains valid PDB)
                // and the resulting PDB has Age = existing_age + 1.
                _pdbStream = new ComMemoryStream();

                if (_deterministic)
                {
                    if (!(symWriter is ISymUnmanagedWriter7))
                    {
                        throw new NotSupportedException(CodeAnalysisResources.SymWriterNotDeterministic);
                    }

                    ((ISymUnmanagedWriter7)symWriter).InitializeDeterministic(new PdbMetadataWrapper(metadataWriter), _pdbStream);
                }
                else
                {
                    symWriter.Initialize(new PdbMetadataWrapper(metadataWriter), _fileName, _pdbStream, fullBuild: true);
                }

                _metadataWriter = metadataWriter;
                _symWriter = symWriter;
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }
        }
示例#5
0
        private bool WritePeToStream(MetadataWriter mdWriter, Func<Stream> getPeStream, Func<Stream> getPortablePdbStreamOpt, PdbWriter nativePdbWriterOpt)
        {
            // TODO: we can precalculate the exact size of IL stream
            var ilWriter = new BlobWriter(32 * 1024);
            var metadataWriter = new BlobWriter(16 * 1024);
            var mappedFieldDataWriter = new BlobWriter();
            var managedResourceWriter = new BlobWriter(1024);

            var debugMetadataWriterOpt = (getPortablePdbStreamOpt != null) ? new BlobWriter(16 * 1024) : null;

            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(_module.PersistentIdentifier == default(Guid));

            int moduleVersionIdOffsetInMetadataStream;
            var calculateMethodBodyStreamRva = new Func<MetadataSizes, int>(mdSizes =>
            {
                FillInTextSectionHeader(mdSizes);
                return (int)_textSection.RelativeVirtualAddress + _sizeOfImportAddressTable + 72;
            });

            int entryPointToken;
            MetadataSizes metadataSizes;
            mdWriter.SerializeMetadataAndIL(
                metadataWriter,
                debugMetadataWriterOpt,
                nativePdbWriterOpt,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                calculateMethodBodyStreamRva,
                CalculateMappedFieldDataStreamRva,
                out moduleVersionIdOffsetInMetadataStream,
                out entryPointToken,
                out metadataSizes);

            ContentId nativePdbContentId;
            if (nativePdbWriterOpt != null)
            {
                if (entryPointToken != 0)
                {
                    nativePdbWriterOpt.SetEntryPoint((uint)entryPointToken);
                }

                var assembly = _module.AsAssembly;
                if (assembly != null && assembly.Kind == ModuleKind.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(_module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(_module.GetSymbolToLocationMap());
#endif
                }

                nativePdbContentId = nativePdbWriterOpt.GetContentId();

                // the writer shall not be used after this point for writing:
                nativePdbWriterOpt = null;
            }
            else
            {
                nativePdbContentId = default(ContentId);
            }

            FillInSectionHeaders();

            // fill in header fields.
            FillInNtHeader(metadataSizes, CalculateMappedFieldDataStreamRva(metadataSizes));
            var corHeader = CreateCorHeader(metadataSizes, entryPointToken);

            // write to PE stream.
            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return false;
            }

            long ntHeaderTimestampPosition;
            long metadataPosition;

            WriteHeaders(peStream, out ntHeaderTimestampPosition);

            WriteTextSection(
                peStream,
                corHeader,
                metadataWriter,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                metadataSizes,
                nativePdbContentId,
                out metadataPosition);

            WriteRdataSection(peStream);
            WriteSdataSection(peStream);
            WriteCoverSection(peStream);
            WriteTlsSection(peStream);
            WriteResourceSection(peStream);
            WriteRelocSection(peStream);

            if (_deterministic)
            {
                var mvidPosition = metadataPosition + moduleVersionIdOffsetInMetadataStream;
                WriteDeterministicGuidAndTimestamps(peStream, mvidPosition, ntHeaderTimestampPosition);
            }

            return true;
        }
示例#6
0
        private void WritePeToStream(MetadataWriter mdWriter, Stream peStream, PdbWriter nativePdbWriterOpt, out uint entryPointToken)
        {
            // TODO: we can precalculate the exact size of IL stream
            var ilBuffer = new MemoryStream(32 * 1024);
            var ilWriter = new BinaryWriter(ilBuffer);
            var metadataBuffer = new MemoryStream(16 * 1024);
            var metadataWriter = new BinaryWriter(metadataBuffer);
            var mappedFieldDataBuffer = new MemoryStream();
            var mappedFieldDataWriter = new BinaryWriter(mappedFieldDataBuffer);
            var managedResourceBuffer = new MemoryStream(1024);
            var managedResourceWriter = new BinaryWriter(managedResourceBuffer);

            // 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(_module.PersistentIdentifier == default(Guid));

            uint moduleVersionIdOffsetInMetadataStream;
            var calculateMethodBodyStreamRva = new Func<MetadataSizes, int>(mdSizes =>
            {
                FillInTextSectionHeader(mdSizes);
                return (int)(_textSection.RelativeVirtualAddress + _sizeOfImportAddressTable + 72);
            });

            MetadataSizes metadataSizes;
            mdWriter.SerializeMetadataAndIL(
                nativePdbWriterOpt,
                metadataWriter,
                ilWriter,
                mappedFieldDataWriter,
                managedResourceWriter,
                calculateMethodBodyStreamRva,
                CalculateMappedFieldDataStreamRva,
                out moduleVersionIdOffsetInMetadataStream,
                out entryPointToken,
                out metadataSizes);

            FillInSectionHeaders();

            // fill in header fields.
            FillInNtHeader(metadataSizes, CalculateMappedFieldDataStreamRva(metadataSizes));
            var corHeader = CreateCorHeader(metadataSizes, entryPointToken);

            // write to pe stream.
            long positionOfHeaderTimestamp;
            WriteHeaders(peStream, out positionOfHeaderTimestamp);

            long startOfMetadataStream;
            long positionOfDebugTableTimestamp;

            WriteTextSection(
                peStream,
                corHeader,
                metadataBuffer,
                ilBuffer,
                mappedFieldDataBuffer,
                managedResourceBuffer,
                out startOfMetadataStream,
                out positionOfDebugTableTimestamp);

            WriteRdataSection(peStream);
            WriteSdataSection(peStream);
            WriteCoverSection(peStream);
            WriteTlsSection(peStream);
            WriteResourceSection(peStream);
            WriteRelocSection(peStream);

            if (_deterministic)
            {
                var positionOfModuleVersionId = startOfMetadataStream + moduleVersionIdOffsetInMetadataStream;
                WriteDeterministicGuidAndTimestamps(peStream, positionOfModuleVersionId, positionOfHeaderTimestamp, positionOfDebugTableTimestamp);
            }
        }
示例#7
0
 private static void CheckIsTooLong(string fullName, int maxLength, bool withinLimit)
 {
     Assert.NotEqual(withinLimit, MetadataWriter.IsTooLongInternal(fullName, maxLength));
 }
        protected void ComputeMetadata <TPolicy>(
            TPolicy policy,
            NodeFactory factory,
            out byte[] metadataBlob,
            out List <MetadataMapping <MetadataType> > typeMappings,
            out List <MetadataMapping <MethodDesc> > methodMappings,
            out List <MetadataMapping <FieldDesc> > fieldMappings,
            out List <MetadataMapping <MethodDesc> > stackTraceMapping) where TPolicy : struct, IMetadataPolicy
        {
            var transformed             = MetadataTransform.Run(policy, GetCompilationModulesWithMetadata());
            MetadataTransform transform = transformed.Transform;

            // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate
            //       TypeReference records for _typeDefinitionsGenerated that don't have metadata.
            //       (To be used in MissingMetadataException messages)

            // Generate metadata blob
            var writer = new MetadataWriter();

            writer.ScopeDefinitions.AddRange(transformed.Scopes);

            // Generate entries in the blob for methods that will be necessary for stack trace purposes.
            var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >();

            foreach (var methodBody in GetCompiledMethodBodies())
            {
                MethodDesc method = methodBody.Method;

                MethodDesc typicalMethod = method.GetTypicalMethodDefinition();

                // Methods that will end up in the reflection invoke table should not have an entry in stack trace table
                // We'll try looking them up in reflection data at runtime.
                if (transformed.GetTransformedMethodDefinition(typicalMethod) != null &&
                    ShouldMethodBeInInvokeMap(method) &&
                    (GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) != 0)
                {
                    continue;
                }

                if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method))
                {
                    continue;
                }

                MetadataRecord record = CreateStackTraceRecord(transform, method);

                stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>(
                                          method,
                                          record));

                writer.AdditionalRootRecords.Add(record);
            }

            var ms = new MemoryStream();

            // .NET metadata is UTF-16 and UTF-16 contains code points that don't translate to UTF-8.
            var noThrowUtf8Encoding = new UTF8Encoding(false, false);

            using (var logWriter = _metadataLogFile != null ? new StreamWriter(File.Open(_metadataLogFile, FileMode.Create, FileAccess.Write, FileShare.Read), noThrowUtf8Encoding) : null)
            {
                writer.LogWriter = logWriter;
                writer.Write(ms);
            }

            metadataBlob = ms.ToArray();

            typeMappings      = new List <MetadataMapping <MetadataType> >();
            methodMappings    = new List <MetadataMapping <MethodDesc> >();
            fieldMappings     = new List <MetadataMapping <FieldDesc> >();
            stackTraceMapping = new List <MetadataMapping <MethodDesc> >();

            // Generate type definition mappings
            foreach (var type in factory.MetadataManager.GetTypesWithEETypes())
            {
                MetadataType definition = type.IsTypeDefinition ? type as MetadataType : null;
                if (definition == null)
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedTypeDefinition(definition);

                // Reflection requires that we maintain type identity. Even if we only generated a TypeReference record,
                // if there is an EEType for it, we also need a mapping table entry for it.
                if (record == null)
                {
                    record = transformed.GetTransformedTypeReference(definition);
                }

                if (record != null)
                {
                    typeMappings.Add(new MetadataMapping <MetadataType>(definition, writer.GetRecordHandle(record)));
                }
            }

            foreach (var method in GetCompiledMethods())
            {
                if (method.IsCanonicalMethod(CanonicalFormKind.Specific))
                {
                    // Canonical methods are not interesting.
                    continue;
                }

                if (IsReflectionBlocked(method.Instantiation) || IsReflectionBlocked(method.OwningType.Instantiation))
                {
                    continue;
                }

                if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0)
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition());

                if (record != null)
                {
                    methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record)));
                }
            }

            foreach (var field in GetFieldsWithRuntimeMapping())
            {
                Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition());
                if (record != null)
                {
                    fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record)));
                }
            }

            // Generate stack trace metadata mapping
            foreach (var stackTraceRecord in stackTraceRecords)
            {
                stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value)));
            }
        }
示例#9
0
 public SignatureWriter(MetadataWriter mdWriter)
 {
     m_mdWriter  = mdWriter;
     m_sigWriter = new MemoryBinaryWriter();
 }
示例#10
0
        protected void ComputeMetadata <TPolicy>(
            TPolicy policy,
            NodeFactory factory,
            out byte[] metadataBlob,
            out List <MetadataMapping <MetadataType> > typeMappings,
            out List <MetadataMapping <MethodDesc> > methodMappings,
            out List <MetadataMapping <FieldDesc> > fieldMappings,
            out List <MetadataMapping <MethodDesc> > stackTraceMapping) where TPolicy : struct, IMetadataPolicy
        {
            var transformed             = MetadataTransform.Run(policy, GetCompilationModulesWithMetadata());
            MetadataTransform transform = transformed.Transform;

            // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate
            //       TypeReference records for _typeDefinitionsGenerated that don't have metadata.
            //       (To be used in MissingMetadataException messages)

            // Generate metadata blob
            var writer = new MetadataWriter();

            writer.ScopeDefinitions.AddRange(transformed.Scopes);

            // Generate entries in the blob for methods that will be necessary for stack trace purposes.
            var stackTraceRecords = new List <KeyValuePair <MethodDesc, MetadataRecord> >();

            foreach (var methodBody in GetCompiledMethodBodies())
            {
                MethodDesc method = methodBody.Method;

                MethodDesc typicalMethod = method.GetTypicalMethodDefinition();

                // Methods that will end up in the reflection invoke table should not have an entry in stack trace table
                // We'll try looking them up in reflection data at runtime.
                if (transformed.GetTransformedMethodDefinition(typicalMethod) != null &&
                    ShouldMethodBeInInvokeMap(method) &&
                    (GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) != 0)
                {
                    continue;
                }

                if (!_stackTraceEmissionPolicy.ShouldIncludeMethod(method))
                {
                    continue;
                }

                MetadataRecord record = CreateStackTraceRecord(transform, method);

                stackTraceRecords.Add(new KeyValuePair <MethodDesc, MetadataRecord>(
                                          method,
                                          record));

                writer.AdditionalRootRecords.Add(record);
            }

            var ms = new MemoryStream();

            // .NET metadata is UTF-16 and UTF-16 contains code points that don't translate to UTF-8.
            var noThrowUtf8Encoding = new UTF8Encoding(false, false);

            using (var logWriter = _metadataLogFile != null ? new StreamWriter(File.Open(_metadataLogFile, FileMode.Create, FileAccess.Write, FileShare.Read), noThrowUtf8Encoding) : null)
            {
                writer.LogWriter = logWriter;
                writer.Write(ms);
            }

            metadataBlob = ms.ToArray();

            const int MaxAllowedMetadataOffset = 0xFFFFFF;

            if (metadataBlob.Length > MaxAllowedMetadataOffset)
            {
                // Offset portion of metadata handles is limited to 16 MB.
                throw new InvalidOperationException($"Metadata blob exceeded the addressing range (allowed: {MaxAllowedMetadataOffset}, actual: {metadataBlob.Length})");
            }

            typeMappings      = new List <MetadataMapping <MetadataType> >();
            methodMappings    = new List <MetadataMapping <MethodDesc> >();
            fieldMappings     = new List <MetadataMapping <FieldDesc> >();
            stackTraceMapping = new List <MetadataMapping <MethodDesc> >();

            // Generate type definition mappings
            foreach (var type in factory.MetadataManager.GetTypesWithEETypes())
            {
                MetadataType definition = type.IsTypeDefinition ? type as MetadataType : null;
                if (definition == null)
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedTypeDefinition(definition);

                // Reflection requires that we maintain type identity. Even if we only generated a TypeReference record,
                // if there is an MethodTable for it, we also need a mapping table entry for it.
                if (record == null)
                {
                    record = transformed.GetTransformedTypeReference(definition);
                }

                if (record != null)
                {
                    typeMappings.Add(new MetadataMapping <MetadataType>(definition, writer.GetRecordHandle(record)));
                }
            }

            HashSet <MethodDesc> canonicalGenericMethods = new HashSet <MethodDesc>();

            foreach (var method in GetReflectableMethods())
            {
                if (method.IsGenericMethodDefinition || method.OwningType.IsGenericDefinition)
                {
                    // Generic definitions don't have runtime artifacts we would need to map to.
                    continue;
                }

                if ((method.HasInstantiation && method.IsCanonicalMethod(CanonicalFormKind.Specific)) ||
                    (!method.HasInstantiation && method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method))
                {
                    // Methods that are not in their canonical form are not interesting with the exception
                    // of generic methods: their dictionaries convey their identity.
                    continue;
                }

                if (IsReflectionBlocked(method.Instantiation) || IsReflectionBlocked(method.OwningType.Instantiation))
                {
                    continue;
                }

                if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0)
                {
                    continue;
                }

                // If we already added a canonically equivalent generic method, skip this one.
                if (method.HasInstantiation && !canonicalGenericMethods.Add(method.GetCanonMethodTarget(CanonicalFormKind.Specific)))
                {
                    continue;
                }

                MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition());

                if (record != null)
                {
                    methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record)));
                }
            }

            HashSet <FieldDesc> canonicalFields = new HashSet <FieldDesc>();

            foreach (var field in GetFieldsWithRuntimeMapping())
            {
                FieldDesc fieldToAdd = field;
                if (!field.IsStatic)
                {
                    TypeDesc canonOwningType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
                    if (canonOwningType != field.OwningType)
                    {
                        FieldDesc canonField = _typeSystemContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwningType);

                        // If we already added a canonically equivalent field, skip this one.
                        if (!canonicalFields.Add(canonField))
                        {
                            continue;
                        }

                        fieldToAdd = canonField;
                    }
                }

                Field record = transformed.GetTransformedFieldDefinition(fieldToAdd.GetTypicalFieldDefinition());
                if (record != null)
                {
                    fieldMappings.Add(new MetadataMapping <FieldDesc>(fieldToAdd, writer.GetRecordHandle(record)));
                }
            }

            // Generate stack trace metadata mapping
            foreach (var stackTraceRecord in stackTraceRecords)
            {
                stackTraceMapping.Add(new MetadataMapping <MethodDesc>(stackTraceRecord.Key, writer.GetRecordHandle(stackTraceRecord.Value)));
            }
        }
示例#11
0
        private void EnsureMetadataGenerated()
        {
            if (_metadataBlob != null)
            {
                return;
            }

            var transformed = MetadataTransform.Run(new DummyMetadataPolicy(this), _modulesSeen);

            // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate
            //       TypeReference records for _typeDefinitionsGenerated that don't have metadata.
            //       (To be used in MissingMetadataException messages)

            // Generate metadata blob
            var writer = new MetadataWriter();

            writer.ScopeDefinitions.AddRange(transformed.Scopes);
            var ms = new MemoryStream();

            writer.Write(ms);
            _metadataBlob = ms.ToArray();

            // Generate type definition mappings
            foreach (var definition in _typeDefinitionsGenerated)
            {
                MetadataRecord record = transformed.GetTransformedTypeDefinition(definition);

                // Reflection requires that we maintain type identity. Even if we only generated a TypeReference record,
                // if there is an EEType for it, we also need a mapping table entry for it.
                if (record == null)
                {
                    record = transformed.GetTransformedTypeReference(definition);
                }

                if (record != null)
                {
                    _typeMappings.Add(new MetadataMapping <MetadataType>(definition, writer.GetRecordHandle(record)));
                }
            }

            foreach (var method in _methodsGenerated)
            {
                MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition());

                if (record != null)
                {
                    _methodMappings.Add(new MetadataMapping <MethodDesc>(method, writer.GetRecordHandle(record)));
                }
            }

            foreach (var eetypeGenerated in _typesWithEETypesGenerated)
            {
                if (eetypeGenerated.IsGenericDefinition)
                {
                    continue;
                }

                foreach (FieldDesc field in eetypeGenerated.GetFields())
                {
                    Field record = transformed.GetTransformedFieldDefinition(field.GetTypicalFieldDefinition());
                    if (record != null)
                    {
                        _fieldMappings.Add(new MetadataMapping <FieldDesc>(field, writer.GetRecordHandle(record)));
                    }
                }
            }
        }
示例#12
0
        public void SetMetadataEmitter(MetadataWriter metadataWriter)
        {
            try
            {
                var instance = (ISymUnmanagedWriter2)(_symWriterFactory != null ? _symWriterFactory() : Activator.CreateInstance(GetCorSymWriterSxSType()));
                instance.Initialize(new PdbMetadataWrapper(metadataWriter), _fileName, _stream, true);

                _metadataWriter = metadataWriter;
                _symWriter = instance;
            }
            catch (Exception ex)
            {
                throw new PdbWritingException(ex);
            }
        }