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 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 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