• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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. */
5 
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <assert.h>
10 
11 #include <sys/syscall.h>
12 #include <unistd.h>
13 
14 #define VG_STRINGIFZ(__str)  #__str
15 #define VG_STRINGIFY(__str)  VG_STRINGIFZ(__str)
16 
17 #if defined(VGO_linux) || defined(VGO_darwin)
18 #define __NR_READLINK        VG_STRINGIFY(__NR_readlink)
19 
20 extern long my_readlink ( const char* path );
21 asm(
22 ".text\n"
23 ".globl my_readlink\n"
24 "my_readlink:\n"
25 "\tsubq    $0x1008,%rsp\n"
26 "\tmovq    %rdi,%rdi\n"              // path is in rdi
27 "\tmovq    %rsp,%rsi\n"              // &buf[0] -> rsi
28 "\tmovl    $0x1000,%edx\n"           // sizeof(buf) in rdx
29 "\tmovl    $"__NR_READLINK",%eax\n"  // syscall number
30 "\tsyscall\n"
31 "\taddq    $0x1008,%rsp\n"
32 "\tret\n"
33 ".previous\n"
34 );
35 
36 #elif defined(VGO_solaris)
37 #define __NR_READLINKAT      VG_STRINGIFY(SYS_readlinkat)
38 
39 extern long my_readlink ( const char* path );
40 asm(
41 ".text\n"
42 ".globl my_readlink\n"
43 "my_readlink:\n"
44 "\tsubq    $0x1008,%rsp\n"
45 "\tmovq    %rdi,%rsi\n"
46 "\txorq    %rdi,%rdi\n"
47 "\tmovq    %rsp,%rdx\n"
48 "\tmovq    $0x1000,%r10\n"
49 "\tmovl    $"__NR_READLINKAT",%eax\n"
50 "\tsyscall\n"
51 "\taddq    $0x1008,%rsp\n"
52 "\tret\n"
53 ".previous\n"
54 );
55 
56 #else
57 #error "Unknown OS"
58 #endif
59 
recurse(const char * path,long count)60 long recurse ( const char* path, long count )
61 {
62    if (count <= 0) {
63       return my_readlink(path);
64    } else {
65       long r = recurse(path, count-1);
66       return r;
67    }
68 }
69 
main(void)70 int main ( void )
71 {
72    long i, r;
73    for (i = 0; i < 2000; i++) {
74       printf("depth %ld: ", i );
75       r = recurse( "/proc/self", i );
76       if (r > 1) r = 1; /* to make the output repeatable */
77       assert(r >= 1);
78       printf("r = %ld\n", r);
79    }
80    return 0;
81 }
82