Пример #1
0
 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
 }
Пример #2
0
        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());
        }
Пример #3
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
     dataBuilder.EmitReloc(_delayLoadHelper,
                           factory.Target.PointerSize == 4 ? RelocType.IMAGE_REL_BASED_HIGHLOW : RelocType.IMAGE_REL_BASED_DIR64);
 }
Пример #4
0
        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));
            }
        }
Пример #5
0
        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());
        }
Пример #6
0
        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());
        }
Пример #7
0
        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);
                }
            }
        }
Пример #8
0
        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());
        }
Пример #9
0
        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());
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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);
            }
        }
Пример #13
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);
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
 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);
     }
 }
Пример #16
0
 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);
     }
 }
Пример #17
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);
                }
            }
        }
Пример #18
0
        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);
            }
        }
Пример #19
0
        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);
                }
            }
        }
Пример #20
0
 public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
 {
     _builder.EmitReloc(symbol, relocType, delta);
 }
Пример #21
0
        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());
        }
Пример #22
0
        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());
        }
Пример #23
0
 public void EmitJMP(ISymbolNode symbol)
 {
     Builder.EmitByte(0xE9);
     Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
 }