sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 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 | |
| 11 | static siginfo_t si; |
| 12 | static ucontext_t uc; |
| 13 | /* x0 is always zero, but is visible to Valgrind as uninitialised. */ |
| 14 | static int x0; |
| 15 | |
| 16 | static 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 | |
| 24 | int 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 | |