Example #1
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);
                }
            }
        }
Example #2
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            if (relocsOnly)
            {
                return;
            }

            bool isFound = factory.RuntimeFunctionsGCInfo.Deduplicator.TryGetValue(this, out var found);

            if (isFound && (found != this))
            {
                return;
            }

            factory.RuntimeFunctionsGCInfo.Deduplicator.Add(this);

            foreach (var item in EncodeDataCore(factory))
            {
                if (item.Bytes != null)
                {
                    dataBuilder.EmitBytes(item.Bytes);
                    // Maintain 4-alignment for the next unwind / GC info block
                    int align4Pad = -item.Bytes.Length & 3;
                    dataBuilder.EmitZeros(align4Pad);
                }
                else
                {
                    dataBuilder.EmitReloc(item.Symbol, RelocType.IMAGE_REL_BASED_ADDR32NB, item.SymbolDelta);
                }
            }
        }
Example #3
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);
                }
            }
        }
Example #4
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();
            builder.AddSymbol(this);

            // Emit empty entry. This will be filled with data after the output image is emitted
            builder.EmitZeros(RSDSSize);

            return(builder.ToObjectData());
        }