Mark Wielaard 87fefb
commit 3967a99c26e8b314634a6b1fd8927cbb2bb5d060
Mark Wielaard 87fefb
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard 87fefb
Date:   Wed Dec 12 14:11:29 2018 +0100
Mark Wielaard 87fefb
Mark Wielaard 87fefb
    Implement minimal ptrace support for ppc64[le]-linux.
Mark Wielaard 87fefb
Mark Wielaard 87fefb
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 87fefb
index 6549dd1..0fdcc8e 100644
Mark Wielaard 87fefb
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 87fefb
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
Mark Wielaard 87fefb
@@ -388,6 +388,7 @@ DECL_TEMPLATE(ppc64_linux, sys_mmap);
Mark Wielaard 87fefb
 //zz DECL_TEMPLATE(ppc64_linux, sys_sigreturn);
Mark Wielaard 87fefb
 DECL_TEMPLATE(ppc64_linux, sys_rt_sigreturn);
Mark Wielaard 87fefb
 DECL_TEMPLATE(ppc64_linux, sys_fadvise64);
Mark Wielaard 87fefb
+DECL_TEMPLATE(ppc64_linux, sys_ptrace);
Mark Wielaard 87fefb
 
Mark Wielaard 87fefb
 PRE(sys_mmap)
Mark Wielaard 87fefb
 {
Mark Wielaard 87fefb
@@ -511,6 +512,72 @@ PRE(sys_rt_sigreturn)
Mark Wielaard 87fefb
    *flags |= SfPollAfter;
Mark Wielaard 87fefb
 }
Mark Wielaard 87fefb
 
Mark Wielaard 87fefb
+// ARG3 is only used for pointers into the traced process's address
Mark Wielaard 87fefb
+// space and for offsets into the traced process's struct
Mark Wielaard 87fefb
+// user_regs_struct. It is never a pointer into this process's memory
Mark Wielaard 87fefb
+// space, and we should therefore not check anything it points to.
Mark Wielaard 87fefb
+// powerpc does have other ways to get/set registers, we only support
Mark Wielaard 87fefb
+// GET/SETREGSET for now.
Mark Wielaard 87fefb
+PRE(sys_ptrace)
Mark Wielaard 87fefb
+{
Mark Wielaard 87fefb
+   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
Mark Wielaard 87fefb
+   PRE_REG_READ4(int, "ptrace",
Mark Wielaard 87fefb
+                 long, request, long, pid, long, addr, long, data);
Mark Wielaard 87fefb
+   switch (ARG1) {
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKDATA:
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKUSR:
Mark Wielaard 87fefb
+      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
Mark Wielaard 87fefb
+                     sizeof (long));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 87fefb
+      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 87fefb
+      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_SETSIGINFO:
Mark Wielaard 87fefb
+      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETREGSET:
Mark Wielaard 87fefb
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_SETREGSET:
Mark Wielaard 87fefb
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   default:
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   }
Mark Wielaard 87fefb
+}
Mark Wielaard 87fefb
+
Mark Wielaard 87fefb
+POST(sys_ptrace)
Mark Wielaard 87fefb
+{
Mark Wielaard 87fefb
+   switch (ARG1) {
Mark Wielaard 87fefb
+   case VKI_PTRACE_TRACEME:
Mark Wielaard 87fefb
+      ML_(linux_POST_traceme)(tid);
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKDATA:
Mark Wielaard 87fefb
+   case VKI_PTRACE_PEEKUSR:
Mark Wielaard 87fefb
+      POST_MEM_WRITE( ARG4, sizeof (long));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 87fefb
+      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 87fefb
+      /* XXX: This is a simplification. Different parts of the
Mark Wielaard 87fefb
+       * siginfo_t are valid depending on the type of signal.
Mark Wielaard 87fefb
+       */
Mark Wielaard 87fefb
+      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   case VKI_PTRACE_GETREGSET:
Mark Wielaard 87fefb
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   default:
Mark Wielaard 87fefb
+      break;
Mark Wielaard 87fefb
+   }
Mark Wielaard 87fefb
+}
Mark Wielaard 87fefb
+
Mark Wielaard 87fefb
 #undef PRE
Mark Wielaard 87fefb
 #undef POST
Mark Wielaard 87fefb
 
Mark Wielaard 87fefb
@@ -562,8 +629,7 @@ static SyscallTableEntry syscall_table[] = {
Mark Wielaard 87fefb
    GENX_(__NR_getuid,            sys_getuid),             //  24
Mark Wielaard 87fefb
 
Mark Wielaard 87fefb
 // _____(__NR_stime,             sys_stime),              //  25
Mark Wielaard 87fefb
-// When ptrace is supported, memcheck/tests/linux/getregset should be enabled
Mark Wielaard 87fefb
-// _____(__NR_ptrace,            sys_ptrace),             //  26
Mark Wielaard 87fefb
+   PLAXY(__NR_ptrace,            sys_ptrace),             //  26
Mark Wielaard 87fefb
    GENX_(__NR_alarm,             sys_alarm),              //  27
Mark Wielaard 87fefb
 // _____(__NR_oldfstat,          sys_oldfstat),           //  28
Mark Wielaard 87fefb
    GENX_(__NR_pause,             sys_pause),              //  29
Mark Wielaard 87fefb
diff --git a/memcheck/tests/linux/getregset.vgtest b/memcheck/tests/linux/getregset.vgtest
Mark Wielaard 87fefb
index 4c66108..c35be4c 100644
Mark Wielaard 87fefb
--- a/memcheck/tests/linux/getregset.vgtest
Mark Wielaard 87fefb
+++ b/memcheck/tests/linux/getregset.vgtest
Mark Wielaard 87fefb
@@ -1,4 +1,4 @@
Mark Wielaard 87fefb
 prog: getregset
Mark Wielaard 87fefb
 vgopts: -q
Mark Wielaard 87fefb
-prereq: ((../../../tests/os_test linux 2.6.33 && ! ../../../tests/arch_test mips32) || ../../../tests/os_test linux 3.10.0 ) && ! ../../../tests/arch_test ppc64
Mark Wielaard 87fefb
+prereq: ((../../../tests/os_test linux 2.6.33 && ! ../../../tests/arch_test mips32) || ../../../tests/os_test linux 3.10.0 )
Mark Wielaard 87fefb