base/dispatch.c: Add notional support for `AT_HWCAP2' entry.
[catacomb] / base / dispatch.c
index 1b0ab2b..875c126 100644 (file)
@@ -47,6 +47,7 @@
 #  define CPUID1D_SSE2 (1u << 26)
 #  define CPUID1D_FXSR (1u << 24)
 #  define CPUID1C_AESNI (1u << 25)
+#  define CPUID1C_RDRAND (1u << 30)
 
 struct cpuid { unsigned a, b, c, d; };
 
@@ -204,13 +205,12 @@ static int xmm_registers_available_p(void)
 /* Try to find the system's definitions for auxiliary vector entries. */
 #ifdef HAVE_SYS_AUXV_H
 #  include <sys/auxv.h>
-#else
-#  ifdef HAVE_LINUX_AUXVEC_H
-#    include <linux/auxvec.h>
-#  endif
-#  ifdef HAVE_ASM_HWCAP_H
-#    include <asm/hwcap.h>
-#  endif
+#endif
+#ifdef HAVE_LINUX_AUXVEC_H
+#  include <linux/auxvec.h>
+#endif
+#ifdef HAVE_ASM_HWCAP_H
+#  include <asm/hwcap.h>
 #endif
 
 /* The type of entries in the auxiliary vector.  I'm assuming that `unsigned
@@ -246,6 +246,9 @@ static unsigned hwcaps = 0;
 #ifndef WANT_AT_HWCAP
 #  define WANT_AT_HWCAP(_)
 #endif
+#ifndef WANT_AT_HWCAP2
+#  define WANT_AT_HWCAP2(_)
+#endif
 
 /* For each CPU family, define two lists.
  *
@@ -319,8 +322,8 @@ static void probe_hwcaps(void)
   /* Shiny new libc lets us request individual entry types.  This is almost
    * too easy.
    */
-#  define CAP__GET(type, slot, ubranch)                                        \
-       probed.slot.ubranch = (AUXUTYPE_##ubranch)getauxval(type);
+#  define CAP__GET(type, ubranch, slot)                                        \
+       probed.slot = (AUXUTYPE_##ubranch)getauxval(type);
   WANTAUX(CAP__GET)
 #else
   /* Otherwise we're a bit stuck, really.  Modern Linux kernels make a copy
@@ -359,6 +362,7 @@ static void probe_hwcaps(void)
 #define CAP__SWITCH(type, ubranch, slot)                               \
        case type: probed.slot = a->value.ubranch; break;
        WANTAUX(CAP__SWITCH)
+       case AT_NULL: goto clean;
       }
     }
 
@@ -515,10 +519,12 @@ int cpu_feature_p(int feat)
     CASE_CPUFEAT(X86_AESNI, "x86:aesni",
                 xmm_registers_available_p() &&
                 cpuid_features_p(CPUID1D_SSE2, CPUID1C_AESNI));
+    CASE_CPUFEAT(X86_RDRAND, "x86:rdrand",
+                cpuid_features_p(0, CPUID1C_RDRAND));
 #endif
 #ifdef CAPMAP
 #  define FEATP__CASE(feat, tok)                                       \
-       CASE_CPUFEAT(feat, tok, get_hwcaps & HF_##feat)
+       CASE_CPUFEAT(feat, tok, get_hwcaps() & HF_##feat)
     CAPMAP(FEATP__CASE)
 #undef FEATP__CASE
 #endif