Crossgen2: set 'X' bit in unwind info for ARM (#32346)
authorAnton Lapounov <antonl@microsoft.com>
Sat, 15 Feb 2020 06:41:29 +0000 (22:41 -0800)
committerGitHub <noreply@github.com>
Sat, 15 Feb 2020 06:41:29 +0000 (22:41 -0800)
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs

index 9b170b2..e9c6309 100644 (file)
@@ -2,9 +2,9 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-using System;
 using System.Collections.Generic;
 using Internal.Text;
+using Internal.TypeSystem;
 
 namespace ILCompiler.DependencyAnalysis.ReadyToRun
 {
@@ -41,7 +41,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                 offsets[frameInfoIndex] = offset;
                 offset += _methodNode.FrameInfos[frameInfoIndex].BlobData.Length;
                 offset += (-offset & 3); // 4-alignment for the personality routine
-                if (factory.Target.Architecture != Internal.TypeSystem.TargetArchitecture.X86)
+                if (factory.Target.Architecture != TargetArchitecture.X86)
                 {
                     offset += sizeof(uint); // personality routine
                 }
@@ -60,11 +60,14 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             {
                 return;
             }
+
+            TargetArchitecture targetArch = factory.Target.Architecture;
+
             for (int frameInfoIndex = 0; frameInfoIndex < _methodNode.FrameInfos.Length; frameInfoIndex++)
             {
                 byte[] unwindInfo = _methodNode.FrameInfos[frameInfoIndex].BlobData;
 
-                if (factory.Target.Architecture == Internal.TypeSystem.TargetArchitecture.X64)
+                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).
@@ -74,12 +77,17 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
 
                     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 (factory.Target.Architecture != Internal.TypeSystem.TargetArchitecture.X86)
+                if (targetArch != TargetArchitecture.X86)
                 {
                     bool isFilterFunclet = (_methodNode.FrameInfos[frameInfoIndex].Flags & FrameInfoFlags.Filter) != 0;
                     ISymbolNode personalityRoutine = (isFilterFunclet ? factory.FilterFuncletPersonalityRoutine : factory.PersonalityRoutine);