valgrind/valgrind-3.8.1-ptrace-setgetregset.patch

482 lines
16 KiB
Diff
Raw Normal View History

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@