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 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); } } }
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); } } }
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()); }