• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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