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