2 /* Check that the main thread's stack, on Linux, is automatically
3 extended down to the lowest valid address when a syscall happens.
4 Failure to do so was causing this test to fail on Linux amd64. */
11 #include <sys/syscall.h>
14 #define VG_STRINGIFZ(__str) #__str
15 #define VG_STRINGIFY(__str) VG_STRINGIFZ(__str)
17 #if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
18 #if !defined(__NR_readlink)
19 # define __NR_readlink 58
22 #define __NR_READLINK VG_STRINGIFY(__NR_readlink)
24 extern long my_readlink ( const char* path
);
27 ".globl my_readlink\n"
29 "\tsubq $0x1008,%rsp\n"
30 "\tmovq %rdi,%rdi\n" // path is in rdi
31 "\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
32 "\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
33 "\tmovl $"__NR_READLINK
",%eax\n" // syscall number
35 "\taddq $0x1008,%rsp\n"
40 #elif defined(VGO_solaris)
41 #define __NR_READLINKAT VG_STRINGIFY(SYS_readlinkat)
43 extern long my_readlink ( const char* path
);
46 ".globl my_readlink\n"
48 "\tsubq $0x1008,%rsp\n"
52 "\tmovq $0x1000,%r10\n"
53 "\tmovl $"__NR_READLINKAT
",%eax\n"
55 "\taddq $0x1008,%rsp\n"
64 long recurse ( const char* path
, long count
)
67 return my_readlink(path
);
69 long r
= recurse(path
, count
-1);
77 for (i
= 0; i
< 2000; i
++) {
78 printf("depth %ld: ", i
);
79 r
= recurse( "/proc/self", i
);
80 if (r
> 1) r
= 1; /* to make the output repeatable */
82 printf("r = %ld\n", r
);