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)); }
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; }
internal ReferenceIndexer(MetadataWriter metadataWriter) : base(metadataWriter.Context) { this.metadataWriter = metadataWriter; }
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); } }
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; }
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); } }
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))); } }
public SignatureWriter(MetadataWriter mdWriter) { m_mdWriter = mdWriter; m_sigWriter = new MemoryBinaryWriter(); }
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))); } }
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))); } } } }
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); } }