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