Mark Wielaard 4217db
commit 122225d7ed260f6bd9de4472e5260ec768ce972d
Mark Wielaard 4217db
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard 4217db
Date:   Tue Jun 19 18:26:43 2018 +0200
Mark Wielaard 4217db
Mark Wielaard 4217db
    Implement ptrace syscall wrapper for arm64-linux.
Mark Wielaard 4217db
    
Mark Wielaard 4217db
    With this valgrind is able to run gdb on arm64.
Mark Wielaard 4217db
    Also fixes the memcheck/tests/linux/getregset testcase.
Mark Wielaard 4217db
    
Mark Wielaard 4217db
    https://bugs.kde.org/show_bug.cgi?id=368913
Mark Wielaard 4217db
Mark Wielaard 4217db
diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 4217db
index 32b87bf..24a6493 100644
Mark Wielaard 4217db
--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 4217db
+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
Mark Wielaard 4217db
@@ -265,7 +265,7 @@ DECL_TEMPLATE(arm64_linux, sys_rt_sigreturn);
Mark Wielaard 4217db
 //ZZ DECL_TEMPLATE(arm_linux, sys_sigsuspend);
Mark Wielaard 4217db
 //ZZ DECL_TEMPLATE(arm_linux, sys_set_tls);
Mark Wielaard 4217db
 //ZZ DECL_TEMPLATE(arm_linux, sys_cacheflush);
Mark Wielaard 4217db
-//ZZ DECL_TEMPLATE(arm_linux, sys_ptrace);
Mark Wielaard 4217db
+DECL_TEMPLATE(arm64_linux, sys_ptrace);
Mark Wielaard 4217db
 
Mark Wielaard 4217db
 //ZZ PRE(sys_mmap2)
Mark Wielaard 4217db
 //ZZ {
Mark Wielaard 4217db
@@ -459,137 +459,70 @@ PRE(sys_rt_sigreturn)
Mark Wielaard 4217db
 //ZZ                               "PRE(sys_cacheflush)" );
Mark Wielaard 4217db
 //ZZ    SET_STATUS_Success(0);
Mark Wielaard 4217db
 //ZZ }
Mark Wielaard 4217db
-//ZZ 
Mark Wielaard 4217db
-//ZZ // ARG3 is only used for pointers into the traced process's address
Mark Wielaard 4217db
-//ZZ // space and for offsets into the traced process's struct
Mark Wielaard 4217db
-//ZZ // user_regs_struct. It is never a pointer into this process's memory
Mark Wielaard 4217db
-//ZZ // space, and we should therefore not check anything it points to.
Mark Wielaard 4217db
-//ZZ PRE(sys_ptrace)
Mark Wielaard 4217db
-//ZZ {
Mark Wielaard 4217db
-//ZZ    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
Mark Wielaard 4217db
-//ZZ    PRE_REG_READ4(int, "ptrace", 
Mark Wielaard 4217db
-//ZZ                  long, request, long, pid, long, addr, long, data);
Mark Wielaard 4217db
-//ZZ    switch (ARG1) {
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKDATA:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKUSR:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(peek)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     sizeof (long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     sizeof (struct vki_user_regs_struct));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETFPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     sizeof (struct vki_user_fp));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETWMMXREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     VKI_IWMMXT_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETCRUNCHREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     VKI_CRUNCH_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETVFPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ                      sizeof (struct vki_user_vfp) );
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETHBPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ                      sizeof (unsigned long) );
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     sizeof (struct vki_user_regs_struct));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETFPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     sizeof (struct vki_user_fp));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETWMMXREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     VKI_IWMMXT_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETCRUNCHREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ 		     VKI_CRUNCH_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETVFPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setvfpregs)", ARG4, 
Mark Wielaard 4217db
-//ZZ                      sizeof (struct vki_user_vfp));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETHBPREGS:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GET_THREAD_AREA:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETSIGINFO:
Mark Wielaard 4217db
-//ZZ       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETREGSET:
Mark Wielaard 4217db
-//ZZ       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_SETREGSET:
Mark Wielaard 4217db
-//ZZ       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    default:
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    }
Mark Wielaard 4217db
-//ZZ }
Mark Wielaard 4217db
-//ZZ 
Mark Wielaard 4217db
-//ZZ POST(sys_ptrace)
Mark Wielaard 4217db
-//ZZ {
Mark Wielaard 4217db
-//ZZ    switch (ARG1) {
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKDATA:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_PEEKUSR:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof (long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETREGS:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETFPREGS:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETWMMXREGS:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETCRUNCHREGS:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETVFPREGS:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GET_THREAD_AREA:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETHBPREGS:
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 4217db
-//ZZ       /* XXX: This is a simplification. Different parts of the
Mark Wielaard 4217db
-//ZZ        * siginfo_t are valid depending on the type of signal.
Mark Wielaard 4217db
-//ZZ        */
Mark Wielaard 4217db
-//ZZ       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    case VKI_PTRACE_GETREGSET:
Mark Wielaard 4217db
-//ZZ       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    default:
Mark Wielaard 4217db
-//ZZ       break;
Mark Wielaard 4217db
-//ZZ    }
Mark Wielaard 4217db
-//ZZ }
Mark Wielaard 4217db
-//ZZ 
Mark Wielaard 4217db
-//ZZ #undef PRE
Mark Wielaard 4217db
-//ZZ #undef POST
Mark Wielaard 4217db
+
Mark Wielaard 4217db
+// ARG3 is only used for pointers into the traced process's address
Mark Wielaard 4217db
+// space and for offsets into the traced process's struct
Mark Wielaard 4217db
+// user_regs_struct. It is never a pointer into this process's memory
Mark Wielaard 4217db
+// space, and we should therefore not check anything it points to.
Mark Wielaard 4217db
+PRE(sys_ptrace)
Mark Wielaard 4217db
+{
Mark Wielaard 4217db
+   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
Mark Wielaard 4217db
+   PRE_REG_READ4(int, "ptrace",
Mark Wielaard 4217db
+                 long, request, long, pid, long, addr, long, data);
Mark Wielaard 4217db
+   switch (ARG1) {
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKDATA:
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKUSR:
Mark Wielaard 4217db
+      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
Mark Wielaard 4217db
+		     sizeof (long));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 4217db
+      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 4217db
+      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_SETSIGINFO:
Mark Wielaard 4217db
+      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETREGSET:
Mark Wielaard 4217db
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_SETREGSET:
Mark Wielaard 4217db
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   default:
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   }
Mark Wielaard 4217db
+}
Mark Wielaard 4217db
+
Mark Wielaard 4217db
+POST(sys_ptrace)
Mark Wielaard 4217db
+{
Mark Wielaard 4217db
+   switch (ARG1) {
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKTEXT:
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKDATA:
Mark Wielaard 4217db
+   case VKI_PTRACE_PEEKUSR:
Mark Wielaard 4217db
+      POST_MEM_WRITE( ARG4, sizeof (long));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETEVENTMSG:
Mark Wielaard 4217db
+      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETSIGINFO:
Mark Wielaard 4217db
+      /* XXX: This is a simplification. Different parts of the
Mark Wielaard 4217db
+       * siginfo_t are valid depending on the type of signal.
Mark Wielaard 4217db
+       */
Mark Wielaard 4217db
+      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   case VKI_PTRACE_GETREGSET:
Mark Wielaard 4217db
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   default:
Mark Wielaard 4217db
+      break;
Mark Wielaard 4217db
+   }
Mark Wielaard 4217db
+}
Mark Wielaard 4217db
+
Mark Wielaard 4217db
+#undef PRE
Mark Wielaard 4217db
+#undef POST
Mark Wielaard 4217db
 
Mark Wielaard 4217db
 /* ---------------------------------------------------------------------
Mark Wielaard 4217db
    The arm64/Linux syscall table
Mark Wielaard 4217db
@@ -730,7 +663,7 @@ static SyscallTableEntry syscall_main_table[] = {
Mark Wielaard 4217db
    LINXY(__NR_clock_getres,      sys_clock_getres),      // 114
Mark Wielaard 4217db
    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 115
Mark Wielaard 4217db
    LINXY(__NR_syslog,            sys_syslog),            // 116
Mark Wielaard 4217db
-   //   (__NR_ptrace,            sys_ptrace),            // 117
Mark Wielaard 4217db
+   PLAXY(__NR_ptrace,            sys_ptrace),            // 117
Mark Wielaard 4217db
    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 118
Mark Wielaard 4217db
    LINX_(__NR_sched_setscheduler,sys_sched_setscheduler),// 119
Mark Wielaard 4217db
    LINX_(__NR_sched_getscheduler,sys_sched_getscheduler),// 120