• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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