1 /* Test if rflags values are correctly propagated in and out of a signal 2 handler. Note that we actually test only the propagation of the overflow 3 and sign flags. */ 4 5 #include <assert.h> 6 #include <signal.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <sys/regset.h> 11 #include <sys/syscall.h> 12 #include <sys/ucontext.h> 13 14 #define OBIT(rflags) (!!((rflags) & (1 << 11))) 15 #define SBIT(rflags) (!!((rflags) & (1 << 7))) 16 17 static siginfo_t si; 18 static ucontext_t uc; 19 20 static void sighandler(int sig, siginfo_t *sip, void *arg) 21 { 22 si = *sip; 23 uc = *((ucontext_t *) arg); 24 } 25 26 int main(void) 27 { 28 struct sigaction sa; 29 pid_t pid; 30 long rflags; 31 32 sa.sa_sigaction = sighandler; 33 sa.sa_flags = SA_SIGINFO; 34 if (sigfillset(&sa.sa_mask)) { 35 perror("sigfillset"); 36 return 1; 37 } 38 if (sigaction(SIGUSR1, &sa, NULL)) { 39 perror("sigaction"); 40 return 1; 41 } 42 43 pid = getpid(); 44 45 __asm__ __volatile__( 46 /* Set overflow and sign flags. */ 47 "movl $1, %%edx\n" 48 "addl $0x7fffffff, %%edx\n" 49 50 /* Trigger the signal handler. */ 51 "syscall\n" 52 "pushfq\n" 53 "popq %%rdx\n" 54 : "=d" (rflags) 55 : "a" (SYS_kill), "D" (pid), "S" (SIGUSR1) 56 : "cc", "memory"); 57 58 printf("Values in the signal handler:\n"); 59 printf(" overflow=%d, sign=%d\n", 60 OBIT(uc.uc_mcontext.gregs[REG_RFL]), 61 SBIT(uc.uc_mcontext.gregs[REG_RFL])); 62 63 printf("Values after the return from the signal handler:\n"); 64 printf(" overflow=%d, sign=%d\n", OBIT(rflags), SBIT(rflags)); 65 66 return 0; 67 } 68 69