aboutsummaryrefslogtreecommitdiff
path: root/memcheck/tests/x86-solaris/context_eflags2.c
diff options
context:
space:
mode:
Diffstat (limited to 'memcheck/tests/x86-solaris/context_eflags2.c')
-rw-r--r--memcheck/tests/x86-solaris/context_eflags2.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/memcheck/tests/x86-solaris/context_eflags2.c b/memcheck/tests/x86-solaris/context_eflags2.c
new file mode 100644
index 000000000..4f37693ea
--- /dev/null
+++ b/memcheck/tests/x86-solaris/context_eflags2.c
@@ -0,0 +1,80 @@
+/* x86 variant of the amd64-solaris/context_rflags2.c test. */
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/ucontext.h>
+
+#define OBIT(eflags) (!!((eflags) & (1 << 11)))
+#define SBIT(eflags) (!!((eflags) & (1 << 7)))
+
+static siginfo_t si;
+static ucontext_t uc;
+
+void break_out(void);
+
+static void sighandler(int sig, siginfo_t *sip, ucontext_t *ucp)
+{
+ si = *sip;
+ uc = *ucp;
+
+ /* Break out of the endless loop. */
+ *(uintptr_t*)&ucp->uc_mcontext.gregs[EIP] = (uintptr_t)break_out;
+}
+
+int main(void)
+{
+ struct sigaction sa;
+ int eflags;
+ int x1;
+
+ /* Uninitialised, but we know px[0] is 0x0. */
+ int *px = malloc(sizeof(*px));
+ x1 = px[0] + 1;
+
+ sa.sa_handler = sighandler;
+ sa.sa_flags = SA_SIGINFO;
+ if (sigfillset(&sa.sa_mask)) {
+ perror("sigfillset");
+ return 1;
+ }
+ if (sigaction(SIGALRM, &sa, NULL)) {
+ perror("sigaction");
+ return 1;
+ }
+
+ alarm(2);
+
+ __asm__ __volatile__(
+ /* Set overflow and sign flags. */
+ "movl %[x1], %%edx\n"
+ "addl $0x7fffffff, %%edx\n"
+
+ /* Loopity loop, this is where the SIGALRM is triggered. */
+ "1:\n"
+ "jmp 1b\n"
+
+ "break_out:\n"
+ "pushfl\n"
+ "popl %%edx\n"
+ : "=d" (eflags)
+ : [x1] "m" (x1)
+ : "cc", "memory");
+
+ /* Check that the overflow and sign flags are uninitialised.
+
+ Note: This actually fails because the eflags are only approximate
+ (always initialised) in the signal handler. */
+ if (!OBIT(uc.uc_mcontext.gregs[EFL]) || !SBIT(uc.uc_mcontext.gregs[EFL]))
+ assert(0);
+
+ /* Check that the overflow and sign flags are uninitialised. */
+ if (!OBIT(eflags) || !SBIT(eflags))
+ assert(0);
+
+ return 0;
+}
+