[arm] Correctly detect hardware features when running as arm32 on arm64 hardware.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Wed, 8 Jun 2016 14:21:13 +0000 (16:21 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Thu, 9 Jun 2016 05:22:57 +0000 (07:22 +0200)
mono/utils/mono-hwcap-arm.c

index 6cf8065d06a43e421bfb59737800ff73536d3f86..d5621323f9f64289ae8e3396cb5f7aaf99f48d23 100644 (file)
@@ -28,6 +28,9 @@
 #include <sys/sysctl.h>
 #include <sys/types.h>
 #else
+#if defined (HAVE_SYS_UTSNAME_H)
+#include <sys/utsname.h>
+#endif
 #include <stdio.h>
 #endif
 
@@ -105,6 +108,50 @@ mono_hwcap_arch_init (void)
         * hit this path if the target doesn't have sys/auxv.h.
         */
 
+#if defined (HAVE_SYS_UTSNAME_H)
+       struct utsname name;
+
+       /* Only fails if `name` is invalid (it isn't). */
+       g_assert (!uname (&name));
+
+       if (!strncmp (name.machine, "aarch64", 7) || !strncmp (name.machine, "armv8", 5)) {
+               /*
+                * We're a 32-bit program running on an ARMv8 system.
+                * Whether the system is actually 32-bit or 64-bit
+                * doesn't matter to us. The important thing is that
+                * all 3 of ARMv8's execution states (A64, A32, T32)
+                * are guaranteed to have all of the features that
+                * we want to detect and use.
+                *
+                * We do this ARMv8 detection via uname () because
+                * in the early days of ARMv8 on Linux, the
+                * /proc/cpuinfo format was a disaster and there
+                * were multiple (merged into mainline) attempts at
+                * cleaning it up (read: breaking applications that
+                * tried to rely on it). So now multiple ARMv8
+                * systems in the wild have different /proc/cpuinfo
+                * output, some of which are downright useless.
+                *
+                * So, when it comes to detecting ARMv8 in a 32-bit
+                * program, it's better to just avoid /proc/cpuinfo
+                * entirely. Maybe in a decade or two, we won't
+                * have to worry about this mess that the Linux ARM
+                * maintainers created. One can hope.
+                */
+
+               mono_hwcap_arm_is_v5 = TRUE;
+               mono_hwcap_arm_is_v6 = TRUE;
+               mono_hwcap_arm_is_v7 = TRUE;
+
+               mono_hwcap_arm_has_vfp = TRUE;
+               mono_hwcap_arm_has_vfp3 = TRUE;
+               mono_hwcap_arm_has_vfp3_d16 = TRUE;
+
+               mono_hwcap_arm_has_thumb = TRUE;
+               mono_hwcap_arm_has_thumb2 = TRUE;
+       }
+#endif
+
        char buf [512];
        char *line;