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
syscall_rval(int sysno,uint64_t * rval_hi,uint64_t * rval_lo)10 static 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
syscall_rval1(void)25 static 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
syscall_rval2(void)39 static 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
main(void)53 int 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