1/* Tests that Valgrind correctly handles syscalls returning 2 either 1 (in %rax) or 2 values (in %rdx:%rax). */ 3 4#include <stdio.h> 5#include <sys/syscall.h> 6#include <sys/types.h> 7 8#define GARBAGE 0x0caffedeadbeef 9 10static void syscall_rval(int sysno, uint64_t *rval_hi, uint64_t *rval_lo) 11{ 12 __asm__ ( 13 "movq %[INPUT1],%%rdx\n" 14 "movq %[SYSCALL_NUMBER],%%rax\n" 15 "syscall\n" 16 "movq %[RVAL_HI],%%rcx\n" 17 "movq %%rdx,(%%rcx)\n" 18 "movq %[RVAL_LO],%%rcx\n" 19 "movq %%rax,(%%rcx)\n" 20 : [RVAL_HI] "=m" (rval_hi), [RVAL_LO] "=m" (rval_lo) /* output */ 21 : [INPUT1] "i" (GARBAGE), [SYSCALL_NUMBER] "g" (sysno) /* input */ 22 : "rax", "rcx", "rdx", "cc", "memory"); /* clobbers */ 23} 24 25static int syscall_rval1(void) { 26 uint64_t valHi, valLo; 27 28 /* Syscall lwp_self returns just tid in rax. */ 29 valHi = valLo = GARBAGE; 30 syscall_rval(SYS_lwp_self, &valHi, &valLo); 31 if ((valHi != GARBAGE) || (valLo != 1)) { 32 fprintf(stderr, "rval1 FAILED [%#lx:%#lx]\n", valHi, valLo); 33 return 1; 34 } 35 36 return 0; 37} 38 39static int syscall_rval2(void) { 40 uint64_t valHi, valLo; 41 42 /* Syscall getpid returns pid in rax and ppid in rdx. */ 43 valHi = valLo = GARBAGE; 44 syscall_rval(SYS_getpid, &valHi, &valLo); 45 if ((valHi == GARBAGE) || (valLo == GARBAGE)) { 46 fprintf(stderr, "rval2 FAILED [%#lx:%#lx]\n", valHi, valLo); 47 return 1; 48 } 49 50 return 0; 51} 52 53int main(void) { 54 int ret = 0; 55 56 ret |= syscall_rval1(); 57 ret |= syscall_rval2(); 58 59 if (ret != 0) 60 fprintf(stderr, "FAIL\n"); 61 62 return ret; 63} 64