1*57718be8SEnji Cooper /* $NetBSD: t_siginfo.c,v 1.23 2014/02/09 21:26:07 jmmv Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /*- 4*57718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 9*57718be8SEnji Cooper * are met: 10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*57718be8SEnji Cooper * 16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 27*57718be8SEnji Cooper */ 28*57718be8SEnji Cooper 29*57718be8SEnji Cooper #include <atf-c.h> 30*57718be8SEnji Cooper #include <atf-c/config.h> 31*57718be8SEnji Cooper 32*57718be8SEnji Cooper #include <sys/inttypes.h> 33*57718be8SEnji Cooper #include <sys/resource.h> 34*57718be8SEnji Cooper #include <sys/sysctl.h> 35*57718be8SEnji Cooper #include <sys/time.h> 36*57718be8SEnji Cooper #include <sys/ucontext.h> 37*57718be8SEnji Cooper #include <sys/wait.h> 38*57718be8SEnji Cooper 39*57718be8SEnji Cooper #include <assert.h> 40*57718be8SEnji Cooper #include <signal.h> 41*57718be8SEnji Cooper #include <stdio.h> 42*57718be8SEnji Cooper #include <stdlib.h> 43*57718be8SEnji Cooper #include <string.h> 44*57718be8SEnji Cooper #include <unistd.h> 45*57718be8SEnji Cooper #include <setjmp.h> 46*57718be8SEnji Cooper #include <float.h> 47*57718be8SEnji Cooper 48*57718be8SEnji Cooper #ifdef HAVE_FENV 49*57718be8SEnji Cooper #include <fenv.h> 50*57718be8SEnji Cooper #elif defined(_FLOAT_IEEE754) 51*57718be8SEnji Cooper #include <ieeefp.h> 52*57718be8SEnji Cooper #endif 53*57718be8SEnji Cooper 54*57718be8SEnji Cooper #include "isqemu.h" 55*57718be8SEnji Cooper 56*57718be8SEnji Cooper /* for sigbus */ 57*57718be8SEnji Cooper volatile char *addr; 58*57718be8SEnji Cooper 59*57718be8SEnji Cooper /* for sigchild */ 60*57718be8SEnji Cooper pid_t child; 61*57718be8SEnji Cooper int code; 62*57718be8SEnji Cooper int status; 63*57718be8SEnji Cooper 64*57718be8SEnji Cooper /* for sigfpe */ 65*57718be8SEnji Cooper sig_atomic_t fltdiv_signalled = 0; 66*57718be8SEnji Cooper sig_atomic_t intdiv_signalled = 0; 67*57718be8SEnji Cooper 68*57718be8SEnji Cooper static void 69*57718be8SEnji Cooper sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) 70*57718be8SEnji Cooper { 71*57718be8SEnji Cooper unsigned int i; 72*57718be8SEnji Cooper 73*57718be8SEnji Cooper printf("%d %p %p\n", signo, info, ctx); 74*57718be8SEnji Cooper if (info != NULL) { 75*57718be8SEnji Cooper printf("si_signo=%d\n", info->si_signo); 76*57718be8SEnji Cooper printf("si_errno=%d\n", info->si_errno); 77*57718be8SEnji Cooper printf("si_code=%d\n", info->si_code); 78*57718be8SEnji Cooper printf("si_value.sival_int=%d\n", info->si_value.sival_int); 79*57718be8SEnji Cooper } 80*57718be8SEnji Cooper if (ctx != NULL) { 81*57718be8SEnji Cooper printf("uc_flags 0x%x\n", ctx->uc_flags); 82*57718be8SEnji Cooper printf("uc_link %p\n", ctx->uc_link); 83*57718be8SEnji Cooper for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++) 84*57718be8SEnji Cooper printf("uc_sigmask[%d] 0x%x\n", i, 85*57718be8SEnji Cooper ctx->uc_sigmask.__bits[i]); 86*57718be8SEnji Cooper printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, 87*57718be8SEnji Cooper (unsigned long)ctx->uc_stack.ss_size, 88*57718be8SEnji Cooper ctx->uc_stack.ss_flags); 89*57718be8SEnji Cooper for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) 90*57718be8SEnji Cooper printf("uc_mcontext.greg[%d] 0x%lx\n", i, 91*57718be8SEnji Cooper (long)ctx->uc_mcontext.__gregs[i]); 92*57718be8SEnji Cooper } 93*57718be8SEnji Cooper } 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper static void 96*57718be8SEnji Cooper sigalrm_action(int signo, siginfo_t *info, void *ptr) 97*57718be8SEnji Cooper { 98*57718be8SEnji Cooper 99*57718be8SEnji Cooper sig_debug(signo, info, (ucontext_t *)ptr); 100*57718be8SEnji Cooper 101*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGALRM); 102*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, SI_TIMER); 103*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); 104*57718be8SEnji Cooper 105*57718be8SEnji Cooper atf_tc_pass(); 106*57718be8SEnji Cooper /* NOTREACHED */ 107*57718be8SEnji Cooper } 108*57718be8SEnji Cooper 109*57718be8SEnji Cooper ATF_TC(sigalarm); 110*57718be8SEnji Cooper 111*57718be8SEnji Cooper ATF_TC_HEAD(sigalarm, tc) 112*57718be8SEnji Cooper { 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 115*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGALRM handler"); 116*57718be8SEnji Cooper } 117*57718be8SEnji Cooper 118*57718be8SEnji Cooper ATF_TC_BODY(sigalarm, tc) 119*57718be8SEnji Cooper { 120*57718be8SEnji Cooper struct sigaction sa; 121*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 122*57718be8SEnji Cooper sa.sa_sigaction = sigalrm_action; 123*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 124*57718be8SEnji Cooper sigaction(SIGALRM, &sa, NULL); 125*57718be8SEnji Cooper for (;;) { 126*57718be8SEnji Cooper alarm(1); 127*57718be8SEnji Cooper sleep(1); 128*57718be8SEnji Cooper } 129*57718be8SEnji Cooper atf_tc_fail("SIGALRM handler wasn't called"); 130*57718be8SEnji Cooper } 131*57718be8SEnji Cooper 132*57718be8SEnji Cooper static void 133*57718be8SEnji Cooper sigchild_action(int signo, siginfo_t *info, void *ptr) 134*57718be8SEnji Cooper { 135*57718be8SEnji Cooper if (info != NULL) { 136*57718be8SEnji Cooper printf("info=%p\n", info); 137*57718be8SEnji Cooper printf("ptr=%p\n", ptr); 138*57718be8SEnji Cooper printf("si_signo=%d\n", info->si_signo); 139*57718be8SEnji Cooper printf("si_errno=%d\n", info->si_errno); 140*57718be8SEnji Cooper printf("si_code=%d\n", info->si_code); 141*57718be8SEnji Cooper printf("si_uid=%d\n", info->si_uid); 142*57718be8SEnji Cooper printf("si_pid=%d\n", info->si_pid); 143*57718be8SEnji Cooper printf("si_status=%d\n", info->si_status); 144*57718be8SEnji Cooper printf("si_utime=%lu\n", (unsigned long int)info->si_utime); 145*57718be8SEnji Cooper printf("si_stime=%lu\n", (unsigned long int)info->si_stime); 146*57718be8SEnji Cooper } 147*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, code); 148*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGCHLD); 149*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_uid, getuid()); 150*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_pid, child); 151*57718be8SEnji Cooper if (WIFEXITED(info->si_status)) 152*57718be8SEnji Cooper ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status); 153*57718be8SEnji Cooper else if (WIFSTOPPED(info->si_status)) 154*57718be8SEnji Cooper ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status); 155*57718be8SEnji Cooper else if (WIFSIGNALED(info->si_status)) 156*57718be8SEnji Cooper ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status); 157*57718be8SEnji Cooper } 158*57718be8SEnji Cooper 159*57718be8SEnji Cooper static void 160*57718be8SEnji Cooper setchildhandler(void (*action)(int, siginfo_t *, void *)) 161*57718be8SEnji Cooper { 162*57718be8SEnji Cooper struct sigaction sa; 163*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 164*57718be8SEnji Cooper sa.sa_sigaction = action; 165*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 166*57718be8SEnji Cooper sigaction(SIGCHLD, &sa, NULL); 167*57718be8SEnji Cooper } 168*57718be8SEnji Cooper 169*57718be8SEnji Cooper static void 170*57718be8SEnji Cooper sigchild_setup(void) 171*57718be8SEnji Cooper { 172*57718be8SEnji Cooper sigset_t set; 173*57718be8SEnji Cooper struct rlimit rlim; 174*57718be8SEnji Cooper 175*57718be8SEnji Cooper (void)getrlimit(RLIMIT_CORE, &rlim); 176*57718be8SEnji Cooper rlim.rlim_cur = rlim.rlim_max; 177*57718be8SEnji Cooper (void)setrlimit(RLIMIT_CORE, &rlim); 178*57718be8SEnji Cooper 179*57718be8SEnji Cooper setchildhandler(sigchild_action); 180*57718be8SEnji Cooper sigemptyset(&set); 181*57718be8SEnji Cooper sigaddset(&set, SIGCHLD); 182*57718be8SEnji Cooper sigprocmask(SIG_BLOCK, &set, NULL); 183*57718be8SEnji Cooper } 184*57718be8SEnji Cooper 185*57718be8SEnji Cooper ATF_TC(sigchild_normal); 186*57718be8SEnji Cooper ATF_TC_HEAD(sigchild_normal, tc) 187*57718be8SEnji Cooper { 188*57718be8SEnji Cooper 189*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 190*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGCHLD handler " 191*57718be8SEnji Cooper "when child exits normally"); 192*57718be8SEnji Cooper } 193*57718be8SEnji Cooper 194*57718be8SEnji Cooper ATF_TC_BODY(sigchild_normal, tc) 195*57718be8SEnji Cooper { 196*57718be8SEnji Cooper sigset_t set; 197*57718be8SEnji Cooper 198*57718be8SEnji Cooper sigchild_setup(); 199*57718be8SEnji Cooper 200*57718be8SEnji Cooper status = 25; 201*57718be8SEnji Cooper code = CLD_EXITED; 202*57718be8SEnji Cooper 203*57718be8SEnji Cooper switch ((child = fork())) { 204*57718be8SEnji Cooper case 0: 205*57718be8SEnji Cooper sleep(1); 206*57718be8SEnji Cooper exit(status); 207*57718be8SEnji Cooper case -1: 208*57718be8SEnji Cooper atf_tc_fail("fork failed"); 209*57718be8SEnji Cooper default: 210*57718be8SEnji Cooper sigemptyset(&set); 211*57718be8SEnji Cooper sigsuspend(&set); 212*57718be8SEnji Cooper } 213*57718be8SEnji Cooper } 214*57718be8SEnji Cooper 215*57718be8SEnji Cooper ATF_TC(sigchild_dump); 216*57718be8SEnji Cooper ATF_TC_HEAD(sigchild_dump, tc) 217*57718be8SEnji Cooper { 218*57718be8SEnji Cooper 219*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 220*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGCHLD handler " 221*57718be8SEnji Cooper "when child segfaults"); 222*57718be8SEnji Cooper } 223*57718be8SEnji Cooper 224*57718be8SEnji Cooper ATF_TC_BODY(sigchild_dump, tc) 225*57718be8SEnji Cooper { 226*57718be8SEnji Cooper sigset_t set; 227*57718be8SEnji Cooper 228*57718be8SEnji Cooper sigchild_setup(); 229*57718be8SEnji Cooper 230*57718be8SEnji Cooper status = SIGSEGV; 231*57718be8SEnji Cooper code = CLD_DUMPED; 232*57718be8SEnji Cooper 233*57718be8SEnji Cooper switch ((child = fork())) { 234*57718be8SEnji Cooper case 0: 235*57718be8SEnji Cooper sleep(1); 236*57718be8SEnji Cooper *(volatile long *)0 = 0; 237*57718be8SEnji Cooper atf_tc_fail("Child did not segfault"); 238*57718be8SEnji Cooper /* NOTREACHED */ 239*57718be8SEnji Cooper case -1: 240*57718be8SEnji Cooper atf_tc_fail("fork failed"); 241*57718be8SEnji Cooper default: 242*57718be8SEnji Cooper sigemptyset(&set); 243*57718be8SEnji Cooper sigsuspend(&set); 244*57718be8SEnji Cooper } 245*57718be8SEnji Cooper } 246*57718be8SEnji Cooper 247*57718be8SEnji Cooper ATF_TC(sigchild_kill); 248*57718be8SEnji Cooper ATF_TC_HEAD(sigchild_kill, tc) 249*57718be8SEnji Cooper { 250*57718be8SEnji Cooper 251*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 252*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGCHLD handler " 253*57718be8SEnji Cooper "when child is killed"); 254*57718be8SEnji Cooper } 255*57718be8SEnji Cooper 256*57718be8SEnji Cooper ATF_TC_BODY(sigchild_kill, tc) 257*57718be8SEnji Cooper { 258*57718be8SEnji Cooper sigset_t set; 259*57718be8SEnji Cooper 260*57718be8SEnji Cooper sigchild_setup(); 261*57718be8SEnji Cooper 262*57718be8SEnji Cooper status = SIGPIPE; 263*57718be8SEnji Cooper code = CLD_KILLED; 264*57718be8SEnji Cooper 265*57718be8SEnji Cooper switch ((child = fork())) { 266*57718be8SEnji Cooper case 0: 267*57718be8SEnji Cooper sigemptyset(&set); 268*57718be8SEnji Cooper sigsuspend(&set); 269*57718be8SEnji Cooper break; 270*57718be8SEnji Cooper case -1: 271*57718be8SEnji Cooper atf_tc_fail("fork failed"); 272*57718be8SEnji Cooper default: 273*57718be8SEnji Cooper kill(child, SIGPIPE); 274*57718be8SEnji Cooper sigemptyset(&set); 275*57718be8SEnji Cooper sigsuspend(&set); 276*57718be8SEnji Cooper } 277*57718be8SEnji Cooper } 278*57718be8SEnji Cooper 279*57718be8SEnji Cooper static sigjmp_buf sigfpe_flt_env; 280*57718be8SEnji Cooper static void 281*57718be8SEnji Cooper sigfpe_flt_action(int signo, siginfo_t *info, void *ptr) 282*57718be8SEnji Cooper { 283*57718be8SEnji Cooper 284*57718be8SEnji Cooper sig_debug(signo, info, (ucontext_t *)ptr); 285*57718be8SEnji Cooper 286*57718be8SEnji Cooper if (fltdiv_signalled++ != 0) 287*57718be8SEnji Cooper atf_tc_fail("FPE handler called more than once"); 288*57718be8SEnji Cooper 289*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGFPE); 290*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV); 291*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_errno, 0); 292*57718be8SEnji Cooper 293*57718be8SEnji Cooper siglongjmp(sigfpe_flt_env, 1); 294*57718be8SEnji Cooper } 295*57718be8SEnji Cooper 296*57718be8SEnji Cooper ATF_TC(sigfpe_flt); 297*57718be8SEnji Cooper ATF_TC_HEAD(sigfpe_flt, tc) 298*57718be8SEnji Cooper { 299*57718be8SEnji Cooper 300*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 301*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGFPE handler " 302*57718be8SEnji Cooper "for floating div-by-zero"); 303*57718be8SEnji Cooper } 304*57718be8SEnji Cooper 305*57718be8SEnji Cooper ATF_TC_BODY(sigfpe_flt, tc) 306*57718be8SEnji Cooper { 307*57718be8SEnji Cooper struct sigaction sa; 308*57718be8SEnji Cooper double d = strtod("0", NULL); 309*57718be8SEnji Cooper 310*57718be8SEnji Cooper if (isQEMU()) 311*57718be8SEnji Cooper atf_tc_skip("Test does not run correctly under QEMU"); 312*57718be8SEnji Cooper #if defined(__powerpc__) 313*57718be8SEnji Cooper atf_tc_skip("Test not valid on powerpc"); 314*57718be8SEnji Cooper #endif 315*57718be8SEnji Cooper if (sigsetjmp(sigfpe_flt_env, 0) == 0) { 316*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 317*57718be8SEnji Cooper sa.sa_sigaction = sigfpe_flt_action; 318*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 319*57718be8SEnji Cooper sigaction(SIGFPE, &sa, NULL); 320*57718be8SEnji Cooper #ifdef HAVE_FENV 321*57718be8SEnji Cooper feenableexcept(FE_ALL_EXCEPT); 322*57718be8SEnji Cooper #elif defined(_FLOAT_IEEE754) 323*57718be8SEnji Cooper fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); 324*57718be8SEnji Cooper #endif 325*57718be8SEnji Cooper printf("%g\n", 1 / d); 326*57718be8SEnji Cooper } 327*57718be8SEnji Cooper if (fltdiv_signalled == 0) 328*57718be8SEnji Cooper atf_tc_fail("FPE signal handler was not invoked"); 329*57718be8SEnji Cooper } 330*57718be8SEnji Cooper 331*57718be8SEnji Cooper static sigjmp_buf sigfpe_int_env; 332*57718be8SEnji Cooper static void 333*57718be8SEnji Cooper sigfpe_int_action(int signo, siginfo_t *info, void *ptr) 334*57718be8SEnji Cooper { 335*57718be8SEnji Cooper 336*57718be8SEnji Cooper sig_debug(signo, info, (ucontext_t *)ptr); 337*57718be8SEnji Cooper 338*57718be8SEnji Cooper if (intdiv_signalled++ != 0) 339*57718be8SEnji Cooper atf_tc_fail("INTDIV handler called more than once"); 340*57718be8SEnji Cooper 341*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGFPE); 342*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV); 343*57718be8SEnji Cooper atf_tc_expect_pass(); 344*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_errno, 0); 345*57718be8SEnji Cooper 346*57718be8SEnji Cooper siglongjmp(sigfpe_int_env, 1); 347*57718be8SEnji Cooper } 348*57718be8SEnji Cooper 349*57718be8SEnji Cooper ATF_TC(sigfpe_int); 350*57718be8SEnji Cooper ATF_TC_HEAD(sigfpe_int, tc) 351*57718be8SEnji Cooper { 352*57718be8SEnji Cooper 353*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 354*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGFPE handler " 355*57718be8SEnji Cooper "for integer div-by-zero (PR port-i386/43655)"); 356*57718be8SEnji Cooper } 357*57718be8SEnji Cooper 358*57718be8SEnji Cooper ATF_TC_BODY(sigfpe_int, tc) 359*57718be8SEnji Cooper { 360*57718be8SEnji Cooper struct sigaction sa; 361*57718be8SEnji Cooper long l = strtol("0", NULL, 10); 362*57718be8SEnji Cooper 363*57718be8SEnji Cooper #if defined(__powerpc__) 364*57718be8SEnji Cooper atf_tc_skip("Test not valid on powerpc"); 365*57718be8SEnji Cooper #endif 366*57718be8SEnji Cooper if (sigsetjmp(sigfpe_int_env, 0) == 0) { 367*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 368*57718be8SEnji Cooper sa.sa_sigaction = sigfpe_int_action; 369*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 370*57718be8SEnji Cooper sigaction(SIGFPE, &sa, NULL); 371*57718be8SEnji Cooper #ifdef HAVE_FENV 372*57718be8SEnji Cooper feenableexcept(FE_ALL_EXCEPT); 373*57718be8SEnji Cooper #elif defined(_FLOAT_IEEE754) 374*57718be8SEnji Cooper fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); 375*57718be8SEnji Cooper #endif 376*57718be8SEnji Cooper printf("%ld\n", 1 / l); 377*57718be8SEnji Cooper } 378*57718be8SEnji Cooper if (intdiv_signalled == 0) 379*57718be8SEnji Cooper atf_tc_fail("FPE signal handler was not invoked"); 380*57718be8SEnji Cooper } 381*57718be8SEnji Cooper 382*57718be8SEnji Cooper static void 383*57718be8SEnji Cooper sigsegv_action(int signo, siginfo_t *info, void *ptr) 384*57718be8SEnji Cooper { 385*57718be8SEnji Cooper 386*57718be8SEnji Cooper sig_debug(signo, info, (ucontext_t *)ptr); 387*57718be8SEnji Cooper 388*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); 389*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_errno, 0); 390*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); 391*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_addr, (void *)0); 392*57718be8SEnji Cooper 393*57718be8SEnji Cooper atf_tc_pass(); 394*57718be8SEnji Cooper /* NOTREACHED */ 395*57718be8SEnji Cooper } 396*57718be8SEnji Cooper 397*57718be8SEnji Cooper ATF_TC(sigsegv); 398*57718be8SEnji Cooper ATF_TC_HEAD(sigsegv, tc) 399*57718be8SEnji Cooper { 400*57718be8SEnji Cooper 401*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 402*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGSEGV handler"); 403*57718be8SEnji Cooper } 404*57718be8SEnji Cooper 405*57718be8SEnji Cooper ATF_TC_BODY(sigsegv, tc) 406*57718be8SEnji Cooper { 407*57718be8SEnji Cooper struct sigaction sa; 408*57718be8SEnji Cooper 409*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 410*57718be8SEnji Cooper sa.sa_sigaction = sigsegv_action; 411*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 412*57718be8SEnji Cooper sigaction(SIGSEGV, &sa, NULL); 413*57718be8SEnji Cooper 414*57718be8SEnji Cooper *(volatile long *)0 = 0; 415*57718be8SEnji Cooper atf_tc_fail("Test did not fault as expected"); 416*57718be8SEnji Cooper } 417*57718be8SEnji Cooper 418*57718be8SEnji Cooper static void 419*57718be8SEnji Cooper sigbus_action(int signo, siginfo_t *info, void *ptr) 420*57718be8SEnji Cooper { 421*57718be8SEnji Cooper 422*57718be8SEnji Cooper printf("si_addr = %p\n", info->si_addr); 423*57718be8SEnji Cooper sig_debug(signo, info, (ucontext_t *)ptr); 424*57718be8SEnji Cooper 425*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_signo, SIGBUS); 426*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_errno, 0); 427*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); 428*57718be8SEnji Cooper 429*57718be8SEnji Cooper #if defined(__i386__) || defined(__x86_64__) 430*57718be8SEnji Cooper atf_tc_expect_fail("x86 architecture does not correctly " 431*57718be8SEnji Cooper "report the address where the unaligned access occured"); 432*57718be8SEnji Cooper #endif 433*57718be8SEnji Cooper ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); 434*57718be8SEnji Cooper 435*57718be8SEnji Cooper atf_tc_pass(); 436*57718be8SEnji Cooper /* NOTREACHED */ 437*57718be8SEnji Cooper } 438*57718be8SEnji Cooper 439*57718be8SEnji Cooper ATF_TC(sigbus_adraln); 440*57718be8SEnji Cooper ATF_TC_HEAD(sigbus_adraln, tc) 441*57718be8SEnji Cooper { 442*57718be8SEnji Cooper 443*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", 444*57718be8SEnji Cooper "Checks that signal trampoline correctly calls SIGBUS handler " 445*57718be8SEnji Cooper "for invalid address alignment"); 446*57718be8SEnji Cooper } 447*57718be8SEnji Cooper 448*57718be8SEnji Cooper ATF_TC_BODY(sigbus_adraln, tc) 449*57718be8SEnji Cooper { 450*57718be8SEnji Cooper struct sigaction sa; 451*57718be8SEnji Cooper 452*57718be8SEnji Cooper #if defined(__alpha__) 453*57718be8SEnji Cooper int rv, val; 454*57718be8SEnji Cooper size_t len = sizeof(val); 455*57718be8SEnji Cooper rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0); 456*57718be8SEnji Cooper ATF_REQUIRE(rv == 0); 457*57718be8SEnji Cooper if (val == 0) 458*57718be8SEnji Cooper atf_tc_skip("SIGBUS signal not enabled for unaligned accesses"); 459*57718be8SEnji Cooper #endif 460*57718be8SEnji Cooper 461*57718be8SEnji Cooper sa.sa_flags = SA_SIGINFO; 462*57718be8SEnji Cooper sa.sa_sigaction = sigbus_action; 463*57718be8SEnji Cooper sigemptyset(&sa.sa_mask); 464*57718be8SEnji Cooper sigaction(SIGBUS, &sa, NULL); 465*57718be8SEnji Cooper 466*57718be8SEnji Cooper /* Enable alignment checks for x86. 0x40000 is PSL_AC. */ 467*57718be8SEnji Cooper #if defined(__i386__) 468*57718be8SEnji Cooper __asm__("pushf; orl $0x40000, (%esp); popf"); 469*57718be8SEnji Cooper #elif defined(__amd64__) 470*57718be8SEnji Cooper __asm__("pushf; orl $0x40000, (%rsp); popf"); 471*57718be8SEnji Cooper #endif 472*57718be8SEnji Cooper 473*57718be8SEnji Cooper addr = calloc(2, sizeof(int)); 474*57718be8SEnji Cooper ATF_REQUIRE(addr != NULL); 475*57718be8SEnji Cooper 476*57718be8SEnji Cooper if (isQEMU()) 477*57718be8SEnji Cooper atf_tc_expect_fail("QEMU fails to trap unaligned accesses"); 478*57718be8SEnji Cooper 479*57718be8SEnji Cooper /* Force an unaligned access */ 480*57718be8SEnji Cooper addr++; 481*57718be8SEnji Cooper printf("now trying to access unaligned address %p\n", addr); 482*57718be8SEnji Cooper ATF_REQUIRE_EQ(*(volatile int *)addr, 0); 483*57718be8SEnji Cooper 484*57718be8SEnji Cooper atf_tc_fail("Test did not fault as expected"); 485*57718be8SEnji Cooper } 486*57718be8SEnji Cooper 487*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 488*57718be8SEnji Cooper { 489*57718be8SEnji Cooper 490*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigalarm); 491*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigchild_normal); 492*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigchild_dump); 493*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigchild_kill); 494*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigfpe_flt); 495*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigfpe_int); 496*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigsegv); 497*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, sigbus_adraln); 498*57718be8SEnji Cooper 499*57718be8SEnji Cooper return atf_no_error(); 500*57718be8SEnji Cooper } 501