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 
sighandler(int sig,siginfo_t * sip,ucontext_t * ucp)19 static void sighandler(int sig, siginfo_t *sip, ucontext_t *ucp)
20 {
21    si = *sip;
22    uc = *ucp;
23 }
24 
main(void)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