1/* x86 variant of the amd64-solaris/context_gpr.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
11static siginfo_t si;
12static ucontext_t uc;
13/* x0 is always zero, but is visible to Valgrind as uninitialised. */
14static int x0;
15
16static void sighandler(int sig, siginfo_t *sip, ucontext_t *ucp)
17{
18   si = *sip;
19   uc = *ucp;
20
21   ucp->uc_mcontext.gregs[ECX] = x0;
22}
23
24int main(void)
25{
26   struct sigaction sa;
27   pid_t pid;
28   int eax, ebx, ecx, edx, esi, edi;
29   int y0;
30
31   /* Uninitialised, but we know px[0] is 0x0. */
32   int *px = malloc(sizeof(*px));
33   x0 = px[0];
34
35   /* Uninitialised, but we know py[0] is 0x0. */
36   int *py = malloc(sizeof(*py));
37   y0 = py[0];
38
39   sa.sa_handler = sighandler;
40   sa.sa_flags = SA_SIGINFO;
41   if (sigfillset(&sa.sa_mask)) {
42      perror("sigfillset");
43      return 1;
44   }
45   if (sigaction(SIGUSR1, &sa, NULL)) {
46      perror("sigaction");
47      return 1;
48   }
49
50   pid = getpid();
51
52   __asm__ __volatile__(
53      /* Set values in general purpose registers. */
54      "movl   %[y0], %%ebx\n"
55      "movl   $0xf1, %%ecx\n"
56      "movl   $0xf2, %%edx\n"
57      "movl   $0xf3, %%esi\n"
58      "movl   $0xf4, %%edi\n"
59
60      /* Prepare syscall parameters. */
61      "pushl  %[sig]\n"
62      "pushl  %[pid]\n"
63      "pushl  $0xdeadbeef\n"
64      "movl   %[scall], %%eax\n"
65
66      /* Trigger the signal handler. */
67      "int    $0x91\n"
68      "addl   $12, %%esp\n"
69      : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx), "=S" (esi),
70        "=D" (edi)
71      : [scall] "i" (SYS_kill), [pid] "a" (pid), [sig] "i" (SIGUSR1),
72        [y0] "m" (y0)
73      : "cc", "memory");
74
75   printf("Values in the signal handler:\n");
76   printf("  eax=%#x, edx=%#x, esi=%#x, edi=%#x\n",
77          uc.uc_mcontext.gregs[EAX], uc.uc_mcontext.gregs[EDX],
78          uc.uc_mcontext.gregs[ESI], uc.uc_mcontext.gregs[EDI]);
79   /* Check that ebx contains an uninitialised value (origin is py[0]). */
80   if (uc.uc_mcontext.gregs[EBX])
81      assert(0);
82
83   printf("Values after the return from the signal handler:\n");
84   printf("  eax=%#x, edx=%#x, esi=%#x, edi=%#x\n", eax, edx, esi, edi);
85   /* Check that ebx and ecx contain uninitialised values (origin is py[0]
86      and px[0], respectively). */
87   if (ebx || ecx)
88      assert(0);
89
90   return 0;
91}
92
93