Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
    usr/src/uts/common/fs/proc/prcontrol.c
    usr/src/uts/intel/os/archdep.c
    usr/src/uts/intel/sys/ucontext.h
    usr/src/uts/intel/syscall/getcontext.c

@@ -26,11 +26,11 @@
  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  * Copyright (c) 2018, Joyent, Inc. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
  * Copyright 2015 Gary Mills
  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2023 Oxide Computer Company
  */
 
 #include <sys/types.h>
 #include <sys/utsname.h>
 #include <sys/sysmacros.h>

@@ -1079,35 +1079,45 @@
         P->nauxv = (int)n;
 
         return (0);
 }
 
-#ifdef __sparc
+/*
+ * The xregs are not a fixed size on all architectures (notably x86) and in
+ * general the prxregset_t has become opaque to deal with this. This means that
+ * validating the note itself can be a little more challenging. Especially as
+ * this can change across time. In this case we require that our consumers
+ * perform this validation right now ala what mdb does before using the xregs
+ * data.
+ */
 static int
 note_xreg(struct ps_prochandle *P, size_t nbytes)
 {
         core_info_t *core = P->data;
         lwp_info_t *lwp = core->core_lwp;
-        size_t xbytes = sizeof (prxregset_t);
         prxregset_t *xregs;
+        ssize_t sret;
 
-        if (lwp == NULL || lwp->lwp_xregs != NULL || nbytes < xbytes)
+        if (lwp == NULL || lwp->lwp_xregs != NULL)
                 return (0);     /* No lwp yet, already seen, or bad size */
 
-        if ((xregs = malloc(xbytes)) == NULL)
+        if ((xregs = malloc(nbytes)) == NULL)
                 return (-1);
 
-        if (read(P->asfd, xregs, xbytes) != xbytes) {
+        sret = read(P->asfd, xregs, nbytes);
+        if (sret < 0 || (size_t)sret != nbytes) {
                 dprintf("Pgrab_core: failed to read NT_PRXREG\n");
                 free(xregs);
                 return (-1);
         }
 
         lwp->lwp_xregs = xregs;
+        lwp->lwp_xregsize = nbytes;
         return (0);
 }
 
+#ifdef __sparc
 static int
 note_gwindows(struct ps_prochandle *P, size_t nbytes)
 {
         core_info_t *core = P->data;
         lwp_info_t *lwp = core->core_lwp;

@@ -1252,15 +1262,11 @@
 #ifdef __x86
         note_linux_psinfo,              /*  3   NT_PRPSINFO (old)       */
 #else
         note_notsup,            /*  3   NT_PRPSINFO (old)       */
 #endif
-#ifdef __sparc
         note_xreg,              /*  4   NT_PRXREG               */
-#else
-        note_notsup,            /*  4   NT_PRXREG               */
-#endif
         note_platform,          /*  5   NT_PLATFORM             */
         note_auxv,              /*  6   NT_AUXV                 */
 #ifdef __sparc
         note_gwindows,          /*  7   NT_GWINDOWS             */
 #ifdef __sparcv9