1*afc5ab87SWarner Losh /*- 2*afc5ab87SWarner Losh * Copyright (c) 2021 Warner Losh <imp@bsdimp.com> 3*afc5ab87SWarner Losh * 4*afc5ab87SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 5*afc5ab87SWarner Losh */ 6*afc5ab87SWarner Losh 7*afc5ab87SWarner Losh #include <atf-c.h> 8*afc5ab87SWarner Losh #include <errno.h> 9*afc5ab87SWarner Losh #include <signal.h> 10*afc5ab87SWarner Losh #include <stdbool.h> 11*afc5ab87SWarner Losh #include <stdlib.h> 12*afc5ab87SWarner Losh 13*afc5ab87SWarner Losh static volatile sig_atomic_t signal_fired = 0; 14*afc5ab87SWarner Losh 15*afc5ab87SWarner Losh static void 16*afc5ab87SWarner Losh sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused) 17*afc5ab87SWarner Losh { 18*afc5ab87SWarner Losh signal_fired++; 19*afc5ab87SWarner Losh } 20*afc5ab87SWarner Losh 21*afc5ab87SWarner Losh ATF_TC(signal_test); 22*afc5ab87SWarner Losh 23*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test, tc) 24*afc5ab87SWarner Losh { 25*afc5ab87SWarner Losh 26*afc5ab87SWarner Losh atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal"); 27*afc5ab87SWarner Losh } 28*afc5ab87SWarner Losh 29*afc5ab87SWarner Losh ATF_TC_BODY(signal_test, tc) 30*afc5ab87SWarner Losh { 31*afc5ab87SWarner Losh /* 32*afc5ab87SWarner Losh * Setup the signal handlers 33*afc5ab87SWarner Losh */ 34*afc5ab87SWarner Losh struct sigaction sa = { 35*afc5ab87SWarner Losh .sa_sigaction = sig_handler, 36*afc5ab87SWarner Losh .sa_flags = SA_SIGINFO, 37*afc5ab87SWarner Losh }; 38*afc5ab87SWarner Losh ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); 39*afc5ab87SWarner Losh ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); 40*afc5ab87SWarner Losh ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0); 41*afc5ab87SWarner Losh ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0); 42*afc5ab87SWarner Losh 43*afc5ab87SWarner Losh /* 44*afc5ab87SWarner Losh * Fire SIGUSR1 45*afc5ab87SWarner Losh */ 46*afc5ab87SWarner Losh ATF_CHECK(signal_fired == 0); 47*afc5ab87SWarner Losh ATF_REQUIRE(raise(SIGUSR1) == 0); 48*afc5ab87SWarner Losh ATF_CHECK(signal_fired == 1); 49*afc5ab87SWarner Losh 50*afc5ab87SWarner Losh /* 51*afc5ab87SWarner Losh * Fire SIGUSR2 52*afc5ab87SWarner Losh */ 53*afc5ab87SWarner Losh ATF_REQUIRE(raise(SIGUSR2) == 0); 54*afc5ab87SWarner Losh ATF_CHECK(signal_fired == 2); 55*afc5ab87SWarner Losh 56*afc5ab87SWarner Losh /* 57*afc5ab87SWarner Losh * Fire SIGALRM after a timeout 58*afc5ab87SWarner Losh */ 59*afc5ab87SWarner Losh ATF_REQUIRE(alarm(1) == 0); 60*afc5ab87SWarner Losh ATF_REQUIRE(pause() == -1); 61*afc5ab87SWarner Losh ATF_REQUIRE(errno == EINTR); 62*afc5ab87SWarner Losh ATF_CHECK(signal_fired == 3); 63*afc5ab87SWarner Losh } 64*afc5ab87SWarner Losh 65*afc5ab87SWarner Losh /* 66*afc5ab87SWarner Losh * Special tests for 32-bit arm. We can call thumb code (really just t32) from 67*afc5ab87SWarner Losh * normal (a32) mode and vice versa. Likewise, signals can interrupt a T32 68*afc5ab87SWarner Losh * context with A32 code and vice versa. Make sure these all work with a simple 69*afc5ab87SWarner Losh * test that raises the signal and ensures that it executed. No other platform 70*afc5ab87SWarner Losh * has these requirements. Also note: we only support thumb2, so there's no T16 71*afc5ab87SWarner Losh * vs T32 issues we have to test for. 72*afc5ab87SWarner Losh */ 73*afc5ab87SWarner Losh #ifdef __arm__ 74*afc5ab87SWarner Losh 75*afc5ab87SWarner Losh #define a32_isa __attribute__((target("arm"))) 76*afc5ab87SWarner Losh #define t32_isa __attribute__((target("thumb"))) 77*afc5ab87SWarner Losh 78*afc5ab87SWarner Losh static volatile sig_atomic_t t32_fired = 0; 79*afc5ab87SWarner Losh static volatile sig_atomic_t a32_fired = 0; 80*afc5ab87SWarner Losh 81*afc5ab87SWarner Losh a32_isa static void 82*afc5ab87SWarner Losh sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused) 83*afc5ab87SWarner Losh { 84*afc5ab87SWarner Losh a32_fired++; 85*afc5ab87SWarner Losh } 86*afc5ab87SWarner Losh 87*afc5ab87SWarner Losh t32_isa static void 88*afc5ab87SWarner Losh sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused) 89*afc5ab87SWarner Losh { 90*afc5ab87SWarner Losh t32_fired++; 91*afc5ab87SWarner Losh } 92*afc5ab87SWarner Losh 93*afc5ab87SWarner Losh 94*afc5ab87SWarner Losh ATF_TC(signal_test_T32_to_A32); 95*afc5ab87SWarner Losh 96*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test_T32_to_A32, tc) 97*afc5ab87SWarner Losh { 98*afc5ab87SWarner Losh 99*afc5ab87SWarner Losh atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32"); 100*afc5ab87SWarner Losh } 101*afc5ab87SWarner Losh 102*afc5ab87SWarner Losh t32_isa ATF_TC_BODY(signal_test_T32_to_A32, tc) 103*afc5ab87SWarner Losh { 104*afc5ab87SWarner Losh /* 105*afc5ab87SWarner Losh * Setup the signal handlers 106*afc5ab87SWarner Losh */ 107*afc5ab87SWarner Losh struct sigaction sa = { 108*afc5ab87SWarner Losh .sa_sigaction = sig_a32, 109*afc5ab87SWarner Losh .sa_flags = SA_SIGINFO, 110*afc5ab87SWarner Losh }; 111*afc5ab87SWarner Losh ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); 112*afc5ab87SWarner Losh ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); 113*afc5ab87SWarner Losh 114*afc5ab87SWarner Losh ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); /* Make sure compiled as not thumb */ 115*afc5ab87SWarner Losh 116*afc5ab87SWarner Losh ATF_CHECK(a32_fired == 0); 117*afc5ab87SWarner Losh ATF_REQUIRE(raise(SIGUSR1) == 0); 118*afc5ab87SWarner Losh ATF_CHECK(a32_fired == 1); 119*afc5ab87SWarner Losh } 120*afc5ab87SWarner Losh 121*afc5ab87SWarner Losh ATF_TC(signal_test_A32_to_T32); 122*afc5ab87SWarner Losh 123*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test_A32_to_T32, tc) 124*afc5ab87SWarner Losh { 125*afc5ab87SWarner Losh 126*afc5ab87SWarner Losh atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32"); 127*afc5ab87SWarner Losh } 128*afc5ab87SWarner Losh 129*afc5ab87SWarner Losh a32_isa ATF_TC_BODY(signal_test_A32_to_T32, tc) 130*afc5ab87SWarner Losh { 131*afc5ab87SWarner Losh /* 132*afc5ab87SWarner Losh * Setup the signal handlers 133*afc5ab87SWarner Losh */ 134*afc5ab87SWarner Losh struct sigaction sa = { 135*afc5ab87SWarner Losh .sa_sigaction = sig_t32, 136*afc5ab87SWarner Losh .sa_flags = SA_SIGINFO, 137*afc5ab87SWarner Losh }; 138*afc5ab87SWarner Losh ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); 139*afc5ab87SWarner Losh ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); 140*afc5ab87SWarner Losh 141*afc5ab87SWarner Losh ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1); /* Make sure compiled as thumb */ 142*afc5ab87SWarner Losh 143*afc5ab87SWarner Losh ATF_CHECK(t32_fired == 0); 144*afc5ab87SWarner Losh ATF_REQUIRE(raise(SIGUSR1) == 0); 145*afc5ab87SWarner Losh ATF_CHECK(t32_fired == 1); 146*afc5ab87SWarner Losh } 147*afc5ab87SWarner Losh #endif 148*afc5ab87SWarner Losh 149*afc5ab87SWarner Losh ATF_TP_ADD_TCS(tp) 150*afc5ab87SWarner Losh { 151*afc5ab87SWarner Losh 152*afc5ab87SWarner Losh ATF_TP_ADD_TC(tp, signal_test); 153*afc5ab87SWarner Losh #ifdef __arm__ 154*afc5ab87SWarner Losh ATF_TP_ADD_TC(tp, signal_test_T32_to_A32); 155*afc5ab87SWarner Losh ATF_TP_ADD_TC(tp, signal_test_A32_to_T32); 156*afc5ab87SWarner Losh #endif 157*afc5ab87SWarner Losh 158*afc5ab87SWarner Losh return (atf_no_error()); 159*afc5ab87SWarner Losh } 160