Author: kib
Date: Thu Mar 22 20:44:27 2018
New Revision: 331374
URL: https://svnweb.freebsd.org/changeset/base/331374

Log:
  Fixes for ptrace(PT_GETXSTATE_INFO) related to the padding in struct
  ptrace_xstate_info).
  
  struct ptrace_xstate_info has 64bit member but ends up with 32bit
  one. As result, on amd64 there is a 32bit padding at the end, but not
  on i386.
  
  We must clear the padding before doing the copyout. For compat32 case,
  we must copyout the structure which does not have the padding at the
  end.  The later fixes 32bit gdb display of the YMM registers when
  running on amd64 kernel.
  
  Reported by:  Vlad Tsyrklevich
  Reviewed by:  brooks (previous version)
  Sponsored by: The FreeBSD Foundation
  admbugs:      765
  MFC after:    1 week
  Differential revision:        https://reviews.freebsd.org/D14794

Modified:
  head/sys/amd64/amd64/ptrace_machdep.c

Modified: head/sys/amd64/amd64/ptrace_machdep.c
==============================================================================
--- head/sys/amd64/amd64/ptrace_machdep.c       Thu Mar 22 20:21:05 2018        
(r331373)
+++ head/sys/amd64/amd64/ptrace_machdep.c       Thu Mar 22 20:44:27 2018        
(r331374)
@@ -45,10 +45,20 @@ __FBSDID("$FreeBSD$");
 #include <machine/frame.h>
 #include <machine/vmparam.h>
 
+#ifdef COMPAT_FREEBSD32
+struct ptrace_xstate_info32 {
+       uint32_t        xsave_mask1, xsave_mask2;
+       uint32_t        xsave_len;
+};
+#endif
+
 static int
 cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data)
 {
        struct ptrace_xstate_info info;
+#ifdef COMPAT_FREEBSD32
+       struct ptrace_xstate_info32 info32;
+#endif
        char *savefpu;
        int error;
 
@@ -78,13 +88,28 @@ cpu_ptrace_xstate(struct thread *td, int req, void *ad
                break;
 
        case PT_GETXSTATE_INFO:
-               if (data != sizeof(info)) {
-                       error  = EINVAL;
-                       break;
+#ifdef COMPAT_FREEBSD32
+               if (SV_CURPROC_FLAG(SV_ILP32)) {
+                       if (data != sizeof(info32)) {
+                               error = EINVAL;
+                       } else {
+                               info32.xsave_len = cpu_max_ext_state_size;
+                               info32.xsave_mask1 = xsave_mask;
+                               info32.xsave_mask2 = xsave_mask >> 32;
+                               error = copyout(&info32, addr, data);
+                       }
+               } else
+#endif
+               {
+                       if (data != sizeof(info)) {
+                               error  = EINVAL;
+                       } else {
+                               bzero(&info, sizeof(info));
+                               info.xsave_len = cpu_max_ext_state_size;
+                               info.xsave_mask = xsave_mask;
+                               error = copyout(&info, addr, data);
+                       }
                }
-               info.xsave_len = cpu_max_ext_state_size;
-               info.xsave_mask = xsave_mask;
-               error = copyout(&info, addr, data);
                break;
 
        case PT_GETXSTATE:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to