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