xref: /trueos/crypto/openssl/crypto/armcap.c (revision ec48a408d4146ab830a7014b201c3f723e0fbf92)
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;
ill_handler(int sig)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 void _armv7_neon_probe(void);
25 unsigned int _armv7_tick(void);
26 
OPENSSL_rdtsc(void)27 unsigned 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
36 void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
37 #endif
OPENSSL_cpuid_setup(void)38 void 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