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