base/dispatch.c, etc.: Replace inline assembler for the `rdrand' fix.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 29 Oct 2019 18:59:32 +0000 (18:59 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 16 Dec 2019 17:33:02 +0000 (17:33 +0000)
base/dispatch-x86ish.S
base/dispatch.c
debian/catacomb2.symbols

index 2c267b6..3e2d4c8 100644 (file)
@@ -153,4 +153,47 @@ FUNC(dispatch_x86ish_xmmregisters_p)
        ret
 ENDFUNC
 
+///--------------------------------------------------------------------------
+/// Checking `rdrand'.
+
+FUNC(dispatch_x86ish_rdrand)
+       // Enter with one argument: a pointer X_OUT to a 32-bit word.  Try to
+       // generate a random word using `rdrand'.  If successful, set *X_OUT
+       // to the generated word, and return zero; otherwise, return -1.
+
+#if CPUFAM_X86
+#  define X_OUT edx
+#  define COUNT ecx
+       mov     X_OUT, [SP + 4]
+#endif
+#if CPUFAM_AMD64 && ABI_SYSV
+#  define X_OUT rdi
+#  define COUNT ecx
+#endif
+#if CPUFAM_AMD64 && ABI_WIN
+#  define X_OUT rcx
+#  define COUNT edx
+#endif
+  endprologue
+
+       mov     COUNT, 16               // fairly persistent
+0:     rdrand  eax
+       jc      9f
+       dec     COUNT
+       jnz     0b
+
+       // Failed to come up with a random value.
+       mov     eax, -1
+       ret
+
+       // Success.
+9:     mov     [X_OUT], eax
+       xor     eax, eax
+       ret
+
+#undef X_OUT
+#undef COUNT
+
+ENDFUNC
+
 ///----- That's all, folks --------------------------------------------------
index 459302f..65ea2d2 100644 (file)
@@ -54,6 +54,7 @@
 struct cpuid { unsigned a, b, c, d; };
 extern int dispatch_x86ish_cpuid(struct cpuid *, unsigned a, unsigned c);
 extern int dispatch_x86ish_xmmregisters_p(void);
+extern int dispatch_x86ish_rdrand(unsigned *);
 
 static void cpuid(struct cpuid *cc, unsigned a, unsigned c)
 {
@@ -110,25 +111,6 @@ static int xmm_registers_available_p(void)
  *             that it's already been verified to be safe to issue.
  */
 
-#ifdef __GNUC__
-static int rdrand(unsigned *x)
-{
-  int i, rc;
-  unsigned _t;
-
-  i = 16;
-  __asm__ ("" : "=g" (_t));
-  __asm__ ("0: rdrand %2; jc 1f; decl %1; jnz 0b\n"
-          "mov $-1, %0; jmp 9f\n"
-          "1: movl %2, (%3); xorl %0, %0\n"
-          "9:"
-          : "=r" (rc), "+r" (i), "+r" (_t)
-          : "r" (x)
-          : "cc");
-  return (rc);
-}
-#endif
-
 static int rdrand_works_p(void)
 {
   unsigned ref, x, i;
@@ -137,9 +119,9 @@ static int rdrand_works_p(void)
    * will fail with probability %$2^{-128}$% with a truly random generator,
    * which seems fair enough.
    */
-  if (rdrand(&ref)) goto fail;
+  if (dispatch_x86ish_rdrand(&ref)) goto fail;
   for (i = 0; i < 4; i++) {
-    if (rdrand(&x)) goto fail;
+    if (dispatch_x86ish_rdrand(&x)) goto fail;
     if (x != ref) goto not_stuck;
   }
   dispatch_debug("RDRAND always returns 0x%08x!", ref);
index 772d218..33d5915 100644 (file)
@@ -24,6 +24,7 @@ libcatacomb.so.2 catacomb2 #MINVER#
        cpu_feature_p@Base 2.2.3
        dispatch_debug@Base 2.2.3
        (optional|arch=i386 amd64)dispatch_x86ish_cpuid@Base 2.5.0
+       (optional|arch=i386 amd64)dispatch_x86ish_rdrand@Base 2.5.99~
        (optional|arch=i386 amd64)dispatch_x86ish_xmmregisters_p@Base 2.5.0
 
 ## regdump (available with `--enable-asm-debug')