public CopiedFieldRvaNode CopiedFieldRva(FieldDesc field) { Debug.Assert(field.HasRva); EcmaField ecmaField = (EcmaField)field.GetTypicalFieldDefinition(); if (!CompilationModuleGroup.ContainsType(ecmaField.OwningType)) { // TODO: cross-bubble RVA field throw new NotSupportedException($"{ecmaField} ... {ecmaField.Module.Assembly}"); } if (TypeSystemContext.InputFilePaths.Count > 1) { // TODO: RVA fields in merged multi-file compilation throw new NotSupportedException($"{ecmaField} ... {string.Join("; ", TypeSystemContext.InputFilePaths.Keys)}"); } CopiedFieldRvaNode result; if (!_copiedFieldRvas.TryGetValue(ecmaField, out result)) { result = new CopiedFieldRvaNode(ecmaField); _copiedFieldRvas.Add(ecmaField, result); } return(result); }
private unsafe byte[] GetRvaData(int targetPointerSize, out int requiredAlignment) { int size = 0; requiredAlignment = targetPointerSize; MetadataReader metadataReader = _module.MetadataReader; BlobReader metadataBlob = new BlobReader(_module.PEReader.GetMetadata().Pointer, _module.PEReader.GetMetadata().Length); metadataBlob.Offset = metadataReader.GetTableMetadataOffset(TableIndex.FieldRva); bool compressedFieldRef = 6 == metadataReader.GetTableRowSize(TableIndex.FieldRva); for (int i = 1; i <= metadataReader.GetTableRowCount(TableIndex.FieldRva); i++) { int currentFieldRva = metadataBlob.ReadInt32(); int currentFieldRid; if (compressedFieldRef) { currentFieldRid = metadataBlob.ReadUInt16(); } else { currentFieldRid = metadataBlob.ReadInt32(); } if (currentFieldRva != _rva) { continue; } EcmaField field = (EcmaField)_module.GetField(MetadataTokens.FieldDefinitionHandle(currentFieldRid)); Debug.Assert(field.HasRva); int currentSize = field.FieldType.GetElementSize().AsInt; requiredAlignment = Math.Max(requiredAlignment, (field.FieldType as MetadataType)?.GetClassLayout().PackingSize ?? 1); if (currentSize > size) { // We need to handle overlapping fields by reusing blobs based on the rva, and just update // the size and contents size = currentSize; } } Debug.Assert(size > 0); PEMemoryBlock block = _module.PEReader.GetSectionData(_rva); if (block.Length < size) { throw new BadImageFormatException(); } byte[] result = new byte[AlignmentHelper.AlignUp(size, targetPointerSize)]; block.GetContent(0, size).CopyTo(result); return(result); }
public CopiedFieldRvaNode CopiedFieldRva(FieldDesc field) { Debug.Assert(field.HasRva); EcmaField ecmaField = (EcmaField)field.GetTypicalFieldDefinition(); if (!CompilationModuleGroup.ContainsType(ecmaField.OwningType)) { // TODO: cross-bubble RVA field throw new NotSupportedException($"{ecmaField} ... {ecmaField.Module.Assembly}"); } return(_copiedFieldRvas.GetOrAdd(new ModuleAndIntValueKey(ecmaField.GetFieldRvaValue(), ecmaField.Module))); }
public ObjectNode GetRvaFieldNode(FieldDesc fieldDesc) { Debug.Assert(fieldDesc.HasRva); EcmaField ecmaField = (EcmaField)fieldDesc.GetTypicalFieldDefinition(); if (!_codegenNodeFactory.CompilationModuleGroup.ContainsType(ecmaField.OwningType)) { // TODO: cross-bubble RVA field throw new NotSupportedException($"{ecmaField} ... {ecmaField.Module.Assembly}"); } if (_codegenNodeFactory.TypeSystemContext.InputFilePaths.Count > 1) { // TODO: RVA fields in merged multi-file compilation throw new NotSupportedException($"{ecmaField} ... {string.Join("; ", _codegenNodeFactory.TypeSystemContext.InputFilePaths.Keys)}"); } int rva = ecmaField.MetadataReader.GetFieldDefinition(ecmaField.Handle).GetRelativeVirtualAddress(); ObjectNode rvaFieldNode; if (!_rvaFieldSymbols.TryGetValue(rva, out rvaFieldNode)) { PEReader ilReader = ecmaField.Module.PEReader; int sectionIndex; int sectionRelativeOffset = 0; ISymbolNode sectionStartNode = null; for (sectionIndex = ilReader.PEHeaders.SectionHeaders.Length - 1; sectionIndex >= 0; sectionIndex--) { SectionHeader sectionHeader = ilReader.PEHeaders.SectionHeaders[sectionIndex]; if (rva >= sectionHeader.VirtualAddress && rva < sectionHeader.VirtualAddress + sectionHeader.VirtualSize) { sectionRelativeOffset = rva - sectionHeader.VirtualAddress; sectionStartNode = _codegenNodeFactory.SectionStartNode(sectionHeader.Name); break; } } if (sectionIndex < 0) { // Target section for the RVA field was not found throw new NotImplementedException(fieldDesc.ToString()); } rvaFieldNode = new RVAFieldNode(sectionStartNode, sectionRelativeOffset); _rvaFieldSymbols.Add(rva, rvaFieldNode); } return(rvaFieldNode); }
private unsafe byte[] GetRvaData(int targetPointerSize) { int size = 0; byte[] result = Array.Empty <byte>(); MetadataReader metadataReader = _module.MetadataReader; BlobReader metadataBlob = new BlobReader(_module.PEReader.GetMetadata().Pointer, _module.PEReader.GetMetadata().Length); metadataBlob.Offset = metadataReader.GetTableMetadataOffset(TableIndex.FieldRva); ImmutableArray <byte> memBlock = _module.PEReader.GetSectionData(_rva).GetContent(); for (int i = 1; i <= metadataReader.GetTableRowCount(TableIndex.FieldRva); i++) { int currentFieldRva = metadataBlob.ReadInt32(); short currentFieldRid = metadataBlob.ReadInt16(); if (currentFieldRva != _rva) { continue; } EcmaField field = (EcmaField)_module.GetField(MetadataTokens.FieldDefinitionHandle(currentFieldRid)); Debug.Assert(field.HasRva); int currentSize = field.FieldType.GetElementSize().AsInt; if (currentSize > size) { if (currentSize > memBlock.Length) { throw new BadImageFormatException(); } // We need to handle overlapping fields by reusing blobs based on the rva, and just update // the size and contents size = currentSize; result = new byte[AlignmentHelper.AlignUp(size, targetPointerSize)]; memBlock.CopyTo(0, result, 0, size); } } Debug.Assert(size > 0); return(result); }
private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder, ref BlobReader reader) { MetadataReader metadataReader = _sourceModule.MetadataReader; var tableIndex = TableIndex.FieldRva; int rowCount = metadataReader.GetTableRowCount(tableIndex); for (int i = 1; i <= rowCount; i++) { Debug.Assert(builder.CountBytes == reader.Offset); // Rva reader.ReadInt32(); short fieldToken = reader.ReadInt16(); EntityHandle fieldHandle = MetadataTokens.EntityHandle(TableIndex.Field, fieldToken); EcmaField fieldDesc = (EcmaField)_sourceModule.GetField(fieldHandle); Debug.Assert(fieldDesc.HasRva); builder.EmitReloc(((ReadyToRunCodegenNodeFactory)factory).CopiedFieldRva(fieldDesc), RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitShort(fieldToken); } }
private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder, ref BlobReader reader) { MetadataReader metadataReader = _sourceModule.MetadataReader; var tableIndex = TableIndex.FieldRva; int rowCount = metadataReader.GetTableRowCount(tableIndex); bool compressedFieldRef = 6 == metadataReader.GetTableRowSize(TableIndex.FieldRva); for (int i = 1; i <= rowCount; i++) { Debug.Assert(builder.CountBytes == reader.Offset); // Rva reader.ReadInt32(); int fieldToken; if (compressedFieldRef) { fieldToken = reader.ReadInt16(); } else { fieldToken = reader.ReadInt32(); } EntityHandle fieldHandle = MetadataTokens.EntityHandle(TableIndex.Field, fieldToken); EcmaField fieldDesc = (EcmaField)_sourceModule.GetField(fieldHandle); Debug.Assert(fieldDesc.HasRva); builder.EmitReloc(factory.CopiedFieldRva(fieldDesc), RelocType.IMAGE_REL_BASED_ADDR32NB); if (compressedFieldRef) { builder.EmitUShort((ushort)fieldToken); } else { builder.EmitUInt((uint)fieldToken); } } }
public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaField field) { FieldDefinition fieldDef = field.MetadataReader.GetFieldDefinition(field.Handle); AddDependenciesDueToCustomAttributes(ref dependencies, factory, field.Module, fieldDef.GetCustomAttributes()); }
public CopiedFieldRvaNode(EcmaField field) { Debug.Assert(field.HasRva); _field = field; }
public FieldRvaDataNode(EcmaField field) { Debug.Assert(field.HasRva); _field = field; }