1/* Public domain */
2
3#include <signal.h>
4#include <stdint.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8extern void foo(void);
9void (*foobar)(void) = foo;
10
11void
12bar(void)
13{
14	foobar();
15}
16
17void
18handler(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__)
25static int
26has_cet_ibt(void)
27{
28	uint32_t d;
29
30	asm("cpuid" : "=d" (d) : "a" (7), "c" (0));
31	return (d & (1U << 20)) ? 1 : 0;
32}
33#endif
34
35int
36main(void)
37{
38	struct sigaction sa;
39
40#if defined(__amd64__)
41	if (!has_cet_ibt()) {
42		printf("Unsupported CPU\n");
43		printf("SKIPPED\n");
44		exit(0);
45	}
46#endif
47
48	sa.sa_sigaction = handler;
49	sa.sa_mask = 0;
50	sa.sa_flags = SA_SIGINFO;
51	sigaction(SIGILL, &sa, NULL);
52
53	bar();
54	exit(1);
55}
56