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