xref: /openbsd/regress/sys/btcfi/foobar.c (revision 0ecb11e1)
1 /* Public domain */
2 
3 #include <signal.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 extern void foo(void);
9 void (*foobar)(void) = foo;
10 
11 void
bar(void)12 bar(void)
13 {
14 	foobar();
15 }
16 
17 void
handler(int sig,siginfo_t * si,void * context)18 handler(int sig, siginfo_t *si, void *context)
19 {
20 	if (si->si_signo == SIGILL && si->si_code == ILL_BTCFI)
21 		exit(0);
22 }
23 
24 #if defined(__amd64__)
25 
26 static int
has_btcfi(void)27 has_btcfi(void)
28 {
29 	uint32_t d;
30 
31 	asm("cpuid" : "=d" (d) : "a" (7), "c" (0));
32 	return (d & (1U << 20)) ? 1 : 0;
33 }
34 
35 #elif defined(__aarch64__)
36 
37 #include <sys/types.h>
38 #include <sys/sysctl.h>
39 
40 #include <machine/armreg.h>
41 #include <machine/cpu.h>
42 
43 static int
has_btcfi(void)44 has_btcfi(void)
45 {
46 	int mib[] = { CTL_MACHDEP, CPU_ID_AA64PFR1 };
47 	uint64_t id_aa64pfr1 = 0;
48 	size_t size = sizeof(id_aa64pfr1);
49 
50 	sysctl(mib, 2, &id_aa64pfr1, &size, NULL, 0);
51 	return ID_AA64PFR1_BT(id_aa64pfr1) >= ID_AA64PFR1_BT_IMPL;
52 }
53 
54 #else
55 
56 static int
has_btcfi(void)57 has_btcfi(void)
58 {
59 	return 0;
60 }
61 
62 #endif
63 
64 int
main(void)65 main(void)
66 {
67 	struct sigaction sa;
68 
69 	if (!has_btcfi()) {
70 		printf("Unsupported CPU\n");
71 		printf("SKIPPED\n");
72 		exit(0);
73 	}
74 
75 	sa.sa_sigaction = handler;
76 	sa.sa_mask = 0;
77 	sa.sa_flags = SA_SIGINFO;
78 	sigaction(SIGILL, &sa, NULL);
79 
80 	bar();
81 	exit(1);
82 }
83