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 10unsigned int OPENSSL_armcap_P; 11 12static sigset_t all_masked; 13 14static sigjmp_buf ill_jmp; 15static 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 */ 24void _armv7_neon_probe(void); 25unsigned int _armv7_tick(void); 26 27unsigned int OPENSSL_rdtsc(void) 28{ 29 if (OPENSSL_armcap_P & ARMV7_TICK) 30 return _armv7_tick(); 31 else 32 return 0; 33} 34 35#if defined(__GNUC__) && __GNUC__>=2 36void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); 37#endif 38void OPENSSL_cpuid_setup(void) 39{ 40 char *e; 41 struct sigaction ill_oact, ill_act; 42 sigset_t oset; 43 static int trigger = 0; 44 45 if (trigger) 46 return; 47 trigger = 1; 48 49 if ((e = getenv("OPENSSL_armcap"))) { 50 OPENSSL_armcap_P = strtoul(e, NULL, 0); 51 return; 52 } 53 54 sigfillset(&all_masked); 55 sigdelset(&all_masked, SIGILL); 56 sigdelset(&all_masked, SIGTRAP); 57 sigdelset(&all_masked, SIGFPE); 58 sigdelset(&all_masked, SIGBUS); 59 sigdelset(&all_masked, SIGSEGV); 60 61 OPENSSL_armcap_P = 0; 62 63 memset(&ill_act, 0, sizeof(ill_act)); 64 ill_act.sa_handler = ill_handler; 65 ill_act.sa_mask = all_masked; 66 67 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); 68 sigaction(SIGILL, &ill_act, &ill_oact); 69 70 if (sigsetjmp(ill_jmp, 1) == 0) { 71 _armv7_neon_probe(); 72 OPENSSL_armcap_P |= ARMV7_NEON; 73 } 74 if (sigsetjmp(ill_jmp, 1) == 0) { 75 _armv7_tick(); 76 OPENSSL_armcap_P |= ARMV7_TICK; 77 } 78 79 sigaction(SIGILL, &ill_oact, NULL); 80 sigprocmask(SIG_SETMASK, &oset, NULL); 81} 82