public static void Write(ref ObjectDataBuilder dataBuilder, ISymbolNode node, int offsetFromSymbol, int sizeOfData) { dataBuilder.EmitReloc(node, RelocType.IMAGE_REL_BASED_ADDR32NB, offsetFromSymbol); dataBuilder.EmitInt(sizeOfData); dataBuilder.EmitInt(1252); // CODEPAGE = DEFAULT_CODEPAGE dataBuilder.EmitInt(0); // RESERVED }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.AddSymbol(this); foreach (AssemblyHeaderNode assemblyHeader in _assemblyHeaders) { // TODO: IMAGE_DATA_DIRECTORY CorHeader - no support for embedded MSIL yet builder.EmitInt(0); builder.EmitInt(0); // IMAGE_DATA_DIRECTORY ReadyToRunHeader builder.EmitReloc(assemblyHeader, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitReloc(assemblyHeader, RelocType.IMAGE_REL_SYMBOL_SIZE); } return(builder.ToObjectData()); }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { // This needs to be an empty target pointer since it will be filled in with Module* // when loaded by CoreCLR dataBuilder.EmitReloc(_delayLoadHelper, factory.Target.PointerSize == 4 ? RelocType.IMAGE_REL_BASED_HIGHLOW : RelocType.IMAGE_REL_BASED_DIR64); }
private void WriteMethodTableRvas(NodeFactory factory, ref ObjectDataBuilder builder, ref BlobReader reader) { MetadataReader metadataReader = _sourceModule.MetadataReader; var tableIndex = TableIndex.MethodDef; int rowCount = metadataReader.GetTableRowCount(tableIndex); int rowSize = metadataReader.GetTableRowSize(tableIndex); for (int i = 1; i <= rowCount; i++) { Debug.Assert(builder.CountBytes == reader.Offset); int inputRva = reader.ReadInt32(); if (inputRva == 0) { // Don't fix up 0 Rvas (abstract methods in the methodDef table) builder.EmitInt(0); } else { var methodDefHandle = MetadataTokens.EntityHandle(TableIndex.MethodDef, i); EcmaMethod method = _sourceModule.GetMethod(methodDefHandle) as EcmaMethod; builder.EmitReloc(factory.CopiedMethodIL(method), RelocType.IMAGE_REL_BASED_ADDR32NB); } // Skip the rest of the row int remainingBytes = rowSize - sizeof(int); builder.EmitBytes(reader.ReadBytes(remainingBytes)); } }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); EmitHeaderPrefix(ref builder); // Don't bother sorting if we're not emitting the contents if (!relocsOnly) { _items.MergeSort((x, y) => Comparer <int> .Default.Compare((int)x.Id, (int)y.Id)); } // ReadyToRunHeader.Flags builder.EmitInt((int)_flags); // ReadyToRunHeader.NumberOfSections ObjectDataBuilder.Reservation sectionCountReservation = builder.ReserveInt(); int count = 0; foreach (var item in _items) { // Skip empty entries if (!relocsOnly && item.Node is ObjectNode on && on.ShouldSkipEmittingObjectNode(factory)) { continue; } builder.EmitInt((int)item.Id); builder.EmitReloc(item.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB); // The header entry for the runtime functions table should not include the 4 byte 0xffffffff sentinel // value in the covered range. int delta = item.Id == ReadyToRunSectionType.RuntimeFunctions ? RuntimeFunctionsTableNode.SentinelSizeAdjustment : 0; builder.EmitReloc(item.StartSymbol, RelocType.IMAGE_REL_SYMBOL_SIZE, delta); count++; } builder.EmitInt(sectionCountReservation, count); return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } if (_methodNodes == null) { LayoutRuntimeFunctions(); } ObjectDataBuilder runtimeFunctionsBuilder = new ObjectDataBuilder(factory, relocsOnly); ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory; // Add the symbol representing this object node runtimeFunctionsBuilder.AddSymbol(this); foreach (MethodWithGCInfo method in _methodNodes) { int methodOffset = runtimeFunctionsBuilder.CountBytes; int[] funcletOffsets = method.GCInfoNode.CalculateFuncletOffsets(factory); for (int frameIndex = 0; frameIndex < method.FrameInfos.Length; frameIndex++) { FrameInfo frameInfo = method.FrameInfos[frameIndex]; // StartOffset of the runtime function runtimeFunctionsBuilder.EmitReloc(method, RelocType.IMAGE_REL_BASED_ADDR32NB, delta: frameInfo.StartOffset); if (!relocsOnly && Target.Architecture == TargetArchitecture.X64) { // On Amd64, the 2nd word contains the EndOffset of the runtime function runtimeFunctionsBuilder.EmitReloc(method, RelocType.IMAGE_REL_BASED_ADDR32NB, delta: frameInfo.EndOffset); } runtimeFunctionsBuilder.EmitReloc(r2rFactory.RuntimeFunctionsGCInfo.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, funcletOffsets[frameIndex]); } } // Emit sentinel entry runtimeFunctionsBuilder.EmitUInt(~0u); _tableSize = runtimeFunctionsBuilder.CountBytes; return(runtimeFunctionsBuilder.ToObjectData()); }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { if (relocsOnly) { return; } TargetArchitecture targetArch = factory.Target.Architecture; for (int frameInfoIndex = 0; frameInfoIndex < _methodNode.FrameInfos.Length; frameInfoIndex++) { byte[] unwindInfo = _methodNode.FrameInfos[frameInfoIndex].BlobData; if (targetArch == TargetArchitecture.X64) { // On Amd64, patch the first byte of the unwind info by setting the flags to EHANDLER | UHANDLER // as that's what CoreCLR does (zapcode.cpp, ZapUnwindData::Save). const byte UNW_FLAG_EHANDLER = 1; const byte UNW_FLAG_UHANDLER = 2; const byte FlagsShift = 3; unwindInfo[0] |= (byte)((UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER) << FlagsShift); } else if ((targetArch == TargetArchitecture.ARM) || (targetArch == TargetArchitecture.ARM64)) { // Set the 'X' bit to indicate that there is a personality routine associated with this method unwindInfo[2] |= 1 << 4; } dataBuilder.EmitBytes(unwindInfo); // 4-align after emitting the unwind info dataBuilder.EmitZeros(-unwindInfo.Length & 3); if (targetArch != TargetArchitecture.X86) { bool isFilterFunclet = (_methodNode.FrameInfos[frameInfoIndex].Flags & FrameInfoFlags.Filter) != 0; ISymbolNode personalityRoutine = (isFilterFunclet ? factory.FilterFuncletPersonalityRoutine : factory.PersonalityRoutine); int codeDelta = 0; if (targetArch == TargetArchitecture.ARM) { // THUMB_CODE codeDelta = 1; } dataBuilder.EmitReloc(personalityRoutine, RelocType.IMAGE_REL_BASED_ADDR32NB, codeDelta); } if (frameInfoIndex == 0 && _methodNode.GCInfo != null) { dataBuilder.EmitBytes(_methodNode.GCInfo); // Maintain 4-alignment for the next unwind / GC info block int align4Pad = -_methodNode.GCInfo.Length & 3; dataBuilder.EmitZeros(align4Pad); } } }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); EmitHeaderPrefix(ref builder); // Don't bother sorting if we're not emitting the contents if (!relocsOnly) { _items.MergeSort((x, y) => Comparer <int> .Default.Compare((int)x.Id, (int)y.Id)); } // ReadyToRunHeader.Flags builder.EmitInt((int)_flags); // ReadyToRunHeader.NumberOfSections ObjectDataBuilder.Reservation sectionCountReservation = builder.ReserveInt(); int count = 0; foreach (var item in _items) { // Skip empty entries if (!relocsOnly && item.Node.ShouldSkipEmittingObjectNode(factory)) { continue; } builder.EmitInt((int)item.Id); builder.EmitReloc(item.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitReloc(item.StartSymbol, RelocType.IMAGE_REL_SYMBOL_SIZE); count++; } builder.EmitInt(sectionCountReservation, count); return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); // Don't bother sorting if we're not emitting the contents if (!relocsOnly) { _items.Sort((x, y) => Comparer <int> .Default.Compare((int)x.Id, (int)y.Id)); } // ReadyToRunHeader.Magic builder.EmitInt((int)(ReadyToRunHeaderConstants.Signature)); // ReadyToRunHeader.MajorVersion builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMajorVersion)); builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMinorVersion)); // ReadyToRunHeader.Flags builder.EmitInt(0); // ReadyToRunHeader.NumberOfSections ObjectDataBuilder.Reservation sectionCountReservation = builder.ReserveInt(); int count = 0; foreach (var item in _items) { // Skip empty entries if (!relocsOnly && item.Node.ShouldSkipEmittingObjectNode(factory)) { continue; } builder.EmitInt((int)item.Id); builder.EmitReloc(item.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB); if (!relocsOnly) { builder.EmitInt(item.Node.GetData(factory).Data.Length); } count++; } builder.EmitInt(sectionCountReservation, count); return(builder.ToObjectData()); }
public void EmitJMP(ISymbolNode symbol) { if (symbol.RepresentsIndirectionCell) { Debug.Assert(false, "The following code to emit an jump stub to an indirection cell is untested. When testing on ARM64 please remove this assert and verify it is correct"); // xip0 register num is 0x10 // ADRP xip0, [symbol (21bit ADRP thing)] // 0x90000000 + (xip regnum) Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21); Builder.EmitByte(0x10); Builder.EmitByte(0x00); Builder.EmitByte(0x00); Builder.EmitByte(0x90); // LDR xip0, [xip0 + 12bit LDR page offset reloc)] // 0xF9400000 + ((xip0 regnum) << 5) + (xip regnum) Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L); Builder.EmitByte(0x10); Builder.EmitByte(0x02); Builder.EmitByte(0x40); Builder.EmitByte(0xF9); // BR xip0 // 0xD61F0000 + (xip0 regnum) << 5) Builder.EmitByte(0x00); Builder.EmitByte(0x02); Builder.EmitByte(0x1F); Builder.EmitByte(0xD6); } else { Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_BRANCH26); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0x14); } }
public void EmitJMP(ISymbolNode symbol) { if (symbol.RepresentsIndirectionCell) { // xip0 register num is 0x10 // ADRP xip0, [symbol (21bit ADRP thing)] // 0x90000000 + (xip regnum) Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21); Builder.EmitByte(0x10); Builder.EmitByte(0x00); Builder.EmitByte(0x00); Builder.EmitByte(0x90); // LDR xip0, [xip0 + 12bit LDR page offset reloc)] // 0xF9400000 + ((xip0 regnum) << 5) + (xip regnum) Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L); Builder.EmitByte(0x10); Builder.EmitByte(0x02); Builder.EmitByte(0x40); Builder.EmitByte(0xF9); // BR xip0 // 0xD61F0000 + (xip0 regnum) << 5) Builder.EmitByte(0x00); Builder.EmitByte(0x02); Builder.EmitByte(0x1F); Builder.EmitByte(0xD6); } else { Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_BRANCH26); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0x14); } }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { if (!_imports.ShouldSkipEmittingObjectNode(factory)) { dataBuilder.EmitReloc(_imports.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0); } else { dataBuilder.EmitUInt(0); } if (!relocsOnly) { dataBuilder.EmitInt(_imports.GetData(factory, false).Data.Length); dataBuilder.EmitShort((short)_flags); dataBuilder.EmitByte((byte)_type); dataBuilder.EmitByte(_entrySize); } if (!_signatures.ShouldSkipEmittingObjectNode(factory)) { dataBuilder.EmitReloc(_signatures.StartSymbol, RelocType.IMAGE_REL_BASED_ADDR32NB, 0); } else { dataBuilder.EmitUInt(0); } if (_emitGCRefMap) { dataBuilder.EmitReloc(_gcRefMap, RelocType.IMAGE_REL_BASED_ADDR32NB, 0); } else { dataBuilder.EmitUInt(0); } }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { // This needs to be an empty target pointer since it will be filled in with Module* // when loaded by CoreCLR int codeDelta = 0; if (factory.Target.Architecture == TargetArchitecture.ARM) { // THUMB_CODE codeDelta = 1; } dataBuilder.EmitReloc(_delayLoadHelper, factory.Target.PointerSize == 4 ? RelocType.IMAGE_REL_BASED_HIGHLOW : RelocType.IMAGE_REL_BASED_DIR64, codeDelta); }
public void EmitJMP(ISymbolNode symbol) { if (symbol.RepresentsIndirectionCell) { // ldr x12, [PC+0xc] EmitLDR(Register.X12, 0xc); // ldr x12, [x12] EmitLDR(Register.X12, Register.X12); // br x12 Builder.EmitUInt(0xd61f0180); Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64); } else { Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_BRANCH26); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0x14); } }
public void EmitJMP(ISymbolNode symbol) { if (symbol.RepresentsIndirectionCell) { throw new NotImplementedException(); } else { Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_ARM64_BRANCH26); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0); Builder.EmitByte(0x14); } }
public void EmitMOV(Register regDst, ISymbolNode node) { if (node.RepresentsIndirectionCell) { Builder.EmitByte(0x67); Builder.EmitByte(0x48); Builder.EmitByte(0x8B); Builder.EmitByte((byte)(0x00 | ((byte)regDst << 3) | 0x05)); Builder.EmitReloc(node, RelocType.IMAGE_REL_BASED_REL32); } else { EmitLEAQ(regDst, node, delta: 0); } }
public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly) { if (relocsOnly) { return; } for (int frameInfoIndex = 0; frameInfoIndex < _methodNode.FrameInfos.Length; frameInfoIndex++) { byte[] unwindInfo = _methodNode.FrameInfos[frameInfoIndex].BlobData; if (factory.Target.Architecture == Internal.TypeSystem.TargetArchitecture.X64) { // On Amd64, patch the first byte of the unwind info by setting the flags to EHANDLER | UHANDLER // as that's what CoreCLR does (zapcode.cpp, ZapUnwindData::Save). const byte UNW_FLAG_EHANDLER = 1; const byte UNW_FLAG_UHANDLER = 2; const byte FlagsShift = 3; unwindInfo[0] |= (byte)((UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER) << FlagsShift); } dataBuilder.EmitBytes(unwindInfo); // 4-align after emitting the unwind info dataBuilder.EmitZeros(-unwindInfo.Length & 3); if (factory.Target.Architecture != Internal.TypeSystem.TargetArchitecture.X86) { bool isFilterFunclet = (_methodNode.FrameInfos[frameInfoIndex].Flags & FrameInfoFlags.Filter) != 0; ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory; ISymbolNode personalityRoutine = (isFilterFunclet ? r2rFactory.FilterFuncletPersonalityRoutine : r2rFactory.PersonalityRoutine); dataBuilder.EmitReloc(personalityRoutine, RelocType.IMAGE_REL_BASED_ADDR32NB); } if (frameInfoIndex == 0 && _methodNode.GCInfo != null) { dataBuilder.EmitBytes(_methodNode.GCInfo); // Maintain 4-alignment for the next unwind / GC info block int align4Pad = -_methodNode.GCInfo.Length & 3; dataBuilder.EmitZeros(align4Pad); } } }
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 void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0) { _builder.EmitReloc(symbol, relocType, delta); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); ImmutableArray <DebugDirectoryEntry> entries = default(ImmutableArray <DebugDirectoryEntry>); if (_module != null) { entries = _module.PEReader.ReadDebugDirectory(); } int numEntries = GetNumDebugDirectoryEntriesInModule(); // First, write the native debug directory entry { var entry = _nativeEntry; builder.EmitUInt(0 /* Characteristics */); if (numEntries > 0) { builder.EmitUInt(entries[0].Stamp); builder.EmitUShort(entries[0].MajorVersion); } else { builder.EmitUInt(0); builder.EmitUShort(0); } // Make sure the "is portable pdb" indicator (MinorVersion == 0x504d) is clear // for the NGen debug directory entry since this debug directory can be copied // from an existing entry which could be a portable pdb. builder.EmitUShort(0 /* MinorVersion */); builder.EmitInt((int)DebugDirectoryEntryType.CodeView); builder.EmitInt(entry.Size); builder.EmitReloc(entry, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitReloc(entry, RelocType.IMAGE_REL_FILE_ABSOLUTE); } // If generating a composite image, emit the deterministic marker if (_insertDeterministicEntry) { builder.EmitUInt(0 /* Characteristics */); builder.EmitUInt(0); builder.EmitUShort(0); builder.EmitUShort(0); builder.EmitInt((int)DebugDirectoryEntryType.Reproducible); builder.EmitInt(0); builder.EmitUInt(0); builder.EmitUInt(0); } // Second, copy existing entries from input module for (int i = 0; i < numEntries; i++) { builder.EmitUInt(0 /* Characteristics */); builder.EmitUInt(entries[i].Stamp); builder.EmitUShort(entries[i].MajorVersion); builder.EmitUShort(entries[i].MinorVersion); builder.EmitInt((int)entries[i].Type); builder.EmitInt(entries[i].DataSize); if (entries[i].DataSize == 0) { builder.EmitUInt(0); builder.EmitUInt(0); } else { builder.EmitReloc(factory.DebugDirectoryEntry(_module, i), RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitReloc(factory.DebugDirectoryEntry(_module, i), RelocType.IMAGE_REL_FILE_ABSOLUTE); } } Debug.Assert(builder.CountBytes == Size); return(builder.ToObjectData()); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.RequireInitialPointerAlignment(); builder.AddSymbol(this); BlobReader reader = _module.PEReader.GetEntireImage().GetReader(); reader.Offset = _module.PEReader.PEHeaders.CorHeaderStartOffset; // Header Size int headerSize = reader.ReadInt32(); builder.EmitInt(headerSize); // Runtime major, minor version builder.EmitUShort(reader.ReadUInt16()); builder.EmitUShort(reader.ReadUInt16()); // Metadata Directory ReadDirectoryEntry(ref reader); var metadataBlob = factory.CopiedMetadataBlob(_module); builder.EmitReloc(metadataBlob, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitInt(metadataBlob.Size); // Flags builder.EmitUInt((uint)(((CorFlags)reader.ReadUInt32() & ~CorFlags.ILOnly) | CorFlags.ILLibrary)); // Entrypoint builder.EmitInt(reader.ReadInt32()); // Resources Directory if (ReadDirectoryEntry(ref reader).Size > 0) { var managedResources = factory.CopiedManagedResources(_module); builder.EmitReloc(managedResources, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitInt(managedResources.Size); } else { WriteEmptyDirectoryEntry(ref builder); } // Strong Name Signature Directory if (ReadDirectoryEntry(ref reader).Size > 0) { var strongNameSignature = factory.CopiedStrongNameSignature(_module); builder.EmitReloc(strongNameSignature, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitInt(strongNameSignature.Size); } else { WriteEmptyDirectoryEntry(ref builder); } // Code Manager Table Directory ReadDirectoryEntry(ref reader); WriteEmptyDirectoryEntry(ref builder); // VTable Fixups Directory ReadDirectoryEntry(ref reader); WriteEmptyDirectoryEntry(ref builder); // Export Address Table Jumps Directory ReadDirectoryEntry(ref reader); WriteEmptyDirectoryEntry(ref builder); // Managed Native (ReadyToRun) Header Directory ReadDirectoryEntry(ref reader); builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_BASED_ADDR32NB); builder.EmitReloc(factory.Header, RelocType.IMAGE_REL_SYMBOL_SIZE); // Did we fully read the header? Debug.Assert(reader.Offset - headerSize == _module.PEReader.PEHeaders.CorHeaderStartOffset); Debug.Assert(builder.CountBytes == headerSize); Debug.Assert(headerSize == Size); return(builder.ToObjectData()); }
public void EmitJMP(ISymbolNode symbol) { Builder.EmitByte(0xE9); Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32); }