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