bug137714-amd64.vgtest bug137714-amd64.stdout.exp \
bug137714-amd64.stderr.exp \
bug132918.vgtest bug132918.stderr.exp bug132918.stdout.exp \
+ bug156404-amd64.vgtest bug156404-amd64.stdout.exp \
+ bug156404-amd64.stderr.exp \
clc.vgtest clc.stdout.exp clc.stderr.exp \
faultstatus.disabled faultstatus.stderr.exp \
fcmovnu.vgtest fcmovnu.stderr.exp fcmovnu.stdout.exp \
check_PROGRAMS = \
bug127521-64 bug132813-amd64 bug137714-amd64 bug132918 \
+ bug156404-amd64 \
clc \
faultstatus fcmovnu fxtract $(INSN_TESTS) looper jrcxz \
rcl-amd64 \
--- /dev/null
+
+/* Check that the main thread's stack, on Linux, is automatically
+ extended down to the lowest valid address when a syscall happens.
+ Failure to do so was causing this test to fail on Linux amd64. */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#define VG_STRINGIFZ(__str) #__str
+#define VG_STRINGIFY(__str) VG_STRINGIFZ(__str)
+
+#define __NR_READLINK VG_STRINGIFY(__NR_readlink)
+
+extern long my_readlink ( const char* path );
+asm(
+".text\n"
+".globl my_readlink\n"
+"my_readlink:\n"
+"\tsubq $0x1008,%rsp\n"
+"\tmovq %rdi,%rdi\n" // path is in rdi
+"\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
+"\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
+"\tmovl $"__NR_READLINK",%eax\n" // syscall number
+"\tsyscall\n"
+"\taddq $0x1008,%rsp\n"
+"\tret\n"
+".previous\n"
+);
+
+long recurse ( const char* path, long count )
+{
+ if (count <= 0) {
+ return my_readlink(path);
+ } else {
+ long r = recurse(path, count-1);
+ return r;
+ }
+}
+
+int main ( void )
+{
+ long i, r;
+ for (i = 0; i < 2000; i++) {
+ printf("depth %ld: ", i );
+ r = recurse( "/proc/self", i );
+ if (r > 1) r = 1; /* to make the output repeatable */
+ assert(r >= 1);
+ printf("r = %ld\n", r);
+ }
+ return 0;
+}