1 /* 2 * Copyright 2021 IBM Corp. 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or (at 5 * your option) any later version. See the COPYING file in the top-level 6 * directory. 7 */ 8 9 #include <stdarg.h> 10 #include <stdint.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <unistd.h> 14 #include <errno.h> 15 #include <string.h> 16 #include <signal.h> 17 18 static void error1(const char *filename, int line, const char *fmt, ...) 19 { 20 va_list ap; 21 va_start(ap, fmt); 22 fprintf(stderr, "%s:%d: ", filename, line); 23 vfprintf(stderr, fmt, ap); 24 fprintf(stderr, "\n"); 25 va_end(ap); 26 exit(1); 27 } 28 29 static int __chk_error(const char *filename, int line, int ret) 30 { 31 if (ret < 0) { 32 error1(filename, line, "%m (ret=%d, errno=%d/%s)", 33 ret, errno, strerror(errno)); 34 } 35 return ret; 36 } 37 38 #define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__) 39 40 #define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) 41 42 int sigfpe_count; 43 int sigill_count; 44 45 static void sig_handler(int sig, siginfo_t *si, void *puc) 46 { 47 if (sig == SIGFPE) { 48 if (si->si_code != 0) { 49 error("unexpected si_code: 0x%x != 0", si->si_code); 50 } 51 ++sigfpe_count; 52 return; 53 } 54 55 if (sig == SIGILL) { 56 ++sigill_count; 57 return; 58 } 59 60 error("unexpected signal 0x%x\n", sig); 61 } 62 63 int main(int argc, char **argv) 64 { 65 sigfpe_count = sigill_count = 0; 66 67 struct sigaction act; 68 69 /* Set up SIG handler */ 70 act.sa_sigaction = sig_handler; 71 sigemptyset(&act.sa_mask); 72 act.sa_flags = SA_SIGINFO; 73 chk_error(sigaction(SIGFPE, &act, NULL)); 74 chk_error(sigaction(SIGILL, &act, NULL)); 75 76 uint64_t z = 0x0ull; 77 uint64_t lz = 0xffffffffffffffffull; 78 asm volatile ( 79 "lg %%r13,%[lz]\n" 80 "cgitne %%r13,0\n" /* SIGFPE */ 81 "lg %%r13,%[z]\n" 82 "cgitne %%r13,0\n" /* no trap */ 83 "nopr\n" 84 "lg %%r13,%[lz]\n" 85 "citne %%r13,0\n" /* SIGFPE */ 86 "lg %%r13,%[z]\n" 87 "citne %%r13,0\n" /* no trap */ 88 "nopr\n" 89 : 90 : [z] "m" (z), [lz] "m" (lz) 91 : "memory", "r13"); 92 93 if (sigfpe_count != 2) { 94 error("unexpected SIGFPE count: %d != 2", sigfpe_count); 95 } 96 if (sigill_count != 0) { 97 error("unexpected SIGILL count: %d != 0", sigill_count); 98 } 99 100 printf("PASS\n"); 101 return 0; 102 } 103