Blob Blame Raw
commit 7be84ee45ccc827a63353868558bed6c824b4a68
Author: cborntra <cborntra@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Date:   Thu Nov 8 19:42:00 2012 +0000

    Add ptrace getreset testcase from Andreas Arnez
    arnez AT  linux DOT vnet DOT ibm DOT com
    
    
    
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13110 a5019735-40e9-0310-863c-91ae7b9d1cf9

diff --git a/memcheck/tests/linux/getregset.c b/memcheck/tests/linux/getregset.c
new file mode 100644
index 0000000..70b5ce2
--- /dev/null
+++ b/memcheck/tests/linux/getregset.c
@@ -0,0 +1,76 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+#include <assert.h>
+#include <elf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+
+static int
+err_out(const char *msg)
+{
+   perror(msg);
+   return 1;
+}
+
+static int
+non_empty(const char *buf, size_t len)
+{
+   size_t i;
+   int c;
+   volatile const char *p = buf;
+
+   for (i = 0; i != len; i++)
+      c |= p[i];
+   return c;
+}
+
+static int
+do_child(void)
+{
+   if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1)
+      return err_out("ptrace traceme");
+   raise(SIGUSR1);
+   return 0;
+}
+
+int
+main(void)
+{
+   char buf[1024];
+   struct iovec iov;
+   pid_t cpid, pid;
+   int status;
+
+   cpid = fork();
+   if (cpid == -1)
+      return err_out("fork");
+   if (cpid == 0)
+      return do_child();
+
+   pid = wait(&status);
+   if (pid == -1)
+      return err_out("wait");
+
+   /* Intentionally provide an uninitialized buffer to ptrace. */
+   iov.iov_len = sizeof(buf);
+   iov.iov_base = buf;
+   if (ptrace(0x4204, cpid, NT_PRSTATUS, &iov) == -1)
+      return err_out("ptrace getregset");
+
+   assert(iov.iov_base == buf);
+   assert(iov.iov_len > 0 && iov.iov_len < sizeof(buf));
+
+   /* We're assuming here that NT_PRSTATUS never contains
+      all-zeros. */
+   assert(non_empty(buf, iov.iov_len));
+   puts("OK");
+   return 0;
+}
diff --git a/memcheck/tests/linux/getregset.stderr.exp b/memcheck/tests/linux/getregset.stderr.exp
new file mode 100644
index 0000000..e69de29
diff --git a/memcheck/tests/linux/getregset.stdout.exp b/memcheck/tests/linux/getregset.stdout.exp
new file mode 100644
index 0000000..d86bac9
--- /dev/null
+++ b/memcheck/tests/linux/getregset.stdout.exp
@@ -0,0 +1 @@
+OK
diff --git a/memcheck/tests/linux/getregset.vgtest b/memcheck/tests/linux/getregset.vgtest
new file mode 100644
index 0000000..73f52f7
--- /dev/null
+++ b/memcheck/tests/linux/getregset.vgtest
@@ -0,0 +1,2 @@
+prog: getregset
+vgopts: -q
\ No newline at end of file

commit e48a444c9dfdf8083da562e87521c54876f8edc3
Author: cborntra <cborntra@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Date:   Thu Nov 8 20:10:10 2012 +0000

    add s390 specific fix for getregset
    
    
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13112 a5019735-40e9-0310-863c-91ae7b9d1cf9

diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
index 6638f14..ea043d7 100644
--- a/coregrind/m_syswrap/priv_syswrap-linux.h
+++ b/coregrind/m_syswrap/priv_syswrap-linux.h
@@ -290,6 +290,11 @@ extern void ML_(linux_POST_sys_msgctl)     ( TId, UW, UW, UW, UW );
 extern void ML_(linux_PRE_sys_getsockopt)  ( TId, UW, UW, UW, UW, UW );
 extern void ML_(linux_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW );
 
+// Linux-specific (but non-arch-specific) ptrace wrapper helpers
+extern void ML_(linux_PRE_getregset) ( ThreadId, long, long );
+extern void ML_(linux_PRE_setregset) ( ThreadId, long, long );
+extern void ML_(linux_POST_getregset)( ThreadId, long, long );
+
 #undef TId
 #undef UW
 #undef SR
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index cec1c20..18bb548 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -7230,6 +7230,46 @@ ML_(linux_POST_sys_getsockopt) ( ThreadId tid,
    }
 }
 
+/* ---------------------------------------------------------------------
+   ptrace wrapper helpers
+   ------------------------------------------------------------------ */
+
+void
+ML_(linux_PRE_getregset) ( ThreadId tid, long arg3, long arg4 )
+{
+   struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+   PRE_MEM_READ("ptrace(getregset iovec->iov_base)",
+		(unsigned long) &iov->iov_base, sizeof(iov->iov_base));
+   PRE_MEM_READ("ptrace(getregset iovec->iov_len)",
+		(unsigned long) &iov->iov_len, sizeof(iov->iov_len));
+   PRE_MEM_WRITE("ptrace(getregset *(iovec->iov_base))",
+		 (unsigned long) iov->iov_base, iov->iov_len);
+}
+
+void
+ML_(linux_PRE_setregset) ( ThreadId tid, long arg3, long arg4 )
+{
+   struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+   PRE_MEM_READ("ptrace(setregset iovec->iov_base)",
+		(unsigned long) &iov->iov_base, sizeof(iov->iov_base));
+   PRE_MEM_READ("ptrace(setregset iovec->iov_len)",
+		(unsigned long) &iov->iov_len, sizeof(iov->iov_len));
+   PRE_MEM_READ("ptrace(setregset *(iovec->iov_base))",
+		(unsigned long) iov->iov_base, iov->iov_len);
+}
+
+void
+ML_(linux_POST_getregset) ( ThreadId tid, long arg3, long arg4 )
+{
+   struct vki_iovec *iov = (struct vki_iovec *) arg4;
+
+   /* XXX: The actual amount of data written by the kernel might be
+      less than iov_len, depending on the regset (arg3). */
+   POST_MEM_WRITE((unsigned long) iov->iov_base, iov->iov_len);
+}
+
 #undef PRE
 #undef POST
 
diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c
index 10d83e7..84c2f29 100644
--- a/coregrind/m_syswrap/syswrap-s390x-linux.c
+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c
@@ -345,10 +345,13 @@ DECL_TEMPLATE(s390x_linux, sys_sigreturn);
 DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
 DECL_TEMPLATE(s390x_linux, sys_fadvise64);
 
-// PEEK TEXT,DATA and USER are common to all architectures
-// PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
-// containing the real addr, data, and len field pointed to by ARG3
-// instead of ARG4
+/* PEEK TEXT,DATA and USER are common to all architectures.
+   PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
+   containing the real addr, data, and len field pointed to by ARG3
+   instead of ARG4.
+   GETREGSET and SETREGSET use a struct iovec (pointed to by ARG4) for
+   the address and size of the user buffer. */
+
 PRE(sys_ptrace)
 {
    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
@@ -404,6 +407,12 @@ PRE(sys_ptrace)
                        pa->vki_process_addr, pa->vki_len);
          break;
       }
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
@@ -432,7 +441,11 @@ POST(sys_ptrace)
 
 	 pa = (vki_ptrace_area *) ARG3;
          POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
+	 break;
       }
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
index 64ba6a4..cee687d 100644
--- a/include/vki/vki-linux.h
+++ b/include/vki/vki-linux.h
@@ -2251,6 +2251,8 @@ typedef __vki_kernel_uid32_t vki_qid_t; /* Type in which we store ids in memory
 #define VKI_PTRACE_GETEVENTMSG	0x4201
 #define VKI_PTRACE_GETSIGINFO	0x4202
 #define VKI_PTRACE_SETSIGINFO	0x4203
+#define VKI_PTRACE_GETREGSET	0x4204
+#define VKI_PTRACE_SETREGSET	0x4205
 
 //----------------------------------------------------------------------
 // From linux-2.6.14/include/sound/asound.h
diff --git a/memcheck/tests/linux/getregset.c b/memcheck/tests/linux/getregset.c
index 70b5ce2..3a67663 100644
--- a/memcheck/tests/linux/getregset.c
+++ b/memcheck/tests/linux/getregset.c
@@ -24,7 +24,7 @@ static int
 non_empty(const char *buf, size_t len)
 {
    size_t i;
-   int c;
+   int c = 0;
    volatile const char *p = buf;
 
    for (i = 0; i != len; i++)

commit b2cd1bc0abb95119df1b9b8e6dcc71e48b828a94
Author: cborntra <cborntra@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Date:   Thu Nov 8 20:27:05 2012 +0000

    also wire up arm, x86 and amd64 regarding ptrace regsets
    original patch from
    Andreas Arnez <arnez AT  linux DOT vnet DOT ibm DOT com>
    
    Seems that ppc and mips dont have ptrace support....
    
    
    
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13113 a5019735-40e9-0310-863c-91ae7b9d1cf9

diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
index 035f7b8..2f2b0a4 100644
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
@@ -617,6 +617,12 @@ PRE(sys_ptrace)
    case VKI_PTRACE_SETSIGINFO:
       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
@@ -645,6 +651,9 @@ POST(sys_ptrace)
        */
       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c
index 27ecc8c..f60d771 100644
--- a/coregrind/m_syswrap/syswrap-arm-linux.c
+++ b/coregrind/m_syswrap/syswrap-arm-linux.c
@@ -1110,6 +1110,12 @@ PRE(sys_ptrace)
    case VKI_PTRACE_SETSIGINFO:
       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
@@ -1149,6 +1155,9 @@ POST(sys_ptrace)
        */
       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
index 8f47efd..b9f94b6 100644
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
@@ -1139,6 +1139,12 @@ PRE(sys_ptrace)
    case VKI_PTRACE_SETSIGINFO:
       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
@@ -1170,6 +1176,9 @@ POST(sys_ptrace)
        */
       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
       break;
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }

commit 49cc754d63a30accef06cd9a18315051b206373c
Author: cborntra <cborntra@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Date:   Fri Nov 9 08:06:14 2012 +0000

    GETREGSET was introduced with 2.6.33.
    
    
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13115 a5019735-40e9-0310-863c-91ae7b9d1cf9

diff --git a/memcheck/tests/linux/getregset.vgtest b/memcheck/tests/linux/getregset.vgtest
index 73f52f7..14be523 100644
--- a/memcheck/tests/linux/getregset.vgtest
+++ b/memcheck/tests/linux/getregset.vgtest
@@ -1,2 +1,4 @@
 prog: getregset
-vgopts: -q
\ No newline at end of file
+vgopts: -q
+prereq: ../../../tests/os_test linux 2.6.33
+
commit a9a475d568840ecdfcc312cc4b02c29e20b81fab
Author: cborntra <cborntra@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Date:   Thu Nov 8 19:46:29 2012 +0000

    wire up testcase
    
    
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13111 a5019735-40e9-0310-863c-91ae7b9d1cf9

diff --git a/memcheck/tests/linux/Makefile.am b/memcheck/tests/linux/Makefile.am
index b59afae..5885ab0 100644
--- a/memcheck/tests/linux/Makefile.am
+++ b/memcheck/tests/linux/Makefile.am
@@ -16,11 +16,13 @@ EXTRA_DIST = \
 	syslog-syscall.vgtest syslog-syscall.stderr.exp \
 	timerfd-syscall.vgtest timerfd-syscall.stderr.exp \
 	with-space.stderr.exp with-space.stdout.exp with-space.vgtest \
-	proc-auxv.vgtest proc-auxv.stderr.exp
+	proc-auxv.vgtest proc-auxv.stderr.exp getregset.vgtest \
+	getregset.stderr.exp getregset.stdout.exp
 
 check_PROGRAMS = \
 	brk \
 	capget \
+	getregset \
 	lsframe1 \
 	lsframe2 \
 	sigqueue \
--- valgrind-3.8.1/memcheck/tests/linux/Makefile.in.orig	2013-02-19 15:22:18.550589954 +0100
+++ valgrind-3.8.1/memcheck/tests/linux/Makefile.in	2013-02-19 15:22:30.941543855 +0100
@@ -54,11 +54,11 @@
 @VGCONF_HAVE_PLATFORM_SEC_TRUE@am__append_2 = -DVGA_SEC_@VGCONF_ARCH_SEC@=1  \
 @VGCONF_HAVE_PLATFORM_SEC_TRUE@		-DVGP_SEC_@VGCONF_ARCH_PRI@_@VGCONF_OS@=1
 
-check_PROGRAMS = brk$(EXEEXT) capget$(EXEEXT) lsframe1$(EXEEXT) \
-	lsframe2$(EXEEXT) sigqueue$(EXEEXT) stack_changes$(EXEEXT) \
-	stack_switch$(EXEEXT) syscalls-2007$(EXEEXT) \
-	syslog-syscall$(EXEEXT) timerfd-syscall$(EXEEXT) \
-	proc-auxv$(EXEEXT)
+check_PROGRAMS = brk$(EXEEXT) capget$(EXEEXT) getregset$(EXEEXT) \
+	lsframe1$(EXEEXT) lsframe2$(EXEEXT) sigqueue$(EXEEXT) \
+	stack_changes$(EXEEXT) stack_switch$(EXEEXT) \
+	syscalls-2007$(EXEEXT) syslog-syscall$(EXEEXT) \
+	timerfd-syscall$(EXEEXT) proc-auxv$(EXEEXT)
 subdir = memcheck/tests/linux
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
@@ -74,6 +74,9 @@
 capget_SOURCES = capget.c
 capget_OBJECTS = capget.$(OBJEXT)
 capget_LDADD = $(LDADD)
+getregset_SOURCES = getregset.c
+getregset_OBJECTS = getregset.$(OBJEXT)
+getregset_LDADD = $(LDADD)
 lsframe1_SOURCES = lsframe1.c
 lsframe1_OBJECTS = lsframe1.$(OBJEXT)
 lsframe1_LDADD = $(LDADD)
@@ -110,12 +113,12 @@
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = brk.c capget.c lsframe1.c lsframe2.c proc-auxv.c sigqueue.c \
-	stack_changes.c stack_switch.c syscalls-2007.c \
-	syslog-syscall.c timerfd-syscall.c
-DIST_SOURCES = brk.c capget.c lsframe1.c lsframe2.c proc-auxv.c \
+SOURCES = brk.c capget.c getregset.c lsframe1.c lsframe2.c proc-auxv.c \
 	sigqueue.c stack_changes.c stack_switch.c syscalls-2007.c \
 	syslog-syscall.c timerfd-syscall.c
+DIST_SOURCES = brk.c capget.c getregset.c lsframe1.c lsframe2.c \
+	proc-auxv.c sigqueue.c stack_changes.c stack_switch.c \
+	syscalls-2007.c syslog-syscall.c timerfd-syscall.c
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -409,7 +412,8 @@
 	syslog-syscall.vgtest syslog-syscall.stderr.exp \
 	timerfd-syscall.vgtest timerfd-syscall.stderr.exp \
 	with-space.stderr.exp with-space.stdout.exp with-space.vgtest \
-	proc-auxv.vgtest proc-auxv.stderr.exp
+	proc-auxv.vgtest proc-auxv.stderr.exp getregset.vgtest \
+	getregset.stderr.exp getregset.stdout.exp
 
 stack_switch_LDADD = -lpthread
 timerfd_syscall_LDADD = -lrt
@@ -456,6 +460,9 @@
 capget$(EXEEXT): $(capget_OBJECTS) $(capget_DEPENDENCIES) 
 	@rm -f capget$(EXEEXT)
 	$(LINK) $(capget_OBJECTS) $(capget_LDADD) $(LIBS)
+getregset$(EXEEXT): $(getregset_OBJECTS) $(getregset_DEPENDENCIES) 
+	@rm -f getregset$(EXEEXT)
+	$(LINK) $(getregset_OBJECTS) $(getregset_LDADD) $(LIBS)
 lsframe1$(EXEEXT): $(lsframe1_OBJECTS) $(lsframe1_DEPENDENCIES) 
 	@rm -f lsframe1$(EXEEXT)
 	$(LINK) $(lsframe1_OBJECTS) $(lsframe1_LDADD) $(LIBS)
@@ -492,6 +499,7 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brk.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/capget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getregset.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsframe1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsframe2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc-auxv.Po@am__quote@