1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define _GNU_SOURCE 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <signal.h> 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/ucontext.h> 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <asm/unistd.h> 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VAL1 0x11223344 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VAL2 0x44332211 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handler1(int sig, siginfo_t *si, ucontext_t *uc) 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Since the handler will be called as kill leaves the kernel, 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this is replacing the kill syscall's return value. */ 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (uc->uc_mcontext.gregs[REG_EAX] != 0) 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("FAILED: handler2 expected eax == 0, not %d\n", uc->uc_mcontext.gregs[REG_EAX]); 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc->uc_mcontext.gregs[REG_EAX] = VAL1; 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown asm volatile ( 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%edx\n" 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%esi\n" 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%edi\n" 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : : : "edx", "esi", "edi"); 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handler2(int sig, struct sigcontext sc) 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Since the handler will be called as kill leaves the kernel, 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this is replacing the kill syscall's return value. */ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sc.eax != 0) 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("FAILED: handler2 expected eax == 0, not %p\n", (void*)sc.eax); 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sc.eax = VAL2; 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown asm volatile ( 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%edx\n" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%esi\n" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0, %%edi\n" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : : : "edx", "esi", "edi"); 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main() 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sigaction sa; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int ret; 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int v2, v3, v4; 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sa.sa_handler = (void*)handler1; 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sa.sa_flags = SA_SIGINFO; 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigfillset(&sa.sa_mask); 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigaction(SIGUSR1, &sa, NULL); 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sa.sa_handler = (void*)handler2; 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sa.sa_flags = 0; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigfillset(&sa.sa_mask); 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigaction(SIGUSR2, &sa, NULL); 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown asm volatile ( 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //"movl $0x11111111, %%ebp\n" 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x22222222, %%edx\n" 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x33333333, %%esi\n" 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x44444444, %%edi\n" 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "int $0x80" 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (ret), "=d" (v2), "=S" (v3), "=D" (v4) 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "0" (__NR_kill), "b" (getpid()), "c" (SIGUSR1)); 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("v2=%x v3=%x v4=%x\n", v2, v3, v4); 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ret == VAL1) 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("PASS %x\n", ret); 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("FAIL ret=%x not %x\n", ret, VAL1); 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown asm volatile ( 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //"movl $0x11111111, %%ebp\n" 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x22222222, %%edx\n" 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x33333333, %%esi\n" 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl $0x44444444, %%edi\n" 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "int $0x80" 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=a" (ret), "=d" (v2), "=S" (v3), "=D" (v4) 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "0" (__NR_kill), "b" (getpid()), "c" (SIGUSR2)); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("v2=%x v3=%x v4=%x\n", v2, v3, v4); 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ret == VAL2) 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("PASS %x\n", ret); 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("FAIL ret=%x not %x\n", ret, VAL2); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 93