1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <setjmp.h> 5 #include <signal.h> 6 #include <crypto.h> 7 8 #include "arm_arch.h" 9 10 unsigned int OPENSSL_armcap_P; 11 12 static sigset_t all_masked; 13 14 static sigjmp_buf ill_jmp; 15 static void ill_handler(int sig) 16 { 17 siglongjmp(ill_jmp, sig); 18 } 19 20 /* 21 * Following subroutines could have been inlined, but it's not all 22 * ARM compilers support inline assembler... 23 */ 24 #if __ARM_MAX_ARCH__>=7 25 void _armv7_neon_probe(void); 26 unsigned int _armv7_tick(void); 27 #endif 28 29 unsigned int OPENSSL_rdtsc(void) 30 { 31 #if __ARM_MAX_ARCH__>=7 32 if (OPENSSL_armcap_P & ARMV7_TICK) 33 return _armv7_tick(); 34 else 35 #endif 36 return 0; 37 } 38 39 #if defined(__GNUC__) && __GNUC__>=2 40 void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); 41 #endif 42 void OPENSSL_cpuid_setup(void) 43 { 44 char *e; 45 struct sigaction ill_oact, ill_act; 46 sigset_t oset; 47 static int trigger = 0; 48 49 if (trigger) 50 return; 51 trigger = 1; 52 53 if ((e = getenv("OPENSSL_armcap"))) { 54 OPENSSL_armcap_P = strtoul(e, NULL, 0); 55 return; 56 } 57 58 sigfillset(&all_masked); 59 sigdelset(&all_masked, SIGILL); 60 sigdelset(&all_masked, SIGTRAP); 61 sigdelset(&all_masked, SIGFPE); 62 sigdelset(&all_masked, SIGBUS); 63 sigdelset(&all_masked, SIGSEGV); 64 65 OPENSSL_armcap_P = 0; 66 67 memset(&ill_act, 0, sizeof(ill_act)); 68 ill_act.sa_handler = ill_handler; 69 ill_act.sa_mask = all_masked; 70 71 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); 72 sigaction(SIGILL, &ill_act, &ill_oact); 73 74 #if __ARM_MAX_ARCH__>=7 75 if (sigsetjmp(ill_jmp, 1) == 0) { 76 _armv7_neon_probe(); 77 OPENSSL_armcap_P |= ARMV7_NEON; 78 } 79 if (sigsetjmp(ill_jmp, 1) == 0) { 80 _armv7_tick(); 81 OPENSSL_armcap_P |= ARMV7_TICK; 82 } 83 #endif 84 85 sigaction(SIGILL, &ill_oact, NULL); 86 sigprocmask(SIG_SETMASK, &oset, NULL); 87 } 88