1 /* x86 variant of the amd64-solaris/context_rflags2.c test. */
2 
3 #include <assert.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <sys/regset.h>
9 #include <sys/syscall.h>
10 #include <sys/ucontext.h>
11 
12 #define OBIT(eflags) (!!((eflags) & (1 << 11)))
13 #define SBIT(eflags) (!!((eflags) & (1 << 7)))
14 
15 static siginfo_t si;
16 static ucontext_t uc;
17 
18 void break_out(void);
19 
sighandler(int sig,siginfo_t * sip,void * arg)20 static void sighandler(int sig, siginfo_t *sip, void *arg)
21 {
22    ucontext_t *ucp = (ucontext_t *) arg;
23 
24    si = *sip;
25    uc = *ucp;
26 
27    /* Break out of the endless loop. */
28    *(uintptr_t*)&ucp->uc_mcontext.gregs[EIP] = (uintptr_t)break_out;
29 }
30 
main(void)31 int main(void)
32 {
33    struct sigaction sa;
34    int eflags;
35    int x1;
36 
37    /* Uninitialised, but we know px[0] is 0x0. */
38    int *px = malloc(sizeof(*px));
39    x1 = px[0] + 1;
40 
41    sa.sa_sigaction = sighandler;
42    sa.sa_flags = SA_SIGINFO;
43    if (sigfillset(&sa.sa_mask)) {
44       perror("sigfillset");
45       return 1;
46    }
47    if (sigaction(SIGALRM, &sa, NULL)) {
48       perror("sigaction");
49       return 1;
50    }
51 
52    alarm(2);
53 
54    __asm__ __volatile__(
55       /* Set overflow and sign flags. */
56       "movl   %[x1], %%edx\n"
57       "addl   $0x7fffffff, %%edx\n"
58 
59       /* Loopity loop, this is where the SIGALRM is triggered. */
60       "1:\n"
61       "jmp    1b\n"
62 
63       "break_out:\n"
64       "pushfl\n"
65       "popl   %%edx\n"
66       : "=d" (eflags)
67       : [x1] "m" (x1)
68       : "cc", "memory");
69 
70    /* Check that the overflow and sign flags are uninitialised.
71 
72       Note: This actually fails because the eflags are only approximate
73       (always initialised) in the signal handler. */
74    if (!OBIT(uc.uc_mcontext.gregs[EFL]) || !SBIT(uc.uc_mcontext.gregs[EFL]))
75       assert(0);
76 
77    /* Check that the overflow and sign flags are uninitialised. */
78    if (!OBIT(eflags) || !SBIT(eflags))
79       assert(0);
80 
81    return 0;
82 }
83 
84