commit 7be84ee45ccc827a63353868558bed6c824b4a68 Author: cborntra 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 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 Date: Thu Nov 8 20:27:05 2012 +0000 also wire up arm, x86 and amd64 regarding ptrace regsets original patch from Andreas Arnez 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 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 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@