2 * Copyright (c) 2021 M. Warner Losh <imp@FreeBSD.org>
4 * SPDX-License-Identifier: BSD-2-Clause
13 #if defined(__aarch64__)
14 #include <machine/armreg.h>
15 #define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_gpregs.gp_spsr |= PSR_SS
16 #define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_gpregs.gp_spsr &= ~PSR_SS
17 #elif defined(__amd64__)
18 #include <machine/psl.h>
19 #define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_rflags |= PSL_T
20 #define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_rflags &= ~PSL_T
21 #elif defined(__i386__)
22 #include <machine/psl.h>
23 #define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags |= PSL_T
24 #define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags &= ~PSL_T
27 static volatile sig_atomic_t signal_fired = 0;
30 sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused)
37 ATF_TC_HEAD(signal_test, tc)
40 atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal");
43 ATF_TC_BODY(signal_test, tc)
46 * Setup the signal handlers
48 struct sigaction sa = {
49 .sa_sigaction = sig_handler,
50 .sa_flags = SA_SIGINFO,
52 ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
53 ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
54 ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0);
55 ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0);
60 ATF_CHECK(signal_fired == 0);
61 ATF_REQUIRE(raise(SIGUSR1) == 0);
62 ATF_CHECK(signal_fired == 1);
67 ATF_REQUIRE(raise(SIGUSR2) == 0);
68 ATF_CHECK(signal_fired == 2);
71 * Fire SIGALRM after a timeout
73 ATF_REQUIRE(alarm(1) == 0);
74 ATF_REQUIRE(pause() == -1);
75 ATF_REQUIRE(errno == EINTR);
76 ATF_CHECK(signal_fired == 3);
80 * Check setting the machine dependent single step flag works when supported.
83 static volatile sig_atomic_t trap_signal_fired = 0;
86 trap_sig_handler(int signo, siginfo_t *info __unused, void *_ucp)
88 ucontext_t *ucp = _ucp;
90 if (trap_signal_fired < 9) {
98 ATF_TC(trap_signal_test);
100 ATF_TC_HEAD(trap_signal_test, tc)
103 atf_tc_set_md_var(tc, "descr",
104 "Testing signal handler setting the MD single step flag");
107 ATF_TC_BODY(trap_signal_test, tc)
110 * Setup the signal handlers
112 struct sigaction sa = {
113 .sa_sigaction = trap_sig_handler,
114 .sa_flags = SA_SIGINFO,
116 ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
117 ATF_REQUIRE(sigaction(SIGTRAP, &sa, NULL) == 0);
122 ATF_CHECK(trap_signal_fired == 0);
123 ATF_REQUIRE(raise(SIGTRAP) == 0);
124 ATF_CHECK(trap_signal_fired == 10);
129 * Special tests for 32-bit arm. We can call thumb code (really just t32) from
130 * normal (a32) mode and vice versa. Likewise, signals can interrupt a T32
131 * context with A32 code and vice versa. Make sure these all work with a simple
132 * test that raises the signal and ensures that it executed. No other platform
133 * has these requirements. Also note: we only support thumb2, so there's no T16
134 * vs T32 issues we have to test for.
138 #define a32_isa __attribute__((target("arm")))
139 #define t32_isa __attribute__((target("thumb")))
141 static volatile sig_atomic_t t32_fired = 0;
142 static volatile sig_atomic_t a32_fired = 0;
145 sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused)
151 sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused)
157 ATF_TC(signal_test_T32_to_A32);
159 ATF_TC_HEAD(signal_test_T32_to_A32, tc)
162 atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32");
165 t32_isa ATF_TC_BODY(signal_test_T32_to_A32, tc)
168 * Setup the signal handlers
170 struct sigaction sa = {
171 .sa_sigaction = sig_a32,
172 .sa_flags = SA_SIGINFO,
174 ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
175 ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
177 ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); /* Make sure compiled as not thumb */
179 ATF_CHECK(a32_fired == 0);
180 ATF_REQUIRE(raise(SIGUSR1) == 0);
181 ATF_CHECK(a32_fired == 1);
184 ATF_TC(signal_test_A32_to_T32);
186 ATF_TC_HEAD(signal_test_A32_to_T32, tc)
189 atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32");
192 a32_isa ATF_TC_BODY(signal_test_A32_to_T32, tc)
195 * Setup the signal handlers
197 struct sigaction sa = {
198 .sa_sigaction = sig_t32,
199 .sa_flags = SA_SIGINFO,
201 ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
202 ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
204 ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1); /* Make sure compiled as thumb */
206 ATF_CHECK(t32_fired == 0);
207 ATF_REQUIRE(raise(SIGUSR1) == 0);
208 ATF_CHECK(t32_fired == 1);
215 ATF_TP_ADD_TC(tp, signal_test);
216 #ifdef SET_TRACE_FLAG
217 ATF_TP_ADD_TC(tp, trap_signal_test);
220 ATF_TP_ADD_TC(tp, signal_test_T32_to_A32);
221 ATF_TP_ADD_TC(tp, signal_test_A32_to_T32);
224 return (atf_no_error());