Kyle McMartin cb06961
diff --git a/crypto/armcap.c b/crypto/armcap.c
Kyle McMartin cb06961
index 5258d2f..efb4009 100644
Kyle McMartin cb06961
--- a/crypto/armcap.c
Kyle McMartin cb06961
+++ b/crypto/armcap.c
Kyle McMartin cb06961
@@ -9,11 +9,6 @@
Kyle McMartin cb06961
 
Kyle McMartin cb06961
 unsigned int OPENSSL_armcap_P;
Kyle McMartin cb06961
 
Kyle McMartin cb06961
-static sigset_t all_masked;
Kyle McMartin cb06961
-
Kyle McMartin cb06961
-static sigjmp_buf ill_jmp;
Kyle McMartin cb06961
-static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
Kyle McMartin cb06961
-
Kyle McMartin cb06961
 /*
Kyle McMartin cb06961
  * Following subroutines could have been inlined, but it's not all
Kyle McMartin cb06961
  * ARM compilers support inline assembler...
Kyle McMartin cb06961
@@ -29,24 +24,26 @@ unsigned int OPENSSL_rdtsc(void)
Kyle McMartin cb06961
 		return 0;
Kyle McMartin cb06961
 	}
Kyle McMartin cb06961
 
Kyle McMartin cb06961
-#if defined(__GNUC__) && __GNUC__>=2
Kyle McMartin cb06961
-void OPENSSL_cpuid_setup(void) __attribute__((constructor));
Kyle McMartin cb06961
-#endif
Kyle McMartin cb06961
-void OPENSSL_cpuid_setup(void)
Kyle McMartin cb06961
+#if defined(__GLIBC__) && __GLIBC__>=2 && __GLIBC_MINOR__>=16
Kyle McMartin cb06961
+#include <sys/auxv.h>
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+void OPENSSL_cpuid_find(void)
Kyle McMartin cb06961
+	{
Kyle McMartin cb06961
+		unsigned long hwcap = getauxval(AT_HWCAP);
Kyle McMartin cb06961
+		char *plat = (char *)getauxval(AT_PLATFORM);
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+		OPENSSL_armcap_P |= hwcap & HWCAP_ARM_NEON ? ARMV7_NEON : 0;
Kyle McMartin cb06961
+		OPENSSL_armcap_P |= plat ? (plat[1] == '7' ? ARMV7_TICK : 0) : 0;
Kyle McMartin cb06961
+	}
Kyle McMartin cb06961
+#else
Kyle McMartin cb06961
+static sigset_t all_masked;
Kyle McMartin cb06961
+static sigjmp_buf ill_jmp;
Kyle McMartin cb06961
+static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+void OPENSSL_cpuid_find(void)
Kyle McMartin cb06961
 	{
Kyle McMartin cb06961
-	char *e;
Kyle McMartin cb06961
 	struct sigaction	ill_oact,ill_act;
Kyle McMartin cb06961
 	sigset_t		oset;
Kyle McMartin cb06961
-	static int trigger=0;
Kyle McMartin cb06961
-
Kyle McMartin cb06961
-	if (trigger) return;
Kyle McMartin cb06961
-	trigger=1;
Kyle McMartin cb06961
- 
Kyle McMartin cb06961
-	if ((e=getenv("OPENSSL_armcap")))
Kyle McMartin cb06961
-		{
Kyle McMartin cb06961
-		OPENSSL_armcap_P=strtoul(e,NULL,0);
Kyle McMartin cb06961
-		return;
Kyle McMartin cb06961
-		}
Kyle McMartin cb06961
 
Kyle McMartin cb06961
 	sigfillset(&all_masked);
Kyle McMartin cb06961
 	sigdelset(&all_masked,SIGILL);
Kyle McMartin cb06961
@@ -55,8 +52,6 @@ void OPENSSL_cpuid_setup(void)
Kyle McMartin cb06961
 	sigdelset(&all_masked,SIGBUS);
Kyle McMartin cb06961
 	sigdelset(&all_masked,SIGSEGV);
Kyle McMartin cb06961
 
Kyle McMartin cb06961
-	OPENSSL_armcap_P = 0;
Kyle McMartin cb06961
-
Kyle McMartin cb06961
 	memset(&ill_act,0,sizeof(ill_act));
Kyle McMartin cb06961
 	ill_act.sa_handler = ill_handler;
Kyle McMartin cb06961
 	ill_act.sa_mask    = all_masked;
Kyle McMartin cb06961
@@ -78,3 +73,25 @@ void OPENSSL_cpuid_setup(void)
Kyle McMartin cb06961
 	sigaction (SIGILL,&ill_oact,NULL);
Kyle McMartin cb06961
 	sigprocmask(SIG_SETMASK,&oset,NULL);
Kyle McMartin cb06961
 	}
Kyle McMartin cb06961
+#endif
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+#if defined(__GNUC__) && __GNUC__>=2
Kyle McMartin cb06961
+void OPENSSL_cpuid_setup(void) __attribute__((constructor));
Kyle McMartin cb06961
+#endif
Kyle McMartin cb06961
+void OPENSSL_cpuid_setup(void)
Kyle McMartin cb06961
+	{
Kyle McMartin cb06961
+	char *e;
Kyle McMartin cb06961
+	static int trigger=0;
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+	if (trigger) return;
Kyle McMartin cb06961
+	trigger=1;
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+	if ((e=getenv("OPENSSL_armcap")))
Kyle McMartin cb06961
+		{
Kyle McMartin cb06961
+		OPENSSL_armcap_P=strtoul(e,NULL,0);
Kyle McMartin cb06961
+		return;
Kyle McMartin cb06961
+		}
Kyle McMartin cb06961
+
Kyle McMartin cb06961
+	OPENSSL_armcap_P = 0;
Kyle McMartin cb06961
+	OPENSSL_cpuid_find();
Kyle McMartin cb06961
+	}