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