#include <sys/sysctl.h>
#include <sys/types.h>
#else
+#if defined (HAVE_SYS_UTSNAME_H)
+#include <sys/utsname.h>
+#endif
#include <stdio.h>
#endif
* 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;